[Bf-blender-cvs] [f68b5cd7e1c] sculpt-dev: sculpt-dev: Cleanup collapse code

Joseph Eagar noreply at git.blender.org
Sat Jan 28 09:35:04 CET 2023


Commit: f68b5cd7e1c831dcf6518107d485443d2cf5d6d1
Author: Joseph Eagar
Date:   Fri Jan 27 23:35:48 2023 -0800
Branches: sculpt-dev
https://developer.blender.org/rBf68b5cd7e1c831dcf6518107d485443d2cf5d6d1

sculpt-dev: Cleanup collapse code

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

M	source/blender/blenkernel/intern/dyntopo_collapse.cc
M	source/blender/bmesh/intern/bmesh_idmap.h

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

diff --git a/source/blender/blenkernel/intern/dyntopo_collapse.cc b/source/blender/blenkernel/intern/dyntopo_collapse.cc
index dc7173f66ad..33ab9617891 100644
--- a/source/blender/blenkernel/intern/dyntopo_collapse.cc
+++ b/source/blender/blenkernel/intern/dyntopo_collapse.cc
@@ -34,6 +34,7 @@
 #include "dyntopo_intern.hh"
 #include "pbvh_intern.h"
 
+#include <functional>
 #include <stdio.h>
 
 using blender::float2;
@@ -131,8 +132,7 @@ inline bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
 
 typedef struct TraceData {
   PBVH *pbvh;
-  SmallHash visit;
-  blender::Set<void *> visit2;
+  blender::Set<void *> visit;
   BMEdge *e;
 } TraceData;
 
@@ -146,10 +146,9 @@ ATTR_NO_OPT void col_on_vert_kill(BMesh *bm, BMVert *v, void *userdata)
     blender::dyntopo::pbvh_bmesh_vert_remove(pbvh, v);
   }
 
-  if (!BLI_smallhash_haskey(&data->visit, (uintptr_t)v)) {
+  if (!data->visit.add(static_cast<void *>(v))) {
     // printf("vert kill!\n");
     BM_log_vert_pre(pbvh->bm_log, v);
-    BLI_smallhash_insert(&data->visit, (uintptr_t)v, nullptr);
 #ifdef USE_NEW_IDMAP
     BM_idmap_release(pbvh->bm_idmap, reinterpret_cast<BMElem *>(v), true);
 #endif
@@ -161,10 +160,9 @@ ATTR_NO_OPT void col_on_edge_kill(BMesh *bm, BMEdge *e, void *userdata)
   TraceData *data = (TraceData *)userdata;
   PBVH *pbvh = data->pbvh;
 
-  if (!BLI_smallhash_haskey(&data->visit, (uintptr_t)e)) {
+  if (!data->visit.add(static_cast<void *>(e))) {
     // printf("edge kill!\n");
     BM_log_edge_pre(pbvh->bm_log, e);
-    BLI_smallhash_insert(&data->visit, (uintptr_t)e, nullptr);
 #ifdef USE_NEW_IDMAP
     BM_idmap_release(pbvh->bm_idmap, reinterpret_cast<BMElem *>(e), true);
 #endif
@@ -180,9 +178,8 @@ ATTR_NO_OPT void col_on_face_kill(BMesh *bm, BMFace *f, void *userdata)
     pbvh_bmesh_face_remove(pbvh, f, false, false, false);
   }
 
-  if (!BLI_smallhash_haskey(&data->visit, (uintptr_t)f)) {
+  if (!data->visit.add(static_cast<void *>(f))) {
     BM_log_face_pre(pbvh->bm_log, f);
-    BLI_smallhash_insert(&data->visit, (uintptr_t)f, nullptr);
 #ifdef USE_NEW_IDMAP
     BM_idmap_release(pbvh->bm_idmap, reinterpret_cast<BMElem *>(f), true);
 #endif
@@ -206,8 +203,8 @@ ATTR_NO_OPT void col_on_vert_add(BMesh *bm, BMVert *v, void *userdata)
   TraceData *data = (TraceData *)userdata;
   PBVH *pbvh = data->pbvh;
 
-  if (!data->visit2.add(static_cast<void *>(v))) {
-    // return;
+  if (!data->visit.add(static_cast<void *>(v))) {
+    //  return;
   }
 
   pbvh_boundary_update_bmesh(pbvh, v);
@@ -224,7 +221,7 @@ ATTR_NO_OPT void col_on_edge_add(BMesh *bm, BMEdge *e, void *userdata)
   TraceData *data = (TraceData *)userdata;
   PBVH *pbvh = data->pbvh;
 
-  if (!data->visit2.add(static_cast<void *>(e))) {
+  if (!data->visit.add(static_cast<void *>(e))) {
     // return;
   }
 
@@ -237,7 +234,7 @@ ATTR_NO_OPT void col_on_face_add(BMesh *bm, BMFace *f, void *userdata)
   TraceData *data = (TraceData *)userdata;
   PBVH *pbvh = data->pbvh;
 
-  if (!data->visit2.add(static_cast<void *>(f))) {
+  if (!data->visit.add(static_cast<void *>(f))) {
     // return;
   }
 
@@ -326,7 +323,7 @@ ATTR_NO_OPT static void vert_ring_untag_inner_faces(BMVert *v, int tag, int face
 }
 
 ATTR_NO_OPT void vert_ring_do_apply(BMVert *v,
-                                    void (*callback)(BMElem *elem, void *userdata),
+                                    std::function<void(BMElem *elem, void *userdata)> callback,
                                     void *userdata,
                                     int tag,
                                     int facetag,
@@ -385,12 +382,12 @@ ATTR_NO_OPT void vert_ring_do_apply(BMVert *v,
 const int COLLAPSE_TAG = BM_ELEM_INTERNAL_TAG;
 const int COLLAPSE_FACE_TAG = BM_ELEM_TAG_ALT;
 
-ATTR_NO_OPT static void vert_ring_do(BMVert *v,
-                                     void (*callback)(BMElem *elem, void *userdata),
-                                     void *userdata,
-                                     int tag,
-                                     int facetag,
-                                     int depth)
+ATTR_NO_OPT static void vert_ring_do_old(BMVert *v,
+                                         void (*callback)(BMElem *elem, void *userdata),
+                                         void *userdata,
+                                         int tag,
+                                         int facetag,
+                                         int depth)
 {
   if (!v->e) {
     v->head.hflag &= ~tag;
@@ -403,12 +400,71 @@ ATTR_NO_OPT static void vert_ring_do(BMVert *v,
   vert_ring_do_apply(v, callback, userdata, tag, facetag, depth);
 }
 
-static void edge_ring_do(BMEdge *e,
-                         void (*callback)(BMElem *elem, void *userdata),
-                         void *userdata,
-                         int tag,
-                         int facetag,
-                         int depth)
+ATTR_NO_OPT static void collapse_ring_callback_pre(BMElem *elem, void *userdata)
+{
+  TraceData *data = static_cast<TraceData *>(userdata);
+
+  if (!data->visit.add(static_cast<void *>(elem))) {
+    return;
+  }
+
+  switch (elem->head.htype) {
+    case BM_VERT: {
+      BMVert *v = reinterpret_cast<BMVert *>(elem);
+
+      BM_log_vert_removed(data->pbvh->bm_log, v, -1);
+      pbvh_bmesh_vert_remove(data->pbvh, v);
+      break;
+    }
+    case BM_EDGE: {
+      BMEdge *e = reinterpret_cast<BMEdge *>(elem);
+      BM_log_edge_removed(data->pbvh->bm_log, e);
+      break;
+    }
+    case BM_FACE: {
+      BMFace *f = reinterpret_cast<BMFace *>(elem);
+      BM_log_face_removed(data->pbvh->bm_log, f);
+      pbvh_bmesh_face_remove(data->pbvh, f, false, false, false);
+      break;
+    }
+  }
+}
+
+ATTR_NO_OPT static void collapse_ring_callback_post(BMElem *elem, void *userdata)
+{
+  TraceData *data = static_cast<TraceData *>(userdata);
+
+  if (!data->visit.add(static_cast<void *>(elem))) {
+    return;
+  }
+
+  switch (elem->head.htype) {
+    case BM_VERT: {
+      BMVert *v = reinterpret_cast<BMVert *>(elem);
+
+      BM_log_vert_added(data->pbvh->bm_log, v, -1);
+      break;
+    }
+    case BM_EDGE: {
+      BMEdge *e = reinterpret_cast<BMEdge *>(elem);
+      BM_log_edge_added(data->pbvh->bm_log, e);
+      break;
+    }
+    case BM_FACE: {
+      BMFace *f = reinterpret_cast<BMFace *>(elem);
+      BM_log_face_added(data->pbvh->bm_log, f);
+      BKE_pbvh_bmesh_add_face(data->pbvh, f, false, false);
+      break;
+    }
+  }
+}
+
+static void edge_ring_do_old(BMEdge *e,
+                             std::function<void(BMElem *elem, void *userdata)> callback,
+                             void *userdata,
+                             int tag,
+                             int facetag,
+                             int depth)
 {
 
   vert_ring_do_tag(e->v1, tag, facetag, depth);
@@ -419,140 +475,113 @@ static void edge_ring_do(BMEdge *e,
 
   vert_ring_do_apply(e->v1, callback, userdata, tag, facetag, depth);
   vert_ring_do_apply(e->v2, callback, userdata, tag, facetag, depth);
+}
+
+ATTR_NO_OPT static void vert_ring_do(BMVert *v,
+                                     BMVert *v_extra,
+                                     void (*callback)(BMElem *elem, void *userdata),
+                                     void *userdata,
+                                     int tag,
+                                     int facetag,
+                                     int depth)
+{
+  blender::Set<BMFace *> faces;
 
-  return;
-  for (int i = 0; i < 2; i++) {
-    BMVert *v2 = i ? e->v2 : e->v1;
-    BMEdge *e2 = v2->e;
+  std::function<void(BMVert * v, int depth)> recurse = [&](BMVert *v, int depth) {
+    if (!v->e) {
+      return;
+    }
 
+    const int max_depth = 2;
+    BMEdge *e = v->e;
     do {
-      e2->head.hflag |= tag;
-      e2->v1->head.hflag |= tag;
-      e2->v2->head.hflag |= tag;
+      BMVert *v2 = BM_edge_other_vert(e, v);
 
-      if (!e2->l) {
+      if (!e->l) {
+        if (depth < max_depth) {
+          recurse(v2, depth + 1);
+        }
         continue;
       }
 
-      BMLoop *l = e2->l;
-
+      BMLoop *l = e->l;
       do {
-        BMLoop *l2 = l;
-        do {
-          l2->v->head.hflag |= tag;
-          l2->e->head.hflag |= tag;
-          l2->f->head.hflag |= tag;
-        } while ((l2 = l2->next) != l);
-      } while ((l = l->radial_next) != e2->l);
-    } while ((e2 = BM_DISK_EDGE_NEXT(e2, v2)) != v2->e);
+        faces.add(l->f);
+      } while ((l = l->radial_next) != e->l);
+
+      if (depth < max_depth) {
+        recurse(v2, depth + 1);
+      }
+    } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+  };
+
+  recurse(v, 0);
+  if (v_extra) {
+    recurse(v_extra, 0);
   }
 
-  for (int i = 0; i < 2; i++) {
-    BMVert *v2 = i ? e->v2 : e->v1;
-    BMEdge *e2 = v2->e;
+  blender::Set<BMVert *> verts;
+  blender::Set<BMEdge *> edges;
 
-    if (v2->head.hflag & tag) {
-      v2->head.hflag &= ~tag;
-      callback((BMElem *)v2, userdata);
-    }
+  for (BMFace *f : faces) {
+    BMLoop *l = f->l_first;
 
     do {
-      if (e2->head.hflag & tag) {
-        e2->head.hflag &= ~tag;
-        callback((BMElem *)e2, userdata);
-      }
+      bool bad = false;
 
-      if (!e2->l) {
-        continue;
+      BMLoop *l2 = l->radial_next;
+      do {
+        if (!faces.contains(l2->f)) {
+          bad = true;
+          break;
+        }
+      } while ((l2 = l2->radial_next) != l);
+
+      if (!bad) {
+        edges.add(l->e);
       }
+    } while ((l = l->next) != f->l_first);
+  }
 
-      BMLoop *l = e2->l;
+  for (BMFace *f : faces) {
+    BMLoop *l = f->l_first;
+    do {
+      bool bad = false;
+      BMEdge *e = l->v->e;
 
       do {
-        BMLoop *l2 = l;
-        do {
-          if (l2->v->head.hflag & tag) {
-            callback((BMElem *)l2->v, userdata);
-            l2->v->head.hflag &= ~tag;
-          }
+        if (!edges.contains(e)) {
+          bad = true;
+          break;
+        }
+      } while ((e = BM_DISK_EDGE_NEXT(e, l->v)) != l->v->e);
 
-          if (l2->e->head.hflag & tag) {
-            callback((BMElem *)l2->e, userdata);
-            l2->e->head.hflag &= ~tag;
-          }
+      if (!bad) {
+        verts.add(l->v);
+      }
+    } while ((

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list