diff options
author | Jacques Lucke <jacques@blender.org> | 2020-03-30 13:04:42 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-03-30 13:04:42 +0300 |
commit | cd5f9516db8e1a74b60038cf16be6a5a3b99b729 (patch) | |
tree | d1f55d08b660675c5751c48707aaa2e209be2c35 /source/blender/modifiers | |
parent | 8ce5c50411e81c4cac0c72097739633188415574 (diff) | |
parent | 513885a9911841aed4d039f5170171e039a74c68 (diff) |
Merge branch 'master' into functions
Diffstat (limited to 'source/blender/modifiers')
19 files changed, 460 insertions, 152 deletions
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 3e78662da6c..275c16873a8 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -234,7 +234,7 @@ static void deformMatrices(ModifierData *md, amd->defgrp_name, NULL); - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 668fcef5dd2..67610e8cd29 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -351,7 +351,7 @@ ModifierTypeInfo modifierType_Boolean = { /* structName */ "BooleanModifierData", /* structSize */ sizeof(BooleanModifierData), /* type */ eModifierTypeType_Nonconstructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache, + /* flags */ eModifierTypeFlag_AcceptsMesh, /* copyData */ modifier_copyData_generic, diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index ed4a53ba2f3..eb6292e5e46 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -513,7 +513,7 @@ static void deformVertsEM(ModifierData *md, sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts); } - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index af468cb2d27..e1595488d08 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -231,7 +231,7 @@ static void deformVerts(ModifierData *md, } } - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index 4eea9092e10..52003f8b1d8 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -740,7 +740,7 @@ static void deformVerts(ModifierData *md, correctivesmooth_modifier_do( md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, NULL); - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } @@ -758,7 +758,7 @@ static void deformVertsEM(ModifierData *md, correctivesmooth_modifier_do( md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, editData); - if (mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh)) { BKE_id_free(NULL, mesh_src); } } diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 742d100ac44..ad8e0a9f259 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -61,7 +61,7 @@ static void initData(ModifierData *md) mmd->totlvl = 0; mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; mmd->quality = 4; - mmd->flags |= eMultiresModifierFlag_UseCrease; + mmd->flags |= (eMultiresModifierFlag_UseCrease | eMultiresModifierFlag_ControlEdges); } static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag) @@ -119,11 +119,17 @@ static Mesh *multires_as_mesh(MultiresModifierData *mmd, Mesh *result = mesh; const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY); + const bool ignore_control_edges = (ctx->flag & MOD_APPLY_TO_BASE_MESH); const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); Object *object = ctx->object; SubdivToMeshSettings mesh_settings; - BKE_multires_subdiv_mesh_settings_init( - &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify); + BKE_multires_subdiv_mesh_settings_init(&mesh_settings, + scene, + object, + mmd, + use_render_params, + ignore_simplify, + ignore_control_edges); if (mesh_settings.resolution < 3) { return result; } diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index e6229e27e4b..05bfe9aeff0 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -189,7 +189,7 @@ static void deformVerts(ModifierData *md, BKE_mesh_tessface_ensure(psmd->mesh_original); } - if (mesh_src != psmd->mesh_final && mesh_src != mesh) { + if (!ELEM(mesh_src, NULL, mesh, psmd->mesh_final)) { BKE_id_free(NULL, mesh_src); } diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 8921ddb894f..e832a23b4ed 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -352,12 +352,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes * Note! smaller then `FLT_EPSILON * 100` * gives problems with float precision so its never closed. */ if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && - fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) { + fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f) && step_tot > 3) { close = 1; step_tot--; - if (step_tot < 3) { - step_tot = 3; - } maxVerts = totvert * step_tot; /* -1 because we're joining back up */ maxEdges = (totvert * step_tot) + /* these are the edges between new verts */ @@ -368,8 +365,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } else { close = 0; - if (step_tot < 3) { - step_tot = 3; + if (step_tot < 2) { + step_tot = 2; } maxVerts = totvert * step_tot; /* -1 because we're joining back up */ diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index 679fdb634f4..efe6b188fa0 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -79,7 +79,8 @@ ModifierTypeInfo modifierType_Softbody = { /* structSize */ sizeof(SoftbodyModifierData), /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice | - eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_Single, + eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_Single | + eModifierTypeFlag_UsesPointCache, /* copyData */ NULL, diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 8ea0a602b65..0eed2335ed7 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -62,7 +62,8 @@ static void requiredDataMask(Object *UNUSED(ob), SolidifyModifierData *smd = (SolidifyModifierData *)md; /* ask for vertexgroups if we need them */ - if (smd->defgrp_name[0] != '\0') { + if (smd->defgrp_name[0] != '\0' || smd->shell_defgrp_name[0] != '\0' || + smd->rim_defgrp_name[0] != '\0') { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; } } @@ -70,11 +71,13 @@ static void requiredDataMask(Object *UNUSED(ob), static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { const SolidifyModifierData *smd = (SolidifyModifierData *)md; - if (smd->mode == MOD_SOLIDIFY_MODE_EXTRUDE) { - return MOD_solidify_extrude_applyModifier(md, ctx, mesh); - } - else if (smd->mode == MOD_SOLIDIFY_MODE_NONMANIFOLD) { - return MOD_solidify_nonmanifold_applyModifier(md, ctx, mesh); + switch (smd->mode) { + case MOD_SOLIDIFY_MODE_EXTRUDE: + return MOD_solidify_extrude_applyModifier(md, ctx, mesh); + case MOD_SOLIDIFY_MODE_NONMANIFOLD: + return MOD_solidify_nonmanifold_applyModifier(md, ctx, mesh); + default: + BLI_assert(0); } return mesh; } diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 8febf78fef5..ecd62e5e1fe 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -240,6 +240,9 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, MDeformVert *dvert; const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; int defgrp_index; + const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object, + smd->shell_defgrp_name); + const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name); /* array size is doubled in case of using a shell */ const uint stride = do_shell ? 2 : 1; @@ -886,6 +889,36 @@ Mesh *MOD_solidify_extrude_applyModifier(ModifierData *md, } } + /* Add vertex weights for rim and shell vgroups. */ + if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { + dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if (dvert == NULL) { + /* Add a valid data layer! */ + dvert = CustomData_add_layer( + &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert); + } + /* Ultimate security check. */ + if (!dvert) { + return result; + } + result->dvert = dvert; + + if (rim_defgrp_index != -1) { + for (uint i = 0; i < rimVerts; i++) { + BKE_defvert_ensure_index(&result->dvert[new_vert_arr[i]], rim_defgrp_index)->weight = 1.0f; + BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + numVerts], + rim_defgrp_index) + ->weight = 1.0f; + } + } + + if (shell_defgrp_index != -1) { + for (uint i = numVerts; i < result->totvert; i++) { + BKE_defvert_ensure_index(&result->dvert[i], shell_defgrp_index)->weight = 1.0f; + } + } + } if (smd->flag & MOD_SOLIDIFY_RIM) { uint i; diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 23053adfd5a..0f9f5952a26 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -178,6 +178,9 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MDeformVert *dvert; const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; int defgrp_index; + const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object, + smd->shell_defgrp_name); + const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name); MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); @@ -243,6 +246,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, if (mp->totloop > largest_ngon) { largest_ngon = (uint)mp->totloop; } + /* add to final mesh face count */ if (do_shell) { numNewPolys += 2; numNewLoops += (uint)mp->totloop * 2; @@ -272,7 +276,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, /* Edge groups for every original vert. */ EdgeGroup **orig_vert_groups_arr = MEM_calloc_arrayN( numVerts, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify"); - /* Duplicate verts map. */ + /* vertex map used to map duplicates. */ uint *vm = MEM_malloc_arrayN(numVerts, sizeof(*vm), "orig_vert_map in solidify"); for (uint i = 0; i < numVerts; i++) { vm[i] = i; @@ -285,8 +289,6 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, bool has_singularities = false; /* Vert edge adjacent map. */ - uint *vert_adj_edges_len = MEM_calloc_arrayN( - numVerts, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify"); OldVertEdgeRef **vert_adj_edges = MEM_calloc_arrayN( numVerts, sizeof(*vert_adj_edges), "vert_adj_edges in solidify"); @@ -309,15 +311,15 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, BLI_assert(len > 0); uint *adj_faces = MEM_malloc_arrayN( len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); - bool *adj_faces_loops_reversed = MEM_malloc_arrayN( - len, sizeof(*adj_faces_loops_reversed), "OldEdgeFaceRef::reversed in solidify"); + bool *adj_faces_reversed = MEM_malloc_arrayN( + len, sizeof(*adj_faces_reversed), "OldEdgeFaceRef::reversed in solidify"); adj_faces[0] = i; for (uint k = 1; k < len; k++) { adj_faces[k] = MOD_SOLIDIFY_EMPTY_TAG; } - adj_faces_loops_reversed[0] = reversed; + adj_faces_reversed[0] = reversed; OldEdgeFaceRef *ref = MEM_mallocN(sizeof(*ref), "OldEdgeFaceRef in solidify"); - *ref = (OldEdgeFaceRef){adj_faces, len, adj_faces_loops_reversed, 1}; + *ref = (OldEdgeFaceRef){adj_faces, len, adj_faces_reversed, 1}; edge_adj_faces[edge] = ref; } else { @@ -334,11 +336,14 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } float edgedir[3] = {0, 0, 0}; + uint *vert_adj_edges_len = MEM_calloc_arrayN( + numVerts, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify"); /* Calculate edge lengths and len vert_adj edges. */ { bool *face_singularity = MEM_calloc_arrayN( numPolys, sizeof(*face_singularity), "face_sides_arr in solidify"); + ed = orig_medge; for (uint i = 0; i < numEdges; i++, ed++) { if (edge_adj_faces_len[i] > 0) { @@ -347,63 +352,82 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, if (v1 != v2) { sub_v3_v3v3(edgedir, orig_mvert[v2].co, orig_mvert[v1].co); orig_edge_lengths[i] = len_squared_v3(edgedir); - } - if (v1 == v2 || orig_edge_lengths[i] <= FLT_EPSILON) { - if (v2 > v1) { - for (uint j = v2; j < numVerts; j++) { - if (vm[j] == v2) { - vm[j] = v1; - vert_adj_edges_len[v1] += vert_adj_edges_len[j]; - vert_adj_edges_len[j] = 0; + if (orig_edge_lengths[i] <= FLT_EPSILON) { + if (v2 > v1) { + for (uint j = v2; j < numVerts; j++) { + if (vm[j] == v2) { + vm[j] = v1; + vert_adj_edges_len[v1] += vert_adj_edges_len[j]; + vert_adj_edges_len[j] = 0; + } } } - } - else if (v2 < v1) { - for (uint j = v1; j < numVerts; j++) { - if (vm[j] == v1) { - vm[j] = v2; - vert_adj_edges_len[v2] += vert_adj_edges_len[j]; - vert_adj_edges_len[j] = 0; + else if (v2 < v1) { + for (uint j = v1; j < numVerts; j++) { + if (vm[j] == v1) { + vm[j] = v2; + vert_adj_edges_len[v2] += vert_adj_edges_len[j]; + vert_adj_edges_len[j] = 0; + } } } + if (do_shell) { + numNewLoops -= edge_adj_faces_len[i] * 2; + } + + edge_adj_faces_len[i] = 0; + MEM_freeN(edge_adj_faces[i]->faces); + MEM_freeN(edge_adj_faces[i]->faces_reversed); + MEM_freeN(edge_adj_faces[i]); + edge_adj_faces[i] = NULL; } - if (do_shell) { - numNewLoops -= edge_adj_faces_len[i] * 2; + else { + orig_edge_lengths[i] = sqrtf(orig_edge_lengths[i]); + vert_adj_edges_len[v1]++; + vert_adj_edges_len[v2]++; } - if (v1 == v2) { - /* Remove polys. */ - for (uint j = 0; j < edge_adj_faces[i]->faces_len; j++) { - const uint face = edge_adj_faces[i]->faces[j]; - if (!face_singularity[face]) { - bool is_singularity = true; - for (uint k = 0; k < orig_mpoly[face].totloop; k++) { - if (vm[orig_mloop[((uint)orig_mpoly[face].loopstart) + k].v] != v1) { - is_singularity = false; - break; - } - } - if (is_singularity) { - face_singularity[face] = true; - if (do_shell) { - numNewPolys -= 2; - } - } + } + } + } + /* remove zero faces in a second pass */ + ed = orig_medge; + for (uint i = 0; i < numEdges; i++, ed++) { + const uint v1 = vm[ed->v1]; + const uint v2 = vm[ed->v2]; + if (v1 == v2 && edge_adj_faces[i]) { + /* Remove polys. */ + for (uint j = 0; j < edge_adj_faces[i]->faces_len; j++) { + const uint face = edge_adj_faces[i]->faces[j]; + if (!face_singularity[face]) { + bool is_singularity = true; + for (uint k = 0; k < orig_mpoly[face].totloop; k++) { + if (vm[orig_mloop[((uint)orig_mpoly[face].loopstart) + k].v] != v1) { + is_singularity = false; + break; + } + } + if (is_singularity) { + face_singularity[face] = true; + /* remove from final mesh poly count */ + if (do_shell) { + numNewPolys -= 2; } } } - edge_adj_faces_len[i] = 0; - MEM_freeN(edge_adj_faces[i]->faces); - MEM_freeN(edge_adj_faces[i]->faces_reversed); - MEM_freeN(edge_adj_faces[i]); - edge_adj_faces[i] = NULL; } - else if (edge_adj_faces_len[i] > 0) { - orig_edge_lengths[i] = sqrtf(orig_edge_lengths[i]); - vert_adj_edges_len[v1]++; - vert_adj_edges_len[v2]++; + + if (do_shell) { + numNewLoops -= edge_adj_faces_len[i] * 2; } + + edge_adj_faces_len[i] = 0; + MEM_freeN(edge_adj_faces[i]->faces); + MEM_freeN(edge_adj_faces[i]->faces_reversed); + MEM_freeN(edge_adj_faces[i]); + edge_adj_faces[i] = NULL; } } + MEM_freeN(face_singularity); } @@ -452,8 +476,8 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } if (invalid_edge_index) { - /* Should never actually be executed. */ if (j == 1) { + /* Should never actually be executed. */ vert_adj_edges[vs[0]]->edges_len--; } break; @@ -461,6 +485,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } } + /* Remove zero faces that are in shape of an edge. */ if (invalid_edge_index) { const uint tmp = invalid_edge_index - 1; invalid_edge_index = i; @@ -478,6 +503,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } } + /* remove from final face count */ if (do_shell) { numNewPolys -= 2 * j; numNewLoops -= 4 * j; @@ -487,6 +513,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); bool *adj_faces_loops_reversed = MEM_malloc_arrayN( len, sizeof(*adj_faces_loops_reversed), "OldEdgeFaceRef::reversed in solidify"); + /* Clean merge of adj_faces. */ j = 0; for (uint k = 0; k < i_adj_faces->faces_len; k++) { if (i_adj_faces->faces[k] != MOD_SOLIDIFY_EMPTY_TAG) { @@ -521,13 +548,19 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + MEM_freeN(vert_adj_edges_len); + /* Filter duplicate polys. */ { ed = orig_medge; + /* Iterate over edges and only check the faces around an edge for duplicates + * (performance optimization). */ for (uint i = 0; i < numEdges; i++, ed++) { if (edge_adj_faces_len[i] > 0) { const OldEdgeFaceRef *adj_faces = edge_adj_faces[i]; uint adj_len = adj_faces->faces_len; + /* Not that #adj_len doesn't need to equal edge_adj_faces_len anymore + * because #adj_len is shared when a face got collapsed to an edge. */ if (adj_len > 1) { /* For each face pair check if they have equal verts. */ for (uint j = 0; j < adj_len; j++) { @@ -564,40 +597,56 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, uint del_loops = 0; for (uint m = 0; m < totloop; m++, ml++) { const uint e = ml->e; - uint face_index = j; - uint *e_adj_faces_faces = edge_adj_faces[e]->faces; - bool *e_adj_faces_reversed = edge_adj_faces[e]->faces_reversed; - const uint faces_len = edge_adj_faces[e]->faces_len; - if (e != i) { - /* Find index of e in #adj_faces. */ - for (face_index = 0; - face_index < faces_len && e_adj_faces_faces[face_index] != face; - face_index++) { - /* Pass. */ + OldEdgeFaceRef *e_adj_faces = edge_adj_faces[e]; + if (e_adj_faces) { + uint face_index = j; + uint *e_adj_faces_faces = e_adj_faces->faces; + bool *e_adj_faces_reversed = e_adj_faces->faces_reversed; + const uint faces_len = e_adj_faces->faces_len; + if (e != i) { + /* Find index of e in #adj_faces. */ + for (face_index = 0; + face_index < faces_len && e_adj_faces_faces[face_index] != face; + face_index++) { + /* Pass. */ + } + /* If not found. */ + if (face_index == faces_len) { + continue; + } + } + else { + /* If we shrink #edge_adj_faces[i] we need to update this field. */ + adj_len--; } - /* If not found. */ - if (face_index == faces_len) { - continue; + memmove(e_adj_faces_faces + face_index, + e_adj_faces_faces + face_index + 1, + (faces_len - face_index - 1) * sizeof(*e_adj_faces_faces)); + memmove(e_adj_faces_reversed + face_index, + e_adj_faces_reversed + face_index + 1, + (faces_len - face_index - 1) * sizeof(*e_adj_faces_reversed)); + e_adj_faces->faces_len--; + if (edge_adj_faces_len[e] > 0) { + edge_adj_faces_len[e]--; + if (edge_adj_faces_len[e] == 0) { + e_adj_faces->used--; + edge_adj_faces[e] = NULL; + } } - } - else { - adj_len--; - } - memmove(e_adj_faces_faces + face_index, - e_adj_faces_faces + face_index + 1, - (faces_len - face_index - 1) * sizeof(*e_adj_faces_faces)); - memmove(e_adj_faces_reversed + face_index, - e_adj_faces_reversed + face_index + 1, - (faces_len - face_index - 1) * sizeof(*e_adj_faces_reversed)); - edge_adj_faces[e]->faces_len--; - if (edge_adj_faces_len[e] > 0) { - edge_adj_faces_len[e]--; - if (edge_adj_faces_len[e] == 0) { - edge_adj_faces[e]->used--; - edge_adj_faces[e] = NULL; + else if (e_adj_faces->used > 1) { + for (uint n = 0; n < numEdges; n++) { + if (edge_adj_faces[n] == e_adj_faces && edge_adj_faces_len[n] > 0) { + edge_adj_faces_len[n]--; + if (edge_adj_faces_len[n] == 0) { + edge_adj_faces[n]->used--; + edge_adj_faces[n] = NULL; + } + break; + } + } } + del_loops++; } - del_loops++; } if (do_shell) { numNewPolys -= 2; @@ -755,8 +804,6 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEM_freeN(edge_adj_faces); } - MEM_freeN(vert_adj_edges_len); - /* Create sorted edge groups for every vert. */ { OldVertEdgeRef **adj_edges_ptr = vert_adj_edges; @@ -779,6 +826,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, /* TODO check where the null pointer come from, * because there should not be any... */ if (new_edges) { + /* count the number of new edges around the original vert */ while (*new_edges) { unassigned_edges_len++; new_edges++; @@ -797,8 +845,11 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + /* An edge group will always contain min 2 edges + * so max edge group count can be calculated. */ + uint edge_groups_len = unassigned_edges_len / 2; edge_groups = MEM_calloc_arrayN( - (unassigned_edges_len / 2) + 1, sizeof(*edge_groups), "edge_groups in solidify"); + edge_groups_len + 1, sizeof(*edge_groups), "edge_groups in solidify"); uint assigned_edges_len = 0; NewEdgeRef *found_edge = NULL; @@ -807,14 +858,16 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, uint eg_capacity = 5; NewFaceRef *eg_track_faces[2] = {NULL, NULL}; NewFaceRef *last_open_edge_track = NULL; - NewEdgeRef *edge = NULL; while (assigned_edges_len < unassigned_edges_len) { found_edge = NULL; insert_at_start = false; if (eg_index >= 0 && edge_groups[eg_index].edges_len == 0) { + /* Called every time a new group was started in the last iteration. */ + /* Find an unused edge to start the next group + * and setup variables to start creating it. */ uint j = 0; - edge = NULL; + NewEdgeRef *edge = NULL; while (!edge && j < unassigned_edges_len) { edge = unassigned_edges[j++]; if (edge && last_open_edge_track && @@ -856,7 +909,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, for (found_edge_index = 0; found_edge_index < unassigned_edges_len; found_edge_index++, edge_ptr++) { if (*edge_ptr) { - edge = *edge_ptr; + NewEdgeRef *edge = *edge_ptr; if (edge->faces[0] == eg_track_faces[1]) { insert_at_start = false; eg_track_faces[1] = edge->faces[1]; @@ -932,8 +985,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } else { + /* called on first iteration to clean up the eg_index = -1 and start the first group, + * or when the current group is found to be complete (no new found_edge) */ eg_index++; - BLI_assert(eg_index < (unassigned_edges_len / 2)); + BLI_assert(eg_index < edge_groups_len); eg_capacity = 5; NewEdgeRef **edges = MEM_calloc_arrayN( eg_capacity, sizeof(*edges), "edge_group in solidify"); @@ -959,7 +1014,11 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, eg_index++; /* #topo_groups is the number of topo groups from here on. */ topo_groups++; + MEM_freeN(unassigned_edges); + + /* TODO reshape the edge_groups array to its actual size + * after writing is finished to save on memory. */ } /* Split of long self intersection groups */ @@ -1722,6 +1781,18 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, int *origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); int *origindex_poly = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); + /* Checks that result has dvert data. */ + if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { + dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if (dvert == NULL) { + /* Add a valid data layer! */ + dvert = CustomData_add_layer( + &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert); + } + result->dvert = dvert; + } + /* Make_new_verts. */ { gs_ptr = orig_vert_groups_arr; @@ -1785,13 +1856,32 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEM_freeN(singularity_edges); } - /* DEBUG CODE FOR BUGFIXING (can not be removed because every bugfix needs this badly!). */ + /* DEBUG CODE FOR BUG-FIXING (can not be removed because every bug-fix needs this badly!). */ #if 0 { + /* this code will output the content of orig_vert_groups_arr. + * in orig_vert_groups_arr these conditions must be met for every vertex: + * - new_edge value should have no duplicates + * - every old_edge value should appear twice + * - every group should have at least two members (edges) + * Note: that there can be vertices that only have one group. They are called singularities. + * These vertices will only have one side (there is no way of telling apart front + * from back like on a mobius strip) + */ + + /* Debug output format: + * <original vertex id>: + * { + * { <old edge id>/<new edge id>, } \ + * (tg:<topology group id>)(s:<is split group>,c:<is closed group (before splitting)>) + * } + */ gs_ptr = orig_vert_groups_arr; for (uint i = 0; i < numVerts; i++, gs_ptr++) { EdgeGroup *gs = *gs_ptr; + /* check if the vertex is present (may be dissolved because of proximity) */ if (gs) { + printf("%d:\n", i); for (EdgeGroup *g = gs; g->valid; g++) { NewEdgeRef **e = g->edges; for (uint j = 0; j < g->edges_len; j++, e++) { @@ -1799,7 +1889,6 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } printf("(tg:%u)(s:%u,c:%d)\n", g->topo_group, g->split, g->is_orig_closed); } - printf("\n"); } } } @@ -2027,12 +2116,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MEdge *open_face_edge; uint open_face_edge_index; if (!do_flip) { + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v1; mloop[loop_index++].e = edge1->new_edge; if (!v2_singularity) { open_face_edge_index = edge1->link_edge_groups[1]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v2; open_face_edge = medge + open_face_edge_index; @@ -2044,12 +2141,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v2; mloop[loop_index++].e = edge2->new_edge; if (!v1_singularity) { open_face_edge_index = edge2->link_edge_groups[0]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v1; open_face_edge = medge + open_face_edge_index; @@ -2064,6 +2169,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, else { if (!v1_singularity) { open_face_edge_index = edge1->link_edge_groups[0]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v1; open_face_edge = medge + open_face_edge_index; @@ -2075,12 +2184,20 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v1; mloop[loop_index++].e = edge2->new_edge; if (!v2_singularity) { open_face_edge_index = edge2->link_edge_groups[1]->open_face_edge; + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge2->new_edge].v2; open_face_edge = medge + open_face_edge_index; @@ -2092,6 +2209,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } + if (rim_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); mloop[loop_index].v = medge[edge1->new_edge].v2; mloop[loop_index++].e = edge1->new_edge; @@ -2164,11 +2285,15 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, CustomData_copy_data(&mesh->pdata, &result->pdata, (int)(i / 2), (int)poly_index, 1); mpoly[poly_index].loopstart = (int)loop_index; mpoly[poly_index].totloop = (int)k; - mpoly[poly_index].mat_nr = fr->face->mat_nr + mat_ofs; + mpoly[poly_index].mat_nr = fr->face->mat_nr + (fr->reversed ? mat_ofs : 0); CLAMP(mpoly[poly_index].mat_nr, 0, mat_nr_max); mpoly[poly_index].flag = fr->face->flag; if (fr->reversed != do_flip) { for (int l = (int)k - 1; l >= 0; l--) { + if (shell_defgrp_index != -1) { + BKE_defvert_ensure_index(&result->dvert[face_verts[l]], shell_defgrp_index) + ->weight = 1.0f; + } CustomData_copy_data( &mesh->ldata, &result->ldata, (int)face_loops[l], (int)loop_index, 1); mloop[loop_index].v = face_verts[l]; diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 56180564be2..b3bc5a66e8c 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -58,7 +58,7 @@ static void initData(ModifierData *md) smd->renderLevels = 2; smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; smd->quality = 3; - smd->flags |= eSubsurfModifierFlag_UseCrease; + smd->flags |= (eSubsurfModifierFlag_UseCrease | eSubsurfModifierFlag_ControlEdges); } static void copyData(const ModifierData *md, ModifierData *target, const int flag) @@ -148,7 +148,8 @@ static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, { const int level = subdiv_levels_for_modifier_get(smd, ctx); settings->resolution = (1 << level) + 1; - settings->use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges); + settings->use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges) && + !(ctx->flag & MOD_APPLY_TO_BASE_MESH); } static Mesh *subdiv_as_mesh(SubsurfModifierData *smd, diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 57e7e2fa98b..4ef1f32462a 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -36,6 +36,8 @@ #include "BKE_mesh_runtime.h" #include "BKE_modifier.h" +#include "BKE_deform.h" + #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -110,6 +112,8 @@ typedef struct SDefDeformData { const SDefVert *const bind_verts; float (*const targetCos)[3]; float (*const vertexCos)[3]; + float(*const weights); + float const strength; } SDefDeformData; /* Bind result values */ @@ -136,6 +140,19 @@ static void initData(ModifierData *md) smd->verts = NULL; smd->flags = 0; smd->falloff = 4.0f; + smd->strength = 1.0f; +} + +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *md, + CustomData_MeshMasks *r_cddata_masks) +{ + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + + /* Ask for vertex groups if we need them. */ + if (smd->defgrp_name[0] != '\0') { + r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; + } } static void freeData(ModifierData *md) @@ -1123,9 +1140,16 @@ static void deformVert(void *__restrict userdata, const SDefBind *sdbind = data->bind_verts[index].binds; const int num_binds = data->bind_verts[index].numbinds; float *const vertexCos = data->vertexCos[index]; - float norm[3], temp[3]; + float norm[3], temp[3], offset[3]; + const float weight = (data->weights != NULL) ? data->weights[index] : 1.0f; - zero_v3(vertexCos); + /* Check if this vertex will be deformed. If it is not deformed we return and avoid + * unnecessary calculations. */ + if (weight == 0.0f) { + return; + } + + zero_v3(offset); /* Allocate a `coords_buffer` that fits all the temp-data. */ int max_verts = 0; @@ -1170,8 +1194,13 @@ static void deformVert(void *__restrict userdata, /* Apply normal offset (generic for all modes) */ madd_v3_v3fl(temp, norm, sdbind->normal_dist); - madd_v3_v3fl(vertexCos, temp, sdbind->influence); + madd_v3_v3fl(offset, temp, sdbind->influence); } + /* Subtract the vertex coord to get the deformation offset. */ + sub_v3_v3(offset, vertexCos); + + /* Add the offset to start coord multiplied by the strength and weight values. */ + madd_v3_v3fl(vertexCos, offset, data->strength * weight); MEM_freeN(coords_buffer); } @@ -1179,7 +1208,8 @@ static void surfacedeformModifier_do(ModifierData *md, const ModifierEvalContext *ctx, float (*vertexCos)[3], uint numverts, - Object *ob) + Object *ob, + Mesh *mesh) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; Mesh *target; @@ -1238,11 +1268,44 @@ static void surfacedeformModifier_do(ModifierData *md, return; } + /* Early out if modifier would not affect input at all - still *after* the sanity checks (and + * potential binding) above. + */ + if (smd->strength == 0.0f) { + return; + } + + int defgrp_index; + MDeformVert *dvert; + MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index); + float *weights = NULL; + const bool invert_group = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0; + + if (defgrp_index != -1) { + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, mesh->totvert); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + if (dvert == NULL) { + /* Add a valid data layer! */ + dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert); + } + + if (dvert) { + weights = MEM_calloc_arrayN((size_t)numverts, sizeof(*weights), __func__); + MDeformVert *dv = dvert; + for (uint i = 0; i < numverts; i++, dv++) { + weights[i] = invert_group ? (1.0f - BKE_defvert_find_weight(dv, defgrp_index)) : + BKE_defvert_find_weight(dv, defgrp_index); + } + } + } + /* Actual vertex location update starts here */ SDefDeformData data = { .bind_verts = smd->verts, .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"), .vertexCos = vertexCos, + .weights = weights, + .strength = smd->strength, }; if (data.targetCos != NULL) { @@ -1259,25 +1322,51 @@ static void surfacedeformModifier_do(ModifierData *md, MEM_freeN(data.targetCos); } + + MEM_SAFE_FREE(weights); } static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, - Mesh *UNUSED(mesh), + Mesh *mesh, float (*vertexCos)[3], int numVerts) { - surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object); + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + Mesh *mesh_src = NULL; + + if (smd->defgrp_name[0] != '\0') { + /* Only need to use mesh_src when a vgroup is used. */ + mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false); + } + + surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src); + + if (!ELEM(mesh_src, NULL, mesh)) { + BKE_id_free(NULL, mesh_src); + } } static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, - struct BMEditMesh *UNUSED(editData), - Mesh *UNUSED(mesh), + struct BMEditMesh *em, + Mesh *mesh, float (*vertexCos)[3], int numVerts) { - surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object); + SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; + Mesh *mesh_src = NULL; + + if (smd->defgrp_name[0] != '\0') { + /* Only need to use mesh_src when a vgroup is used. */ + mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false); + } + + surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src); + + if (!ELEM(mesh_src, NULL, mesh)) { + BKE_id_free(NULL, mesh_src); + } } static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams)) @@ -1309,7 +1398,7 @@ ModifierTypeInfo modifierType_SurfaceDeform = { /* applyModifier */ NULL, /* initData */ initData, - /* requiredDataMask */ NULL, + /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, /* isDisabled */ isDisabled, /* updateDepsgraph */ updateDepsgraph, diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 4a98afbb91c..b8db14f610a 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -32,6 +32,7 @@ #include "BKE_colortools.h" #include "BKE_deform.h" +#include "BKE_action.h" /* BKE_pose_channel_find_name */ #include "BKE_editmesh.h" #include "BKE_lib_id.h" #include "BKE_lib_query.h" @@ -85,6 +86,19 @@ static void requiredDataMask(Object *UNUSED(ob), } } +static void matrix_from_obj_pchan(float mat[4][4], float obinv[4][4], Object *ob, const char *bonename) +{ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename); + if (pchan) { + float mat_bone_world[4][4]; + mul_m4_m4m4(mat_bone_world, ob->obmat, pchan->pose_mat); + mul_m4_m4m4(mat, obinv, mat_bone_world); + } + else { + mul_m4_m4m4(mat, obinv, ob->obmat); + } +} + static bool dependsOnTime(ModifierData *md) { WarpModifierData *wmd = (WarpModifierData *)md; @@ -135,15 +149,29 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void walk(userData, ob, md, "texture"); } +static void warp_deps_object_bone_new(struct DepsNodeHandle *node, + Object *object, + const char *bonename) +{ + if (bonename[0] && object->type == OB_ARMATURE) { + DEG_add_object_relation(node, object, DEG_OB_COMP_EVAL_POSE, "Warp Modifier"); + } + else { + DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Warp Modifier"); + } +} + static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { WarpModifierData *wmd = (WarpModifierData *)md; + if (wmd->object_from != NULL && wmd->object_to != NULL) { - DEG_add_modifier_to_transform_relation(ctx->node, "Warplace Modifier"); - DEG_add_object_relation( - ctx->node, wmd->object_from, DEG_OB_COMP_TRANSFORM, "Warp Modifier from"); - DEG_add_object_relation(ctx->node, wmd->object_to, DEG_OB_COMP_TRANSFORM, "Warp Modifier to"); + warp_deps_object_bone_new(ctx->node, wmd->object_from, wmd->bone_from); + warp_deps_object_bone_new(ctx->node, wmd->object_to, wmd->bone_to); + + DEG_add_modifier_to_transform_relation(ctx->node, "Warp Modifier"); } + if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) { DEG_add_object_relation( ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Warp Modifier map"); @@ -197,8 +225,9 @@ static void warpModifier_do(WarpModifierData *wmd, invert_m4_m4(obinv, ob->obmat); - mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat); - mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat); + /* Checks that the objects/bones are available. */ + matrix_from_obj_pchan(mat_from, obinv, wmd->object_from, wmd->bone_from); + matrix_from_obj_pchan(mat_to, obinv, wmd->object_to, wmd->bone_to); invert_m4_m4(tmat, mat_from); // swap? mul_m4_m4m4(mat_final, tmat, mat_to); diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index e93ab608498..23e4da32ed7 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -54,20 +54,22 @@ * mapping to the real vertex index (in case the weight tables do not cover the whole vertices...). * cmap might be NULL, in which case curve mapping mode will return unmodified data. */ -void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cmap, RNG *rng) +void weightvg_do_map( + int num, float *new_w, short falloff_type, const bool do_invert, CurveMapping *cmap, RNG *rng) { int i; /* Return immediately, if we have nothing to do! */ /* Also security checks... */ - if (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) || !ELEM(falloff_type, - MOD_WVG_MAPPING_CURVE, - MOD_WVG_MAPPING_SHARP, - MOD_WVG_MAPPING_SMOOTH, - MOD_WVG_MAPPING_ROOT, - MOD_WVG_MAPPING_SPHERE, - MOD_WVG_MAPPING_RANDOM, - MOD_WVG_MAPPING_STEP)) { + if (!do_invert && (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) || + !ELEM(falloff_type, + MOD_WVG_MAPPING_CURVE, + MOD_WVG_MAPPING_SHARP, + MOD_WVG_MAPPING_SMOOTH, + MOD_WVG_MAPPING_ROOT, + MOD_WVG_MAPPING_SPHERE, + MOD_WVG_MAPPING_RANDOM, + MOD_WVG_MAPPING_STEP))) { return; } @@ -103,9 +105,14 @@ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cm case MOD_WVG_MAPPING_STEP: fac = (fac >= 0.5f) ? 1.0f : 0.0f; break; + case MOD_WVG_MAPPING_NONE: + BLI_assert(do_invert); + break; + default: + BLI_assert(0); } - new_w[i] = fac; + new_w[i] = do_invert ? 1.0f - fac : fac; } } diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h index fa3c61a6b6f..bcd1076eac6 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.h +++ b/source/blender/modifiers/intern/MOD_weightvg_util.h @@ -52,8 +52,12 @@ struct Tex; */ #define MOD_WVG_ZEROFLOOR 1.0e-32f -void weightvg_do_map( - int num, float *new_w, short mode, struct CurveMapping *cmap, struct RNG *rng); +void weightvg_do_map(int num, + float *new_w, + short mode, + const bool do_invert, + struct CurveMapping *cmap, + struct RNG *rng); void weightvg_do_mask(const ModifierEvalContext *ctx, const int num, diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 6acbbefe745..ba1745f7b5e 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -230,14 +230,15 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Do mapping. */ - if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) { + const bool do_invert_mapping = (wmd->edit_flags & MOD_WVG_INVERT_FALLOFF) != 0; + if (do_invert_mapping || wmd->falloff_type != MOD_WVG_MAPPING_NONE) { RNG *rng = NULL; if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) { rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2)); } - weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng); + weightvg_do_map(numVerts, new_w, wmd->falloff_type, do_invert_mapping, wmd->cmap_curve, rng); if (rng) { BLI_rng_free(rng); diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index e2e8e732311..7c9242ed900 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -239,8 +239,13 @@ static float get_ob2ob_distance(const Object *ob, const Object *obr) /** * Maps distances to weights, with an optional "smoothing" mapping. */ -static void do_map( - Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode) +static void do_map(Object *ob, + float *weights, + const int nidx, + const float min_d, + const float max_d, + short mode, + const bool do_invert_mapping) { const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */ uint i = nidx; @@ -276,14 +281,15 @@ static void do_map( } } - if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) { + BLI_assert(mode != MOD_WVG_MAPPING_CURVE); + if (do_invert_mapping || mode != MOD_WVG_MAPPING_NONE) { RNG *rng = NULL; if (mode == MOD_WVG_MAPPING_RANDOM) { rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2)); } - weightvg_do_map(nidx, weights, mode, NULL, rng); + weightvg_do_map(nidx, weights, mode, do_invert_mapping, NULL, rng); if (rng) { BLI_rng_free(rng); @@ -559,7 +565,13 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Map distances to weights. */ - do_map(ob, new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type); + do_map(ob, + new_w, + numIdx, + wmd->min_dist, + wmd->max_dist, + wmd->falloff_type, + (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_FALLOFF) != 0); /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); |