diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-03-13 21:31:26 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-03-13 21:31:26 +0400 |
commit | 1d73ee50a48012712bc2846602fb475bb76f7c21 (patch) | |
tree | 43cc3472c294cbb0e41ca77e11cffa52d7d3a71a | |
parent | 385650974a3f38cfcebdcbfb71bac24b021e850d (diff) |
solidify modifier: thickness clamping helps prevent self intersections when there are small details on a larger model.
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_modifier.py | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 7 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify.c | 60 |
4 files changed, 70 insertions, 2 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 66db1352032..b38e2a7e98c 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -750,6 +750,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.prop(md, "thickness") + col.prop(md, "thickness_clamp") col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") col.label(text="Crease:") @@ -761,6 +762,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.prop(md, "offset") + col.prop(md, "use_flip_normals") sub = col.column() sub.active = bool(md.vertex_group) sub.prop(md, "invert_vertex_group", text="Invert") @@ -776,7 +778,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row = row.row() row.active = md.use_rim row.prop(md, "material_offset_rim", text="Rim") - sub.prop(md, "use_flip_normals") def SUBSURF(self, layout, ob, md): layout.row().prop(md, "subdivision_type", expand=True) diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 117eac0e42b..66685c131d4 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -744,6 +744,8 @@ typedef struct SolidifyModifierData { float offset; /* new surface offset level*/ float offset_fac; /* midpoint of the offset */ float offset_fac_vg; /* factor for the minimum weight to use when vgroups are used, avoids 0.0 weights giving duplicate geometry */ + float offset_clamp; /* clamp offset based on surrounding geometry */ + float pad; float crease_inner; float crease_outer; float crease_rim; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 19333b3dbc8..fa436e30200 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2648,6 +2648,13 @@ static void rna_def_modifier_solidify(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Thickness", "Thickness of the shell"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "thickness_clamp", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "offset_clamp"); + RNA_def_property_range(prop, 0, 100.0); + RNA_def_property_ui_range(prop, 0, 2.0, 0.1, 4); + RNA_def_property_ui_text(prop, "Clamp", "Offset clamp based on geometry scale"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "thickness_vertex_group", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "offset_fac_vg"); RNA_def_property_range(prop, 0.0, 1.0); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index a198eaf8ca9..9cdd52f2375 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -251,7 +251,8 @@ static DerivedMesh *applyModifier( const float ofs_new = smd->offset + ofs_orig; const float offset_fac_vg = smd->offset_fac_vg; const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg; - const int do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0; + const bool do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0; + const bool do_clamp = (smd->offset_clamp != 0.0f); /* weights */ MDeformVert *dvert, *dv = NULL; @@ -423,6 +424,20 @@ static DerivedMesh *applyModifier( float scalar_short; float scalar_short_vgroup; + /* for clamping */ + float *vert_lens = NULL; + const float offset = fabsf(smd->offset) * smd->offset_clamp; + const float offset_sq = offset * offset; + + if (do_clamp) { + vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens"); + fill_vn_fl(vert_lens, numVerts, FLT_MAX); + for (i = 0; i < numEdges; i++) { + const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); + vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len); + vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len); + } + } if (ofs_new != 0.0f) { scalar_short = scalar_short_vgroup = ofs_new / 32767.0f; @@ -435,6 +450,16 @@ static DerivedMesh *applyModifier( scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; dv++; } + if (do_clamp) { + /* always reset becaise we may have set before */ + if (dv == NULL) { + scalar_short_vgroup = scalar_short; + } + if (vert_lens[i] < offset_sq) { + float scalar = sqrtf(vert_lens[i]) / offset; + scalar_short_vgroup *= scalar; + } + } madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup); } } @@ -450,9 +475,23 @@ static DerivedMesh *applyModifier( scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; dv++; } + if (do_clamp) { + /* always reset becaise we may have set before */ + if (dv == NULL) { + scalar_short_vgroup = scalar_short; + } + if (vert_lens[i] < offset_sq) { + float scalar = sqrtf(vert_lens[i]) / offset; + scalar_short_vgroup *= scalar; + } + } madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup); } } + + if (do_clamp) { + MEM_freeN(vert_lens); + } } else { /* make a face normal layer if not present */ @@ -540,6 +579,25 @@ static DerivedMesh *applyModifier( } } + if (do_clamp) { + float *vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens"); + const float offset = fabsf(smd->offset) * smd->offset_clamp; + const float offset_sq = offset * offset; + fill_vn_fl(vert_lens, numVerts, FLT_MAX); + for (i = 0; i < numEdges; i++) { + const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); + vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len); + vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len); + } + for (i = 0; i < numVerts; i++) { + if (vert_lens[i] < offset_sq) { + float scalar = sqrtf(vert_lens[i]) / offset; + vert_angles[i] *= scalar; + } + } + MEM_freeN(vert_lens); + } + if (ofs_new) { mv = mvert + (((ofs_new >= ofs_orig) == do_flip) ? numVerts : 0); |