diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 9 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify_nonmanifold.c | 48 |
3 files changed, 56 insertions, 2 deletions
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 225842e4b9e..9e58d7df042 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1192,6 +1192,7 @@ enum { MOD_SOLIDIFY_FLIP = (1 << 5), MOD_SOLIDIFY_NOSHELL = (1 << 6), MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP = (1 << 7), + MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES = (1 << 8), }; /** #SolidifyModifierData.mode */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 5898bdd6b1a..e13b9caa90c 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -4502,6 +4502,15 @@ static void rna_def_modifier_solidify(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Vertex Group Invert", "Invert the vertex group influence"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_flat_faces", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES); + RNA_def_property_ui_text(prop, + "Flat Faces", + "Make faces use the minimal vertex weight assigned to their vertices" + "(ensures new faces remain parallel to their original ones, slow, " + "disable when not needed)"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_flip_normals", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SOLIDIFY_FLIP); RNA_def_property_ui_text(prop, "Flip Normals", "Invert the face direction"); diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 70aec2d797b..e56ae82379e 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -186,6 +186,8 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); + const bool do_flat_faces = dvert && (smd->flag & MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES); + orig_mvert = mesh->mvert; orig_medge = mesh->medge; orig_mloop = mesh->mloop; @@ -1305,6 +1307,30 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, /* Calculate EdgeGroup vertex coordinates. */ { + float *face_weight = NULL; + + if (do_flat_faces) { + face_weight = MEM_malloc_arrayN(numPolys, sizeof(*face_weight), "face_weight in solidify"); + + mp = orig_mpoly; + for (uint i = 0; i < numPolys; i++, mp++) { + float scalar_vgroup = 1.0f; + int loopend = mp->loopstart + mp->totloop; + ml = orig_mloop + mp->loopstart; + for (int j = mp->loopstart; j < loopend; j++, ml++) { + MDeformVert *dv = &dvert[ml->v]; + if (defgrp_invert) { + scalar_vgroup = min_ff(1.0f - BKE_defvert_find_weight(dv, defgrp_index), + scalar_vgroup); + } + else { + scalar_vgroup = min_ff(BKE_defvert_find_weight(dv, defgrp_index), scalar_vgroup); + } + } + face_weight[i] = scalar_vgroup; + } + } + mv = orig_mvert; gs_ptr = orig_vert_groups_arr; for (uint i = 0; i < numVerts; i++, mv++, gs_ptr++) { @@ -1337,14 +1363,22 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, NewFaceRef *face = edge->faces[l]; if (face && (first_edge == NULL || (first_edge->faces[0] != face && first_edge->faces[1] != face))) { - const float ofs = face->reversed ? ofs_back_clamped : ofs_front_clamped; + float ofs = face->reversed ? ofs_back_clamped : ofs_front_clamped; + /* Use face_weight here to make faces thinner. */ + if (do_flat_faces) { + ofs *= face_weight[face->index]; + } + if (!null_faces[face->index]) { + /* And normal to the queue. */ mul_v3_v3fl(normals_queue[queue_index], poly_nors[face->index], face->reversed ? -1 : 1); normals_queue[queue_index++][3] = ofs; } else { + /* Just use this approximate normal of the null face if there is no other + * normal to use. */ mul_v3_v3fl(face_nors[0], poly_nors[face->index], face->reversed ? -1 : 1); nor_ofs[0] = ofs; } @@ -1446,6 +1480,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } MEM_freeN(normals_queue); + /* When up to 3 constraint normals are found. */ if (ELEM(face_nors_len, 2, 3)) { const float q = dot_v3v3(face_nors[0], face_nors[1]); @@ -1500,6 +1535,11 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, (first_edge->faces[0] != face && first_edge->faces[1] != face))) { float angle = 1.0f; float ofs = face->reversed ? -ofs_back_clamped : ofs_front_clamped; + /* Use face_weight here to make faces thinner. */ + if (do_flat_faces) { + ofs *= face_weight[face->index]; + } + if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) { MLoop *ml_next = orig_mloop + face->face->loopstart; @@ -1669,7 +1709,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } float scalar_vgroup = 1; /* Use vertex group. */ - if (dvert) { + if (dvert && !do_flat_faces) { MDeformVert *dv = &dvert[i]; if (defgrp_invert) { scalar_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); @@ -1728,6 +1768,10 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md, } } } + + if (do_flat_faces) { + MEM_freeN(face_weight); + } } MEM_freeN(orig_mvert_co); |