[Bf-blender-cvs] [3d00ac2961b] master: Cleanup: Various improvements to old mesh edge split code

Hans Goudey noreply at git.blender.org
Thu Dec 8 22:14:43 CET 2022


Commit: 3d00ac2961b836385efa0ee102edfaecc4e14966
Author: Hans Goudey
Date:   Thu Dec 8 14:59:26 2022 -0600
Branches: master
https://developer.blender.org/rB3d00ac2961b836385efa0ee102edfaecc4e14966

Cleanup: Various improvements to old mesh edge split code

There is a more recent implementation as a geometry node, but this code
is used by RNA and Cycles still. In order to help understand the code
to tell if it can be replaced this makes some small changes:
 - Use indexing instead of pointer incrementing
 - Add const to unchanged arguments
 - Avoid unnecessary indentation
 - Use references for expected non-null arguments

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

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

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

diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index deaa9aec3f7..f59cd4f3a7c 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -1832,7 +1832,7 @@ struct SplitFaceNewVert {
   struct SplitFaceNewVert *next;
   int new_index;
   int orig_index;
-  float *vnor;
+  const float *vnor;
 };
 
 struct SplitFaceNewEdge {
@@ -1843,82 +1843,79 @@ struct SplitFaceNewEdge {
   int v2;
 };
 
-/* Detect needed new vertices, and update accordingly loops' vertex indices.
- * WARNING! Leaves mesh in invalid state. */
-static int split_faces_prepare_new_verts(Mesh *mesh,
-                                         MLoopNorSpaceArray *lnors_spacearr,
+/**
+ * Detect necessary new vertices, and update loop vertex indices accordingly.
+ * \warning Leaves mesh in invalid state.
+ * \param lnors_spacearr: Mandatory because trying to do the job in simple way without that data is
+ * doomed to fail, even when only dealing with smooth/flat faces one can find cases that no simple
+ * algorithm can handle properly.
+ */
+static int split_faces_prepare_new_verts(Mesh &mesh,
+                                         const MLoopNorSpaceArray &lnors_spacearr,
                                          SplitFaceNewVert **new_verts,
-                                         MemArena *memarena)
+                                         MemArena &memarena)
 {
-  /* This is now mandatory, trying to do the job in simple way without that data is doomed to fail,
-   * even when only dealing with smooth/flat faces one can find cases that no simple algorithm
-   * can handle properly. */
-  BLI_assert(lnors_spacearr != nullptr);
-
-  const int loops_len = mesh->totloop;
-  int verts_len = mesh->totvert;
-  MutableSpan<MLoop> loops = mesh->loops_for_write();
-  BKE_mesh_vertex_normals_ensure(mesh);
-  float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh);
+  const int loops_len = mesh.totloop;
+  int verts_len = mesh.totvert;
+  MutableSpan<MLoop> loops = mesh.loops_for_write();
+  BKE_mesh_vertex_normals_ensure(&mesh);
+  float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(&mesh);
 
   BitVector<> verts_used(verts_len, false);
   BitVector<> done_loops(loops_len, false);
 
-  MLoop *ml = loops.data();
-  MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr;
-
-  BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX);
-
-  for (int loop_idx = 0; loop_idx < loops_len; loop_idx++, ml++, lnor_space++) {
-    if (!done_loops[loop_idx]) {
-      const int vert_idx = ml->v;
-      const bool vert_used = verts_used[vert_idx];
-      /* If vert is already used by another smooth fan, we need a new vert for this one. */
-      const int new_vert_idx = vert_used ? verts_len++ : vert_idx;
+  BLI_assert(lnors_spacearr.data_type == MLNOR_SPACEARR_LOOP_INDEX);
 
-      BLI_assert(*lnor_space);
-
-      if ((*lnor_space)->flags & MLNOR_SPACE_IS_SINGLE) {
-        /* Single loop in this fan... */
-        BLI_assert(POINTER_AS_INT((*lnor_space)->loops) == loop_idx);
-        done_loops[loop_idx].set();
-        if (vert_used) {
-          ml->v = new_vert_idx;
-        }
+  for (int loop_idx = 0; loop_idx < loops_len; loop_idx++) {
+    if (done_loops[loop_idx]) {
+      continue;
+    }
+    const MLoopNorSpace &lnor_space = *lnors_spacearr.lspacearr[loop_idx];
+    const int vert_idx = loops[loop_idx].v;
+    const bool vert_used = verts_used[vert_idx];
+    /* If vert is already used by another smooth fan, we need a new vert for this one. */
+    const int new_vert_idx = vert_used ? verts_len++ : vert_idx;
+
+    if (lnor_space.flags & MLNOR_SPACE_IS_SINGLE) {
+      /* Single loop in this fan... */
+      BLI_assert(POINTER_AS_INT(lnor_space.loops) == loop_idx);
+      done_loops[loop_idx].set();
+      if (vert_used) {
+        loops[loop_idx].v = new_vert_idx;
       }
-      else {
-        for (LinkNode *lnode = (*lnor_space)->loops; lnode; lnode = lnode->next) {
-          const int ml_fan_idx = POINTER_AS_INT(lnode->link);
-          done_loops[ml_fan_idx].set();
-          if (vert_used) {
-            loops[ml_fan_idx].v = new_vert_idx;
-          }
+    }
+    else {
+      for (const LinkNode *lnode = lnor_space.loops; lnode; lnode = lnode->next) {
+        const int ml_fan_idx = POINTER_AS_INT(lnode->link);
+        done_loops[ml_fan_idx].set();
+        if (vert_used) {
+          loops[ml_fan_idx].v = new_vert_idx;
         }
       }
+    }
 
-      if (!vert_used) {
-        verts_used[vert_idx].set();
-        /* We need to update that vertex's normal here, we won't go over it again. */
-        /* This is important! *DO NOT* set vnor to final computed lnor,
-         * vnor should always be defined to 'automatic normal' value computed from its polys,
-         * not some custom normal.
-         * Fortunately, that's the loop normal space's 'lnor' reference vector. ;) */
-        copy_v3_v3(vert_normals[vert_idx], (*lnor_space)->vec_lnor);
-      }
-      else {
-        /* Add new vert to list. */
-        SplitFaceNewVert *new_vert = (SplitFaceNewVert *)BLI_memarena_alloc(memarena,
-                                                                            sizeof(*new_vert));
-        new_vert->orig_index = vert_idx;
-        new_vert->new_index = new_vert_idx;
-        new_vert->vnor = (*lnor_space)->vec_lnor; /* See note above. */
-        new_vert->next = *new_verts;
-        *new_verts = new_vert;
-      }
+    if (!vert_used) {
+      verts_used[vert_idx].set();
+      /* We need to update that vertex's normal here, we won't go over it again. */
+      /* This is important! *DO NOT* set vnor to final computed lnor,
+       * vnor should always be defined to 'automatic normal' value computed from its polys,
+       * not some custom normal.
+       * Fortunately, that's the loop normal space's 'lnor' reference vector. ;) */
+      copy_v3_v3(vert_normals[vert_idx], lnor_space.vec_lnor);
+    }
+    else {
+      /* Add new vert to list. */
+      SplitFaceNewVert *new_vert = static_cast<SplitFaceNewVert *>(
+          BLI_memarena_alloc(&memarena, sizeof(*new_vert)));
+      new_vert->orig_index = vert_idx;
+      new_vert->new_index = new_vert_idx;
+      new_vert->vnor = lnor_space.vec_lnor; /* See note above. */
+      new_vert->next = *new_verts;
+      *new_verts = new_vert;
     }
   }
 
-  return verts_len - mesh->totvert;
+  return verts_len - mesh.totvert;
 }
 
 /* Detect needed new edges, and update accordingly loops' edge indices.
@@ -2045,7 +2042,7 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
 
   /* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */
   const int num_new_verts = split_faces_prepare_new_verts(
-      mesh, &lnors_spacearr, &new_verts, memarena);
+      *mesh, lnors_spacearr, &new_verts, *memarena);
 
   if (num_new_verts > 0) {
     /* Reminder: beyond this point, there is no way out, mesh is in invalid state



More information about the Bf-blender-cvs mailing list