[Bf-blender-cvs] [77769090266] newboolean: Change boolean blenlib interface to be purely C++.

Howard Trickey noreply at git.blender.org
Thu Jul 2 16:14:40 CEST 2020


Commit: 777690902663f3dc820f183329e404a6388485f4
Author: Howard Trickey
Date:   Wed Jul 1 12:42:04 2020 -0400
Branches: newboolean
https://developer.blender.org/rB777690902663f3dc820f183329e404a6388485f4

Change boolean blenlib interface to be purely C++.

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

R066	source/blender/blenlib/BLI_boolean.h	source/blender/blenlib/BLI_boolean.hh
M	source/blender/blenlib/CMakeLists.txt
M	source/blender/blenlib/intern/boolean.cc
M	source/blender/bmesh/tools/bmesh_boolean.cc
M	tests/gtests/blenlib/BLI_boolean_test.cc

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

diff --git a/source/blender/blenlib/BLI_boolean.h b/source/blender/blenlib/BLI_boolean.hh
similarity index 66%
rename from source/blender/blenlib/BLI_boolean.h
rename to source/blender/blenlib/BLI_boolean.hh
index 55155afc1d4..1ced075a907 100644
--- a/source/blender/blenlib/BLI_boolean.h
+++ b/source/blender/blenlib/BLI_boolean.hh
@@ -14,48 +14,13 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#ifndef __BLI_BOOLEAN_H__
-#define __BLI_BOOLEAN_H__
+#ifndef __BLI_BOOLEAN_HH__
+#define __BLI_BOOLEAN_HH__
 
 /** \file
  * \ingroup bli
  */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum bool_optype {
-  BOOLEAN_NONE = -1,
-  /* Aligned with BooleanModifierOp. */
-  BOOLEAN_ISECT = 0,
-  BOOLEAN_UNION = 1,
-  BOOLEAN_DIFFERENCE = 2,
-} bool_optype;
-
-typedef struct Boolean_trimesh_input {
-  int vert_len;
-  int tri_len;
-  float (*vert_coord)[3];
-  int (*tri)[3];
-} Boolean_trimesh_input;
-
-typedef struct Boolean_trimesh_output {
-  int vert_len;
-  int tri_len;
-  float (*vert_coord)[3];
-  int (*tri)[3];
-} Boolean_trimesh_output;
-
-Boolean_trimesh_output *BLI_boolean_trimesh(const Boolean_trimesh_input *in0,
-                                            const Boolean_trimesh_input *in1,
-                                            int bool_optype);
-
-void BLI_boolean_trimesh_free(Boolean_trimesh_output *output);
-
-#ifdef __cplusplus
-}
-
 #  include "BLI_array.hh"
 #  include "BLI_math_mpq.hh"
 #  include "BLI_mesh_intersect.hh"
@@ -64,6 +29,15 @@ void BLI_boolean_trimesh_free(Boolean_trimesh_output *output);
 namespace blender {
 namespace meshintersect {
 
+/* Enum values after BOOLEAN_NONE need to match BMESH_ISECT_BOOLEAN_... values in editmesh_intersect.c. */
+enum bool_optype {
+  BOOLEAN_NONE = -1,
+  /* Aligned with BooleanModifierOp. */
+  BOOLEAN_ISECT = 0,
+  BOOLEAN_UNION = 1,
+  BOOLEAN_DIFFERENCE = 2,
+};
+
 struct PolyMeshOrig {
   Array<int> vert_orig;
   Array<Array<int>> face_orig;
@@ -79,7 +53,9 @@ struct PolyMesh {
   PolyMeshOrig orig;
 };
 
-PolyMesh boolean(PolyMesh &pm, int bool_optype, int nshapes, std::function<int(int)> shape_fn);
+PolyMesh boolean(PolyMesh &pm, bool_optype op, int nshapes, std::function<int(int)> shape_fn);
+
+TriMesh boolean_trimesh(const TriMesh &tm, bool_optype op, int nshapes, std::function<int(int)> shape_fn);
 
 void write_obj_polymesh(const Array<mpq3> &vert,
                         const Array<Array<int>> &face,
@@ -88,6 +64,4 @@ void write_obj_polymesh(const Array<mpq3> &vert,
 }  // namespace meshintersect
 }  // namespace blender
 
-#endif
-
-#endif /* __BLI_BOOLEAN_H__ */
+#endif /* __BLI_BOOLEAN_HH__ */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 8d5d370df3d..52cdd6ca1af 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -157,7 +157,7 @@ set(SRC
   BLI_bitmap.h
   BLI_bitmap_draw_2d.h
   BLI_blenlib.h
-  BLI_boolean.h
+  BLI_boolean.hh
   BLI_boxpack_2d.h
   BLI_buffer.h
   BLI_color.hh
diff --git a/source/blender/blenlib/intern/boolean.cc b/source/blender/blenlib/intern/boolean.cc
index 55f969c1b81..bdf9b56dda6 100644
--- a/source/blender/blenlib/intern/boolean.cc
+++ b/source/blender/blenlib/intern/boolean.cc
@@ -33,7 +33,7 @@
 #include "BLI_vector.hh"
 #include "BLI_vector_set.hh"
 
-#include "BLI_boolean.h"
+#include "BLI_boolean.hh"
 
 namespace blender {
 
@@ -987,7 +987,7 @@ static int find_ambient_cell(const TriMesh &tm,
 static void propagate_windings_and_flag(PatchesInfo &pinfo,
                                         CellsInfo &cinfo,
                                         int c_ambient,
-                                        int bool_optype,
+                                        bool_optype op,
                                         int nshapes,
                                         std::function<int(int)> shape_fn)
 {
@@ -1025,7 +1025,7 @@ static void propagate_windings_and_flag(PatchesInfo &pinfo,
         if (dbg_level > 1) {
           std::cout << "    representative tri " << t << ": in shape " << shape << "\n";
         }
-        cell_neighbor.set_winding_and_flag(cell, shape, winding_delta, bool_optype);
+        cell_neighbor.set_winding_and_flag(cell, shape, winding_delta, op);
         if (dbg_level > 1) {
           std::cout << "    now cell_neighbor = " << cell_neighbor << "\n";
         }
@@ -1177,9 +1177,9 @@ static TriMesh extract_from_flag_diffs(const TriMesh &tm_subdivided,
   return tm_out;
 }
 
-static const char *bool_optype_name(int bool_optype)
+static const char *bool_optype_name(bool_optype op)
 {
-  switch (bool_optype) {
+  switch (op) {
     case BOOLEAN_NONE:
       return "none";
       break;
@@ -1196,72 +1196,6 @@ static const char *bool_optype_name(int bool_optype)
   }
 }
 
-/*
- * This function does a boolean operation on nshapes inputs.
- * All the shapes are combined in tm_in.
- * The shape_fn function should take a triangle index in tm_in and return
- * a number in the range 0 to nshapes-1, to say which shape that triangle is in.
- */
-static TriMesh nary_boolean(const TriMesh &tm_in,
-                            int bool_optype,
-                            int nshapes,
-                            std::function<int(int)> shape_fn)
-{
-  constexpr int dbg_level = 0;
-  if (dbg_level > 0) {
-    std::cout << "BOOLEAN of " << nshapes << " operand" << (nshapes == 1 ? "" : "s")
-              << " op=" << bool_optype_name(bool_optype) << "\n";
-  }
-  if (tm_in.vert.size() == 0 || tm_in.tri.size() == 0) {
-    return TriMesh(tm_in);
-  }
-  TriMesh tm_si = trimesh_self_intersect(tm_in);
-  /* It is possible for tm_si to be empty if all the input triangles are bogus/degenerate. */
-  if (tm_si.tri.size() == 0 || bool_optype == BOOLEAN_NONE) {
-    return tm_si;
-  }
-  auto si_shape_fn = [shape_fn, tm_si](int t) { return shape_fn(tm_si.tri[t].orig()); };
-  if (dbg_level > 1) {
-    write_obj_trimesh(tm_si.vert, tm_si.tri, "boolean_tm_input");
-    std::cout << "boolean tm input:\n";
-    for (int t = 0; t < static_cast<int>(tm_si.tri.size()); ++t) {
-      std::cout << "tri " << t << " = " << tm_si.tri[t] << " shape " << si_shape_fn(t) << "\n";
-    }
-  }
-  TriMeshTopology tm_si_topo(&tm_si);
-  PatchesInfo pinfo = find_patches(tm_si, tm_si_topo);
-  CellsInfo cinfo = find_cells(tm_si, tm_si_topo, pinfo);
-  cinfo.init_windings(nshapes);
-  int c_ambient = find_ambient_cell(tm_si, tm_si_topo, pinfo);
-  if (c_ambient == -1) {
-    /* TODO: find a way to propagate this error to user properly. */
-    std::cout << "Could not find an ambient cell; input not valid?\n";
-    return TriMesh(tm_si);
-  }
-  propagate_windings_and_flag(pinfo, cinfo, c_ambient, bool_optype, nshapes, si_shape_fn);
-  TriMesh tm_out = extract_from_flag_diffs(tm_si, pinfo, cinfo);
-  if (dbg_level > 1) {
-    write_obj_trimesh(tm_out.vert, tm_out.tri, "boolean_tm_output");
-  }
-  return tm_out;
-}
-
-static TriMesh self_boolean(const TriMesh &tm_in, int bool_optype)
-{
-  return nary_boolean(tm_in, bool_optype, 1, [](int UNUSED(t)) { return 0; });
-}
-
-static TriMesh binary_boolean(const TriMesh &tm_in_a, const TriMesh &tm_in_b, int bool_optype)
-{
-  /* Just combine the two pieces. We can tell by original triangle number which side it came
-   * from.
-   */
-  TriMesh tm_in = concat_trimeshes(tm_in_a, tm_in_b);
-  int b_tri_start = static_cast<int>(tm_in_a.tri.size());
-  auto shape_fn = [b_tri_start](int t) { return (t >= b_tri_start ? 1 : 0); };
-  return nary_boolean(tm_in, bool_optype, 2, shape_fn);
-}
-
 static Array<IndexedTriangle> triangulate_poly(int orig_face,
                                                const Array<int> &face,
                                                const Array<mpq3> &vert)
@@ -1985,7 +1919,57 @@ static PolyMesh polymesh_from_trimesh_with_dissolve(const TriMesh &tm_out, const
   return pm_out;
 }
 
-/* Do the boolean operation bool_optype on the polygon mesh pm_in.
+/*
+ * This function does a boolean operation on a TriMesh with nshapes inputs.
+ * All the shapes are combined in tm_in.
+ * The shape_fn function should take a triangle index in tm_in and return
+ * a number in the range 0 to nshapes-1, to say which shape that triangle is in.
+ */
+TriMesh boolean_trimesh(const TriMesh &tm_in,
+                            bool_optype op,
+                            int nshapes,
+                            std::function<int(int)> shape_fn)
+{
+  constexpr int dbg_level = 0;
+  if (dbg_level > 0) {
+    std::cout << "BOOLEAN of " << nshapes << " operand" << (nshapes == 1 ? "" : "s")
+              << " op=" << bool_optype_name(op) << "\n";
+  }
+  if (tm_in.vert.size() == 0 || tm_in.tri.size() == 0) {
+    return TriMesh(tm_in);
+  }
+  TriMesh tm_si = trimesh_self_intersect(tm_in);
+  /* It is possible for tm_si to be empty if all the input triangles are bogus/degenerate. */
+  if (tm_si.tri.size() == 0 || op == BOOLEAN_NONE) {
+    return tm_si;
+  }
+  auto si_shape_fn = [shape_fn, tm_si](int t) { return shape_fn(tm_si.tri[t].orig()); };
+  if (dbg_level > 1) {
+    write_obj_trimesh(tm_si.vert, tm_si.tri, "boolean_tm_input");
+    std::cout << "boolean tm input:\n";
+    for (int t = 0; t < static_cast<int>(tm_si.tri.size()); ++t) {
+      std::cout << "tri " << t << " = " << tm_si.tri[t] << " shape " << si_shape_fn(t) << "\n";
+    }
+  }
+  TriMeshTopology tm_si_topo(&tm_si);
+  PatchesInfo pinfo = find_patches(tm_si, tm_si_topo);
+  CellsInfo cinfo = find_cells(tm_si, tm_si_topo, pinfo);
+  cinfo.init_windings(nshapes);
+  int c_ambient = find_ambient_cell(tm_si, tm_si_topo, pinfo);
+  if (c_ambient == -1) {
+    /* TODO: find a way to propagate this error to user properly. */
+    std::cout << "Could not find an ambient cell; input not valid?\n";
+    return TriMesh(tm_si);
+  }
+  propagate_windings_and_flag(pinfo, cinfo, c_ambient, op, nshapes, si_shape_fn);
+  TriMesh tm_out = extract_from_flag_diffs(tm_si, pinfo, cinfo);
+  if (dbg_level > 1) {
+    write_obj_trimesh(tm_out.vert, tm_out.tri, "boolean_tm_output");
+  }
+  return tm_out;
+}
+
+/* Do the boolean operation op on the polygon mesh pm_in.
  * The boolean operation has nshapes input shapes. Each 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list