forked from bartvdbraak/blender
solidify modifier: thickness clamping helps prevent self intersections when there are small details on a larger model.
This commit is contained in:
parent
385650974a
commit
1d73ee50a4
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user