diff options
Diffstat (limited to 'source/blender/modifiers/intern')
23 files changed, 344 insertions, 245 deletions
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index a7364af10a3..0b2ea0e1ade 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -396,10 +396,12 @@ static void panelRegister(ARegionType *region_type) region_type, "shading", "Shading", NULL, shading_panel_draw, panel_type); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md) { const BevelModifierData *bmd = (const BevelModifierData *)md; + BLO_write_struct(writer, BevelModifierData, bmd); + if (bmd->custom_profile) { BKE_curveprofile_blend_write(writer, bmd->custom_profile); } diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index 52162eaacc5..8b6c306dae8 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -798,12 +798,25 @@ static void panelRegister(ARegionType *region_type) modifier_panel_register(region_type, eModifierType_CorrectiveSmooth, panel_draw); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierData *md) { - const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md; + CorrectiveSmoothModifierData csmd = *(const CorrectiveSmoothModifierData *)md; + + if (ID_IS_OVERRIDE_LIBRARY(id_owner)) { + BLI_assert(!ID_IS_LINKED(id_owner)); + const bool is_local = (md->flag & eModifierFlag_OverrideLibrary_Local) != 0; + if (!is_local) { + /* Modifier coming from linked data cannot be bound from an override, so we can remove all + * binding data, can save a significant amount of memory. */ + csmd.bind_coords_num = 0; + csmd.bind_coords = NULL; + } + } - if (csmd->bind_coords) { - BLO_write_float3_array(writer, csmd->bind_coords_num, (float *)csmd->bind_coords); + BLO_write_struct_at_address(writer, CorrectiveSmoothModifierData, md, &csmd); + + if (csmd.bind_coords != NULL) { + BLO_write_float3_array(writer, csmd.bind_coords_num, (float *)csmd.bind_coords); } } diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 7ad7d6eef3d..149cf0c0cbb 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -310,13 +310,11 @@ static void displaceModifier_do(DisplaceModifierData *dmd, CustomData *ldata = &mesh->ldata; if (CustomData_has_layer(ldata, CD_CUSTOMLOOPNORMAL)) { - float(*clnors)[3] = NULL; - if (!CustomData_has_layer(ldata, CD_NORMAL)) { BKE_mesh_calc_normals_split(mesh); } - clnors = CustomData_get_layer(ldata, CD_NORMAL); + float(*clnors)[3] = CustomData_get_layer(ldata, CD_NORMAL); vert_clnors = MEM_malloc_arrayN(verts_num, sizeof(*vert_clnors), __func__); BKE_mesh_normals_loop_to_vertex( verts_num, mesh->mloop, mesh->totloop, (const float(*)[3])clnors, vert_clnors); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 9e2bb79138e..d76a750f7e8 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -124,7 +124,7 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p /* set protected verts */ if (emd->vgroup) { - MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); + const MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); if (dvert) { const int defgrp_index = emd->vgroup - 1; for (i = 0; i < totvert; i++, dvert++) { @@ -911,7 +911,6 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0; int i, v, u; uint ed_v1, ed_v2, mindex = 0; - MTFace *mtface = NULL, *mtf; totface = mesh->totface; totvert = mesh->totvert; @@ -977,7 +976,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* the final duplicated vertices */ explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0); - mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname); + MTFace *mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname); /* getting back to object space */ invert_m4_m4(imat, ctx->object->obmat); @@ -1086,7 +1085,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* Clamp to this range to avoid flipping to the other side of the coordinates. */ CLAMP(age, 0.001f, 0.999f); - mtf = mtface + u; + MTFace *mtf = mtface + u; mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age; mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f; diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 1000bbf45d6..3649ece12e1 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -519,10 +519,12 @@ static void panelRegister(ARegionType *region_type) region_type, "falloff", "Falloff", NULL, falloff_panel_draw, panel_type); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md) { const HookModifierData *hmd = (const HookModifierData *)md; + BLO_write_struct(writer, HookModifierData, hmd); + if (hmd->curfalloff) { BKE_curvemapping_blend_write(writer, hmd->curfalloff); } diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index 239cb7f5a5a..06ded1c4488 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -843,11 +843,26 @@ static void panelRegister(ARegionType *region_type) modifier_panel_register(region_type, eModifierType_LaplacianDeform, panel_draw); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierData *md) { - LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md; + LaplacianDeformModifierData lmd = *(const LaplacianDeformModifierData *)md; + + if (ID_IS_OVERRIDE_LIBRARY(id_owner)) { + BLI_assert(!ID_IS_LINKED(id_owner)); + const bool is_local = (md->flag & eModifierFlag_OverrideLibrary_Local) != 0; + if (!is_local) { + /* Modifier coming from linked data cannot be bound from an override, so we can remove all + * binding data, can save a significant amount of memory. */ + lmd.verts_num = 0; + lmd.vertexco = NULL; + } + } - BLO_write_float3_array(writer, lmd->verts_num, lmd->vertexco); + BLO_write_struct_at_address(writer, LaplacianDeformModifierData, md, &lmd); + + if (lmd.vertexco != NULL) { + BLO_write_float3_array(writer, lmd.verts_num, lmd.vertexco); + } } static void blendRead(BlendDataReader *reader, ModifierData *md) diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 900dee98268..0813901fc49 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -91,7 +91,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte } /* A vertex will be in the mask if a selected bone influences it more than a certain threshold. */ -static void compute_vertex_mask__armature_mode(MDeformVert *dvert, +static void compute_vertex_mask__armature_mode(const MDeformVert *dvert, Mesh *mesh, Object *armature_ob, float threshold, @@ -125,7 +125,7 @@ static void compute_vertex_mask__armature_mode(MDeformVert *dvert, } /* A vertex will be in the mask if the vertex group influences it more than a certain threshold. */ -static void compute_vertex_mask__vertex_group_mode(MDeformVert *dvert, +static void compute_vertex_mask__vertex_group_mode(const MDeformVert *dvert, int defgrp_index, float threshold, MutableSpan<bool> r_vertex_mask) @@ -347,7 +347,7 @@ static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, } static float get_interp_factor_from_vgroup( - MDeformVert *dvert, int defgrp_index, float threshold, uint v1, uint v2) + const MDeformVert *dvert, int defgrp_index, float threshold, uint v1, uint v2) { /* NOTE: this calculation is done twice for every vertex, * instead of storing it the first time and then reusing it. */ @@ -360,7 +360,7 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span<bool> vertex_mask, Span<int> vertex_map, - MDeformVert *dvert, + const MDeformVert *dvert, int defgrp_index, float threshold, uint edges_masked_num, @@ -478,7 +478,7 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, Span<bool> vertex_mask, Span<int> vertex_map, Span<int> edge_map, - MDeformVert *dvert, + const MDeformVert *dvert, int defgrp_index, float threshold, Span<int> masked_poly_indices, @@ -619,7 +619,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) (mmd->flag & MOD_MASK_SMOOTH); /* Return empty or input mesh when there are no vertex groups. */ - MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); + const MDeformVert *dvert = (const MDeformVert *)CustomData_get_layer(&mesh->vdata, + CD_MDEFORMVERT); if (dvert == nullptr) { return invert_mask ? mesh : BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0); } diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index c2e9e5ebe7d..0cff85d30ec 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -581,26 +581,49 @@ static void panelRegister(ARegionType *region_type) modifier_panel_register(region_type, eModifierType_MeshDeform, panel_draw); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierData *md) { - MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; - int size = mmd->dyngridsize; + MeshDeformModifierData mmd = *(const MeshDeformModifierData *)md; + + if (ID_IS_OVERRIDE_LIBRARY(id_owner)) { + BLI_assert(!ID_IS_LINKED(id_owner)); + const bool is_local = (md->flag & eModifierFlag_OverrideLibrary_Local) != 0; + if (!is_local) { + /* Modifier coming from linked data cannot be bound from an override, so we can remove all + * binding data, can save a significant amount of memory. */ + mmd.influences_num = 0; + mmd.bindinfluences = NULL; + mmd.verts_num = 0; + mmd.bindoffsets = NULL; + mmd.cage_verts_num = 0; + mmd.bindcagecos = NULL; + mmd.dyngridsize = 0; + mmd.dyngrid = NULL; + mmd.influences_num = 0; + mmd.dyninfluences = NULL; + mmd.dynverts = NULL; + } + } - BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->bindinfluences); + const int size = mmd.dyngridsize; + + BLO_write_struct_at_address(writer, MeshDeformModifierData, md, &mmd); + + BLO_write_struct_array(writer, MDefInfluence, mmd.influences_num, mmd.bindinfluences); /* NOTE: `bindoffset` is abusing `verts_num + 1` as its size, this becomes an incorrect value in * case `verts_num == 0`, since `bindoffset` is then NULL, not a size 1 allocated array. */ - if (mmd->verts_num > 0) { - BLO_write_int32_array(writer, mmd->verts_num + 1, mmd->bindoffsets); + if (mmd.verts_num > 0) { + BLO_write_int32_array(writer, mmd.verts_num + 1, mmd.bindoffsets); } else { - BLI_assert(mmd->bindoffsets == NULL); + BLI_assert(mmd.bindoffsets == NULL); } - BLO_write_float3_array(writer, mmd->cage_verts_num, mmd->bindcagecos); - BLO_write_struct_array(writer, MDefCell, size * size * size, mmd->dyngrid); - BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->dyninfluences); - BLO_write_int32_array(writer, mmd->verts_num, mmd->dynverts); + BLO_write_float3_array(writer, mmd.cage_verts_num, mmd.bindcagecos); + BLO_write_struct_array(writer, MDefCell, size * size * size, mmd.dyngrid); + BLO_write_struct_array(writer, MDefInfluence, mmd.influences_num, mmd.dyninfluences); + BLO_write_int32_array(writer, mmd.verts_num, mmd.dynverts); } static void blendRead(BlendDataReader *reader, ModifierData *md) diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc index 998fb0a94a3..273050eafd8 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc @@ -5,8 +5,9 @@ */ #include <cstring> +#include <limits> -#include "BLI_math_vector.h" +#include "BLI_math_vector.hh" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -15,7 +16,6 @@ #include "DNA_cachefile_types.h" #include "DNA_defaults.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -42,6 +42,8 @@ #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_query.h" +#include "GEO_mesh_primitive_cuboid.hh" + #include "MOD_modifiertypes.h" #include "MOD_ui_common.h" @@ -104,40 +106,17 @@ static bool isDisabled(const struct Scene *UNUSED(scene), return (mcmd->cache_file == nullptr) || (mcmd->object_path[0] == '\0'); } -static Mesh *generate_bounding_box_mesh(Object *object, Mesh *org_mesh) +static Mesh *generate_bounding_box_mesh(const Mesh *org_mesh) { - const BoundBox *bb = BKE_object_boundbox_get(object); - Mesh *result = BKE_mesh_new_nomain_from_template(org_mesh, 8, 0, 0, 24, 6); - - MVert *mvert = result->mvert; - for (int i = 0; i < 8; ++i) { - copy_v3_v3(mvert[i].co, bb->vec[i]); - } - - /* See DNA_object_types.h for the diagram showing the order of the vertices for a BoundBox. */ - static unsigned int loops_v[6][4] = { - {0, 4, 5, 1}, - {4, 7, 6, 5}, - {7, 3, 2, 6}, - {3, 0, 1, 2}, - {1, 5, 6, 2}, - {3, 7, 4, 0}, - }; - - MLoop *mloop = result->mloop; - for (int i = 0; i < 6; ++i) { - for (int j = 0; j < 4; ++j, ++mloop) { - mloop->v = loops_v[i][j]; - } - } - - MPoly *mpoly = result->mpoly; - for (int i = 0; i < 6; ++i) { - mpoly[i].loopstart = i * 4; - mpoly[i].totloop = 4; + using namespace blender; + float3 min(std::numeric_limits<float>::max()); + float3 max(-std::numeric_limits<float>::max()); + if (!BKE_mesh_minmax(org_mesh, min, max)) { + return nullptr; } - BKE_mesh_calc_edges(result, false, false); + Mesh *result = geometry::create_cuboid_mesh(max - min, 2, 2, 2); + BKE_mesh_translate(result, math::midpoint(min, max), false); return result; } @@ -170,7 +149,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Do not process data if using a render procedural, return a box instead for displaying in the * viewport. */ if (BKE_cache_file_uses_render_procedural(cache_file, scene)) { - return generate_bounding_box_mesh(ctx->object, org_mesh); + return generate_bounding_box_mesh(org_mesh); } /* If this invocation is for the ORCO mesh, and the mesh hasn't changed topology, we diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 21041e8e1b2..0d8cef3e083 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -985,17 +985,16 @@ static Vector<OutputAttributeToStore> compute_attributes_to_store( if (!component.attribute_domain_supported(domain)) { continue; } - const int domain_size = component.attribute_domain_size(domain); + const int domain_num = component.attribute_domain_num(domain); blender::bke::GeometryComponentFieldContext field_context{component, domain}; - blender::fn::FieldEvaluator field_evaluator{field_context, domain_size}; + blender::fn::FieldEvaluator field_evaluator{field_context, domain_num}; for (const OutputAttributeInfo &output_info : outputs_info) { const CPPType &type = output_info.field.cpp_type(); OutputAttributeToStore store{ component_type, domain, output_info.name, - GMutableSpan{ - type, MEM_malloc_arrayN(domain_size, type.size(), __func__), domain_size}}; + GMutableSpan{type, MEM_malloc_arrayN(domain_num, type.size(), __func__), domain_num}}; field_evaluator.add_with_destination(output_info.field, store.data); attributes_to_store.append(store); } @@ -1730,9 +1729,12 @@ static void panelRegister(ARegionType *region_type) panel_type); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md) { const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md); + + BLO_write_struct(writer, NodesModifierData, nmd); + if (nmd->settings.properties != nullptr) { /* Note that the property settings are based on the socket type info * and don't necessarily need to be written, but we can't just free them. */ @@ -1799,7 +1801,7 @@ ModifierTypeInfo modifierType_Nodes = { eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_SupportsMapping), - /* icon */ ICON_NODETREE, + /* icon */ ICON_GEOMETRY_NODES, /* copyData */ copyData, diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index fe05f48a868..c215ac601a1 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -136,7 +136,7 @@ static void mix_normals(const float mix_factor, if (dvert) { facs = MEM_malloc_arrayN((size_t)loops_num, sizeof(*facs), __func__); BKE_defvert_extract_vgroup_to_loopweights( - dvert, defgrp_index, verts_num, mloop, loops_num, facs, use_invert_vgroup); + dvert, defgrp_index, verts_num, mloop, loops_num, use_invert_vgroup, facs); } for (i = loops_num, no_new = nos_new, no_old = nos_old, wfac = facs; i--; @@ -532,14 +532,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, MDeformVert *dvert; float(*loopnors)[3] = NULL; - short(*clnors)[2] = NULL; CustomData *ldata = &result->ldata; const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(result); const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(result); - clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); + short(*clnors)[2] = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); if (use_current_clnors) { clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num); loopnors = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loopnors), __func__); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.cc index 032227307e7..c6a606360e3 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.cc @@ -5,8 +5,8 @@ * \ingroup modifiers */ -#include <stddef.h> -#include <string.h> +#include <cstddef> +#include <cstring> #include "BLI_utildefines.h" @@ -51,11 +51,11 @@ static void freeData(ModifierData *md) ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; if (psmd->mesh_final) { - BKE_id_free(NULL, psmd->mesh_final); - psmd->mesh_final = NULL; + BKE_id_free(nullptr, psmd->mesh_final); + psmd->mesh_final = nullptr; if (psmd->mesh_original) { - BKE_id_free(NULL, psmd->mesh_original); - psmd->mesh_original = NULL; + BKE_id_free(nullptr, psmd->mesh_original); + psmd->mesh_original = nullptr; } } psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; @@ -81,8 +81,8 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla * code has to be called then to ensure proper remapping of that pointer. See e.g. * `BKE_object_copy_particlesystems` or `BKE_object_copy_modifier`. */ - tpsmd->mesh_final = NULL; - tpsmd->mesh_original = NULL; + tpsmd->mesh_final = nullptr; + tpsmd->mesh_original = nullptr; tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0; } @@ -104,7 +104,7 @@ static void deformVerts(ModifierData *md, { Mesh *mesh_src = mesh; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - ParticleSystem *psys = NULL; + ParticleSystem *psys = nullptr; if (ctx->object->particlesystem.first) { psys = psmd->psys; @@ -117,28 +117,28 @@ static void deformVerts(ModifierData *md, return; } - if (mesh_src == NULL) { + if (mesh_src == nullptr) { mesh_src = MOD_deform_mesh_eval_get( - ctx->object, NULL, NULL, vertexCos, verts_num, false, true); - if (mesh_src == NULL) { + ctx->object, nullptr, nullptr, vertexCos, verts_num, false, true); + if (mesh_src == nullptr) { return; } } /* clear old dm */ - bool had_mesh_final = (psmd->mesh_final != NULL); + bool had_mesh_final = (psmd->mesh_final != nullptr); if (psmd->mesh_final) { - BKE_id_free(NULL, psmd->mesh_final); - psmd->mesh_final = NULL; + BKE_id_free(nullptr, psmd->mesh_final); + psmd->mesh_final = nullptr; if (psmd->mesh_original) { - BKE_id_free(NULL, psmd->mesh_original); - psmd->mesh_original = NULL; + BKE_id_free(nullptr, psmd->mesh_original); + psmd->mesh_original = nullptr; } } else if (psmd->flag & eParticleSystemFlag_file_loaded) { /* in file read mesh just wasn't saved in file so no need to reset everything */ psmd->flag &= ~eParticleSystemFlag_file_loaded; - if (psys->particles == NULL) { + if (psys->particles == nullptr) { psys->recalc |= ID_RECALC_PSYS_RESET; } /* TODO(sergey): This is not how particles were working prior to copy on @@ -165,18 +165,18 @@ static void deformVerts(ModifierData *md, /* Get the original mesh from the object, this is what the particles * are attached to so in case of non-deform modifiers we need to remap * them to the final mesh (typically subdivision surfaces). */ - Mesh *mesh_original = NULL; + Mesh *mesh_original = nullptr; if (ctx->object->type == OB_MESH) { BMEditMesh *em = BKE_editmesh_from_object(ctx->object); if (em) { /* In edit mode get directly from the edit mesh. */ - psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, mesh); + psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, nullptr, mesh); } else { /* Otherwise get regular mesh. */ - mesh_original = ctx->object->data; + mesh_original = static_cast<Mesh *>(ctx->object->data); } } else { @@ -193,8 +193,8 @@ static void deformVerts(ModifierData *md, BKE_mesh_tessface_ensure(psmd->mesh_original); } - if (!ELEM(mesh_src, NULL, mesh, psmd->mesh_final)) { - BKE_id_free(NULL, mesh_src); + if (!ELEM(mesh_src, nullptr, mesh, psmd->mesh_final)) { + BKE_id_free(nullptr, mesh_src); } /* Report change in mesh structure. @@ -221,7 +221,7 @@ static void deformVerts(ModifierData *md, if (DEG_is_active(ctx->depsgraph)) { Object *object_orig = DEG_get_original_object(ctx->object); ModifierData *md_orig = BKE_modifiers_findby_name(object_orig, psmd->modifier.name); - BLI_assert(md_orig != NULL); + BLI_assert(md_orig != nullptr); ParticleSystemModifierData *psmd_orig = (ParticleSystemModifierData *)md_orig; psmd_orig->flag = psmd->flag; } @@ -237,16 +237,16 @@ static void deformVertsEM(ModifierData *md, float (*vertexCos)[3], int verts_num) { - const bool do_temp_mesh = (mesh == NULL); + const bool do_temp_mesh = (mesh == nullptr); if (do_temp_mesh) { mesh = BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name); - BM_mesh_bm_to_me(NULL, editData->bm, mesh, &((BMeshToMeshParams){0})); + BM_mesh_bm_to_me(nullptr, editData->bm, mesh, &((BMeshToMeshParams){0})); } deformVerts(md, ob, mesh, vertexCos, verts_num); if (derivedData) { - BKE_id_free(NULL, mesh); + BKE_id_free(nullptr, mesh); } } #endif @@ -258,7 +258,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) PointerRNA ob_ptr; PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr); - Object *ob = ob_ptr.data; + Object *ob = static_cast<Object *>(ob_ptr.data); ModifierData *md = (ModifierData *)ptr->data; ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys; @@ -291,8 +291,8 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - psmd->mesh_final = NULL; - psmd->mesh_original = NULL; + psmd->mesh_final = nullptr; + psmd->mesh_original = nullptr; /* This is written as part of ob->particlesystem. */ BLO_read_data_address(reader, &psmd->psys); psmd->flag &= ~eParticleSystemFlag_psys_updated; @@ -315,23 +315,23 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* copyData */ copyData, /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /* deformMatrices */ nullptr, + /* deformVertsEM */ nullptr, + /* deformMatricesEM */ nullptr, + /* modifyMesh */ nullptr, + /* modifyGeometrySet */ nullptr, /* initData */ initData, /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, + /* isDisabled */ nullptr, + /* updateDepsgraph */ nullptr, + /* dependsOnTime */ nullptr, + /* dependsOnNormals */ nullptr, + /* foreachIDLink */ nullptr, + /* foreachTexLink */ nullptr, + /* freeRuntimeData */ nullptr, /* panelRegister */ panelRegister, - /* blendWrite */ NULL, + /* blendWrite */ nullptr, /* blendRead */ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 08925e8aeb1..0e22f59c2fb 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -182,7 +182,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ScrewModifierData *ltmd = (ScrewModifierData *)md; const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER) != 0; - int *origindex; int mpoly_index = 0; uint step; uint i, j; @@ -375,6 +374,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f)); } + /* The `screw_ofs` cannot change from now on. */ + const bool do_remove_doubles = (ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f); + /* Only calculate normals if `do_remove_doubles` since removing doubles frees the normals. */ + const bool do_normal_create = (ltmd->flag & MOD_SCREW_NORMAL_CALC) && + (do_remove_doubles == false); + result = BKE_mesh_new_nomain_from_template( mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); @@ -383,7 +388,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * medge_orig = mesh->medge; mvert_new = result->mvert; - float(*vert_normals_new)[3] = BKE_mesh_vertex_normals_for_write(result); mpoly_new = result->mpoly; mloop_new = result->mloop; medge_new = result->medge; @@ -392,7 +396,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, (int)maxPolys); } - origindex = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); + int *origindex = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert); @@ -472,7 +476,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } } + float(*vert_normals_new)[3] = do_normal_create ? BKE_mesh_vertex_normals_for_write(result) : + NULL; + if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { + /* * Normal Calculation (for face flipping) * Sort edge verts for correct face flipping @@ -766,68 +774,69 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * * calculate vertex normals that can be propagated on lathing * use edge connectivity work this out */ - if (SV_IS_VALID(vc->v[0])) { - if (SV_IS_VALID(vc->v[1])) { - /* 2 edges connected. */ - /* make 2 connecting vert locations relative to the middle vert */ - sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); - sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co); - /* normalize so both edges have the same influence, no matter their length */ - normalize_v3(tmp_vec1); - normalize_v3(tmp_vec2); - - /* vc_no_tmp1 - this line is the average direction of both connecting edges - * - * Use the edge order to make the subtraction, flip the normal the right way - * edge should be there but check just in case... */ - if (vc->e[0]->v1 == i) { - sub_v3_v3(tmp_vec1, tmp_vec2); - } - else { - sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1); - } - } - else { - /* only 1 edge connected - same as above except - * don't need to average edge direction */ - if (vc->e[0]->v2 == i) { - sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co); + if (do_normal_create) { + if (SV_IS_VALID(vc->v[0])) { + if (SV_IS_VALID(vc->v[1])) { + /* 2 edges connected. */ + /* make 2 connecting vert locations relative to the middle vert */ + sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co); + /* normalize so both edges have the same influence, no matter their length */ + normalize_v3(tmp_vec1); + normalize_v3(tmp_vec2); + + /* vc_no_tmp1 - this line is the average direction of both connecting edges + * + * Use the edge order to make the subtraction, flip the normal the right way + * edge should be there but check just in case... */ + if (vc->e[0]->v1 == i) { + sub_v3_v3(tmp_vec1, tmp_vec2); + } + else { + sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1); + } } else { - sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + /* only 1 edge connected - same as above except + * don't need to average edge direction */ + if (vc->e[0]->v2 == i) { + sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co); + } + else { + sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + } } - } - /* tmp_vec2 - is a line 90d from the pivot to the vec - * This is used so the resulting normal points directly away from the middle */ - cross_v3_v3v3(tmp_vec2, axis_vec, vc->co); + /* tmp_vec2 - is a line 90d from the pivot to the vec + * This is used so the resulting normal points directly away from the middle */ + cross_v3_v3v3(tmp_vec2, axis_vec, vc->co); - if (UNLIKELY(is_zero_v3(tmp_vec2))) { - /* we're _on_ the axis, so copy it based on our winding */ - if (vc->e[0]->v2 == i) { - negate_v3_v3(vc->no, axis_vec); + if (UNLIKELY(is_zero_v3(tmp_vec2))) { + /* we're _on_ the axis, so copy it based on our winding */ + if (vc->e[0]->v2 == i) { + negate_v3_v3(vc->no, axis_vec); + } + else { + copy_v3_v3(vc->no, axis_vec); + } } else { - copy_v3_v3(vc->no, axis_vec); + /* edge average vector and right angle to the pivot make the normal */ + cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2); } } else { - /* edge average vector and right angle to the pivot make the normal */ - cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2); + copy_v3_v3(vc->no, vc->co); } - } - else { - copy_v3_v3(vc->no, vc->co); - } - - /* we won't be looping on this data again so copy normals here */ - if ((angle < 0.0f) != do_flip) { - negate_v3(vc->no); - } - normalize_v3(vc->no); - copy_v3_v3(vert_normals_new[i], vc->no); + /* we won't be looping on this data again so copy normals here */ + if ((angle < 0.0f) != do_flip) { + negate_v3(vc->no); + } + normalize_v3(vc->no); + copy_v3_v3(vert_normals_new[i], vc->no); + } /* Done with normals */ } } @@ -846,7 +855,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * for (step = 1; step < step_tot; step++) { const uint varray_stride = totvert * step; float step_angle; - float nor_tx[3]; float mat[4][4]; /* Rotation Matrix */ step_angle = (angle / (float)(step_tot - (!close))) * (float)step; @@ -872,10 +880,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) { /* set normal */ if (vert_connect) { - mul_v3_m3v3(nor_tx, mat3, vert_connect[j].no); - - /* set the normal now its transformed */ - copy_v3_v3(vert_normals_new[mv_new - mvert_new], nor_tx); + if (do_normal_create) { + /* Set the normal now its transformed. */ + mul_v3_m3v3(vert_normals_new[mv_new - mvert_new], mat3, vert_connect[j].no); + } } /* set location */ @@ -1118,11 +1126,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEM_freeN(vert_loop_map); } - if ((ltmd->flag & MOD_SCREW_NORMAL_CALC)) { + if (do_normal_create) { BKE_mesh_vertex_normals_clear_dirty(result); } - if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) { + if (do_remove_doubles) { result = mesh_remove_doubles_on_axis(result, mvert_new, totvert, diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 7f96dcb82fb..5f238209015 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -881,34 +881,29 @@ static int calc_edge_subdivisions(const MVert *mvert, /* Take a Mesh and subdivide its edges to keep skin nodes * reasonably close. */ -static Mesh *subdivide_base(Mesh *orig) +static Mesh *subdivide_base(const Mesh *orig) { - Mesh *result; - MVertSkin *orignode, *outnode; - MVert *origvert, *outvert; - MEdge *origedge, *outedge, *e; - MDeformVert *origdvert, *outdvert; - int orig_vert_num, orig_edge_num; - int subd_num, *degree, *edge_subd; + const MEdge *e; + int subd_num; int i, j, k, u, v; float radrat; - orignode = CustomData_get_layer(&orig->vdata, CD_MVERT_SKIN); - origvert = orig->mvert; - origedge = orig->medge; - origdvert = orig->dvert; - orig_vert_num = orig->totvert; - orig_edge_num = orig->totedge; + const MVertSkin *orignode = CustomData_get_layer(&orig->vdata, CD_MVERT_SKIN); + const MVert *origvert = orig->mvert; + const MEdge *origedge = orig->medge; + const MDeformVert *origdvert = orig->dvert; + int orig_vert_num = orig->totvert; + int orig_edge_num = orig->totedge; /* Get degree of all vertices */ - degree = MEM_calloc_arrayN(orig_vert_num, sizeof(int), "degree"); + int *degree = MEM_calloc_arrayN(orig_vert_num, sizeof(int), "degree"); for (i = 0; i < orig_edge_num; i++) { degree[origedge[i].v1]++; degree[origedge[i].v2]++; } /* Per edge, store how many subdivisions are needed */ - edge_subd = MEM_calloc_arrayN((uint)orig_edge_num, sizeof(int), "edge_subd"); + int *edge_subd = MEM_calloc_arrayN((uint)orig_edge_num, sizeof(int), "edge_subd"); for (i = 0, subd_num = 0; i < orig_edge_num; i++) { edge_subd[i] += calc_edge_subdivisions(origvert, orignode, &origedge[i], degree); BLI_assert(edge_subd[i] >= 0); @@ -918,13 +913,13 @@ static Mesh *subdivide_base(Mesh *orig) MEM_freeN(degree); /* Allocate output mesh */ - result = BKE_mesh_new_nomain_from_template( + Mesh *result = BKE_mesh_new_nomain_from_template( orig, orig_vert_num + subd_num, orig_edge_num + subd_num, 0, 0, 0); - outvert = result->mvert; - outedge = result->medge; - outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN); - outdvert = result->dvert; + MVert *outvert = result->mvert; + MEdge *outedge = result->medge; + MVertSkin *outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN); + MDeformVert *outdvert = result->dvert; /* Copy original vertex data */ CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, orig_vert_num); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 48154a3670d..1f0aee7d689 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -75,7 +75,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * case MOD_SOLIDIFY_MODE_NONMANIFOLD: return MOD_solidify_nonmanifold_modifyMesh(md, ctx, mesh); default: - BLI_assert(0); + BLI_assert_unreachable(); } return mesh; } diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index a80918b8d2b..9b0012e3890 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1166,8 +1166,8 @@ static bool surfacedeformBind(Object *ob, SurfaceDeformModifierData *smd_eval, float (*vertexCos)[3], uint verts_num, - uint tpolys_num, - uint tverts_num, + uint target_polys_num, + uint target_verts_num, Mesh *target, Mesh *mesh) { @@ -1182,7 +1182,7 @@ static bool surfacedeformBind(Object *ob, SDefAdjacency *adj_array; SDefEdgePolys *edge_polys; - vert_edges = MEM_calloc_arrayN(tverts_num, sizeof(*vert_edges), "SDefVertEdgeMap"); + vert_edges = MEM_calloc_arrayN(target_verts_num, sizeof(*vert_edges), "SDefVertEdgeMap"); if (vert_edges == NULL) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); return false; @@ -1220,7 +1220,7 @@ static bool surfacedeformBind(Object *ob, } adj_result = buildAdjacencyMap( - mpoly, medge, mloop, tpolys_num, tedges_num, vert_edges, adj_array, edge_polys); + mpoly, medge, mloop, target_polys_num, tedges_num, vert_edges, adj_array, edge_polys); if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) { BKE_modifier_set_error( @@ -1233,7 +1233,8 @@ static bool surfacedeformBind(Object *ob, } smd_orig->mesh_verts_num = verts_num; - smd_orig->polys_num = tpolys_num; + smd_orig->target_verts_num = target_verts_num; + smd_orig->target_polys_num = target_polys_num; int defgrp_index; MDeformVert *dvert; @@ -1249,7 +1250,8 @@ static bool surfacedeformBind(Object *ob, .medge = medge, .mloop = mloop, .looptri = BKE_mesh_runtime_looptri_ensure(target), - .targetCos = MEM_malloc_arrayN(tverts_num, sizeof(float[3]), "SDefTargetBindVertArray"), + .targetCos = MEM_malloc_arrayN( + target_verts_num, sizeof(float[3]), "SDefTargetBindVertArray"), .bind_verts = smd_orig->verts, .vertexCos = vertexCos, .falloff = smd_orig->falloff, @@ -1268,7 +1270,7 @@ static bool surfacedeformBind(Object *ob, invert_m4_m4(data.imat, smd_orig->mat); - for (int i = 0; i < tverts_num; i++) { + for (int i = 0; i < target_verts_num; i++) { mul_v3_m4v3(data.targetCos[i], smd_orig->mat, mvert[i].co); } @@ -1431,7 +1433,7 @@ static void surfacedeformModifier_do(ModifierData *md, { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; Mesh *target; - uint tverts_num, tpolys_num; + uint target_verts_num, target_polys_num; /* Exit function if bind flag is not set (free bind data if any). */ if (!(smd->flags & MOD_SDEF_BIND)) { @@ -1453,8 +1455,8 @@ static void surfacedeformModifier_do(ModifierData *md, return; } - tverts_num = BKE_mesh_wrapper_vert_len(target); - tpolys_num = BKE_mesh_wrapper_poly_len(target); + target_verts_num = BKE_mesh_wrapper_vert_len(target); + target_polys_num = BKE_mesh_wrapper_poly_len(target); /* If not bound, execute bind. */ if (smd->verts == NULL) { @@ -1473,25 +1475,62 @@ static void surfacedeformModifier_do(ModifierData *md, /* Avoid converting edit-mesh data, binding is an exception. */ BKE_mesh_wrapper_ensure_mdata(target); - if (!surfacedeformBind( - ob, smd_orig, smd, vertexCos, verts_num, tpolys_num, tverts_num, target, mesh)) { + if (!surfacedeformBind(ob, + smd_orig, + smd, + vertexCos, + verts_num, + target_polys_num, + target_verts_num, + target, + mesh)) { smd->flags &= ~MOD_SDEF_BIND; } /* Early abort, this is binding 'call', no need to perform whole evaluation. */ return; } - /* Poly count checks */ + /* Geometry count on the deforming mesh. */ if (smd->mesh_verts_num != verts_num) { BKE_modifier_set_error( ob, md, "Vertices changed from %u to %u", smd->mesh_verts_num, verts_num); return; } - if (smd->polys_num != tpolys_num) { + + /* Geometry count on the target mesh. */ + if (smd->target_polys_num != target_polys_num && smd->target_verts_num == 0) { + /* Change in the number of polygons does not really imply change in the vertex count, but + * this is how the modifier worked before the vertex count was known. Follow the legacy + * logic without requirement to re-bind the mesh. */ BKE_modifier_set_error( - ob, md, "Target polygons changed from %u to %u", smd->polys_num, tpolys_num); + ob, md, "Target polygons changed from %u to %u", smd->target_polys_num, target_polys_num); return; } + if (smd->target_verts_num != 0 && smd->target_verts_num != target_verts_num) { + if (smd->target_verts_num > target_verts_num) { + /* Number of vertices on the target did reduce. There is no usable recovery from this. */ + BKE_modifier_set_error(ob, + md, + "Target vertices changed from %u to %u", + smd->target_verts_num, + target_verts_num); + return; + } + + /* Assume the increase in the vertex count means that the "new" vertices in the target mesh are + * added after the original ones. This covers typical case when target was at the subdivision + * level 0 and then subdivision was increased (i.e. for the render purposes). */ + + BKE_modifier_set_error(ob, + md, + "Target vertices changed from %u to %u, continuing anyway", + smd->target_verts_num, + target_verts_num); + + /* In theory we only need the `smd->verts_num` vertices in the `targetCos` for evaluation, but + * it is not currently possible to request a subset of coordinates: the API expects that the + * caller needs coordinates of all vertices and asserts for it. */ + } /* Early out if modifier would not affect input at all - still *after* the sanity checks * (and potential binding) above. */ @@ -1507,7 +1546,7 @@ static void surfacedeformModifier_do(ModifierData *md, /* Actual vertex location update starts here */ SDefDeformData data = { .bind_verts = smd->verts, - .targetCos = MEM_malloc_arrayN(tverts_num, sizeof(float[3]), "SDefTargetVertArray"), + .targetCos = MEM_malloc_arrayN(target_verts_num, sizeof(float[3]), "SDefTargetVertArray"), .vertexCos = vertexCos, .dvert = dvert, .defgrp_index = defgrp_index, @@ -1516,7 +1555,8 @@ static void surfacedeformModifier_do(ModifierData *md, }; if (data.targetCos != NULL) { - BKE_mesh_wrapper_vert_coords_copy_with_mat4(target, data.targetCos, tverts_num, smd->mat); + BKE_mesh_wrapper_vert_coords_copy_with_mat4( + target, data.targetCos, target_verts_num, smd->mat); TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -1629,27 +1669,41 @@ static void panelRegister(ARegionType *region_type) modifier_panel_register(region_type, eModifierType_SurfaceDeform, panel_draw); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierData *md) { - const SurfaceDeformModifierData *smd = (const SurfaceDeformModifierData *)md; + SurfaceDeformModifierData smd = *(const SurfaceDeformModifierData *)md; + + if (ID_IS_OVERRIDE_LIBRARY(id_owner)) { + BLI_assert(!ID_IS_LINKED(id_owner)); + const bool is_local = (md->flag & eModifierFlag_OverrideLibrary_Local) != 0; + if (!is_local) { + /* Modifier coming from linked data cannot be bound from an override, so we can remove all + * binding data, can save a significant amount of memory. */ + smd.bind_verts_num = 0; + smd.verts = NULL; + } + } - BLO_write_struct_array(writer, SDefVert, smd->bind_verts_num, smd->verts); + BLO_write_struct_at_address(writer, SurfaceDeformModifierData, md, &smd); - if (smd->verts) { - for (int i = 0; i < smd->bind_verts_num; i++) { - BLO_write_struct_array(writer, SDefBind, smd->verts[i].binds_num, smd->verts[i].binds); + if (smd.verts != NULL) { + SDefVert *bind_verts = smd.verts; + BLO_write_struct_array(writer, SDefVert, smd.bind_verts_num, bind_verts); - if (smd->verts[i].binds) { - for (int j = 0; j < smd->verts[i].binds_num; j++) { + for (int i = 0; i < smd.bind_verts_num; i++) { + BLO_write_struct_array(writer, SDefBind, bind_verts[i].binds_num, bind_verts[i].binds); + + if (bind_verts[i].binds) { + for (int j = 0; j < bind_verts[i].binds_num; j++) { BLO_write_uint32_array( - writer, smd->verts[i].binds[j].verts_num, smd->verts[i].binds[j].vert_inds); + writer, bind_verts[i].binds[j].verts_num, bind_verts[i].binds[j].vert_inds); - if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) { - BLO_write_float3_array(writer, 1, smd->verts[i].binds[j].vert_weights); + if (ELEM(bind_verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) { + BLO_write_float3_array(writer, 1, bind_verts[i].binds[j].vert_weights); } else { BLO_write_float_array( - writer, smd->verts[i].binds[j].verts_num, smd->verts[i].binds[j].vert_weights); + writer, bind_verts[i].binds[j].verts_num, bind_verts[i].binds[j].vert_weights); } } } diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index a58e8e23147..575182a846b 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -100,10 +100,9 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__); const int polys_num = mesh->totpoly; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; - MLoopUV *mloop_uv; CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, dmd->uvlayer_name, uvname); - mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname); + const MLoopUV *mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname); /* verts are given the UV from the first face that uses them */ for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index aef254b1103..b3b75898557 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -11,6 +11,10 @@ #include "DEG_depsgraph_build.h" +#ifdef __cplusplus +extern "C" { +#endif + struct MDeformVert; struct Mesh; struct ModifierData; @@ -51,3 +55,7 @@ void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node, struct Object *object, const char *bonename, const char *description); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 79972d1911d..402d7b2c99e 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -489,10 +489,12 @@ static void panelRegister(ARegionType *region_type) region_type, "texture", "Texture", NULL, texture_panel_draw, panel_type); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md) { const WarpModifierData *wmd = (const WarpModifierData *)md; + BLO_write_struct(writer, WarpModifierData, wmd); + if (wmd->curfalloff) { BKE_curvemapping_blend_write(writer, wmd->curfalloff); } diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index c79dbdb0b1a..d436acb8ad5 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -82,7 +82,7 @@ typedef struct WeightedNormalData { MPoly *mpoly; const float (*polynors)[3]; - int *poly_strength; + const int *poly_strength; MDeformVert *dvert; const int defgrp_index; @@ -195,7 +195,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, MPoly *mpoly = wn_data->mpoly; const float(*polynors)[3] = wn_data->polynors; - int *poly_strength = wn_data->poly_strength; + const int *poly_strength = wn_data->poly_strength; MDeformVert *dvert = wn_data->dvert; @@ -326,7 +326,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, } break; default: - BLI_assert(0); + BLI_assert_unreachable(); } /* Validate computed weighted normals. */ @@ -603,15 +603,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } const float split_angle = mesh->smoothresh; - short(*clnors)[2]; - CustomData *ldata = &result->ldata; - clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); + short(*clnors)[2] = CustomData_get_layer(&result->ldata, CD_CUSTOMLOOPNORMAL); /* Keep info whether we had clnors, * it helps when generating clnor spaces and default normals. */ const bool has_clnors = clnors != NULL; if (!clnors) { - clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, loops_num); + clnors = CustomData_add_layer(&result->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, loops_num); } MDeformVert *dvert; diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index b251825cd95..65393370268 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -96,7 +96,7 @@ void weightvg_do_map( BLI_assert(do_invert); break; default: - BLI_assert(0); + BLI_assert_unreachable(); } new_w[i] = do_invert ? 1.0f - fac : fac; @@ -206,8 +206,6 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, MEM_freeN(tex_co); } else if ((ref_didx = BKE_id_defgroup_name_index(&mesh->id, defgrp_name)) != -1) { - MDeformVert *dvert = NULL; - /* Check whether we want to set vgroup weights from a constant weight factor or a vertex * group. */ @@ -215,7 +213,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, /* Proceed only if vgroup is valid, else use constant factor. */ /* Get actual dverts (ie vertex group data). */ - dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); + const MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); /* Proceed only if vgroup is valid, else assume factor = O. */ if (dvert == NULL) { return; diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 2c733542e51..e1b43157adb 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -375,10 +375,12 @@ static void panelRegister(ARegionType *region_type) region_type, "influence", "Influence", NULL, influence_panel_draw, panel_type); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md) { const WeightVGEditModifierData *wmd = (const WeightVGEditModifierData *)md; + BLO_write_struct(writer, WeightVGEditModifierData, wmd); + if (wmd->cmap_curve) { BKE_curvemapping_blend_write(writer, wmd->cmap_curve); } diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 43a90b2a4ac..1bea5b93c97 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -715,10 +715,12 @@ static void panelRegister(ARegionType *region_type) region_type, "influence", "Influence", NULL, influence_panel_draw, panel_type); } -static void blendWrite(BlendWriter *writer, const ModifierData *md) +static void blendWrite(BlendWriter *writer, const ID *UNUSED(id_owner), const ModifierData *md) { const WeightVGProximityModifierData *wmd = (const WeightVGProximityModifierData *)md; + BLO_write_struct(writer, WeightVGProximityModifierData, wmd); + if (wmd->cmap_curve) { BKE_curvemapping_blend_write(writer, wmd->cmap_curve); } |