Commit: 77242de80e483d89fd72fac1cc5a80aa9fc0ab05
Author: Howard Trickey
Date:   Wed Aug 26 06:59:58 2020 -0400
Branches: newboolean
https://developer.blender.org/rB77242de80e483d89fd72fac1cc5a80aa9fc0ab05

Refactor to defer building Plane for Faces until later.

This is a precursor to a big speed optimization in the "finding clusters"
code. Right now there is no speedup, maybe even a bit of a slowdown,
but following commits should lead to nice speed increases.

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

M       release/datafiles/locale
M       release/scripts/addons
M       source/blender/blenlib/BLI_double3.hh
M       source/blender/blenlib/BLI_mesh_intersect.hh
M       source/blender/blenlib/intern/math_vec.cc
M       source/blender/blenlib/intern/mesh_boolean.cc
M       source/blender/blenlib/intern/mesh_intersect.cc
M       source/blender/blenlib/tests/BLI_mesh_boolean_test.cc
M       source/blender/blenlib/tests/BLI_mesh_intersect_test.cc
M       source/blender/bmesh/tools/bmesh_boolean.cc
M       source/tools

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

diff --git a/release/datafiles/locale b/release/datafiles/locale
index bc6623180ae..260b439d0fb 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit bc6623180aee561cba84ac11f5959b31016612ef
+Subproject commit 260b439d0fb15e3cd1efe5c120cf24f91d13d855
diff --git a/release/scripts/addons b/release/scripts/addons
index 1bc96468a14..26ba60a3f0c 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 1bc96468a144750348ea6b134d4aaf457d7cc6cf
+Subproject commit 26ba60a3f0c8dd229a0ac8f36190490a1ebf5145
diff --git a/source/blender/blenlib/BLI_double3.hh 
b/source/blender/blenlib/BLI_double3.hh
index fb9823c3ec0..4884b8f287c 100644
--- a/source/blender/blenlib/BLI_double3.hh
+++ b/source/blender/blenlib/BLI_double3.hh
@@ -19,6 +19,7 @@
 #include <iostream>
 
 #include "BLI_math_vector.h"
+#include "BLI_span.hh"
 
 namespace blender {
 
@@ -226,6 +227,16 @@ struct double3 {
     return double3(fabs(a.x), fabs(a.y), fabs(a.z));
   }
 
+  static int dominant_axis(const double3 &a)
+  {
+    double x = (a.x >= 0) ? a.x : -a.x;
+    double y = (a.y >= 0) ? a.y : -a.y;
+    double z = (a.z >= 0) ? a.z : -a.z;
+    return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
+  }
+
+  static double3 cross_poly(Span<double3> poly);
+
   /* orient3d gives the exact result, using multiprecision artihmetic when 
result
    * is close to zero. orient3d_fast just uses double arithmetic, so may be
    * wrong if the answer is very close to zero.
diff --git a/source/blender/blenlib/BLI_mesh_intersect.hh 
b/source/blender/blenlib/BLI_mesh_intersect.hh
index d7cf0b01823..6e2a9a6424b 100644
--- a/source/blender/blenlib/BLI_mesh_intersect.hh
+++ b/source/blender/blenlib/BLI_mesh_intersect.hh
@@ -74,7 +74,12 @@ struct Vert {
 
 std::ostream &operator<<(std::ostream &os, const Vert *v);
 
-/* A Plane whose equation is dot(nprm, p) + d = 0. */
+/* A Plane whose equation is dot(norm, p) + d = 0.
+ * The norm and d fields are always present, but the norm_exact
+ * and d_exact fields may be lazily populated. Since we don't
+ * store degenerate planes, we can tell if a the exact versions
+ * are not populated yet by having norm_exact == 0.
+ */
 struct Plane {
   mpq3 norm_exact;
   mpq_class d_exact;
@@ -83,6 +88,7 @@ struct Plane {
 
   Plane() = default;
   Plane(const mpq3 &norm_exact, const mpq_class &d_exact);
+  Plane(const double3 &norm, const double d);
 
   /* Test equality on the exact fields. */
   bool operator==(const Plane &other) const;
@@ -91,9 +97,11 @@ struct Plane {
   uint64_t hash() const;
 
   void make_canonical();
+  bool exact_populated() const;
+  void populate_exact();
 };
 
-std::ostream &operator<<(std::ostream &os, const Plane &plane);
+std::ostream &operator<<(std::ostream &os, const Plane *plane);
 
 /* A Face has a sequence of Verts that for a CCW ordering around them.
  * Faces carry an index, created at allocation time, useful for making
@@ -107,13 +115,14 @@ std::ostream &operator<<(std::ostream &os, const Plane 
&plane);
  * for each edge whether or not it is the result of intersecting
  * with another face in the intersect algorithm.
  * Since the intersect algorithm needs the plane for each face,
- * a Face also stores the Plane of the face.
+ * a Face also stores the Plane of the face, but this is only
+ * populate later because not all faces will be intersected.
  */
-struct Face {
+struct Face : NonCopyable {
   Array<const Vert *> vert;
   Array<int> edge_orig;
   Array<bool> is_intersect;
-  Plane plane;
+  Plane *plane = nullptr;
   int id = NO_INDEX;
   int orig = NO_INDEX;
 
@@ -122,7 +131,7 @@ struct Face {
   Face() = default;
   Face(Span<const Vert *> verts, int id, int orig, Span<int> edge_origs, 
Span<bool> is_intersect);
   Face(Span<const Vert *> verts, int id, int orig);
-  ~Face() = default;
+  ~Face();
 
   bool is_tri() const
   {
@@ -169,6 +178,13 @@ struct Face {
   {
     return IndexRange(vert.size());
   }
+
+  void populate_plane(bool need_exact);
+
+  bool plane_populated() const
+  {
+    return plane != nullptr;
+  }
 };
 
 std::ostream &operator<<(std::ostream &os, const Face *f);
@@ -203,12 +219,12 @@ class IMeshArena : NonCopyable, NonMovable {
   const Vert *add_or_find_vert(const mpq3 &co, int orig);
   const Vert *add_or_find_vert(const double3 &co, int orig);
 
-  const Face *add_face(Span<const Vert *> verts,
-                       int orig,
-                       Span<int> edge_origs,
-                       Span<bool> is_intersect);
-  const Face *add_face(Span<const Vert *> verts, int orig, Span<int> 
edge_origs);
-  const Face *add_face(Span<const Vert *> verts, int orig);
+  Face *add_face(Span<const Vert *> verts,
+                 int orig,
+                 Span<int> edge_origs,
+                 Span<bool> is_intersect);
+  Face *add_face(Span<const Vert *> verts, int orig, Span<int> edge_origs);
+  Face *add_face(Span<const Vert *> verts, int orig);
 
   /* The following return nullptr if not found. */
   const Vert *find_vert(const mpq3 &co) const;
@@ -226,19 +242,19 @@ class IMeshArena : NonCopyable, NonMovable {
  */
 
 class IMesh {
-  Array<const Face *> face_;
+  Array<Face *> face_;                   /* Not const so can lazily populate 
planes. */
   Array<const Vert *> vert_;             /* Only valid if vert_populated_. */
   Map<const Vert *, int> vert_to_index_; /* Only valid if vert_populated_. */
   bool vert_populated_ = false;
 
  public:
   IMesh() = default;
-  IMesh(Span<const Face *> faces) : face_(faces)
+  IMesh(Span<Face *> faces) : face_(faces)
   {
   }
 
-  void set_faces(Span<const Face *> faces);
-  const Face *face(int index) const
+  void set_faces(Span<Face *> faces);
+  Face *face(int index) const
   {
     return face_[index];
   }
@@ -297,9 +313,9 @@ class IMesh {
     return Span<const Vert *>(vert_);
   }
 
-  Span<const Face *> faces() const
+  Span<Face *> faces() const
   {
-    return Span<const Face *>(face_);
+    return Span<Face *>(face_);
   }
 
   /* Replace face at given index with one that elides the
diff --git a/source/blender/blenlib/intern/math_vec.cc 
b/source/blender/blenlib/intern/math_vec.cc
index 501b26da862..cfeee6266a9 100644
--- a/source/blender/blenlib/intern/math_vec.cc
+++ b/source/blender/blenlib/intern/math_vec.cc
@@ -122,6 +122,29 @@ mpq2::isect_result mpq2::isect_seg_seg(const mpq2 &v1,
   return ans;
 }
 
+double3 double3::cross_poly(Span<double3> poly)
+{
+  /* Newell's Method. */
+  int nv = static_cast<int>(poly.size());
+  if (nv < 3) {
+    return double3(0, 0, 0);
+  }
+  const double3 *v_prev = &poly[nv - 1];
+  const double3 *v_curr = &poly[0];
+  double3 n(0, 0, 0);
+  for (int i = 0; i < nv;) {
+    n[0] = n[0] + ((*v_prev)[1] - (*v_curr)[1]) * ((*v_prev)[2] + 
(*v_curr)[2]);
+    n[1] = n[1] + ((*v_prev)[2] - (*v_curr)[2]) * ((*v_prev)[0] + 
(*v_curr)[0]);
+    n[2] = n[2] + ((*v_prev)[0] - (*v_curr)[0]) * ((*v_prev)[1] + 
(*v_curr)[1]);
+    v_prev = v_curr;
+    ++i;
+    if (i < nv) {
+      v_curr = &poly[i];
+    }
+  }
+  return n;
+}
+
 mpq3 mpq3::cross_poly(Span<mpq3> poly)
 {
   /* Newell's Method. */
diff --git a/source/blender/blenlib/intern/mesh_boolean.cc 
b/source/blender/blenlib/intern/mesh_boolean.cc
index aba7102e2dd..a628cfa500f 100644
--- a/source/blender/blenlib/intern/mesh_boolean.cc
+++ b/source/blender/blenlib/intern/mesh_boolean.cc
@@ -1778,7 +1778,7 @@ static Vector<ComponentContainer> 
find_component_containers(int comp,
     for (int p : components[comp_other]) {
       const Patch &patch = pinfo.patch(p);
       for (int t : patch.tris()) {
-        const Face tri = *tm.face(t);
+        const Face &tri = *tm.face(t);
         if (dbg_level > 1) {
           std::cout << "tri " << t << " = " << &tri << "\n";
         }
@@ -2062,7 +2062,7 @@ static bool apply_bool_op(BoolOpType bool_optype, const 
Array<int> &winding)
  * triangles that are part of stacks of geometrically identical
  * triangles enclosing zero volume cells.
  */
-static void extract_zero_volume_cell_tris(Vector<const Face *> &r_tris,
+static void extract_zero_volume_cell_tris(Vector<Face *> &r_tris,
                                           const IMesh &tm_subdivided,
                                           const PatchesInfo &pinfo,
                                           const CellsInfo &cinfo,
@@ -2170,7 +2170,7 @@ static void extract_zero_volume_cell_tris(Vector<const 
Face *> &r_tris,
             tri.edge_orig[2], tri.edge_orig[1], tri.edge_orig[0]};
         std::array<bool, 3> flipped_is_intersect = {
             tri.is_intersect[2], tri.is_intersect[1], tri.is_intersect[0]};
-        const Face *flipped_f = arena->add_face(
+        Face *flipped_f = arena->add_face(
             flipped_vs, f->orig, flipped_e_origs, flipped_is_intersect);
         r_tris.append(flipped_f);
       }
@@ -2197,7 +2197,7 @@ static IMesh extract_from_in_output_volume_diffs(const 
IMesh &tm_subdivided,
   if (dbg_level > 0) {
     std::cout << "\nEXTRACT_FROM_FLAG_DIFFS\n";
   }
-  Vector<const Face *> out_tris;
+  Vector<Face *> out_tris;
   out_tris.reserve(tm_subdivided.face_size());
   bool any_zero_volume_cell = false;
   for (int t : tm_subdivided.face_index_range()) {
@@ -2219,15 +2219,15 @@ static IMesh extract_from_in_output_volume_diffs(const 
IMesh &tm_subdivided,
       if (dbg_level > 0) {
         std::cout << "need tri " << t << " flip=" << flip << "\n";
       }
-      const Face *f = tm_subdivided.face(t);
+      Face *f = tm_subdivided.face(t);
       if (flip) {
-        const Face &tri = *f;
+        Face &tri = *f;
         std::array<const Vert *, 3> flipped_vs = {tri[0], tri[2], tri[1]};
         std::array<int, 3> flipped_e_origs = {
             tri.edge_orig[2], tri.edge_orig[1], tri.edge_orig[0]};
         std::array<bool, 3> flipped_is_intersect = {
             tri.is_intersect[2], tri.is_intersect[1], tri.is_intersect[0]};
-        const Face *flipped_f = arena->add_face(
+        Face *flipped_f = arena->add_face(
             flipped_vs, f->orig, flipped_e_origs, flipped_is_intersect);
         out_tris.append(flipped_f);
       }
@@ -2366,7 +2366,7 @@ static IMesh gwn_boolean(const IMesh &tm,
     std::cout << "GWN_BOOLEAN\n";
   }


@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to