[Bf-blender-cvs] [28754e9c538] temp-T97352-3d-texturing-seam-bleeding-b2: Fix an assert trip in boolean tickled by D11272 example.

Howard Trickey noreply at git.blender.org
Mon Jul 11 15:36:21 CEST 2022


Commit: 28754e9c538b5d50977dc0c22b589427fb460820
Author: Howard Trickey
Date:   Sun Jul 10 14:50:17 2022 -0400
Branches: temp-T97352-3d-texturing-seam-bleeding-b2
https://developer.blender.org/rB28754e9c538b5d50977dc0c22b589427fb460820

Fix an assert trip in boolean tickled by D11272 example.

The face merging code in exact boolean made an assumption that
the tesselated original face was manifold except at the boundaries.
This should be true but sometimes (e.g., if the input faces have
self-intersection, as happens in the example), it is not.
This commit makes face merging tolerant of such a situation.
It might leave some stray edges from triangulation, but it should
only happen if the input is malformed.
Note: the input may be malformed if there were previous booleans
in the stack, since snapping the exact result to float coordinates
is not guaranteed to leave the mesh without defects.

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

M	source/blender/blenlib/intern/mesh_boolean.cc

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

diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc
index 700c126ca4c..464b8f4139e 100644
--- a/source/blender/blenlib/intern/mesh_boolean.cc
+++ b/source/blender/blenlib/intern/mesh_boolean.cc
@@ -2966,6 +2966,11 @@ static std::ostream &operator<<(std::ostream &os, const FaceMergeState &fms)
  * \a tris all have the same original face.
  * Find the 2d edge/triangle topology for these triangles, but only the ones facing in the
  * norm direction, and whether each edge is dissolvable or not.
+ * If we did the initial triangulation properly, and any Delaunay triangulations of interections
+ * properly, then each triangle edge should have at most one neighbor.
+ * However, there can be anonalies. For example, if an input face is self-intersecting, we fall
+ * back on the floating poing polyfill triangulation, which, after which all bets are off.
+ * Hence, try to be tolerant of such unexpected topology.
  */
 static void init_face_merge_state(FaceMergeState *fms,
                                   const Vector<int> &tris,
@@ -3053,16 +3058,35 @@ static void init_face_merge_state(FaceMergeState *fms,
           std::cout << "me.v1 == mf.vert[i] so set edge[" << me_index << "].left_face = " << f
                     << "\n";
         }
-        BLI_assert(me.left_face == -1);
-        fms->edge[me_index].left_face = f;
+        if (me.left_face != 1) {
+          /* Unexpected in the normal case: this means more than one triangle shares this
+           * edge in the same orientation. But be tolerant of this case. By making this
+           * edge not dissolvable, we'll avoid future problems due to this non-manifold topology.
+           */
+          if (dbg_level > 1) {
+            std::cout << "me.left_face was already occupied, so triangulation wasn't good\n";
+          }
+          me.dissolvable = false;
+        }
+        else {
+          fms->edge[me_index].left_face = f;
+        }
       }
       else {
         if (dbg_level > 1) {
           std::cout << "me.v1 != mf.vert[i] so set edge[" << me_index << "].right_face = " << f
                     << "\n";
         }
-        BLI_assert(me.right_face == -1);
-        fms->edge[me_index].right_face = f;
+        if (me.right_face != -1) {
+          /* Unexpected, analogous to the me.left_face != -1 case above. */
+          if (dbg_level > 1) {
+            std::cout << "me.right_face was already occupied, so triangulation wasn't good\n";
+          }
+          me.dissolvable = false;
+        }
+        else {
+          fms->edge[me_index].right_face = f;
+        }
       }
       fms->face[f].edge.append(me_index);
     }



More information about the Bf-blender-cvs mailing list