[Bf-blender-cvs] [023788ef9a4] master: Cleanup: Use span and float matrix type in direct boolean code

Hans Goudey noreply at git.blender.org
Wed Mar 3 03:58:13 CET 2021


Commit: 023788ef9a4e661c00c67505a466a3046b496048
Author: Hans Goudey
Date:   Tue Mar 2 20:58:05 2021 -0600
Branches: master
https://developer.blender.org/rB023788ef9a4e661c00c67505a466a3046b496048

Cleanup: Use span and float matrix type in direct boolean code

This commit includes a few simple improvements to the direct mesh
boolean code added recently.
 - Passing the transforms and meshes to `direct_mesh_boolean` as spans
   makes the function easier to call from C++.
 - The definition of `TransMat`, was unecessary when we have the
   `float4x4` type already used elsewhere in C++ code.

Differential Revision: https://developer.blender.org/D10592

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

M	source/blender/blenkernel/intern/mesh_boolean_convert.cc

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

diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
index 299b1ff1c71..d9564f91a04 100644
--- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
@@ -32,6 +32,7 @@
 
 #include "BLI_alloca.h"
 #include "BLI_float2.hh"
+#include "BLI_float4x4.hh"
 #include "BLI_math.h"
 #include "BLI_mesh_boolean.hh"
 #include "BLI_mesh_intersect.hh"
@@ -50,12 +51,12 @@ constexpr int estimated_max_facelen = 100; /* Used for initial size of some Vect
  * so this is a hack to clean up such matrices.
  * Would be better to change the transformation code itself.
  */
-static void clean_obmat(float cleaned[4][4], const float mat[4][4])
+static void clean_obmat(float4x4 &cleaned, const float4x4 &mat)
 {
   const float fuzz = 1e-6f;
   for (int i = 0; i < 4; i++) {
     for (int j = 0; j < 4; j++) {
-      float f = mat[i][j];
+      float f = mat.values[i][j];
       if (fabsf(f) <= fuzz) {
         f = 0.0f;
       }
@@ -65,17 +66,11 @@ static void clean_obmat(float cleaned[4][4], const float mat[4][4])
       else if (fabsf(f + 1.0f) <= fuzz) {
         f = -1.0f;
       }
-      cleaned[i][j] = f;
+      cleaned.values[i][j] = f;
     }
   }
 }
 
-/* Need to wrap this in a class to use it in an Array. */
-class TransMat {
- public:
-  float mat[4][4];
-};
-
 /* `MeshesToIMeshInfo` keeps track of information used when combining a number
  * of `Mesh`es into a single `IMesh` for doing boolean on.
  * Mostly this means keeping track of the index offsets for various mesh elements. */
@@ -97,7 +92,7 @@ class MeshesToIMeshInfo {
   Array<Face *> mesh_to_imesh_face;
   /* Transformation matrix to transform a coordinate in the corresponding
    * Mesh to the local space of the first Mesh. */
-  Array<TransMat> to_obj0;
+  Array<float4x4> to_obj0;
   /* Total number of input mesh vertices. */
   int tot_meshes_verts;
   /* Total number of input mesh edges. */
@@ -242,7 +237,7 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
  * All allocation of memory for the IMesh comes from `arena`.
  */
 static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
-                             const float (*obmats[])[4][4],
+                             Span<const float4x4 *> obmats,
                              IMeshArena &arena,
                              MeshesToIMeshInfo *r_info)
 {
@@ -271,7 +266,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
   r_info->mesh_vert_offset = Array<int>(nmeshes);
   r_info->mesh_edge_offset = Array<int>(nmeshes);
   r_info->mesh_poly_offset = Array<int>(nmeshes);
-  r_info->to_obj0 = Array<TransMat>(nmeshes);
+  r_info->to_obj0 = Array<float4x4>(nmeshes);
   int v = 0;
   int e = 0;
   int f = 0;
@@ -286,15 +281,15 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
    * of object 0, we multiply each object's `obmat` by the inverse of
    * object 0's `obmat`. Exact Boolean works better if these matrices
    * are 'cleaned' -- see the comment for the `clean_obmat` function, above. */
-  float obj0_mat[4][4];
-  float inv_obj0_mat[4][4];
+  float4x4 obj0_mat;
+  float4x4 inv_obj0_mat;
   if (obmats[0] == nullptr) {
-    unit_m4(obj0_mat);
-    unit_m4(inv_obj0_mat);
+    unit_m4(obj0_mat.values);
+    unit_m4(inv_obj0_mat.values);
   }
   else {
     clean_obmat(obj0_mat, *obmats[0]);
-    invert_m4_m4(inv_obj0_mat, obj0_mat);
+    invert_m4_m4(inv_obj0_mat.values, obj0_mat.values);
   }
 
   /* For each input `Mesh`, make `Vert`s and `Face`s for the corresponding
@@ -303,13 +298,13 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
    * When making `Face`s, we also put in the original indices for `MEdge`s that
    * make up the `MPoly`s using the same scheme. */
   for (int mi : meshes.index_range()) {
-    float objn_to_obj0_mat[4][4];
+    float4x4 objn_to_obj0_mat;
     const Mesh *me = meshes[mi];
     if (mi == 0) {
       r_info->mesh_vert_offset[mi] = 0;
       r_info->mesh_edge_offset[mi] = 0;
       r_info->mesh_poly_offset[mi] = 0;
-      unit_m4(r_info->to_obj0[0].mat);
+      unit_m4(r_info->to_obj0[0].values);
     }
     else {
       r_info->mesh_vert_offset[mi] = v;
@@ -317,23 +312,22 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
       r_info->mesh_poly_offset[mi] = f;
       /* Get matrix that transforms a coordinate in objects[mi]'s local space
        * to object[0]'s local space.*/
-      float objn_mat[4][4];
+      float4x4 objn_mat;
       if (obmats[mi] == nullptr) {
-        unit_m4(objn_mat);
+        unit_m4(objn_mat.values);
       }
       else {
         clean_obmat(objn_mat, *obmats[mi]);
       }
-      mul_m4_m4m4(objn_to_obj0_mat, inv_obj0_mat, objn_mat);
-      copy_m4_m4(r_info->to_obj0[mi].mat, objn_to_obj0_mat);
+      objn_to_obj0_mat = inv_obj0_mat * objn_mat;
+      r_info->to_obj0[mi] = objn_to_obj0_mat;
     }
     for (int vi = 0; vi < me->totvert; ++vi) {
-      float co[3];
-      copy_v3_v3(co, me->mvert[vi].co);
+      float3 co = me->mvert[vi].co;
       if (mi > 0) {
-        mul_m4_v3(objn_to_obj0_mat, co);
+        co = objn_to_obj0_mat * co;
       }
-      r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co[0], co[1], co[2]), v);
+      r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co.x, co.y, co.z), v);
       ++v;
     }
     for (const MPoly &poly : Span(me->mpoly, me->totpoly)) {
@@ -534,7 +528,7 @@ static int fill_orig_loops(const Face *f,
 static void get_poly2d_cos(const Mesh *me,
                            const MPoly *mp,
                            float (*cos_2d)[2],
-                           const TransMat &trans_mat,
+                           const float4x4 &trans_mat,
                            float r_axis_mat[3][3])
 {
   int n = mp->totloop;
@@ -546,9 +540,8 @@ static void get_poly2d_cos(const Mesh *me,
   MLoop *ml = &me->mloop[mp->loopstart];
   const MVert *mverts = me->mvert;
   for (int i = 0; i < n; ++i) {
-    float co[3];
-    copy_v3_v3(co, mverts[ml->v].co);
-    mul_m4_v3(trans_mat.mat, co);
+    float3 co = mverts[ml->v].co;
+    co = trans_mat * co;
     mul_v2_m3v3(cos_2d[i], r_axis_mat, co);
     ++ml;
   }
@@ -763,23 +756,23 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
  * Do Exact Boolean directly, without a round trip through #BMesh.
  * The Mesh operands are in `meshes`, with corresponding transforms in in `obmats`.
  */
-static Mesh *direct_mesh_boolean(const Mesh **meshes,
-                                 const float (*obmats[])[4][4],
-                                 const int meshes_len,
+static Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
+                                 Span<const float4x4 *> obmats,
                                  const bool use_self,
                                  const BoolOpType boolean_mode)
 {
   const int dbg_level = 0;
+  BLI_assert(meshes.size() == obmats.size());
+  const int meshes_len = meshes.size();
   if (meshes_len <= 0) {
     return nullptr;
   }
   if (dbg_level > 0) {
     std::cout << "\nDIRECT_MESH_INTERSECT, nmeshes = " << meshes_len << "\n";
   }
-  Span<const Mesh *> mesh_span(meshes, meshes_len);
   MeshesToIMeshInfo mim;
   IMeshArena arena;
-  IMesh m_in = meshes_to_imesh(mesh_span, obmats, arena, &mim);
+  IMesh m_in = meshes_to_imesh(meshes, obmats, arena, &mim);
   std::function<int(int)> shape_fn = [&mim](int f) {
     for (int mi = 0; mi < mim.mesh_poly_offset.size() - 1; ++mi) {
       if (f < mim.mesh_poly_offset[mi + 1]) {
@@ -814,10 +807,10 @@ Mesh *BKE_mesh_boolean(const Mesh **meshes,
                        const bool use_self,
                        const int boolean_mode)
 {
+  const blender::float4x4 **transforms = (const blender::float4x4 **)obmats;
   return blender::meshintersect::direct_mesh_boolean(
-      meshes,
-      obmats,
-      meshes_len,
+      blender::Span(meshes, meshes_len),
+      blender::Span(transforms, meshes_len),
       use_self,
       static_cast<blender::meshintersect::BoolOpType>(boolean_mode));
 }



More information about the Bf-blender-cvs mailing list