Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-03-13 21:31:26 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-03-13 21:31:26 +0400
commit1d73ee50a48012712bc2846602fb475bb76f7c21 (patch)
tree43cc3472c294cbb0e41ca77e11cffa52d7d3a71a /source/blender/modifiers
parent385650974a3f38cfcebdcbfb71bac24b021e850d (diff)
solidify modifier: thickness clamping helps prevent self intersections when there are small details on a larger model.
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c60
1 files changed, 59 insertions, 1 deletions
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);