[Bf-blender-cvs] [c9c9b805935] sculpt-dev: Sculpt-dev: fixed edge collapse

Joseph Eagar noreply at git.blender.org
Thu Feb 24 05:59:36 CET 2022


Commit: c9c9b8059359dbd86a2cac8ea36aa26f67353624
Author: Joseph Eagar
Date:   Wed Feb 23 20:56:32 2022 -0800
Branches: sculpt-dev
https://developer.blender.org/rBc9c9b8059359dbd86a2cac8ea36aa26f67353624

Sculpt-dev: fixed edge collapse

* Code needs more cleanup
* Added even more debugging tools
  to bmesh_log.c.

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

M	intern/ghost/intern/GHOST_Wintab.cpp
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/bmesh/intern/bmesh_core.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_log_intern.h
M	source/blender/bmesh/intern/bmesh_private.h

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

diff --git a/intern/ghost/intern/GHOST_Wintab.cpp b/intern/ghost/intern/GHOST_Wintab.cpp
index 054f5e67412..07ce0c8079a 100644
--- a/intern/ghost/intern/GHOST_Wintab.cpp
+++ b/intern/ghost/intern/GHOST_Wintab.cpp
@@ -216,7 +216,7 @@ GHOST_Wintab::GHOST_Wintab(unique_hmodule handle,
       m_context{std::move(hctx)},
       m_tabletCoord{tablet},
       m_systemCoord{system},
-      m_pkts{queueSize}
+      m_pkts{(size_t)queueSize}
 {
   m_fpInfo(WTI_INTERFACE, IFC_NDEVICES, &m_numDevices);
   updateCursorInfo();
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 4160d665600..eb7d060d0eb 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -32,10 +32,19 @@
 
 #include "bmesh.h"
 #include "bmesh_log.h"
+
 #include "pbvh_intern.h"
 
 #include <stdio.h>
 
+//#define DYNTOPO_VALIDATE_LOG
+
+#ifdef DYNTOPO_VALIDATE_LOG
+#  define VALIDATE_LOG(log) BM_log_validate_cur(log)
+#else
+#  define VALIDATE_LOG(log)
+#endif
+
 //#define DYNTOPO_REPORT
 //#define WITH_ADAPTIVE_CURVATURE
 //#define DYNTOPO_NO_THREADING
@@ -295,7 +304,7 @@ static void fix_mesh(PBVH *pbvh, BMesh *bm)
   printf("done fixing mesh.\n");
 }
 
-#define CHECKMESH
+//#define CHECKMESH
 //#define TEST_INVALID_NORMALS
 
 #ifndef CHECKMESH
@@ -1276,7 +1285,7 @@ static void pbvh_bmesh_face_remove(
   PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
 
   if (!f_node || !(f_node->flag & PBVH_Leaf)) {
-    printf("%s: pbvh corruption\n", __func__);
+    printf("pbvh corruption\n");
     fflush(stdout);
     return;
   }
@@ -2182,7 +2191,6 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
 
 static bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
 {
-  return false;  // XXXX
   bm_logstack_push();
 
   static int max_faces = 64;
@@ -3025,6 +3033,7 @@ static bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
 typedef struct TraceData {
   PBVH *pbvh;
   SmallHash visit;
+  BMEdge *e;
 } TraceData;
 
 ATTR_NO_OPT void col_on_vert_kill(BMesh *bm, BMVert *v, void *userdata)
@@ -3033,13 +3042,14 @@ ATTR_NO_OPT void col_on_vert_kill(BMesh *bm, BMVert *v, void *userdata)
   PBVH *pbvh = data->pbvh;
 
   if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
-    printf("vert pbvh remove!\n");
+    // printf("vert pbvh remove!\n");
     pbvh_bmesh_vert_remove(pbvh, v);
   }
 
   if (!BLI_smallhash_haskey(&data->visit, (uintptr_t)v)) {
-    printf("vert kill!\n");
+    // printf("vert kill!\n");
     BM_log_vert_topo_pre(pbvh->bm_log, v);
+    BLI_smallhash_insert(&data->visit, (uintptr_t)v, NULL);
   }
 }
 
@@ -3049,8 +3059,9 @@ ATTR_NO_OPT void col_on_edge_kill(BMesh *bm, BMEdge *e, void *userdata)
   PBVH *pbvh = data->pbvh;
 
   if (!BLI_smallhash_haskey(&data->visit, (uintptr_t)e)) {
-    printf("edge kill!\n");
+    // printf("edge kill!\n");
     BM_log_edge_topo_pre(pbvh->bm_log, e);
+    BLI_smallhash_insert(&data->visit, (uintptr_t)e, NULL);
   }
 }
 
@@ -3064,26 +3075,62 @@ ATTR_NO_OPT void col_on_face_kill(BMesh *bm, BMFace *f, void *userdata)
   }
 
   if (!BLI_smallhash_haskey(&data->visit, (uintptr_t)f)) {
-    printf("face kill!\n");
     BM_log_face_topo_pre(pbvh->bm_log, f);
+    BLI_smallhash_insert(&data->visit, (uintptr_t)f, NULL);
   }
 }
 
-ATTR_NO_OPT static void vert_ring_do(BMVert *v,
-                                     void (*callback)(BMElem *elem, void *userdata),
-                                     void *userdata,
-                                     int tag)
+ATTR_NO_OPT void col_on_vert_add(BMesh *bm, BMVert *v, void *userdata)
 {
-  if (!v->e) {
-    v->head.hflag &= ~tag;
-    callback((BMElem *)v, userdata);
+  TraceData *data = (TraceData *)userdata;
+  PBVH *pbvh = data->pbvh;
+
+  MSculptVert *mv = BM_ELEM_CD_GET_VOID_P(v, data->pbvh->cd_sculpt_vert);
+  mv->flag |= SCULPTVERT_NEED_VALENCE | SCULPTVERT_NEED_BOUNDARY | SCULPTVERT_NEED_DISK_SORT;
+
+  BM_log_vert_topo_post(pbvh->bm_log, v);
+}
+
+ATTR_NO_OPT void col_on_edge_add(BMesh *bm, BMEdge *e, void *userdata)
+{
+  TraceData *data = (TraceData *)userdata;
+  PBVH *pbvh = data->pbvh;
+
+  BM_log_edge_topo_post(pbvh->bm_log, e);
+}
+
+ATTR_NO_OPT void col_on_face_add(BMesh *bm, BMFace *f, void *userdata)
+{
+  TraceData *data = (TraceData *)userdata;
+  PBVH *pbvh = data->pbvh;
+
+  if (bm_elem_is_free((BMElem *)f, BM_FACE)) {
+    printf("%s: error, f was freed!\n", __func__);
     return;
   }
 
+  if (BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE) {
+    pbvh_bmesh_face_remove(pbvh, f, false, false, false);
+  }
+
+  BM_log_face_topo_post(pbvh->bm_log, f);
+  BKE_pbvh_bmesh_add_face(pbvh, f, false, false);
+}
+
+/* Faces *outside* the ring region are tagged with facetag, used to detect
+ * border edges.
+ */
+static void vert_ring_do_tag(BMVert *v, int tag, int facetag, int depth)
+{
+
   BMEdge *e = v->e;
   do {
     BMVert *v2 = BM_edge_other_vert(e, v);
 
+    if (depth > 0) {
+      vert_ring_do_tag(v2, tag, facetag, depth - 1);
+    }
+
     e->head.hflag |= tag;
     v2->head.hflag |= tag;
 
@@ -3093,20 +3140,73 @@ ATTR_NO_OPT static void vert_ring_do(BMVert *v,
 
     BMLoop *l = e->l;
     do {
-      BMLoop *l2 = l;
+      l->f->head.hflag |= tag;
 
+      BMLoop *l2 = l;
       do {
         l2->v->head.hflag |= tag;
         l2->e->head.hflag |= tag;
         l2->f->head.hflag |= tag;
+
+        /*set up face tags for faces outside this region*/
+        BMLoop *l3 = l2->radial_next;
+
+        do {
+          l3->f->head.hflag |= facetag;
+        } while ((l3 = l3->radial_next) != l2);
+
       } while ((l2 = l2->next) != l);
     } while ((l = l->radial_next) != e->l);
   } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+}
+
+static void vert_ring_untag_inner_faces(BMVert *v, int tag, int facetag, int depth)
+{
+  if (!v->e) {
+    return;
+  }
+
+  BMEdge *e = v->e;
+
+  /* untag faces inside this region with facetag */
+  do {
+    BMLoop *l = e->l;
+
+    if (depth > 0) {
+      BMVert *v2 = BM_edge_other_vert(e, v);
+      vert_ring_untag_inner_faces(v2, tag, facetag, depth - 1);
+    }
+
+    if (!l) {
+      continue;
+    }
+
+    do {
+      l->f->head.hflag &= ~facetag;
+    } while ((l = l->radial_next) != e->l);
+  } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+}
+
+void vert_ring_do_apply(BMVert *v,
+                        void (*callback)(BMElem *elem, void *userdata),
+                        void *userdata,
+                        int tag,
+                        int facetag,
+                        int depth)
+{
+  BMEdge *e = v->e;
+
+  callback((BMElem *)v, userdata);
+  v->head.hflag &= ~tag;
 
   e = v->e;
   do {
     BMVert *v2 = BM_edge_other_vert(e, v);
 
+    if (depth > 0) {
+      vert_ring_do_apply(v2, callback, userdata, tag, facetag, depth - 1);
+    }
+
     if (v2->head.hflag & tag) {
       v2->head.hflag &= ~tag;
       callback((BMElem *)v2, userdata);
@@ -3129,10 +3229,12 @@ ATTR_NO_OPT static void vert_ring_do(BMVert *v,
           l2->v->head.hflag &= ~tag;
           callback((BMElem *)l2->v, userdata);
         }
+
         if (l2->e->head.hflag & tag) {
           l2->e->head.hflag &= ~tag;
           callback((BMElem *)l2->e, userdata);
         }
+
         if (l2->f->head.hflag & tag) {
           l2->f->head.hflag &= ~tag;
           callback((BMElem *)l2->f, userdata);
@@ -3142,11 +3244,45 @@ ATTR_NO_OPT static void vert_ring_do(BMVert *v,
   } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
 }
 
+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)
+{
+  if (!v->e) {
+    v->head.hflag &= ~tag;
+    callback((BMElem *)v, userdata);
+    return;
+  }
+
+  vert_ring_do_tag(v, tag, facetag, depth);
+  vert_ring_untag_inner_faces(v, tag, facetag, depth);
+  vert_ring_do_apply(v, callback, userdata, tag, facetag, depth);
+}
+
 ATTR_NO_OPT static void edge_ring_do(BMEdge *e,
                                      void (*callback)(BMElem *elem, void *userdata),
                                      void *userdata,
-                                     int tag)
+                                     int tag,
+                                     int facetag,
+                                     int depth)
 {
+
+  vert_ring_do_tag(e->v1, tag, facetag, depth);
+  vert_ring_do_tag(e->v2, tag, facetag, depth);
+
+  vert_ring_untag_inner_faces(e->v1, tag, facetag, depth);
+  vert_ring_untag_inner_faces(e->v2, tag, facetag, depth);
+
+  vert_ring_do_apply(e->v1, callback, userdata, tag, facetag, depth);
+  vert_ring_do_apply(e->v2, callback, userdata, tag, facetag, depth);
+
+  return;
   for (int i = 0; i < 2; i++) {
     BMVert *v2 = i ? e->v2 : e->v1;
     BMEdge *e2 = v2->e;
@@ -3217,6 +3353,27 @@ ATTR_NO_OPT static void edge_ring_do(BMEdge *e,
   }
 }
 
+ATTR_NO_OPT static void collapse_ring_callback_pre2(BMElem *elem, void *userdata)
+{
+  TraceData *data = (TraceData *)userdata;
+  PBVH *pbvh = data->pbvh;
+
+  if (elem->head.htype != BM_FACE) {
+    return;
+  }
+  BMFace *f = (BMFace *)elem;
+
+  if (BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE) {
+    pbvh_bmesh_face_remove(pbvh, f, false, false, false);
+  }
+
+  void **item;
+  if (!BLI_smallhash_ensure_p(&data->visit, (uintptr_t)f, &item)) {
+    *item = NULL;
+    BM_log_face_topo_pre(pbvh->bm_log, f);
+  }
+}
+
 ATTR_NO_OPT static void collapse_ring_callback_pre(BMElem *elem, void *userdata)
 {
   bm_logstack_push();
@@ -3239,8 +3396,28 @@ ATTR_NO_OPT static void collapse_ring_callback_pre(BMElem *elem, void *userdata)
     }
     case BM_EDGE: {
       BMEdge *e = (BMEdge *)elem;
+
+      if (e == data->e || !e->l) {
+        return;
+      }
+
+      BMLoop *l = e->l;
+      do {
+        if (l->f->head.hflag & COLLAPSE_FACE_TAG) {
+          /* do not log boundary edges */
+          // return;
+      

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list