[Bf-blender-cvs] [5cf72833429] master: Fix T75032: New complex solidify algorithm handles poorly merging threshold of small geometry details.

Henrik Dick noreply at git.blender.org
Mon Apr 13 17:18:25 CEST 2020


Commit: 5cf72833429f4c63d27ea0a72878af1fec6dcf4e
Author: Henrik Dick
Date:   Mon Apr 13 17:15:16 2020 +0200
Branches: master
https://developer.blender.org/rB5cf72833429f4c63d27ea0a72878af1fec6dcf4e

Fix T75032: New complex solidify algorithm handles poorly merging threshold of small geometry details.

* Implemented the algortihm that would merge vertices to the weighted
  center between them.
* Exposed the merge threshold to the user.

The new default tolerance is 0.0001 (versionning code ensures that
previous default value remains in use to avoid any change in existing
files).

Review and minor changes/cleanups from Bastien Montagne (@mont29).

===================================================================

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_solidify.c
M	source/blender/modifiers/intern/MOD_solidify_nonmanifold.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 61151b3e02b..62e19129923 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1049,6 +1049,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
             col.prop(md, "edge_crease_inner", text="Inner")
             col.prop(md, "edge_crease_outer", text="Outer")
             col.prop(md, "edge_crease_rim", text="Rim")
+        else:
+            col.prop(md, "nonmanifold_merge_threshold")
 
         col = split.column()
 
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 5c99760dc9c..d53b6cde4ae 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -4890,7 +4890,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
   }
 
   if (!MAIN_VERSION_ATLEAST(bmain, 283, 12)) {
-
     /* Activate f-curve drawing in the sequencer. */
     for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
       for (ScrArea *area = screen->areabase.first; area; area = area->next) {
@@ -4929,5 +4928,18 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
    */
   {
     /* Keep this block, even when empty. */
+
+    /* Solidify modifier merge tolerance. */
+    if (!DNA_struct_elem_find(fd->filesdna, "SolidifyModifierData", "float", "merge_tolerance")) {
+      for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) {
+        for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+          if (md->type == eModifierType_Solidify) {
+            SolidifyModifierData *smd = (SolidifyModifierData *)md;
+            /* set to 0.0003 since that is what was used before, default now is 0.0001 */
+            smd->merge_tolerance = 0.0003f;
+          }
+        }
+      }
+    }
   }
 }
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index b2b2a73848a..431fcb7a243 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1175,6 +1175,9 @@ typedef struct SolidifyModifierData {
   int flag;
   short mat_ofs;
   short mat_ofs_rim;
+
+  float merge_tolerance;
+  char _pad1[4];
 } SolidifyModifierData;
 
 /** #SolidifyModifierData.flag */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 176d8e6de91..2c4818eb972 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4523,6 +4523,13 @@ static void rna_def_modifier_solidify(BlenderRNA *brna)
   RNA_def_property_enum_items(prop, nonmanifold_boundary_mode_items);
   RNA_def_property_ui_text(prop, "Boundary Shape", "Selects the boundary adjustment algorithm");
   RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+  prop = RNA_def_property(srna, "nonmanifold_merge_threshold", PROP_FLOAT, PROP_DISTANCE);
+  RNA_def_property_float_sdna(prop, NULL, "merge_tolerance");
+  RNA_def_property_range(prop, 0.0, 1.0);
+  RNA_def_property_ui_range(prop, 0.0, 1.0, 0.01, 4);
+  RNA_def_property_ui_text(prop, "Merge Threshold", "Distance within which degenerated geometry is merged");
+  RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
 static void rna_def_modifier_screw(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 0eed2335ed7..74d9df7d093 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -53,6 +53,7 @@ static void initData(ModifierData *md)
   smd->mode = MOD_SOLIDIFY_MODE_EXTRUDE;
   smd->nonmanifold_offset_mode = MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS;
   smd->nonmanifold_boundary_mode = MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_NONE;
+  smd->merge_tolerance = 0.0001f;
 }
 
 static void requiredDataMask(Object *UNUSED(ob),
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index 0f9f5952a26..1cf9def46fa 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -291,6 +291,15 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
   /* Vert edge adjacent map. */
   OldVertEdgeRef **vert_adj_edges = MEM_calloc_arrayN(
       numVerts, sizeof(*vert_adj_edges), "vert_adj_edges in solidify");
+  /* Original vertex positions (changed for degenerated geometry). */
+  float(*orig_mvert_co)[3] = MEM_malloc_arrayN(
+      numVerts, sizeof(*orig_mvert_co), "orig_mvert_co in solidify");
+  /* Fill in the original vertex positions. */
+  for (uint i = 0; i < numVerts; i++) {
+    orig_mvert_co[i][0] = orig_mvert[i].co[0];
+    orig_mvert_co[i][1] = orig_mvert[i].co[1];
+    orig_mvert_co[i][2] = orig_mvert[i].co[2];
+  }
 
   /* Create edge to #NewEdgeRef map. */
   {
@@ -344,33 +353,35 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
       bool *face_singularity = MEM_calloc_arrayN(
           numPolys, sizeof(*face_singularity), "face_sides_arr in solidify");
 
+      const float merge_tolerance_sqr = smd->merge_tolerance * smd->merge_tolerance;
+      uint *combined_verts = MEM_calloc_arrayN(
+          numVerts, sizeof(*combined_verts), "combined_verts in solidify");
+
       ed = orig_medge;
       for (uint i = 0; i < numEdges; i++, ed++) {
         if (edge_adj_faces_len[i] > 0) {
-          const uint v1 = vm[ed->v1];
-          const uint v2 = vm[ed->v2];
+          uint v1 = vm[ed->v1];
+          uint v2 = vm[ed->v2];
           if (v1 != v2) {
-            sub_v3_v3v3(edgedir, orig_mvert[v2].co, orig_mvert[v1].co);
+            if (v2 < v1) {
+              SWAP(uint, v1, v2);
+            }
+            sub_v3_v3v3(edgedir, orig_mvert_co[v2], orig_mvert_co[v1]);
             orig_edge_lengths[i] = len_squared_v3(edgedir);
-            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;
-                  }
+            if (orig_edge_lengths[i] <= merge_tolerance_sqr) {
+              mul_v3_fl(edgedir,
+                        (combined_verts[v2] + 1) /
+                            (float)(combined_verts[v1] + combined_verts[v2] + 2));
+              add_v3_v3(orig_mvert_co[v1], edgedir);
+              for (uint j = v2; j < numVerts; j++) {
+                if (vm[j] == v2) {
+                  vm[j] = v1;
                 }
               }
+              vert_adj_edges_len[v1] += vert_adj_edges_len[v2];
+              vert_adj_edges_len[v2] = 0;
+              combined_verts[v1] += combined_verts[v2] + 1;
+
               if (do_shell) {
                 numNewLoops -= edge_adj_faces_len[i] * 2;
               }
@@ -429,6 +440,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
       }
 
       MEM_freeN(face_singularity);
+      MEM_freeN(combined_verts);
     }
 
     /* Create vert_adj_edges for verts. */
@@ -668,7 +680,7 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
         const uint v1 = vm[ed->v1];
         const uint v2 = vm[ed->v2];
         if (edge_adj_faces_len[i] > 0) {
-          sub_v3_v3v3(edgedir, orig_mvert[v2].co, orig_mvert[v1].co);
+          sub_v3_v3v3(edgedir, orig_mvert_co[v2], orig_mvert_co[v1]);
           mul_v3_fl(edgedir, 1.0f / orig_edge_lengths[i]);
 
           OldEdgeFaceRef *adj_faces = edge_adj_faces[i];
@@ -1496,8 +1508,9 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
                           ml_prev = ml;
                           ml = ml_next;
                         }
-                        angle = angle_v3v3v3(
-                            orig_mvert[vm[ml_prev->v]].co, mv->co, orig_mvert[vm[ml_next->v]].co);
+                        angle = angle_v3v3v3(orig_mvert_co[vm[ml_prev->v]],
+                                             orig_mvert_co[i],
+                                             orig_mvert_co[vm[ml_next->v]]);
                         if (face->reversed) {
                           total_angle_back += angle * ofs * ofs;
                         }
@@ -1591,7 +1604,8 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
                 uint k;
                 for (k = 1; k + 1 < g->edges_len; k++, edge_ptr++) {
                   MEdge *e = orig_medge + (*edge_ptr)->old_edge;
-                  sub_v3_v3v3(tmp, orig_mvert[vm[e->v1] == i ? e->v2 : e->v1].co, mv->co);
+                  sub_v3_v3v3(
+                      tmp, orig_mvert_co[vm[e->v1] == i ? e->v2 : e->v1], orig_mvert_co[i]);
                   add_v3_v3(move_nor, tmp);
                 }
                 if (k == 1) {
@@ -1613,10 +1627,12 @@ Mesh *MOD_solidify_nonmanifold_applyModifier(ModifierData *md,
               MEdge *e1_edge = orig_medge + g->edges[g->edges_len - 1]->old_edge;
               float e0[3];
               float e1[3];
-              sub_v3_v3v3(
-                  e0, orig_mvert[vm[e0_edge->v1] == i ? e0_edge->v2 : e0_edge->v1].co, mv->co);
-              sub_v3_v3v3(
-                  e1, orig_mvert[vm[e1_edge->v1] == i ? e1_edge->v2 : e1_edge->v1].co, mv->co);
+              sub_v3_v3v3(e0,
+                          orig_mvert_co[vm[e0_edge->v1] == i ? e0_edge->v2 : e0_edge->v1],
+                          orig_mvert_co[i]);
+              sub_v3_v3v3(e1,
+                       

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list