[Bf-blender-cvs] [7b4bc72a49b] temp-T97352-3d-texturing-seam-bleeding: Remove BMesh.

Jeroen Bakker noreply at git.blender.org
Fri Apr 22 13:51:50 CEST 2022


Commit: 7b4bc72a49bae77477ecf93ceec11ec53e8d8915
Author: Jeroen Bakker
Date:   Fri Apr 22 13:51:45 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding
https://developer.blender.org/rB7b4bc72a49bae77477ecf93ceec11ec53e8d8915

Remove BMesh.

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

M	source/blender/blenkernel/BKE_pbvh_pixels.hh
M	source/blender/blenkernel/intern/pbvh_pixels.cc
M	source/blender/blenkernel/intern/pbvh_pixels_seams.cc

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

diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index 07c17279a44..6d4f5db819c 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -210,7 +210,7 @@ NodeData &BKE_pbvh_pixels_node_data_get(PBVHNode &node);
 void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user);
 
 void BKE_pbvh_pixels_rebuild_seams(
-    PBVH *pbvh, Mesh *me, Image *image, ImageUser *image_user, int cd_loop_uv_offset);
+    PBVH *pbvh, const Mesh *me, Image *image, ImageUser *image_user, const MLoopUV *ldata_uv);
 void BKE_pbvh_pixels_fix_seams(PBVHNode *node, Image *image, ImageUser *image_user);
 
 }  // namespace blender::bke::pbvh::pixels
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index d3c1f71931a..a8a8a1c9325 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -323,8 +323,7 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
   BKE_pbvh_parallel_range_settings(&settings, true, nodes_to_update.size());
   BLI_task_parallel_range(0, nodes_to_update.size(), &user_data, do_encode_pixels, &settings);
 
-  int cd_loop_uv_offset = CustomData_get_offset(&mesh->ldata, CD_MLOOPUV);
-  BKE_pbvh_pixels_rebuild_seams(pbvh, mesh, image, image_user, cd_loop_uv_offset);
+  BKE_pbvh_pixels_rebuild_seams(pbvh, mesh, image, image_user, ldata_uv);
 
   if (USE_WATERTIGHT_CHECK) {
     apply_watertight_check(pbvh, image, image_user);
diff --git a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
index 685ed16372b..effa06d5588 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels_seams.cc
@@ -11,56 +11,105 @@
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
 
+#include "BLI_edgehash.h"
 #include "BLI_vector.hh"
 
-#include "bmesh.h"
-
 #include "pbvh_intern.h"
 
-using BMLoopConnection = std::pair<BMLoop *, BMLoop *>;
-
 namespace blender::bke::pbvh::pixels {
 
-/**
- * Find loops that are connected in 3d space, but not in uv space. Or loops that don't have any
- * connection at all.
- *
- * TODO better name would be to find loops that need uv seam fixes.
- */
-void find_connected_loops(BMesh *bm,
-                          const int cd_loop_uv_offset,
-                          Vector<BMLoopConnection> &r_connected,
-                          Vector<BMLoop *> &r_unconnected)
+struct EdgeLoop {
+  /** Loop indexes that form an edge. */
+  int l[2];
+};
+
+enum class EdgeCheckFlag {
+  /** No connecting edge loop found. */
+  Unconnected,
+  /** A connecting edge loop found. */
+  Connected,
+};
+
+struct EdgeCheck {
+  EdgeCheckFlag flag;
+  EdgeLoop first;
+  EdgeLoop second;
+};
+
+/** Do the two given EdgeLoops share the same uv coordinates. */
+bool share_uv(const MLoopUV *ldata_uvs, EdgeLoop &edge1, EdgeLoop &edge2)
+{
+  const float2 &uv_1_a = ldata_uvs[edge1.l[0]].uv;
+  const float2 &uv_1_b = ldata_uvs[edge1.l[1]].uv;
+  const float2 &uv_2_a = ldata_uvs[edge2.l[0]].uv;
+  const float2 &uv_2_b = ldata_uvs[edge2.l[1]].uv;
+  const float limit = 0.0001f;
+
+  return (compare_v2v2(uv_1_a, uv_2_a, limit) && compare_v2v2(uv_1_b, uv_2_b, limit)) ||
+         (compare_v2v2(uv_1_a, uv_2_b, limit) && compare_v2v2(uv_1_b, uv_2_a, limit));
+}
+
+/** Make a list of connected and unconnected edgeloops that require UV Seam fixes. */
+void find_edges_that_need_fixing(const Mesh *mesh,
+                                 const MLoopUV *ldata_uvs,
+                                 Vector<std::pair<EdgeLoop, EdgeLoop>> &r_connected,
+                                 Vector<EdgeLoop> &r_unconnected)
 {
-  BMEdge *e;
-  BMIter eiter;
-  BMLoop *l;
-  BMIter liter;
-  BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
-    bool first = true;
-    bool connection_found = false;
-    BMLoop *l_first;
-
-    BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
-      if (first) {
-        l_first = l;
-        first = false;
+  EdgeHash *eh = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh->totpoly));
+
+  for (int p = 0; p < mesh->totpoly; p++) {
+    MPoly &mpoly = mesh->mpoly[p];
+    int prev_l = mpoly.loopstart + mpoly.totloop - 1;
+    for (int l = 0; l < mpoly.totloop; l++) {
+      MLoop &prev_mloop = mesh->mloop[prev_l];
+      int current_l = mpoly.loopstart + l;
+      MLoop &mloop = mesh->mloop[current_l];
+
+      void **value_ptr;
+
+      if (!BLI_edgehash_ensure_p(eh, prev_mloop.v, mloop.v, &value_ptr)) {
+        EdgeCheck *value = MEM_cnew<EdgeCheck>(__func__);
+        value->flag = EdgeCheckFlag::Unconnected;
+        value->first.l[0] = min_ii(prev_l, current_l);
+        value->first.l[1] = max_ii(prev_l, current_l);
+        *value_ptr = value;
       }
       else {
-        connection_found = true;
-        if (!BM_loop_uv_share_edge_check(l_first, l, cd_loop_uv_offset)) {
-          /* Edge detected that is connected in 3d space, but not in uv space. */
-          r_connected.append(BMLoopConnection(l_first, l));
-          r_connected.append(BMLoopConnection(l, l_first));
-          break;
+        EdgeCheck *value = static_cast<EdgeCheck *>(*value_ptr);
+        if (value->flag == EdgeCheckFlag::Unconnected) {
+          value->flag = EdgeCheckFlag::Connected;
+          value->second.l[0] = min_ii(prev_l, current_l);
+          value->second.l[1] = max_ii(prev_l, current_l);
         }
       }
+
+      prev_l = current_l;
     }
-    if (!connection_found) {
-      BLI_assert(!first);
-      r_unconnected.append(l_first);
+  }
+
+  EdgeHashIterator iter;
+  BLI_edgehashIterator_init(&iter, eh);
+  while (!BLI_edgehashIterator_isDone(&iter)) {
+    EdgeCheck *value = static_cast<EdgeCheck *>(BLI_edgehashIterator_getValue(&iter));
+    switch (value->flag) {
+      case EdgeCheckFlag::Unconnected: {
+        r_unconnected.append(value->first);
+        break;
+      }
+      case EdgeCheckFlag::Connected: {
+        // check for uv space to add to r_connected
+        if (!share_uv(ldata_uvs, value->first, value->second)) {
+          r_connected.append(std::pair<EdgeLoop, EdgeLoop>(value->first, value->second));
+          r_connected.append(std::pair<EdgeLoop, EdgeLoop>(value->second, value->first));
+        }
+        break;
+      }
     }
+
+    BLI_edgehashIterator_step(&iter);
   }
+
+  BLI_edgehash_free(eh, MEM_freeN);
 }
 
 struct PixelInfo {
@@ -239,7 +288,6 @@ static void add_seam_fix(PBVHNode &node,
 
 /** \name Build fixes for connected edges.
  * \{ */
-
 static void build_fixes(PBVH &pbvh,
                         Bitmap &bitmap,
                         const rcti &uvbounds,
@@ -281,7 +329,7 @@ static void build_fixes(PBVH &pbvh,
        * difference.
        */
       float2 other_closest_point;
-      interp_v2_v2v2(other_closest_point, luv_b_2.uv, luv_b_1.uv, lambda);
+      interp_v2_v2v2(other_closest_point, luv_b_1.uv, luv_b_2.uv, lambda);
       float2 direction_b;
       sub_v2_v2v2(direction_b, luv_b_2.uv, luv_b_1.uv);
       float2 perpedicular_b(direction_b.y, -direction_b.x);
@@ -323,28 +371,23 @@ static void build_fixes(PBVH &pbvh,
 }
 
 static void build_fixes(PBVH &pbvh,
-                        const Vector<BMLoopConnection> &connected,
+                        const Vector<std::pair<EdgeLoop, EdgeLoop>> &connected,
                         Bitmaps &bitmaps,
-                        const int cd_loop_uv_offset)
+                        const MLoopUV *ldata_uvs)
 {
-  for (const BMLoopConnection &pair : connected) {
+  for (const std::pair<EdgeLoop, EdgeLoop> &pair : connected) {
     // determine bounding rect in uv space + margin of 1;
     rctf uvbounds;
     BLI_rctf_init_minmax(&uvbounds);
-    MLoopUV *luv_a_1 = static_cast<MLoopUV *>(
-        BM_ELEM_CD_GET_VOID_P(pair.first, cd_loop_uv_offset));
-    MLoopUV *luv_a_2 = static_cast<MLoopUV *>(
-        BM_ELEM_CD_GET_VOID_P(pair.first->next, cd_loop_uv_offset));
-    BLI_rctf_do_minmax_v(&uvbounds, luv_a_1->uv);
-    BLI_rctf_do_minmax_v(&uvbounds, luv_a_2->uv);
+    const MLoopUV &luv_a_1 = ldata_uvs[pair.first.l[0]];
+    const MLoopUV &luv_a_2 = ldata_uvs[pair.first.l[1]];
+    BLI_rctf_do_minmax_v(&uvbounds, luv_a_1.uv);
+    BLI_rctf_do_minmax_v(&uvbounds, luv_a_2.uv);
 
-    MLoopUV *luv_b_1 = static_cast<MLoopUV *>(
-        BM_ELEM_CD_GET_VOID_P(pair.second, cd_loop_uv_offset));
-    MLoopUV *luv_b_2 = static_cast<MLoopUV *>(
-        BM_ELEM_CD_GET_VOID_P(pair.second->next, cd_loop_uv_offset));
+    const MLoopUV &luv_b_1 = ldata_uvs[pair.second.l[0]];
+    const MLoopUV &luv_b_2 = ldata_uvs[pair.second.l[1]];
 
-    const float scale_factor = len_v2v2(luv_b_1->uv, luv_b_2->uv) /
-                               len_v2v2(luv_a_1->uv, luv_a_2->uv);
+    const float scale_factor = len_v2v2(luv_b_1.uv, luv_b_2.uv) / len_v2v2(luv_a_1.uv, luv_a_2.uv);
 
     for (Bitmap &bitmap : bitmaps.bitmaps) {
       rcti uvbounds_i;
@@ -362,7 +405,7 @@ static void build_fixes(PBVH &pbvh,
                             bitmap.resolution[1] +
                         MARGIN;
 
-      build_fixes(pbvh, bitmap, uvbounds_i, *luv_a_1, *luv_a_2, *luv_b_1, *luv_b_2, scale_factor);
+      build_fixes(pbvh, bitmap, uvbounds_i, luv_a_1, luv_a_2, luv_b_1, luv_b_2, scale_factor);
     }
   }
 }
@@ -426,20 +469,18 @@ static void build_fixes(
 }
 
 static void build_fixes(PBVH &pbvh,
-                        const Vector<BMLoop *> &unconnected,
+                        const Vector<EdgeLoop> &unconnected,
                         Bitmaps &bitmaps,
-                        const int cd_loop_uv_offset)
+                        const MLoopUV *ldata_uv)
 {
-  for (const BMLoop *unconnected_loop : unconnected) {
+  for (const EdgeLoop &unconnected_loop : unconnected) {
     // determine bounding rect in uv space + margin of 1;
     rctf uvbounds;
     BLI_rctf_init_minmax(&uvbounds);
-    MLoopUV *luv_1 = static_cast<MLoopUV *>(
-        BM_ELEM_CD_GET_VOID_P(unconnected_loop, cd_loop_uv_offset));
-    MLoopUV *luv_2 = static_cast<MLoopUV *>(
-        BM_ELEM_CD_GE

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list