diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2020-08-28 17:27:21 +0300 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2020-08-28 17:27:21 +0300 |
commit | b8cc4b93927929e5898f3270013aa8e03ba96724 (patch) | |
tree | 61c1e5b7d6bb6b49fdc914a5115dd7cd1b17ed5c | |
parent | 8556a10bd9f608ebdbf8d1faf573fc53aa59324a (diff) | |
parent | 7b2fe4c9ec683bb7da270a54c44d301016e1470d (diff) |
Merge branch 'master' into newboolean
33 files changed, 1043 insertions, 663 deletions
diff --git a/intern/cycles/device/opencl/device_opencl_impl.cpp b/intern/cycles/device/opencl/device_opencl_impl.cpp index e851749949d..f0683d12f1f 100644 --- a/intern/cycles/device/opencl/device_opencl_impl.cpp +++ b/intern/cycles/device/opencl/device_opencl_impl.cpp @@ -864,6 +864,11 @@ void OpenCLDevice::load_preview_kernels() bool OpenCLDevice::wait_for_availability(const DeviceRequestedFeatures &requested_features) { + if (requested_features.use_baking) { + /* For baking, kernels have already been loaded in load_required_kernels(). */ + return true; + } + if (background) { load_kernel_task_pool.wait_work(); use_preview_kernels = false; @@ -1933,13 +1938,12 @@ void OpenCLDevice::bake(DeviceTask &task, RenderTile &rtile) kernel_set_args(kernel, start_arg_index, sample); enqueue_kernel(kernel, d_w, d_h); + clFinish(cqCommandQueue); rtile.sample = sample + 1; task.update_progress(&rtile, rtile.w * rtile.h); } - - clFinish(cqCommandQueue); } static bool kernel_build_opencl_2(cl_device_id cdDevice) diff --git a/intern/cycles/kernel/kernels/opencl/kernel_bake.cl b/intern/cycles/kernel/kernels/opencl/kernel_bake.cl index 041312b53cb..7b81e387467 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_bake.cl +++ b/intern/cycles/kernel/kernels/opencl/kernel_bake.cl @@ -12,12 +12,11 @@ __kernel void kernel_ocl_bake( ccl_constant KernelData *data, - ccl_global uint4 *input, - ccl_global float4 *output, + ccl_global float *buffer, KERNEL_BUFFER_PARAMS, - int type, int filter, int sx, int sw, int offset, int sample) + int sx, int sy, int sw, int sh, int offset, int stride, int sample) { KernelGlobals kglobals, *kg = &kglobals; @@ -27,12 +26,11 @@ __kernel void kernel_ocl_bake( kernel_set_buffer_info(kg); int x = sx + ccl_global_id(0); + int y = sy + ccl_global_id(1); - if(x < sx + sw) { -#ifdef __NO_BAKING__ - output[x] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); -#else - kernel_bake_evaluate(kg, input, output, (ShaderEvalType)type, filter, x, offset, sample); + if(x < sx + sw && y < sy + sh) { +#ifndef __NO_BAKING__ + kernel_bake_evaluate(kg, buffer, sample, x, y, offset, stride); #endif } } diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 92bfa3a9490..25360d4b3fa 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -37,6 +37,8 @@ struct BMesh; struct CustomData; struct CustomData_MeshMasks; struct ID; +struct BlendWriter; +struct BlendDataReader; typedef uint64_t CustomDataMask; /*a data type large enough to hold 1 element from any customdata layer type*/ @@ -571,6 +573,14 @@ typedef struct CustomDataTransferLayerMap { void CustomData_data_transfer(const struct MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap); +/* .blend file I/O */ +void CustomData_blend_write(struct BlendWriter *writer, + struct CustomData *data, + int count, + CustomDataMask cddata_mask, + struct ID *id); +void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 35111d5240e..a9f81676a7a 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -35,6 +35,8 @@ struct MLoop; struct MPoly; struct Object; struct bDeformGroup; +struct BlendWriter; +struct BlendDataReader; struct bDeformGroup *BKE_object_defgroup_new(struct Object *ob, const char *name); void BKE_defgroup_copy_list(struct ListBase *lb1, const struct ListBase *lb2); @@ -162,6 +164,11 @@ void BKE_defvert_extract_vgroup_to_polyweights(struct MDeformVert *dvert, void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight); +void BKE_defvert_blend_write(struct BlendWriter *writer, int count, struct MDeformVert *dvlist); +void BKE_defvert_blend_read(struct BlendDataReader *reader, + int count, + struct MDeformVert *mdverts); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h index a2cbe537349..7768e903ac3 100644 --- a/source/blender/blenkernel/BKE_lib_id.h +++ b/source/blender/blenkernel/BKE_lib_id.h @@ -59,6 +59,8 @@ struct Main; struct PointerRNA; struct PropertyRNA; struct bContext; +struct BlendWriter; +struct BlendDataReader; size_t BKE_libblock_get_alloc_info(short type, const char **name); void *BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT; @@ -285,6 +287,8 @@ bool BKE_id_is_in_global_main(struct ID *id); void BKE_id_ordered_list(struct ListBase *ordered_lb, const struct ListBase *lb); void BKE_id_reorder(const struct ListBase *lb, struct ID *id, struct ID *relative, bool after); +void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id); + #define IS_TAGGED(_id) ((_id) && (((ID *)_id)->tag & LIB_TAG_DOIT)) #ifdef __cplusplus diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h index c2059144388..ae1e437cd60 100644 --- a/source/blender/blenkernel/BKE_rigidbody.h +++ b/source/blender/blenkernel/BKE_rigidbody.h @@ -143,6 +143,7 @@ void BKE_rigidbody_aftertrans_update(struct Object *ob, float rotAngle); void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime); bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime); +bool BKE_rigidbody_is_affected_by_simulation(struct Object *ob); void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw); void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, struct Scene *scene, float ctime); void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, struct Scene *scene, float ctime); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index f728436a759..b75efb6cdf1 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -35,6 +35,8 @@ #include "DNA_meshdata_types.h" #include "DNA_pointcloud_types.h" +#include "BLI_bitmap.h" +#include "BLI_endian_switch.h" #include "BLI_math.h" #include "BLI_math_color_blend.h" #include "BLI_mempool.h" @@ -47,10 +49,14 @@ #include "BKE_customdata.h" #include "BKE_customdata_file.h" +#include "BKE_deform.h" #include "BKE_main.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_remap.h" #include "BKE_multires.h" +#include "BKE_subsurf.h" + +#include "BLO_read_write.h" #include "bmesh.h" @@ -5155,3 +5161,181 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap, MEM_SAFE_FREE(tmp_data_src); } + +static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external) +{ + if (mdlist) { + BLO_write_struct_array(writer, MDisps, count, mdlist); + for (int i = 0; i < count; i++) { + MDisps *md = &mdlist[i]; + if (md->disps) { + if (!external) { + BLO_write_float3_array(writer, md->totdisp, &md->disps[0][0]); + } + } + + if (md->hidden) { + BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden); + } + } + } +} + +static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask) +{ + if (grid_paint_mask) { + BLO_write_struct_array(writer, GridPaintMask, count, grid_paint_mask); + for (int i = 0; i < count; i++) { + GridPaintMask *gpm = &grid_paint_mask[i]; + if (gpm->data) { + const int gridsize = BKE_ccg_gridsize(gpm->level); + BLO_write_raw(writer, sizeof(*gpm->data) * gridsize * gridsize, gpm->data); + } + } + } +} + +void CustomData_blend_write( + BlendWriter *writer, CustomData *data, int count, CustomDataMask cddata_mask, ID *id) +{ + CustomDataLayer *layers = NULL; + CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE]; + CustomData_file_write_prepare(data, &layers, layers_buff, ARRAY_SIZE(layers_buff)); + + /* write external customdata (not for undo) */ + if (data->external && !BLO_write_is_undo(writer)) { + CustomData_external_write(data, id, cddata_mask, count, 0); + } + + BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers); + + for (int i = 0; i < data->totlayer; i++) { + CustomDataLayer *layer = &layers[i]; + + if (layer->type == CD_MDEFORMVERT) { + /* layer types that allocate own memory need special handling */ + BKE_defvert_blend_write(writer, count, layer->data); + } + else if (layer->type == CD_MDISPS) { + write_mdisps(writer, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); + } + else if (layer->type == CD_PAINT_MASK) { + const float *layer_data = layer->data; + BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); + } + else if (layer->type == CD_SCULPT_FACE_SETS) { + const float *layer_data = layer->data; + BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); + } + else if (layer->type == CD_GRID_PAINT_MASK) { + write_grid_paint_mask(writer, count, layer->data); + } + else if (layer->type == CD_FACEMAP) { + const int *layer_data = layer->data; + BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); + } + else { + const char *structname; + int structnum; + CustomData_file_write_info(layer->type, &structname, &structnum); + if (structnum) { + int datasize = structnum * count; + BLO_write_struct_array_by_name(writer, structname, datasize, layer->data); + } + else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */ + printf("%s error: layer '%s':%d - can't be written to file\n", + __func__, + structname, + layer->type); + } + } + } + + if (data->external) { + BLO_write_struct(writer, CustomDataExternal, data->external); + } + + if (!ELEM(layers, NULL, layers_buff)) { + MEM_freeN(layers); + } +} + +static void blend_read_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external) +{ + if (mdisps) { + for (int i = 0; i < count; i++) { + BLO_read_data_address(reader, &mdisps[i].disps); + BLO_read_data_address(reader, &mdisps[i].hidden); + + if (mdisps[i].totdisp && !mdisps[i].level) { + /* this calculation is only correct for loop mdisps; + * if loading pre-BMesh face mdisps this will be + * overwritten with the correct value in + * bm_corners_to_loops() */ + float gridsize = sqrtf(mdisps[i].totdisp); + mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1; + } + + if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) { + /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */ + /* this does swap for data written at write_mdisps() - readfile.c */ + BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3); + } + if (!external && !mdisps[i].disps) { + mdisps[i].totdisp = 0; + } + } + } +} + +static void blend_read_paint_mask(BlendDataReader *reader, + int count, + GridPaintMask *grid_paint_mask) +{ + if (grid_paint_mask) { + for (int i = 0; i < count; i++) { + GridPaintMask *gpm = &grid_paint_mask[i]; + if (gpm->data) { + BLO_read_data_address(reader, &gpm->data); + } + } + } +} + +void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count) +{ + BLO_read_data_address(reader, &data->layers); + + /* annoying workaround for bug [#31079] loading legacy files with + * no polygons _but_ have stale customdata */ + if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) { + CustomData_reset(data); + return; + } + + BLO_read_data_address(reader, &data->external); + + int i = 0; + while (i < data->totlayer) { + CustomDataLayer *layer = &data->layers[i]; + + if (layer->flag & CD_FLAG_EXTERNAL) { + layer->flag &= ~CD_FLAG_IN_MEMORY; + } + + layer->flag &= ~CD_FLAG_NOFREE; + + if (CustomData_verify_versions(data, i)) { + BLO_read_data_address(reader, &layer->data); + if (layer->type == CD_MDISPS) { + blend_read_mdisps(reader, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); + } + else if (layer->type == CD_GRID_PAINT_MASK) { + blend_read_paint_mask(reader, count, layer->data); + } + i++; + } + } + + CustomData_update_typemap(data); +} diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 1a32deac776..4f5a2740ca6 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -50,6 +50,8 @@ #include "BKE_object.h" #include "BKE_object_deform.h" +#include "BLO_read_write.h" + #include "data_transfer_intern.h" bDeformGroup *BKE_object_defgroup_new(Object *ob, const char *name) @@ -1523,3 +1525,49 @@ void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name .blend file I/O + * \{ */ + +void BKE_defvert_blend_write(BlendWriter *writer, int count, MDeformVert *dvlist) +{ + if (dvlist == NULL) { + return; + } + + /* Write the dvert list */ + BLO_write_struct_array(writer, MDeformVert, count, dvlist); + + /* Write deformation data for each dvert */ + for (int i = 0; i < count; i++) { + if (dvlist[i].dw) { + BLO_write_struct_array(writer, MDeformWeight, dvlist[i].totweight, dvlist[i].dw); + } + } +} + +void BKE_defvert_blend_read(BlendDataReader *reader, int count, MDeformVert *mdverts) +{ + if (mdverts == NULL) { + return; + } + + for (int i = count; i > 0; i--, mdverts++) { + /*convert to vgroup allocation system*/ + MDeformWeight *dw; + if (mdverts->dw && (dw = BLO_read_get_new_data_address(reader, mdverts->dw))) { + const ssize_t dw_len = mdverts->totweight * sizeof(MDeformWeight); + void *dw_tmp = MEM_mallocN(dw_len, __func__); + memcpy(dw_tmp, dw, dw_len); + mdverts->dw = dw_tmp; + MEM_freeN(dw); + } + else { + mdverts->dw = NULL; + mdverts->totweight = 0; + } + } +} + +/** \} */ diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 5782fab905f..7304dd91eea 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -35,6 +35,9 @@ #include "BLT_translation.h" +/* Allow using deprecated functionality for .blend file I/O. */ +#define DNA_DEPRECATED_ALLOW + #include "DNA_curve_types.h" #include "DNA_defaults.h" #include "DNA_key_types.h" @@ -43,7 +46,9 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_anim_data.h" #include "BKE_curve.h" +#include "BKE_deform.h" #include "BKE_displist.h" #include "BKE_idtype.h" #include "BKE_lattice.h" @@ -53,10 +58,10 @@ #include "BKE_modifier.h" #include "BKE_object.h" -#include "BKE_deform.h" - #include "DEG_depsgraph_query.h" +#include "BLO_read_write.h" + static void lattice_init_data(ID *id) { Lattice *lattice = (Lattice *)id; @@ -124,6 +129,59 @@ static void lattice_foreach_id(ID *id, LibraryForeachIDData *data) BKE_LIB_FOREACHID_PROCESS(data, lattice->key, IDWALK_CB_USER); } +static void lattice_blend_write(BlendWriter *writer, ID *id, const void *id_address) +{ + Lattice *lt = (Lattice *)id; + if (lt->id.us > 0 || BLO_write_is_undo(writer)) { + /* Clean up, important in undo case to reduce false detection of changed datablocks. */ + lt->editlatt = NULL; + lt->batch_cache = NULL; + + /* write LibData */ + BLO_write_id_struct(writer, Lattice, id_address, <->id); + BKE_id_blend_write(writer, <->id); + + /* write animdata */ + if (lt->adt) { + BKE_animdata_blend_write(writer, lt->adt); + } + + /* direct data */ + BLO_write_struct_array(writer, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def); + + BKE_defvert_blend_write(writer, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert); + } +} + +static void lattice_blend_read_data(BlendDataReader *reader, ID *id) +{ + Lattice *lt = (Lattice *)id; + BLO_read_data_address(reader, <->def); + + BLO_read_data_address(reader, <->dvert); + BKE_defvert_blend_read(reader, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert); + + lt->editlatt = NULL; + lt->batch_cache = NULL; + + BLO_read_data_address(reader, <->adt); + BKE_animdata_blend_read_data(reader, lt->adt); +} + +static void lattice_blend_read_lib(BlendLibReader *reader, ID *id) +{ + Lattice *lt = (Lattice *)id; + BLO_read_id_address(reader, lt->id.lib, <->ipo); // XXX deprecated - old animation system + BLO_read_id_address(reader, lt->id.lib, <->key); +} + +static void lattice_blend_read_expand(BlendExpander *expander, ID *id) +{ + Lattice *lt = (Lattice *)id; + BLO_expand(expander, lt->ipo); // XXX deprecated - old animation system + BLO_expand(expander, lt->key); +} + IDTypeInfo IDType_ID_LT = { .id_code = ID_LT, .id_filter = FILTER_ID_LT, @@ -141,10 +199,10 @@ IDTypeInfo IDType_ID_LT = { .foreach_id = lattice_foreach_id, .foreach_cache = NULL, - .blend_write = NULL, - .blend_read_data = NULL, - .blend_read_lib = NULL, - .blend_read_expand = NULL, + .blend_write = lattice_blend_write, + .blend_read_data = lattice_blend_read_data, + .blend_read_lib = lattice_blend_read_lib, + .blend_read_expand = lattice_blend_read_expand, }; int BKE_lattice_index_from_uvw(Lattice *lt, const int u, const int v, const int w) diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index 7fb19458eec..678f717efe4 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -75,6 +75,8 @@ #include "RNA_access.h" +#include "BLO_read_write.h" + #include "atomic_ops.h" //#define DEBUG_TIME @@ -2326,3 +2328,30 @@ void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after) *id_order = relative_order - 1; } } + +void BKE_id_blend_write(BlendWriter *writer, ID *id) +{ + /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */ + if (id->properties && !ELEM(GS(id->name), ID_WM)) { + IDP_BlendWrite(writer, id->properties); + } + + if (id->override_library) { + BLO_write_struct(writer, IDOverrideLibrary, id->override_library); + + BLO_write_struct_list(writer, IDOverrideLibraryProperty, &id->override_library->properties); + LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { + BLO_write_string(writer, op->rna_path); + + BLO_write_struct_list(writer, IDOverrideLibraryPropertyOperation, &op->operations); + LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if (opop->subitem_reference_name) { + BLO_write_string(writer, opop->subitem_reference_name); + } + if (opop->subitem_local_name) { + BLO_write_string(writer, opop->subitem_local_name); + } + } + } + } +} diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index cca312270bc..e9244c5af73 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -1685,6 +1685,20 @@ void BKE_lib_override_library_update(Main *bmain, ID *local) /* XXX And crashing in complex cases (e.g. because depsgraph uses same data...). */ BKE_id_free_ex(bmain, tmp_id, LIB_ID_FREE_NO_UI_USER, true); + if (GS(local->name) == ID_AR) { + /* Funtime again, thanks to bone pointers in pose data of objects. We keep same ID addresses, + * but internal data has changed for sure, so we need to invalidate posebones caches. */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + if (ob->pose != NULL && ob->data == local) { + BLI_assert(ob->type == OB_ARMATURE); + ob->pose->flag |= POSE_RECALC; + /* We need to clear pose bone pointers immediately, some code may access those before pose + * is actually recomputed, which can lead to segfault. */ + BKE_pose_clear_pointers(ob->pose); + } + } + } + if (local->override_library->storage) { /* We know this datablock is not used anywhere besides local->override->storage. */ /* XXX For until we get fully shadow copies, we still need to ensure storage releases diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c index d4246056efe..c88513ec2af 100644 --- a/source/blender/blenkernel/intern/lib_remap.c +++ b/source/blender/blenkernel/intern/lib_remap.c @@ -244,17 +244,17 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data) ID *old_id = r_id_remap_data->old_id; if (!old_id || GS(old_id->name) == ID_AR) { Object *ob = (Object *)r_id_remap_data->id_owner; - /* Object's pose holds reference to armature bones... sic */ - /* Note that in theory, we should have to bother about - * linked/non-linked/never-null/etc. flags/states. + /* Object's pose holds reference to armature bones. sic */ + /* Note that in theory, we should have to bother about linked/non-linked/never-null/etc. + * flags/states. * Fortunately, this is just a tag, so we can accept to 'over-tag' a bit for pose recalc, * and avoid another complex and risky condition nightmare like the one we have in - * foreach_libblock_remap_callback()... */ + * foreach_libblock_remap_callback(). */ if (ob->pose && (!old_id || ob->data == old_id)) { BLI_assert(ob->type == OB_ARMATURE); ob->pose->flag |= POSE_RECALC; - /* We need to clear pose bone pointers immediately, things like undo writefile may be - * called before pose is actually recomputed, can lead to segfault... */ + /* We need to clear pose bone pointers immediately, some code may access those before + * pose is actually recomputed, which can lead to segfault. */ BKE_pose_clear_pointers(ob->pose); } } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index b6e77c100f0..a7568bcd6ea 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -23,6 +23,9 @@ #include "MEM_guardedalloc.h" +/* Allow using deprecated functionality for .blend file I/O. */ +#define DNA_DEPRECATED_ALLOW + #include "DNA_defaults.h" #include "DNA_key_types.h" #include "DNA_material_types.h" @@ -32,6 +35,7 @@ #include "BLI_bitmap.h" #include "BLI_edgehash.h" +#include "BLI_endian_switch.h" #include "BLI_ghash.h" #include "BLI_hash.h" #include "BLI_linklist.h" @@ -43,6 +47,7 @@ #include "BLT_translation.h" #include "BKE_anim_data.h" +#include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_idtype.h" @@ -63,6 +68,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "BLO_read_write.h" + static void mesh_clear_geometry(Mesh *mesh); static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata); @@ -163,6 +170,158 @@ static void mesh_foreach_id(ID *id, LibraryForeachIDData *data) } } +static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address) +{ + Mesh *mesh = (Mesh *)id; + if (mesh->id.us > 0 || BLO_write_is_undo(writer)) { + /* cache only - don't write */ + mesh->mface = NULL; + mesh->totface = 0; + memset(&mesh->fdata, 0, sizeof(mesh->fdata)); + memset(&mesh->runtime, 0, sizeof(mesh->runtime)); + + BLO_write_id_struct(writer, Mesh, id_address, &mesh->id); + BKE_id_blend_write(writer, &mesh->id); + + /* direct data */ + if (mesh->adt) { + BKE_animdata_blend_write(writer, mesh->adt); + } + + BLO_write_pointer_array(writer, mesh->totcol, mesh->mat); + BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect); + + CustomData_blend_write(writer, &mesh->vdata, mesh->totvert, CD_MASK_MESH.vmask, &mesh->id); + CustomData_blend_write(writer, &mesh->edata, mesh->totedge, CD_MASK_MESH.emask, &mesh->id); + /* fdata is really a dummy - written so slots align */ + CustomData_blend_write(writer, &mesh->fdata, mesh->totface, CD_MASK_MESH.fmask, &mesh->id); + CustomData_blend_write(writer, &mesh->ldata, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id); + CustomData_blend_write(writer, &mesh->pdata, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id); + } +} + +static void mesh_blend_read_data(BlendDataReader *reader, ID *id) +{ + Mesh *mesh = (Mesh *)id; + BLO_read_pointer_array(reader, (void **)&mesh->mat); + + BLO_read_data_address(reader, &mesh->mvert); + BLO_read_data_address(reader, &mesh->medge); + BLO_read_data_address(reader, &mesh->mface); + BLO_read_data_address(reader, &mesh->mloop); + BLO_read_data_address(reader, &mesh->mpoly); + BLO_read_data_address(reader, &mesh->tface); + BLO_read_data_address(reader, &mesh->mtface); + BLO_read_data_address(reader, &mesh->mcol); + BLO_read_data_address(reader, &mesh->dvert); + BLO_read_data_address(reader, &mesh->mloopcol); + BLO_read_data_address(reader, &mesh->mloopuv); + BLO_read_data_address(reader, &mesh->mselect); + + /* animdata */ + BLO_read_data_address(reader, &mesh->adt); + BKE_animdata_blend_read_data(reader, mesh->adt); + + /* Normally BKE_defvert_blend_read should be called in CustomData_blend_read, + * but for backwards compatibility in do_versions to work we do it here. */ + BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert); + + CustomData_blend_read(reader, &mesh->vdata, mesh->totvert); + CustomData_blend_read(reader, &mesh->edata, mesh->totedge); + CustomData_blend_read(reader, &mesh->fdata, mesh->totface); + CustomData_blend_read(reader, &mesh->ldata, mesh->totloop); + CustomData_blend_read(reader, &mesh->pdata, mesh->totpoly); + + mesh->texflag &= ~ME_AUTOSPACE_EVALUATED; + mesh->edit_mesh = NULL; + BKE_mesh_runtime_reset(mesh); + + /* happens with old files */ + if (mesh->mselect == NULL) { + mesh->totselect = 0; + } + + /* Multires data */ + BLO_read_data_address(reader, &mesh->mr); + if (mesh->mr) { + BLO_read_list(reader, &mesh->mr->levels); + MultiresLevel *lvl = mesh->mr->levels.first; + + CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert); + BKE_defvert_blend_read( + reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT)); + CustomData_blend_read(reader, &mesh->mr->fdata, lvl->totface); + + BLO_read_data_address(reader, &mesh->mr->edge_flags); + BLO_read_data_address(reader, &mesh->mr->edge_creases); + + BLO_read_data_address(reader, &mesh->mr->verts); + + /* If mesh has the same number of vertices as the + * highest multires level, load the current mesh verts + * into multires and discard the old data. Needed + * because some saved files either do not have a verts + * array, or the verts array contains out-of-date + * data. */ + if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) { + if (mesh->mr->verts) { + MEM_freeN(mesh->mr->verts); + } + mesh->mr->verts = MEM_dupallocN(mesh->mvert); + } + + for (; lvl; lvl = lvl->next) { + BLO_read_data_address(reader, &lvl->verts); + BLO_read_data_address(reader, &lvl->faces); + BLO_read_data_address(reader, &lvl->edges); + BLO_read_data_address(reader, &lvl->colfaces); + } + } + + /* if multires is present but has no valid vertex data, + * there's no way to recover it; silently remove multires */ + if (mesh->mr && !mesh->mr->verts) { + multires_free(mesh->mr); + mesh->mr = NULL; + } + + if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) { + TFace *tf = mesh->tface; + for (int i = 0; i < mesh->totface; i++, tf++) { + BLI_endian_switch_uint32_array(tf->col, 4); + } + } +} + +static void mesh_blend_read_lib(BlendLibReader *reader, ID *id) +{ + Mesh *me = (Mesh *)id; + /* this check added for python created meshes */ + if (me->mat) { + for (int i = 0; i < me->totcol; i++) { + BLO_read_id_address(reader, me->id.lib, &me->mat[i]); + } + } + else { + me->totcol = 0; + } + + BLO_read_id_address(reader, me->id.lib, &me->ipo); // XXX: deprecated: old anim sys + BLO_read_id_address(reader, me->id.lib, &me->key); + BLO_read_id_address(reader, me->id.lib, &me->texcomesh); +} + +static void mesh_read_expand(BlendExpander *expander, ID *id) +{ + Mesh *me = (Mesh *)id; + for (int a = 0; a < me->totcol; a++) { + BLO_expand(expander, me->mat[a]); + } + + BLO_expand(expander, me->key); + BLO_expand(expander, me->texcomesh); +} + IDTypeInfo IDType_ID_ME = { .id_code = ID_ME, .id_filter = FILTER_ID_ME, @@ -180,10 +339,10 @@ IDTypeInfo IDType_ID_ME = { .foreach_id = mesh_foreach_id, .foreach_cache = NULL, - .blend_write = NULL, - .blend_read_data = NULL, - .blend_read_lib = NULL, - .blend_read_expand = NULL, + .blend_write = mesh_blend_write, + .blend_read_data = mesh_blend_read_data, + .blend_read_lib = mesh_blend_read_lib, + .blend_read_expand = mesh_read_expand, }; enum { diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index ece7d0f9136..95a8b3b3c15 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -229,6 +229,23 @@ void BKE_rigidbody_free_constraint(Object *ob) ob->rigidbody_constraint = NULL; } +bool BKE_rigidbody_is_affected_by_simulation(Object *ob) +{ + /* Check if the object will have its transform changed by the rigidbody simulation. */ + + /* True if the shape of this object's parent is of type compound */ + bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL && + ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND); + + RigidBodyOb *rbo = ob->rigidbody_object; + if (rbo == NULL || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE || + obCompoundParent) { + return false; + } + + return true; +} + #ifdef WITH_BULLET /* Copying Methods --------------------- */ @@ -1904,18 +1921,13 @@ bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) /* Sync rigid body and object transformations */ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) { - RigidBodyOb *rbo = ob->rigidbody_object; - - /* True if the shape of this object's parent is of type compound */ - bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL && - ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND); - - /* keep original transform for kinematic and passive objects */ - if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE || - obCompoundParent) { + if (!BKE_rigidbody_is_affected_by_simulation(ob)) { + /* Don't sync transforms for objects that are not affected/changed by the simulation. */ return; } + RigidBodyOb *rbo = ob->rigidbody_object; + /* use rigid body transform after cache start frame if objects is not being transformed */ if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->base_flag & BASE_SELECTED && G.moving & G_TRANSFORM_OBJ)) { @@ -1941,8 +1953,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) void BKE_rigidbody_aftertrans_update( Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) { + bool correct_delta = BKE_rigidbody_is_affected_by_simulation(ob); RigidBodyOb *rbo = ob->rigidbody_object; - bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE); /* return rigid body and object to their initial states */ copy_v3_v3(rbo->pos, ob->loc); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c24db724222..aec5a254750 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -120,6 +120,7 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_curveprofile.h" +#include "BKE_deform.h" #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_fcurve_driver.h" @@ -4108,245 +4109,6 @@ static void direct_link_particlesystems(BlendDataReader *reader, ListBase *parti /** \name Read ID: Mesh * \{ */ -static void lib_link_mesh(BlendLibReader *reader, Mesh *me) -{ - /* this check added for python created meshes */ - if (me->mat) { - for (int i = 0; i < me->totcol; i++) { - BLO_read_id_address(reader, me->id.lib, &me->mat[i]); - } - } - else { - me->totcol = 0; - } - - BLO_read_id_address(reader, me->id.lib, &me->ipo); // XXX: deprecated: old anim sys - BLO_read_id_address(reader, me->id.lib, &me->key); - BLO_read_id_address(reader, me->id.lib, &me->texcomesh); -} - -static void direct_link_dverts(BlendDataReader *reader, int count, MDeformVert *mdverts) -{ - if (mdverts == NULL) { - return; - } - - for (int i = count; i > 0; i--, mdverts++) { - /*convert to vgroup allocation system*/ - MDeformWeight *dw; - if (mdverts->dw && (dw = BLO_read_get_new_data_address(reader, mdverts->dw))) { - const ssize_t dw_len = mdverts->totweight * sizeof(MDeformWeight); - void *dw_tmp = MEM_mallocN(dw_len, "direct_link_dverts"); - memcpy(dw_tmp, dw, dw_len); - mdverts->dw = dw_tmp; - MEM_freeN(dw); - } - else { - mdverts->dw = NULL; - mdverts->totweight = 0; - } - } -} - -static void direct_link_mdisps(BlendDataReader *reader, int count, MDisps *mdisps, int external) -{ - if (mdisps) { - for (int i = 0; i < count; i++) { - BLO_read_data_address(reader, &mdisps[i].disps); - BLO_read_data_address(reader, &mdisps[i].hidden); - - if (mdisps[i].totdisp && !mdisps[i].level) { - /* this calculation is only correct for loop mdisps; - * if loading pre-BMesh face mdisps this will be - * overwritten with the correct value in - * bm_corners_to_loops() */ - float gridsize = sqrtf(mdisps[i].totdisp); - mdisps[i].level = (int)(logf(gridsize - 1.0f) / (float)M_LN2) + 1; - } - - if (BLO_read_requires_endian_switch(reader) && (mdisps[i].disps)) { - /* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */ - /* this does swap for data written at write_mdisps() - readfile.c */ - BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3); - } - if (!external && !mdisps[i].disps) { - mdisps[i].totdisp = 0; - } - } - } -} - -static void direct_link_grid_paint_mask(BlendDataReader *reader, - int count, - GridPaintMask *grid_paint_mask) -{ - if (grid_paint_mask) { - for (int i = 0; i < count; i++) { - GridPaintMask *gpm = &grid_paint_mask[i]; - if (gpm->data) { - BLO_read_data_address(reader, &gpm->data); - } - } - } -} - -/*this isn't really a public api function, so prototyped here*/ -static void direct_link_customdata(BlendDataReader *reader, CustomData *data, int count) -{ - - BLO_read_data_address(reader, &data->layers); - - /* annoying workaround for bug [#31079] loading legacy files with - * no polygons _but_ have stale customdata */ - if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) { - CustomData_reset(data); - return; - } - - BLO_read_data_address(reader, &data->external); - - int i = 0; - while (i < data->totlayer) { - CustomDataLayer *layer = &data->layers[i]; - - if (layer->flag & CD_FLAG_EXTERNAL) { - layer->flag &= ~CD_FLAG_IN_MEMORY; - } - - layer->flag &= ~CD_FLAG_NOFREE; - - if (CustomData_verify_versions(data, i)) { - BLO_read_data_address(reader, &layer->data); - if (layer->type == CD_MDISPS) { - direct_link_mdisps(reader, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); - } - else if (layer->type == CD_GRID_PAINT_MASK) { - direct_link_grid_paint_mask(reader, count, layer->data); - } - i++; - } - } - - CustomData_update_typemap(data); -} - -static void direct_link_mesh(BlendDataReader *reader, Mesh *mesh) -{ - BLO_read_pointer_array(reader, (void **)&mesh->mat); - - BLO_read_data_address(reader, &mesh->mvert); - BLO_read_data_address(reader, &mesh->medge); - BLO_read_data_address(reader, &mesh->mface); - BLO_read_data_address(reader, &mesh->mloop); - BLO_read_data_address(reader, &mesh->mpoly); - BLO_read_data_address(reader, &mesh->tface); - BLO_read_data_address(reader, &mesh->mtface); - BLO_read_data_address(reader, &mesh->mcol); - BLO_read_data_address(reader, &mesh->dvert); - BLO_read_data_address(reader, &mesh->mloopcol); - BLO_read_data_address(reader, &mesh->mloopuv); - BLO_read_data_address(reader, &mesh->mselect); - - /* animdata */ - BLO_read_data_address(reader, &mesh->adt); - BKE_animdata_blend_read_data(reader, mesh->adt); - - /* Normally direct_link_dverts should be called in direct_link_customdata, - * but for backwards compatibility in do_versions to work we do it here. */ - direct_link_dverts(reader, mesh->totvert, mesh->dvert); - - direct_link_customdata(reader, &mesh->vdata, mesh->totvert); - direct_link_customdata(reader, &mesh->edata, mesh->totedge); - direct_link_customdata(reader, &mesh->fdata, mesh->totface); - direct_link_customdata(reader, &mesh->ldata, mesh->totloop); - direct_link_customdata(reader, &mesh->pdata, mesh->totpoly); - - mesh->texflag &= ~ME_AUTOSPACE_EVALUATED; - mesh->edit_mesh = NULL; - BKE_mesh_runtime_reset(mesh); - - /* happens with old files */ - if (mesh->mselect == NULL) { - mesh->totselect = 0; - } - - /* Multires data */ - BLO_read_data_address(reader, &mesh->mr); - if (mesh->mr) { - BLO_read_list(reader, &mesh->mr->levels); - MultiresLevel *lvl = mesh->mr->levels.first; - - direct_link_customdata(reader, &mesh->mr->vdata, lvl->totvert); - direct_link_dverts(reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT)); - direct_link_customdata(reader, &mesh->mr->fdata, lvl->totface); - - BLO_read_data_address(reader, &mesh->mr->edge_flags); - BLO_read_data_address(reader, &mesh->mr->edge_creases); - - BLO_read_data_address(reader, &mesh->mr->verts); - - /* If mesh has the same number of vertices as the - * highest multires level, load the current mesh verts - * into multires and discard the old data. Needed - * because some saved files either do not have a verts - * array, or the verts array contains out-of-date - * data. */ - if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) { - if (mesh->mr->verts) { - MEM_freeN(mesh->mr->verts); - } - mesh->mr->verts = MEM_dupallocN(mesh->mvert); - } - - for (; lvl; lvl = lvl->next) { - BLO_read_data_address(reader, &lvl->verts); - BLO_read_data_address(reader, &lvl->faces); - BLO_read_data_address(reader, &lvl->edges); - BLO_read_data_address(reader, &lvl->colfaces); - } - } - - /* if multires is present but has no valid vertex data, - * there's no way to recover it; silently remove multires */ - if (mesh->mr && !mesh->mr->verts) { - multires_free(mesh->mr); - mesh->mr = NULL; - } - - if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) { - TFace *tf = mesh->tface; - for (int i = 0; i < mesh->totface; i++, tf++) { - BLI_endian_switch_uint32_array(tf->col, 4); - } - } -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Read ID: Lattice - * \{ */ - -static void lib_link_latt(BlendLibReader *reader, Lattice *lt) -{ - BLO_read_id_address(reader, lt->id.lib, <->ipo); // XXX deprecated - old animation system - BLO_read_id_address(reader, lt->id.lib, <->key); -} - -static void direct_link_latt(BlendDataReader *reader, Lattice *lt) -{ - BLO_read_data_address(reader, <->def); - - BLO_read_data_address(reader, <->dvert); - direct_link_dverts(reader, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert); - - lt->editlatt = NULL; - lt->batch_cache = NULL; - - BLO_read_data_address(reader, <->adt); - BKE_animdata_blend_read_data(reader, lt->adt); -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -6202,7 +5964,7 @@ static void direct_link_gpencil(BlendDataReader *reader, bGPdata *gpd) /* relink weight data */ if (gps->dvert) { BLO_read_data_address(reader, &gps->dvert); - direct_link_dverts(reader, gps->totpoints, gps->dvert); + BKE_defvert_blend_read(reader, gps->totpoints, gps->dvert); } } } @@ -8005,8 +7767,8 @@ static void direct_link_hair(BlendDataReader *reader, Hair *hair) BKE_animdata_blend_read_data(reader, hair->adt); /* Geometry */ - direct_link_customdata(reader, &hair->pdata, hair->totpoint); - direct_link_customdata(reader, &hair->cdata, hair->totcurve); + CustomData_blend_read(reader, &hair->pdata, hair->totpoint); + CustomData_blend_read(reader, &hair->cdata, hair->totcurve); BKE_hair_update_customdata_pointers(hair); /* Materials */ @@ -8032,7 +7794,7 @@ static void direct_link_pointcloud(BlendDataReader *reader, PointCloud *pointclo BKE_animdata_blend_read_data(reader, pointcloud->adt); /* Geometry */ - direct_link_customdata(reader, &pointcloud->pdata, pointcloud->totpoint); + CustomData_blend_read(reader, &pointcloud->pdata, pointcloud->totpoint); BKE_pointcloud_update_customdata_pointers(pointcloud); /* Materials */ @@ -8093,7 +7855,7 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati BLO_read_data_address(reader, &state->type); if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) { ParticleSimulationState *particle_state = (ParticleSimulationState *)state; - direct_link_customdata(reader, &particle_state->attributes, particle_state->tot_particles); + CustomData_blend_read(reader, &particle_state->attributes, particle_state->tot_particles); } } @@ -8261,9 +8023,6 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID * case ID_OB: direct_link_object(&reader, (Object *)id); break; - case ID_ME: - direct_link_mesh(&reader, (Mesh *)id); - break; case ID_CU: direct_link_curve(&reader, (Curve *)id); break; @@ -8294,9 +8053,6 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID * case ID_KE: direct_link_key(&reader, (Key *)id); break; - case ID_LT: - direct_link_latt(&reader, (Lattice *)id); - break; case ID_WO: direct_link_world(&reader, (World *)id); break; @@ -8369,6 +8125,10 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID * case ID_SIM: direct_link_simulation(&reader, (Simulation *)id); break; + case ID_ME: + case ID_LT: + /* Do nothing. Handled by IDTypeInfo callback. */ + break; } /* try to restore (when undoing) or clear ID's cache pointers. */ @@ -9032,18 +8792,12 @@ static void lib_link_all(FileData *fd, Main *bmain) case ID_LA: lib_link_light(&reader, (Light *)id); break; - case ID_LT: - lib_link_latt(&reader, (Lattice *)id); - break; case ID_MB: lib_link_mball(&reader, (MetaBall *)id); break; case ID_CU: lib_link_curve(&reader, (Curve *)id); break; - case ID_ME: - lib_link_mesh(&reader, (Mesh *)id); - break; case ID_CF: lib_link_cachefiles(&reader, (CacheFile *)id); break; @@ -9097,6 +8851,10 @@ static void lib_link_all(FileData *fd, Main *bmain) case ID_LI: lib_link_library(&reader, (Library *)id); /* Only init users. */ break; + case ID_ME: + case ID_LT: + /* Do nothing. Handled by IDTypeInfo callback. */ + break; } id->tag &= ~LIB_TAG_NEED_LINK; @@ -9911,12 +9669,6 @@ static void expand_light(BlendExpander *expander, Light *la) BLO_expand(expander, la->ipo); // XXX deprecated - old animation system } -static void expand_lattice(BlendExpander *expander, Lattice *lt) -{ - BLO_expand(expander, lt->ipo); // XXX deprecated - old animation system - BLO_expand(expander, lt->key); -} - static void expand_world(BlendExpander *expander, World *wrld) { BLO_expand(expander, wrld->ipo); // XXX deprecated - old animation system @@ -9946,16 +9698,6 @@ static void expand_curve(BlendExpander *expander, Curve *cu) BLO_expand(expander, cu->textoncurve); } -static void expand_mesh(BlendExpander *expander, Mesh *me) -{ - for (int a = 0; a < me->totcol; a++) { - BLO_expand(expander, me->mat[a]); - } - - BLO_expand(expander, me->key); - BLO_expand(expander, me->texcomesh); -} - /* callback function used to expand constraint ID-links */ static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, @@ -10389,9 +10131,6 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_OB: expand_object(&expander, (Object *)id); break; - case ID_ME: - expand_mesh(&expander, (Mesh *)id); - break; case ID_CU: expand_curve(&expander, (Curve *)id); break; @@ -10410,9 +10149,6 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_WO: expand_world(&expander, (World *)id); break; - case ID_LT: - expand_lattice(&expander, (Lattice *)id); - break; case ID_LA: expand_light(&expander, (Light *)id); break; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 6ce822a09c1..a9c92719a33 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -161,6 +161,7 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_curveprofile.h" +#include "BKE_deform.h" #include "BKE_fcurve.h" #include "BKE_fcurve_driver.h" #include "BKE_global.h" // for G @@ -658,33 +659,6 @@ static void writelist_id(WriteData *wd, int filecode, const char *structname, co * These functions are used by blender's .blend system for file saving/loading. * \{ */ -static void write_iddata(BlendWriter *writer, ID *id) -{ - /* ID_WM's id->properties are considered runtime only, and never written in .blend file. */ - if (id->properties && !ELEM(GS(id->name), ID_WM)) { - IDP_BlendWrite(writer, id->properties); - } - - if (id->override_library) { - BLO_write_struct(writer, IDOverrideLibrary, id->override_library); - - BLO_write_struct_list(writer, IDOverrideLibraryProperty, &id->override_library->properties); - LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &id->override_library->properties) { - BLO_write_string(writer, op->rna_path); - - BLO_write_struct_list(writer, IDOverrideLibraryPropertyOperation, &op->operations); - LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { - if (opop->subitem_reference_name) { - BLO_write_string(writer, opop->subitem_reference_name); - } - if (opop->subitem_local_name) { - BLO_write_string(writer, opop->subitem_local_name); - } - } - } - } -} - static void write_previews(BlendWriter *writer, const PreviewImage *prv_orig) { /* Note we write previews also for undo steps. It takes up some memory, @@ -713,7 +687,7 @@ static void write_action(BlendWriter *writer, bAction *act, const void *id_addre { if (act->id.us > 0 || BLO_write_is_undo(writer)) { BLO_write_id_struct(writer, bAction, id_address, &act->id); - write_iddata(writer, &act->id); + BKE_id_blend_write(writer, &act->id); BKE_fcurve_blend_write(writer, &act->curves); @@ -1171,7 +1145,7 @@ static void write_particlesettings(BlendWriter *writer, if (part->id.us > 0 || BLO_write_is_undo(writer)) { /* write LibData */ BLO_write_id_struct(writer, ParticleSettings, id_address, &part->id); - write_iddata(writer, &part->id); + BKE_id_blend_write(writer, &part->id); if (part->adt) { BKE_animdata_blend_write(writer, part->adt); @@ -1593,7 +1567,7 @@ static void write_object(BlendWriter *writer, Object *ob, const void *id_address /* write LibData */ BLO_write_id_struct(writer, Object, id_address, &ob->id); - write_iddata(writer, &ob->id); + BKE_id_blend_write(writer, &ob->id); if (ob->adt) { BKE_animdata_blend_write(writer, ob->adt); @@ -1661,7 +1635,7 @@ static void write_vfont(BlendWriter *writer, VFont *vf, const void *id_address) /* write LibData */ BLO_write_id_struct(writer, VFont, id_address, &vf->id); - write_iddata(writer, &vf->id); + BKE_id_blend_write(writer, &vf->id); /* direct data */ if (vf->packedfile) { @@ -1677,7 +1651,7 @@ static void write_key(BlendWriter *writer, Key *key, const void *id_address) if (key->id.us > 0 || BLO_write_is_undo(writer)) { /* write LibData */ BLO_write_id_struct(writer, Key, id_address, &key->id); - write_iddata(writer, &key->id); + BKE_id_blend_write(writer, &key->id); if (key->adt) { BKE_animdata_blend_write(writer, key->adt); @@ -1698,7 +1672,7 @@ static void write_camera(BlendWriter *writer, Camera *cam, const void *id_addres if (cam->id.us > 0 || BLO_write_is_undo(writer)) { /* write LibData */ BLO_write_id_struct(writer, Camera, id_address, &cam->id); - write_iddata(writer, &cam->id); + BKE_id_blend_write(writer, &cam->id); if (cam->adt) { BKE_animdata_blend_write(writer, cam->adt); @@ -1723,7 +1697,7 @@ static void write_mball(BlendWriter *writer, MetaBall *mb, const void *id_addres /* write LibData */ BLO_write_id_struct(writer, MetaBall, id_address, &mb->id); - write_iddata(writer, &mb->id); + BKE_id_blend_write(writer, &mb->id); /* direct data */ BLO_write_pointer_array(writer, mb->totcol, mb->mat); @@ -1747,7 +1721,7 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address) /* write LibData */ BLO_write_id_struct(writer, Curve, id_address, &cu->id); - write_iddata(writer, &cu->id); + BKE_id_blend_write(writer, &cu->id); /* direct data */ BLO_write_pointer_array(writer, cu->totcol, cu->mat); @@ -1784,200 +1758,6 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address) } } -static void write_dverts(BlendWriter *writer, int count, MDeformVert *dvlist) -{ - if (dvlist) { - - /* Write the dvert list */ - BLO_write_struct_array(writer, MDeformVert, count, dvlist); - - /* Write deformation data for each dvert */ - for (int i = 0; i < count; i++) { - if (dvlist[i].dw) { - BLO_write_struct_array(writer, MDeformWeight, dvlist[i].totweight, dvlist[i].dw); - } - } - } -} - -static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external) -{ - if (mdlist) { - BLO_write_struct_array(writer, MDisps, count, mdlist); - for (int i = 0; i < count; i++) { - MDisps *md = &mdlist[i]; - if (md->disps) { - if (!external) { - BLO_write_float3_array(writer, md->totdisp, &md->disps[0][0]); - } - } - - if (md->hidden) { - BLO_write_raw(writer, BLI_BITMAP_SIZE(md->totdisp), md->hidden); - } - } - } -} - -static void write_grid_paint_mask(BlendWriter *writer, int count, GridPaintMask *grid_paint_mask) -{ - if (grid_paint_mask) { - BLO_write_struct_array(writer, GridPaintMask, count, grid_paint_mask); - for (int i = 0; i < count; i++) { - GridPaintMask *gpm = &grid_paint_mask[i]; - if (gpm->data) { - const int gridsize = BKE_ccg_gridsize(gpm->level); - BLO_write_raw(writer, sizeof(*gpm->data) * gridsize * gridsize, gpm->data); - } - } - } -} - -static void write_customdata(BlendWriter *writer, - ID *id, - int count, - CustomData *data, - CustomDataLayer *layers, - CustomDataMask cddata_mask) -{ - /* write external customdata (not for undo) */ - if (data->external && !BLO_write_is_undo(writer)) { - CustomData_external_write(data, id, cddata_mask, count, 0); - } - - BLO_write_struct_array_at_address(writer, CustomDataLayer, data->totlayer, data->layers, layers); - - for (int i = 0; i < data->totlayer; i++) { - CustomDataLayer *layer = &layers[i]; - const char *structname; - int structnum, datasize; - - if (layer->type == CD_MDEFORMVERT) { - /* layer types that allocate own memory need special handling */ - write_dverts(writer, count, layer->data); - } - else if (layer->type == CD_MDISPS) { - write_mdisps(writer, count, layer->data, layer->flag & CD_FLAG_EXTERNAL); - } - else if (layer->type == CD_PAINT_MASK) { - const float *layer_data = layer->data; - BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); - } - else if (layer->type == CD_SCULPT_FACE_SETS) { - const float *layer_data = layer->data; - BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); - } - else if (layer->type == CD_GRID_PAINT_MASK) { - write_grid_paint_mask(writer, count, layer->data); - } - else if (layer->type == CD_FACEMAP) { - const int *layer_data = layer->data; - BLO_write_raw(writer, sizeof(*layer_data) * count, layer_data); - } - else { - CustomData_file_write_info(layer->type, &structname, &structnum); - if (structnum) { - datasize = structnum * count; - BLO_write_struct_array_by_name(writer, structname, datasize, layer->data); - } - else if (!BLO_write_is_undo(writer)) { /* Do not warn on undo. */ - printf("%s error: layer '%s':%d - can't be written to file\n", - __func__, - structname, - layer->type); - } - } - } - - if (data->external) { - BLO_write_struct(writer, CustomDataExternal, data->external); - } -} - -static void write_mesh(BlendWriter *writer, Mesh *mesh, const void *id_address) -{ - if (mesh->id.us > 0 || BLO_write_is_undo(writer)) { - /* cache only - don't write */ - mesh->mface = NULL; - mesh->totface = 0; - memset(&mesh->fdata, 0, sizeof(mesh->fdata)); - memset(&mesh->runtime, 0, sizeof(mesh->runtime)); - - /* Reduce xdata layers, fill xlayers with layers to be written. - * This makes xdata invalid for Blender, which is why we made a - * temporary local copy. */ - CustomDataLayer *vlayers = NULL, vlayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *elayers = NULL, elayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *flayers = NULL, flayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *llayers = NULL, llayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; - - CustomData_file_write_prepare(&mesh->vdata, &vlayers, vlayers_buff, ARRAY_SIZE(vlayers_buff)); - CustomData_file_write_prepare(&mesh->edata, &elayers, elayers_buff, ARRAY_SIZE(elayers_buff)); - flayers = flayers_buff; - CustomData_file_write_prepare(&mesh->ldata, &llayers, llayers_buff, ARRAY_SIZE(llayers_buff)); - CustomData_file_write_prepare(&mesh->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); - - BLO_write_id_struct(writer, Mesh, id_address, &mesh->id); - write_iddata(writer, &mesh->id); - - /* direct data */ - if (mesh->adt) { - BKE_animdata_blend_write(writer, mesh->adt); - } - - BLO_write_pointer_array(writer, mesh->totcol, mesh->mat); - BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect); - - write_customdata(writer, &mesh->id, mesh->totvert, &mesh->vdata, vlayers, CD_MASK_MESH.vmask); - write_customdata(writer, &mesh->id, mesh->totedge, &mesh->edata, elayers, CD_MASK_MESH.emask); - /* fdata is really a dummy - written so slots align */ - write_customdata(writer, &mesh->id, mesh->totface, &mesh->fdata, flayers, CD_MASK_MESH.fmask); - write_customdata(writer, &mesh->id, mesh->totloop, &mesh->ldata, llayers, CD_MASK_MESH.lmask); - write_customdata(writer, &mesh->id, mesh->totpoly, &mesh->pdata, players, CD_MASK_MESH.pmask); - - /* free temporary data */ - if (vlayers && vlayers != vlayers_buff) { - MEM_freeN(vlayers); - } - if (elayers && elayers != elayers_buff) { - MEM_freeN(elayers); - } - if (flayers && flayers != flayers_buff) { - MEM_freeN(flayers); - } - if (llayers && llayers != llayers_buff) { - MEM_freeN(llayers); - } - if (players && players != players_buff) { - MEM_freeN(players); - } - } -} - -static void write_lattice(BlendWriter *writer, Lattice *lt, const void *id_address) -{ - if (lt->id.us > 0 || BLO_write_is_undo(writer)) { - /* Clean up, important in undo case to reduce false detection of changed datablocks. */ - lt->editlatt = NULL; - lt->batch_cache = NULL; - - /* write LibData */ - BLO_write_id_struct(writer, Lattice, id_address, <->id); - write_iddata(writer, <->id); - - /* write animdata */ - if (lt->adt) { - BKE_animdata_blend_write(writer, lt->adt); - } - - /* direct data */ - BLO_write_struct_array(writer, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def); - - write_dverts(writer, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert); - } -} - static void write_image(BlendWriter *writer, Image *ima, const void *id_address) { if (ima->id.us > 0 || BLO_write_is_undo(writer)) { @@ -1992,7 +1772,7 @@ static void write_image(BlendWriter *writer, Image *ima, const void *id_address) /* write LibData */ BLO_write_id_struct(writer, Image, id_address, &ima->id); - write_iddata(writer, &ima->id); + BKE_id_blend_write(writer, &ima->id); for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) { BLO_write_struct(writer, ImagePackedFile, imapf); @@ -2023,7 +1803,7 @@ static void write_texture(BlendWriter *writer, Tex *tex, const void *id_address) if (tex->id.us > 0 || BLO_write_is_undo(writer)) { /* write LibData */ BLO_write_id_struct(writer, Tex, id_address, &tex->id); - write_iddata(writer, &tex->id); + BKE_id_blend_write(writer, &tex->id); if (tex->adt) { BKE_animdata_blend_write(writer, tex->adt); @@ -2053,7 +1833,7 @@ static void write_material(BlendWriter *writer, Material *ma, const void *id_add /* write LibData */ BLO_write_id_struct(writer, Material, id_address, &ma->id); - write_iddata(writer, &ma->id); + BKE_id_blend_write(writer, &ma->id); if (ma->adt) { BKE_animdata_blend_write(writer, ma->adt); @@ -2082,7 +1862,7 @@ static void write_world(BlendWriter *writer, World *wrld, const void *id_address /* write LibData */ BLO_write_id_struct(writer, World, id_address, &wrld->id); - write_iddata(writer, &wrld->id); + BKE_id_blend_write(writer, &wrld->id); if (wrld->adt) { BKE_animdata_blend_write(writer, wrld->adt); @@ -2103,7 +1883,7 @@ static void write_light(BlendWriter *writer, Light *la, const void *id_address) if (la->id.us > 0 || BLO_write_is_undo(writer)) { /* write LibData */ BLO_write_id_struct(writer, Light, id_address, &la->id); - write_iddata(writer, &la->id); + BKE_id_blend_write(writer, &la->id); if (la->adt) { BKE_animdata_blend_write(writer, la->adt); @@ -2148,7 +1928,7 @@ static void write_collection(BlendWriter *writer, Collection *collection, const /* write LibData */ BLO_write_id_struct(writer, Collection, id_address, &collection->id); - write_iddata(writer, &collection->id); + BKE_id_blend_write(writer, &collection->id); write_collection_nolib(writer, collection); } @@ -2274,7 +2054,7 @@ static void write_scene(BlendWriter *writer, Scene *sce, const void *id_address) /* write LibData */ BLO_write_id_struct(writer, Scene, id_address, &sce->id); - write_iddata(writer, &sce->id); + BKE_id_blend_write(writer, &sce->id); if (sce->adt) { BKE_animdata_blend_write(writer, sce->adt); @@ -2508,7 +2288,7 @@ static void write_gpencil(BlendWriter *writer, bGPdata *gpd, const void *id_addr /* write gpd data block to file */ BLO_write_id_struct(writer, bGPdata, id_address, &gpd->id); - write_iddata(writer, &gpd->id); + BKE_id_blend_write(writer, &gpd->id); if (gpd->adt) { BKE_animdata_blend_write(writer, gpd->adt); @@ -2529,7 +2309,7 @@ static void write_gpencil(BlendWriter *writer, bGPdata *gpd, const void *id_addr LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { BLO_write_struct_array(writer, bGPDspoint, gps->totpoints, gps->points); BLO_write_struct_array(writer, bGPDtriangle, gps->tot_triangles, gps->triangles); - write_dverts(writer, gps->totpoints, gps->dvert); + BKE_defvert_blend_write(writer, gps->totpoints, gps->dvert); } } } @@ -2782,7 +2562,7 @@ static void write_area_map(BlendWriter *writer, ScrAreaMap *area_map) static void write_windowmanager(BlendWriter *writer, wmWindowManager *wm, const void *id_address) { BLO_write_id_struct(writer, wmWindowManager, id_address, &wm->id); - write_iddata(writer, &wm->id); + BKE_id_blend_write(writer, &wm->id); write_wm_xr_data(writer, &wm->xr); LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { @@ -2817,7 +2597,7 @@ static void write_screen(BlendWriter *writer, bScreen *screen, const void *id_ad /* write LibData */ /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ writestruct_at_address(writer->wd, ID_SCRN, bScreen, 1, id_address, screen); - write_iddata(writer, &screen->id); + BKE_id_blend_write(writer, &screen->id); write_previews(writer, screen->preview); @@ -2857,7 +2637,7 @@ static void write_armature(BlendWriter *writer, bArmature *arm, const void *id_a arm->act_edbone = NULL; BLO_write_id_struct(writer, bArmature, id_address, &arm->id); - write_iddata(writer, &arm->id); + BKE_id_blend_write(writer, &arm->id); if (arm->adt) { BKE_animdata_blend_write(writer, arm->adt); @@ -2882,7 +2662,7 @@ static void write_text(BlendWriter *writer, Text *text, const void *id_address) /* write LibData */ BLO_write_id_struct(writer, Text, id_address, &text->id); - write_iddata(writer, &text->id); + BKE_id_blend_write(writer, &text->id); if (text->filepath) { BLO_write_string(writer, text->filepath); @@ -2905,7 +2685,7 @@ static void write_speaker(BlendWriter *writer, Speaker *spk, const void *id_addr if (spk->id.us > 0 || BLO_write_is_undo(writer)) { /* write LibData */ BLO_write_id_struct(writer, Speaker, id_address, &spk->id); - write_iddata(writer, &spk->id); + BKE_id_blend_write(writer, &spk->id); if (spk->adt) { BKE_animdata_blend_write(writer, spk->adt); @@ -2924,7 +2704,7 @@ static void write_sound(BlendWriter *writer, bSound *sound, const void *id_addre /* write LibData */ BLO_write_id_struct(writer, bSound, id_address, &sound->id); - write_iddata(writer, &sound->id); + BKE_id_blend_write(writer, &sound->id); if (sound->packedfile) { PackedFile *pf = sound->packedfile; @@ -2939,7 +2719,7 @@ static void write_probe(BlendWriter *writer, LightProbe *prb, const void *id_add if (prb->id.us > 0 || BLO_write_is_undo(writer)) { /* write LibData */ BLO_write_id_struct(writer, LightProbe, id_address, &prb->id); - write_iddata(writer, &prb->id); + BKE_id_blend_write(writer, &prb->id); if (prb->adt) { BKE_animdata_blend_write(writer, prb->adt); @@ -2961,7 +2741,7 @@ static void write_nodetree(BlendWriter *writer, bNodeTree *ntree, const void *id BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id); /* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot * be linked, etc., so we write actual id data here only, for 'real' ID trees. */ - write_iddata(writer, &ntree->id); + BKE_id_blend_write(writer, &ntree->id); write_nodetree_nolib(writer, ntree); } @@ -2971,7 +2751,7 @@ static void write_brush(BlendWriter *writer, Brush *brush, const void *id_addres { if (brush->id.us > 0 || BLO_write_is_undo(writer)) { BLO_write_id_struct(writer, Brush, id_address, &brush->id); - write_iddata(writer, &brush->id); + BKE_id_blend_write(writer, &brush->id); if (brush->curve) { BKE_curvemapping_blend_write(writer, brush->curve); @@ -3019,7 +2799,7 @@ static void write_palette(BlendWriter *writer, Palette *palette, const void *id_ if (palette->id.us > 0 || BLO_write_is_undo(writer)) { PaletteColor *color; BLO_write_id_struct(writer, Palette, id_address, &palette->id); - write_iddata(writer, &palette->id); + BKE_id_blend_write(writer, &palette->id); for (color = palette->colors.first; color; color = color->next) { BLO_write_struct(writer, PaletteColor, color); @@ -3031,7 +2811,7 @@ static void write_paintcurve(BlendWriter *writer, PaintCurve *pc, const void *id { if (pc->id.us > 0 || BLO_write_is_undo(writer)) { BLO_write_id_struct(writer, PaintCurve, id_address, &pc->id); - write_iddata(writer, &pc->id); + BKE_id_blend_write(writer, &pc->id); BLO_write_struct_array(writer, PaintCurvePoint, pc->tot_points, pc->points); } @@ -3087,7 +2867,7 @@ static void write_movieclip(BlendWriter *writer, MovieClip *clip, const void *id MovieTrackingObject *object; BLO_write_id_struct(writer, MovieClip, id_address, &clip->id); - write_iddata(writer, &clip->id); + BKE_id_blend_write(writer, &clip->id); if (clip->adt) { BKE_animdata_blend_write(writer, clip->adt); @@ -3116,7 +2896,7 @@ static void write_mask(BlendWriter *writer, Mask *mask, const void *id_address) MaskLayer *masklay; BLO_write_id_struct(writer, Mask, id_address, &mask->id); - write_iddata(writer, &mask->id); + BKE_id_blend_write(writer, &mask->id); if (mask->adt) { BKE_animdata_blend_write(writer, mask->adt); @@ -3426,7 +3206,7 @@ static void write_linestyle(BlendWriter *writer, { if (linestyle->id.us > 0 || BLO_write_is_undo(writer)) { BLO_write_id_struct(writer, FreestyleLineStyle, id_address, &linestyle->id); - write_iddata(writer, &linestyle->id); + BKE_id_blend_write(writer, &linestyle->id); if (linestyle->adt) { BKE_animdata_blend_write(writer, linestyle->adt); @@ -3468,7 +3248,7 @@ static void write_cachefile(BlendWriter *writer, CacheFile *cache_file, const vo static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const void *id_address) { BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id); - write_iddata(writer, &workspace->id); + BKE_id_blend_write(writer, &workspace->id); BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts); BLO_write_struct_list(writer, WorkSpaceDataRelation, &workspace->hook_layout_relations); BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids); @@ -3483,30 +3263,17 @@ static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const voi static void write_hair(BlendWriter *writer, Hair *hair, const void *id_address) { if (hair->id.us > 0 || BLO_write_is_undo(writer)) { - CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE]; - CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomData_file_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); - CustomData_file_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff)); - /* Write LibData */ BLO_write_id_struct(writer, Hair, id_address, &hair->id); - write_iddata(writer, &hair->id); + BKE_id_blend_write(writer, &hair->id); /* Direct data */ - write_customdata(writer, &hair->id, hair->totpoint, &hair->pdata, players, CD_MASK_ALL); - write_customdata(writer, &hair->id, hair->totcurve, &hair->cdata, clayers, CD_MASK_ALL); + CustomData_blend_write(writer, &hair->pdata, hair->totpoint, CD_MASK_ALL, &hair->id); + CustomData_blend_write(writer, &hair->cdata, hair->totcurve, CD_MASK_ALL, &hair->id); BLO_write_pointer_array(writer, hair->totcol, hair->mat); if (hair->adt) { BKE_animdata_blend_write(writer, hair->adt); } - - /* Remove temporary data. */ - if (players && players != players_buff) { - MEM_freeN(players); - } - if (clayers && clayers != clayers_buff) { - MEM_freeN(clayers); - } } } @@ -3519,11 +3286,11 @@ static void write_pointcloud(BlendWriter *writer, PointCloud *pointcloud, const /* Write LibData */ BLO_write_id_struct(writer, PointCloud, id_address, &pointcloud->id); - write_iddata(writer, &pointcloud->id); + BKE_id_blend_write(writer, &pointcloud->id); /* Direct data */ - write_customdata( - writer, &pointcloud->id, pointcloud->totpoint, &pointcloud->pdata, players, CD_MASK_ALL); + CustomData_blend_write( + writer, &pointcloud->pdata, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id); BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat); if (pointcloud->adt) { BKE_animdata_blend_write(writer, pointcloud->adt); @@ -3544,7 +3311,7 @@ static void write_volume(BlendWriter *writer, Volume *volume, const void *id_add /* write LibData */ BLO_write_id_struct(writer, Volume, id_address, &volume->id); - write_iddata(writer, &volume->id); + BKE_id_blend_write(writer, &volume->id); /* direct data */ BLO_write_pointer_array(writer, volume->totcol, volume->mat); @@ -3564,7 +3331,7 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const { if (simulation->id.us > 0 || BLO_write_is_undo(writer)) { BLO_write_id_struct(writer, Simulation, id_address, &simulation->id); - write_iddata(writer, &simulation->id); + BKE_id_blend_write(writer, &simulation->id); if (simulation->adt) { BKE_animdata_blend_write(writer, simulation->adt); @@ -3584,21 +3351,11 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const ParticleSimulationState *particle_state = (ParticleSimulationState *)state; BLO_write_struct(writer, ParticleSimulationState, particle_state); - CustomDataLayer *layers = NULL; - CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE]; - CustomData_file_write_prepare( - &particle_state->attributes, &layers, layers_buff, ARRAY_SIZE(layers_buff)); - - write_customdata(writer, - &simulation->id, - particle_state->tot_particles, - &particle_state->attributes, - layers, - CD_MASK_ALL); - - if (layers != NULL && layers != layers_buff) { - MEM_freeN(layers); - } + CustomData_blend_write(writer, + &particle_state->attributes, + particle_state->tot_particles, + CD_MASK_ALL, + &simulation->id); } else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) { ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *) @@ -3654,7 +3411,7 @@ static void write_libraries(WriteData *wd, Main *main) BlendWriter writer = {wd}; writestruct(wd, ID_LI, Library, 1, main->curlib); - write_iddata(&writer, &main->curlib->id); + BKE_id_blend_write(&writer, &main->curlib->id); if (main->curlib->packedfile) { PackedFile *pf = main->curlib->packedfile; @@ -3904,9 +3661,6 @@ static bool write_file_handle(Main *mainvar, case ID_LA: write_light(&writer, (Light *)id_buffer, id); break; - case ID_LT: - write_lattice(&writer, (Lattice *)id_buffer, id); - break; case ID_VF: write_vfont(&writer, (VFont *)id_buffer, id); break; @@ -3946,9 +3700,6 @@ static bool write_file_handle(Main *mainvar, case ID_TE: write_texture(&writer, (Tex *)id_buffer, id); break; - case ID_ME: - write_mesh(&writer, (Mesh *)id_buffer, id); - break; case ID_PA: write_particlesettings(&writer, (ParticleSettings *)id_buffer, id); break; @@ -3985,6 +3736,10 @@ static bool write_file_handle(Main *mainvar, case ID_SIM: write_simulation(&writer, (Simulation *)id_buffer, id); break; + case ID_ME: + case ID_LT: + /* Do nothing, handled in IDTypeInfo callback. */ + break; case ID_LI: /* Do nothing, handled below - and should never be reached. */ BLI_assert(0); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 2669de87bc4..670827dc4d8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -1129,9 +1129,11 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) if (object->rigidbody_object == nullptr) { continue; } - if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) { + + if (!BKE_rigidbody_is_affected_by_simulation(object)) { continue; } + /* Create operation for flushing results. */ /* Object's transform component - where the rigidbody operation * lives. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 6feebe6f542..5f637a92069 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1703,9 +1703,6 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) if (object->rigidbody_object == nullptr) { continue; } - if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) { - continue; - } if (object->parent != nullptr && object->parent->rigidbody_object != nullptr && object->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) { @@ -1716,10 +1713,6 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) continue; } - OperationKey rb_transform_copy_key( - &object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - /* Rigid body synchronization depends on the actual simulation. */ - add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync"); /* Simulation uses object transformation after parenting and solving constraints. */ OperationKey object_transform_simulation_init_key( &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_SIMULATION_INIT); @@ -1737,47 +1730,27 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY); add_relation(object_geometry_key, rb_simulate_key, - "Object Geom Eval -> Rigidbody Rebuild", + "Object Geom Eval -> Rigidbody Sim Eval", RELATION_FLAG_GODMODE); } + /* Final transform is whetever solver gave to us. */ - OperationKey object_transform_final_key( - &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL); - add_relation( - rb_transform_copy_key, object_transform_final_key, "Rigidbody Sync -> Transform Final"); - } - FOREACH_COLLECTION_OBJECT_RECURSIVE_END; - } - /* Constraints. */ - if (rbw->constraints != nullptr) { - FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, object) { - RigidBodyCon *rbc = object->rigidbody_constraint; - if (rbc == nullptr || rbc->ob1 == nullptr || rbc->ob2 == nullptr) { - /* When either ob1 or ob2 is nullptr, the constraint doesn't - * work. */ - continue; - } - /* Make sure indirectly linked objects are fully built. */ - build_object(object); - build_object(rbc->ob1); - build_object(rbc->ob2); - /* final result of the constraint object's transform controls how - * the constraint affects the physics sim for these objects. */ - ComponentKey trans_key(&object->id, NodeType::TRANSFORM); - if (rbc->ob1->rigidbody_object->type == RBO_TYPE_ACTIVE) { - OperationKey ob1_key( - &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - /* Constrained-objects sync depends on the constraint-holder. */ - add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1"); - } - if (rbc->ob2->rigidbody_object->type == RBO_TYPE_ACTIVE) { - OperationKey ob2_key( - &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); - /* Constrained-objects sync depends on the constraint-holder. */ - add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2"); + if (BKE_rigidbody_is_affected_by_simulation(object)) { + /* We do not have to update the objects final transform after the simulation if it is + * passive or controlled by the animation system in blender. + * (Bullet doesn't move the object at all in these cases) + */ + OperationKey rb_transform_copy_key( + &object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY); + /* Rigid body synchronization depends on the actual simulation. */ + add_relation(rb_simulate_key, rb_transform_copy_key, "Rigidbody Sim Eval -> RBO Sync"); + + OperationKey object_transform_final_key( + &object->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL); + add_relation(rb_transform_copy_key, + object_transform_final_key, + "Rigidbody Sync -> Transform Final"); } - /* Ensure that sim depends on this constraint's transform. */ - add_relation(trans_key, rb_simulate_key, "RigidBodyConstraint Transform -> RB Simulation"); } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index f85b03dc517..83d39b606fe 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -419,6 +419,28 @@ if(WITH_XR_OPENXR) add_definitions(-DWITH_XR_OPENXR) endif() +if(WITH_GTESTS) + if(WITH_OPENGL_DRAW_TESTS) + add_definitions(-DWITH_OPENGL_DRAW_TESTS) + endif() +endif() + add_definitions(${GL_DEFINITIONS}) blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") + +if(WITH_GTESTS) + if(WITH_OPENGL_DRAW_TESTS) + set(TEST_SRC + tests/shaders_test.cc + ) + set(TEST_INC + "../../../intern/ghost/" + ) + set(TEST_LIB + bf_draw + ) + include(GTestTesting) + blender_add_test_lib(bf_draw_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") + endif() +endif()
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 9cde9e871e5..b25f21ce929 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -32,6 +32,10 @@ #include "BKE_camera.h" +#ifdef __cplusplus +extern "C" { +#endif + struct EEVEE_ShadowCasterBuffer; struct GPUFrameBuffer; struct Object; @@ -1363,3 +1367,7 @@ static const float cubefacemat[6][4][4] = { {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, }; + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index f8c7a6e16db..9e7e545167a 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -372,6 +372,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) /* If no world or volume material is present just clear the buffer with this drawcall */ grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]); @@ -656,6 +658,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit); DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); DRW_shgroup_call_procedural_triangles(grp, NULL, 1); diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 34d4488d066..852945b25c3 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -24,10 +24,16 @@ #include "DNA_gpencil_types.h" +#include "DRW_render.h" + #include "BLI_bitmap.h" #include "GPU_batch.h" +#ifdef __cplusplus +extern "C" { +#endif + extern DrawEngineType draw_engine_gpencil_type; struct GPENCIL_Data; @@ -397,7 +403,6 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObjec /* Shaders */ struct GPUShader *GPENCIL_shader_antialiasing(int stage); struct GPUShader *GPENCIL_shader_geometry_get(void); -struct GPUShader *GPENCIL_shader_composite_get(void); struct GPUShader *GPENCIL_shader_layer_blend_get(void); struct GPUShader *GPENCIL_shader_mask_invert_get(void); struct GPUShader *GPENCIL_shader_depth_merge_get(void); @@ -438,3 +443,6 @@ void GPENCIL_render_to_image(void *vedata, void gpencil_light_pool_free(void *storage); void gpencil_material_pool_free(void *storage); GPENCIL_ViewLayerData *GPENCIL_view_layer_data_ensure(void); +#ifdef __cplusplus +} +#endif diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h index 7e93382796f..c9d29af91e6 100644 --- a/source/blender/draw/engines/overlay/overlay_private.h +++ b/source/blender/draw/engines/overlay/overlay_private.h @@ -22,6 +22,12 @@ #pragma once +#include "DRW_render.h" + +#ifdef __cplusplus +extern "C" { +#endif + #ifdef __APPLE__ # define USE_GEOM_SHADER_WORKAROUND 1 #else @@ -627,3 +633,7 @@ GPUShader *OVERLAY_shader_xray_fade(void); OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void); void OVERLAY_shader_free(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index eb61edca6c7..122c99ca536 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -1,6 +1,5 @@ #define EPSILON 0.00001 -#define M_PI 3.14159265358979323846 #define CAVITY_BUFFER_RANGE 4.0 diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 12e573a02d0..8983826f16f 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -33,6 +33,10 @@ #include "workbench_engine.h" +#ifdef __cplusplus +extern "C" { +#endif + extern struct DrawEngineType draw_engine_workbench; #define WORKBENCH_ENGINE "BLENDER_WORKBENCH" @@ -519,3 +523,6 @@ void workbench_render(void *ved, void workbench_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer); +#ifdef __cplusplus +} +#endif diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index f6e65338fc7..da11dacefbd 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -84,6 +84,7 @@ #include "draw_color_management.h" #include "draw_manager_profiling.h" +#include "draw_manager_testing.h" #include "draw_manager_text.h" /* only for callbacks */ @@ -2887,6 +2888,8 @@ void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context)) GPU_context_active_set(NULL); } +/** \} */ + #ifdef WITH_XR_OPENXR /* XXX @@ -2922,4 +2925,17 @@ void DRW_xr_drawing_end(void) } #endif + +/** \name Internal testing API for gtests + * \{ */ + +#ifdef WITH_OPENGL_DRAW_TESTS + +void DRW_draw_state_init_gtests(eGPUShaderConfig sh_cfg) +{ + DST.draw_ctx.sh_cfg = sh_cfg; +} + +#endif + /** \} */ diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index b3e1258ff7f..8a81b3db7d8 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -99,6 +99,9 @@ void drw_state_set(DRWState state) if (state & DRW_STATE_WRITE_COLOR) { write_mask |= GPU_WRITE_COLOR; } + if (state & DRW_STATE_WRITE_STENCIL_ENABLED) { + write_mask |= GPU_WRITE_STENCIL; + } switch (state & (DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT)) { case DRW_STATE_CULL_BACK: diff --git a/source/blender/draw/intern/draw_manager_testing.h b/source/blender/draw/intern/draw_manager_testing.h new file mode 100644 index 00000000000..f8b5dd5af46 --- /dev/null +++ b/source/blender/draw/intern/draw_manager_testing.h @@ -0,0 +1,39 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2016, Blender Foundation. + */ + +/** \file + * \ingroup draw + */ + +/* Internal API only for test cases. */ + +#pragma once + +#include "GPU_shader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WITH_OPENGL_DRAW_TESTS +void DRW_draw_state_init_gtests(eGPUShaderConfig sh_cfg); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc new file mode 100644 index 00000000000..b2f1020ed98 --- /dev/null +++ b/source/blender/draw/tests/shaders_test.cc @@ -0,0 +1,270 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "intern/draw_manager_testing.h" + +#include "GPU_context.h" +#include "GPU_init_exit.h" +#include "GPU_shader.h" + +#include "GHOST_C-api.h" + +#include "engines/eevee/eevee_private.h" +#include "engines/gpencil/gpencil_engine.h" +#include "engines/overlay/overlay_private.h" +#include "engines/workbench/workbench_private.h" + +/* Base class for draw test cases. It will setup and tear down the GPU part around each test. */ +class DrawTest : public ::testing::Test { + private: + GHOST_SystemHandle ghost_system; + GHOST_ContextHandle ghost_context; + GPUContext *context; + + void SetUp() override + { + ghost_system = GHOST_CreateSystem(); + ghost_context = GHOST_CreateOpenGLContext(ghost_system); + context = GPU_context_create(0); + GPU_init(); + DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT); + } + + void TearDown() override + { + GPU_exit(); + GPU_context_discard(context); + GHOST_DisposeOpenGLContext(ghost_system, ghost_context); + GHOST_DisposeSystem(ghost_system); + } +}; + +TEST_F(DrawTest, workbench_glsl_shaders) +{ + workbench_shader_library_ensure(); + DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT); + + const int MAX_WPD = 6; + WORKBENCH_PrivateData wpds[MAX_WPD]; + + wpds[0].sh_cfg = GPU_SHADER_CFG_DEFAULT; + wpds[0].shading.light = V3D_LIGHTING_FLAT; + wpds[1].sh_cfg = GPU_SHADER_CFG_DEFAULT; + wpds[1].shading.light = V3D_LIGHTING_MATCAP; + wpds[2].sh_cfg = GPU_SHADER_CFG_DEFAULT; + wpds[2].shading.light = V3D_LIGHTING_STUDIO; + wpds[3].sh_cfg = GPU_SHADER_CFG_CLIPPED; + wpds[3].shading.light = V3D_LIGHTING_FLAT; + wpds[4].sh_cfg = GPU_SHADER_CFG_CLIPPED; + wpds[4].shading.light = V3D_LIGHTING_MATCAP; + wpds[5].sh_cfg = GPU_SHADER_CFG_CLIPPED; + wpds[5].shading.light = V3D_LIGHTING_STUDIO; + + for (int wpd_index = 0; wpd_index < MAX_WPD; wpd_index++) { + WORKBENCH_PrivateData *wpd = &wpds[wpd_index]; + EXPECT_NE(workbench_shader_opaque_get(wpd, WORKBENCH_DATATYPE_MESH), nullptr); + EXPECT_NE(workbench_shader_opaque_get(wpd, WORKBENCH_DATATYPE_HAIR), nullptr); + EXPECT_NE(workbench_shader_opaque_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD), nullptr); + EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_MESH, false), nullptr); + EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_MESH, true), nullptr); + EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_HAIR, false), nullptr); + EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_HAIR, true), nullptr); + EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, false), + nullptr); + EXPECT_NE(workbench_shader_opaque_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, true), + nullptr); + EXPECT_NE(workbench_shader_composite_get(wpd), nullptr); + EXPECT_NE(workbench_shader_merge_infront_get(wpd), nullptr); + + EXPECT_NE(workbench_shader_transparent_get(wpd, WORKBENCH_DATATYPE_MESH), nullptr); + EXPECT_NE(workbench_shader_transparent_get(wpd, WORKBENCH_DATATYPE_HAIR), nullptr); + EXPECT_NE(workbench_shader_transparent_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD), nullptr); + EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_MESH, false), + nullptr); + EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_MESH, true), nullptr); + EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_HAIR, false), + nullptr); + EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_HAIR, true), nullptr); + EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, false), + nullptr); + EXPECT_NE(workbench_shader_transparent_image_get(wpd, WORKBENCH_DATATYPE_POINTCLOUD, true), + nullptr); + EXPECT_NE(workbench_shader_transparent_resolve_get(wpd), nullptr); + } + + EXPECT_NE(workbench_shader_shadow_pass_get(false), nullptr); + EXPECT_NE(workbench_shader_shadow_pass_get(true), nullptr); + EXPECT_NE(workbench_shader_shadow_fail_get(false, false), nullptr); + EXPECT_NE(workbench_shader_shadow_fail_get(false, true), nullptr); + EXPECT_NE(workbench_shader_shadow_fail_get(true, false), nullptr); + EXPECT_NE(workbench_shader_shadow_fail_get(true, true), nullptr); + + /* NOTE: workbench_shader_cavity_get(false, false) isn't a valid option. */ + EXPECT_NE(workbench_shader_cavity_get(false, true), nullptr); + EXPECT_NE(workbench_shader_cavity_get(true, false), nullptr); + EXPECT_NE(workbench_shader_cavity_get(true, true), nullptr); + EXPECT_NE(workbench_shader_outline_get(), nullptr); + + EXPECT_NE(workbench_shader_antialiasing_accumulation_get(), nullptr); + EXPECT_NE(workbench_shader_antialiasing_get(0), nullptr); + EXPECT_NE(workbench_shader_antialiasing_get(1), nullptr); + EXPECT_NE(workbench_shader_antialiasing_get(2), nullptr); + + EXPECT_NE(workbench_shader_volume_get(false, false, false, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(false, false, false, true), nullptr); + EXPECT_NE(workbench_shader_volume_get(false, false, true, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(false, false, true, true), nullptr); + EXPECT_NE(workbench_shader_volume_get(false, true, false, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(false, true, false, true), nullptr); + EXPECT_NE(workbench_shader_volume_get(false, true, true, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(false, true, true, true), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, false, false, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, false, false, true), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, false, true, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, false, true, true), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, true, false, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, true, false, true), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, true, true, false), nullptr); + EXPECT_NE(workbench_shader_volume_get(true, true, true, true), nullptr); + + GPUShader *dof_prepare_sh; + GPUShader *dof_downsample_sh; + GPUShader *dof_blur1_sh; + GPUShader *dof_blur2_sh; + GPUShader *dof_resolve_sh; + workbench_shader_depth_of_field_get( + &dof_prepare_sh, &dof_downsample_sh, &dof_blur1_sh, &dof_blur2_sh, &dof_resolve_sh); + EXPECT_NE(dof_prepare_sh, nullptr); + EXPECT_NE(dof_downsample_sh, nullptr); + EXPECT_NE(dof_blur1_sh, nullptr); + EXPECT_NE(dof_blur2_sh, nullptr); + EXPECT_NE(dof_resolve_sh, nullptr); + + workbench_shader_free(); +} + +TEST_F(DrawTest, gpencil_glsl_shaders) +{ + EXPECT_NE(GPENCIL_shader_antialiasing(0), nullptr); + EXPECT_NE(GPENCIL_shader_antialiasing(1), nullptr); + EXPECT_NE(GPENCIL_shader_antialiasing(2), nullptr); + + EXPECT_NE(GPENCIL_shader_geometry_get(), nullptr); + EXPECT_NE(GPENCIL_shader_layer_blend_get(), nullptr); + EXPECT_NE(GPENCIL_shader_mask_invert_get(), nullptr); + EXPECT_NE(GPENCIL_shader_depth_merge_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_blur_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_colorize_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_composite_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_transform_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_glow_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_pixelize_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_rim_get(), nullptr); + EXPECT_NE(GPENCIL_shader_fx_shadow_get(), nullptr); + + GPENCIL_shader_free(); +} + +TEST_F(DrawTest, overlay_glsl_shaders) +{ + for (int i = 0; i < 2; i++) { + eGPUShaderConfig sh_cfg = i == 0 ? GPU_SHADER_CFG_DEFAULT : GPU_SHADER_CFG_CLIPPED; + DRW_draw_state_init_gtests(sh_cfg); + EXPECT_NE(OVERLAY_shader_antialiasing(), nullptr); + EXPECT_NE(OVERLAY_shader_armature_degrees_of_freedom_wire(), nullptr); + EXPECT_NE(OVERLAY_shader_armature_degrees_of_freedom_solid(), nullptr); + EXPECT_NE(OVERLAY_shader_armature_envelope(false), nullptr); + EXPECT_NE(OVERLAY_shader_armature_envelope(true), nullptr); + EXPECT_NE(OVERLAY_shader_armature_shape(false), nullptr); + EXPECT_NE(OVERLAY_shader_armature_shape(true), nullptr); + EXPECT_NE(OVERLAY_shader_armature_shape_wire(), nullptr); + EXPECT_NE(OVERLAY_shader_armature_sphere(false), nullptr); + EXPECT_NE(OVERLAY_shader_armature_sphere(true), nullptr); + EXPECT_NE(OVERLAY_shader_armature_stick(), nullptr); + EXPECT_NE(OVERLAY_shader_armature_wire(), nullptr); + EXPECT_NE(OVERLAY_shader_background(), nullptr); + EXPECT_NE(OVERLAY_shader_clipbound(), nullptr); + EXPECT_NE(OVERLAY_shader_depth_only(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_curve_handle(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_curve_point(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_curve_wire(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_gpencil_guide_point(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_gpencil_point(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_gpencil_wire(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_lattice_point(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_lattice_wire(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_analysis(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_edge(false), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_edge(true), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_face(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_facedot(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_normal(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_skin_root(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_mesh_vert(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_particle_strand(), nullptr); + EXPECT_NE(OVERLAY_shader_edit_particle_point(), nullptr); + EXPECT_NE(OVERLAY_shader_extra(false), nullptr); + EXPECT_NE(OVERLAY_shader_extra(true), nullptr); + EXPECT_NE(OVERLAY_shader_extra_groundline(), nullptr); + EXPECT_NE(OVERLAY_shader_extra_wire(false, false), nullptr); + EXPECT_NE(OVERLAY_shader_extra_wire(false, true), nullptr); + EXPECT_NE(OVERLAY_shader_extra_wire(true, false), nullptr); + EXPECT_NE(OVERLAY_shader_extra_wire(true, true), nullptr); + EXPECT_NE(OVERLAY_shader_extra_loose_point(), nullptr); + EXPECT_NE(OVERLAY_shader_extra_point(), nullptr); + EXPECT_NE(OVERLAY_shader_facing(), nullptr); + EXPECT_NE(OVERLAY_shader_gpencil_canvas(), nullptr); + EXPECT_NE(OVERLAY_shader_grid(), nullptr); + EXPECT_NE(OVERLAY_shader_image(), nullptr); + EXPECT_NE(OVERLAY_shader_motion_path_line(), nullptr); + EXPECT_NE(OVERLAY_shader_motion_path_vert(), nullptr); + EXPECT_NE(OVERLAY_shader_uniform_color(), nullptr); + EXPECT_NE(OVERLAY_shader_outline_prepass(false), nullptr); + EXPECT_NE(OVERLAY_shader_outline_prepass(true), nullptr); + EXPECT_NE(OVERLAY_shader_outline_prepass_gpencil(), nullptr); + EXPECT_NE(OVERLAY_shader_outline_prepass_pointcloud(), nullptr); + EXPECT_NE(OVERLAY_shader_extra_grid(), nullptr); + EXPECT_NE(OVERLAY_shader_outline_detect(), nullptr); + EXPECT_NE(OVERLAY_shader_paint_face(), nullptr); + EXPECT_NE(OVERLAY_shader_paint_point(), nullptr); + EXPECT_NE(OVERLAY_shader_paint_texture(), nullptr); + EXPECT_NE(OVERLAY_shader_paint_vertcol(), nullptr); + EXPECT_NE(OVERLAY_shader_paint_weight(), nullptr); + EXPECT_NE(OVERLAY_shader_paint_wire(), nullptr); + EXPECT_NE(OVERLAY_shader_particle_dot(), nullptr); + EXPECT_NE(OVERLAY_shader_particle_shape(), nullptr); + EXPECT_NE(OVERLAY_shader_sculpt_mask(), nullptr); + EXPECT_NE(OVERLAY_shader_volume_velocity(false), nullptr); + EXPECT_NE(OVERLAY_shader_volume_velocity(true), nullptr); + EXPECT_NE(OVERLAY_shader_wireframe(false), nullptr); + EXPECT_NE(OVERLAY_shader_wireframe(true), nullptr); + EXPECT_NE(OVERLAY_shader_wireframe_select(), nullptr); + EXPECT_NE(OVERLAY_shader_xray_fade(), nullptr); + } + + OVERLAY_shader_free(); +} + +TEST_F(DrawTest, eevee_glsl_shaders_static) +{ + EEVEE_shaders_lightprobe_shaders_init(); + EEVEE_shaders_material_shaders_init(); + + EXPECT_NE(EEVEE_shaders_probe_filter_glossy_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_probe_filter_diffuse_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_probe_filter_visibility_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_probe_grid_fill_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_probe_planar_downsample_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_studiolight_probe_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_studiolight_background_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_probe_cube_display_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_probe_grid_display_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_probe_planar_display_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_update_noise_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_velocity_resolve_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_taa_resolve_sh_get(EFFECT_TAA), nullptr); + EXPECT_NE(EEVEE_shaders_taa_resolve_sh_get(EFFECT_TAA_REPROJECT), nullptr); + + EEVEE_shaders_free(); +}
\ No newline at end of file diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 9490c807989..f99301371d4 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -970,7 +970,7 @@ static bool do_lasso_select_curve(ViewContext *vc, /* Deselect items that were not added to selection (indicated by temp flag). */ if (deselect_all) { - BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); + data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); } if (data.is_changed) { @@ -2772,7 +2772,7 @@ static bool do_nurbs_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel /* Deselect items that were not added to selection (indicated by temp flag). */ if (deselect_all) { - BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); + data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); } BKE_curve_nurb_vert_active_validate(vc->obedit->data); @@ -3693,7 +3693,6 @@ static bool nurbscurve_circle_select(ViewContext *vc, const bool select = (sel_op != SEL_OP_SUB); const bool deselect_all = (sel_op == SEL_OP_SET); CircleSelectUserData data; - bool changed = false; view3d_userdata_circleselect_init(&data, vc, select, mval, rad); @@ -3711,12 +3710,12 @@ static bool nurbscurve_circle_select(ViewContext *vc, /* Deselect items that were not added to selection (indicated by temp flag). */ if (deselect_all) { - BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); + data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); } BKE_curve_nurb_vert_active_validate(vc->obedit->data); - return changed || data.is_changed; + return data.is_changed; } static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2]) diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h index e56df6d77a7..253877bcca0 100644 --- a/source/blender/gpu/GPU_state.h +++ b/source/blender/gpu/GPU_state.h @@ -29,6 +29,7 @@ typedef enum eGPUWriteMask { GPU_WRITE_BLUE = (1 << 2), GPU_WRITE_ALPHA = (1 << 3), GPU_WRITE_DEPTH = (1 << 4), + GPU_WRITE_STENCIL = (1 << 5), GPU_WRITE_COLOR = (GPU_WRITE_RED | GPU_WRITE_GREEN | GPU_WRITE_BLUE | GPU_WRITE_ALPHA), } eGPUWriteMask; diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index 22de1a0f59e..d56a7b2500b 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -36,7 +36,7 @@ namespace gpu { class Shader { public: /** Uniform & attribute locations for shader. */ - ShaderInterface *interface; + ShaderInterface *interface = nullptr; protected: /** For debugging purpose. */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 7aaedbff1ce..29e29961028 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -1373,6 +1373,7 @@ static int make_structDNA(const char *base_directory, /* write a simple enum with all structs offsets, * should only be accessed via SDNA_TYPE_FROM_STRUCT macro */ { + fprintf(file_offsets, "#pragma once\n"); fprintf(file_offsets, "#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n"); fprintf(file_offsets, "enum {\n"); for (i = 0; i < structs_len; i++) { |