Commit: 1694e2aca4f8dd4203ee63ef2581b480d7a61f09
Author: Joseph Eagar
Date:   Tue Jul 20 04:14:59 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB1694e2aca4f8dd4203ee63ef2581b480d7a61f09

Sculpt dyntopo: Face set boundaries are now presered with dyntopo

* Face set boundaries are now preserved on dyntopo remeshing.
* MDynTopoVert->flag now has a DYNVERT_FSET_BOUNDARY flag
  in addition to DYNVERT_BOUNDARY.
* Instrumented uiBut with ASAN poison regions to hopefully
  find the super evil memory corruption bug that's been driving
  me insane.  It's frustratingly intermittent.  There are five
  poison regions.

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

M       source/blender/blenkernel/BKE_pbvh.h
M       source/blender/blenkernel/intern/dyntopo.c
M       source/blender/blenkernel/intern/pbvh_bmesh.c
M       source/blender/blenkernel/intern/pbvh_intern.h
M       source/blender/editors/interface/interface.c
M       source/blender/editors/interface/interface_handlers.c
M       source/blender/editors/interface/interface_intern.h
M       source/blender/editors/sculpt_paint/sculpt.c
M       source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M       source/blender/makesdna/DNA_meshdata_types.h

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h 
b/source/blender/blenkernel/BKE_pbvh.h
index 84c46ed5315..67c97f17cc0 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -734,6 +734,7 @@ PBVHNode *BKE_pbvh_node_from_face_bmesh(PBVH *pbvh, struct 
BMFace *f);
 PBVHNode *BKE_pbvh_node_from_index(PBVH *pbvh, int node_i);
 
 struct BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh);
+void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, 
struct BMVert *v);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/intern/dyntopo.c 
b/source/blender/blenkernel/intern/dyntopo.c
index b35a12cc06d..ea64b81a713 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -29,6 +29,8 @@
 
 #include <stdio.h>
 
+#define DYNVERT_ALL_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY)
+
 #define DYNTOPO_MAX_ITER 4096
 
 #define DYNTOPO_USE_HEAP
@@ -138,7 +140,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
   } \
   ((void)0)
 
-BLI_INLINE void surface_smooth_v_safe(BMVert *v, int cd_dyn_vert)
+BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
 {
   float co[3];
   float tan[3];
@@ -152,15 +154,19 @@ BLI_INLINE void surface_smooth_v_safe(BMVert *v, int 
cd_dyn_vert)
   if (!e) {
     return;
   }
+  pbvh_check_vert_boundary(pbvh, v);
 
+  const int cd_dyn_vert = pbvh->cd_dyn_vert;
   MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
-  const bool bound1 = mv1->flag & DYNVERT_BOUNDARY;
+  const bool bound1 = mv1->flag & DYNVERT_ALL_BOUNDARY;
 
   do {
     BMVert *v2 = e->v1 == v ? e->v2 : e->v1;
 
+    pbvh_check_vert_boundary(pbvh, v2);
+
     MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, v2);
-    const bool bound2 = mv2->flag & DYNVERT_BOUNDARY;
+    const bool bound2 = mv2->flag & DYNVERT_ALL_BOUNDARY;
 
     if (bound1 != bound2) {
       e = v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
@@ -1349,7 +1355,7 @@ static void long_edge_queue_task_cb(void *__restrict 
userdata,
       do {
         // try to improve convergence by applying a small amount of smoothing 
to topology,
         // but tangentially to surface.
-        surface_smooth_v_safe(l_iter->v, cd_dyn_vert);
+        surface_smooth_v_safe(tdata->pbvh, l_iter->v);
 
 #ifdef USE_EDGEQUEUE_EVEN_SUBDIV
         float w = maskcb_get(eq_ctx, l_iter->e);
@@ -1636,7 +1642,10 @@ static void short_edge_queue_create(EdgeQueueContext 
*eq_ctx,
       mv1 = BKE_PBVH_DYNVERT(cd_dyn_vert, e->v1);
       mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, e->v2);
 
-      if ((mv1->flag & DYNVERT_BOUNDARY) != (mv2->flag & DYNVERT_BOUNDARY)) {
+      pbvh_check_vert_boundary(pbvh, e->v1);
+      pbvh_check_vert_boundary(pbvh, e->v2);
+
+      if ((mv1->flag & DYNVERT_ALL_BOUNDARY) != (mv2->flag & 
DYNVERT_ALL_BOUNDARY)) {
         continue;
       }
 
@@ -1675,8 +1684,10 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext 
*eq_ctx,
   MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v1);
   MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v2);
 
-  bool boundary = (mv1->flag & DYNVERT_BOUNDARY) && (mv2->flag & 
DYNVERT_BOUNDARY);
-  bool check_boundary = (mv1->flag & DYNVERT_BOUNDARY) | (mv2->flag & 
DYNVERT_BOUNDARY);
+  pbvh_check_vert_boundary(pbvh, e->v1);
+  pbvh_check_vert_boundary(pbvh, e->v2);
+
+  bool boundary = (mv1->flag & DYNVERT_ALL_BOUNDARY) && (mv2->flag & 
DYNVERT_ALL_BOUNDARY);
 
   /* Get all faces adjacent to the edge */
   pbvh_bmesh_edge_loops(edge_loops, e);
@@ -1847,14 +1858,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext 
*eq_ctx,
   BM_edge_kill(pbvh->bm, e);
 
   MDynTopoVert *mv_new = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_new);
-  bool boundary2 = boundary || (check_boundary && BM_vert_is_boundary(v_new));
-
-  if (boundary2) {
-    mv_new->flag |= DYNVERT_BOUNDARY;
-  }
-  else {
-    mv_new->flag &= ~DYNVERT_BOUNDARY;
-  }
+  bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, 
v_new);
 }
 
 static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
@@ -2247,12 +2251,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 
     MDynTopoVert *mv_conn = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_conn);
 
-    if (BM_vert_is_boundary(v_conn)) {
-      mv_conn->flag |= DYNVERT_BOUNDARY;
-    }
-    else {
-      mv_conn->flag &= ~DYNVERT_BOUNDARY;
-    }
+    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, 
v_conn);
   }
 
   /* Delete v_del */
@@ -2409,6 +2408,11 @@ ATTR_NO_OPT static bool cleanup_valence_3_4(PBVH *pbvh,
         continue;
       }
 
+      MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_dyn_vert);
+      if (mv->flag & DYNVERT_ALL_BOUNDARY) {
+        continue;
+      }
+
       const int val = BM_vert_edge_count(v);
       if (val != 4 && val != 3) {
         continue;
@@ -2474,6 +2478,23 @@ ATTR_NO_OPT static bool cleanup_valence_3_4(PBVH *pbvh,
         printf("error!\n");
         BLI_table_gset_remove(pbvh->nodes[ni].bm_other_verts, v, NULL);
       }
+      else if (ni < 0) {
+        printf("error!\n");
+
+        // attempt to recover
+
+        BMFace *f;
+        BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
+          int ni2 = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
+
+          if (ni2 != DYNTOPO_NODE_NONE) {
+            PBVHNode *node2 = pbvh->nodes + ni2;
+
+            BLI_table_gset_remove(node2->bm_unique_verts, v, NULL);
+            BLI_table_gset_remove(node2->bm_other_verts, v, NULL);
+          }
+        }
+      }
 
       BM_log_vert_removed(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
       pbvh_bmesh_vert_remove(pbvh, v);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c 
b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 9b733f007d0..7bad50e55c6 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -64,6 +64,10 @@ Topology rake:
 #include "bmesh.h"
 #include "pbvh_intern.h"
 
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
 void pbvh_bmesh_check_nodes(PBVH *pbvh)
 {
 #if 0
@@ -1128,6 +1132,56 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
 
 /***************************** Public API *****************************/
 
+void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, 
BMVert *v)
+{
+  MDynTopoVert *mv = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
+
+  BMEdge *e = v->e;
+  mv->flag &= ~(DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY | 
DYNVERT_NEED_BOUNDARY);
+
+  if (!e) {
+    mv->flag |= DYNVERT_BOUNDARY;
+    return;
+  }
+
+  int lastfset = 0;
+  bool first = true;
+
+  do {
+    if (e->l) {
+      int fset = abs(BM_ELEM_CD_GET_INT(e->l->f, cd_faceset_offset));
+
+      if (!first && fset != lastfset) {
+        mv->flag |= DYNVERT_FSET_BOUNDARY;
+      }
+
+      lastfset = fset;
+      first = false;
+
+      // also check e->l->radial_next, in case we are not manifold
+      // which can mess up the loop order
+      if (e->l->radial_next != e->l) {
+        fset = abs(BM_ELEM_CD_GET_INT(e->l->radial_next->f, 
cd_faceset_offset));
+
+        if (fset != lastfset) {
+          mv->flag |= DYNVERT_FSET_BOUNDARY;
+        }
+      }
+    }
+
+    if (!e->l || e->l->radial_next == e->l) {
+      mv->flag |= DYNVERT_BOUNDARY;
+    }
+
+    e = e->v1 == v ? e->v1_disk_link.next : e->v2_disk_link.next;
+  } while (e != v->e);
+}
+
+void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, 
BMVert *v)
+{
+  bke_pbvh_update_vert_boundary(cd_dyn_vert, cd_faceset_offset, v);
+}
+
 /*Used by symmetrize to update boundary flags*/
 void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh)
 {
@@ -1135,14 +1189,7 @@ void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh)
   BMIter iter;
 
   BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
-    MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
-
-    if (BM_vert_is_boundary(v)) {
-      mv->flag |= DYNVERT_BOUNDARY;
-    }
-    else {
-      mv->flag &= ~DYNVERT_BOUNDARY;
-    }
+    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, 
v);
   }
 }
 
@@ -1184,9 +1231,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
 
     mv->flag = 0;
 
-    if (BM_vert_is_boundary(v)) {
-      mv->flag |= DYNVERT_BOUNDARY;
-    }
+    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, 
v);
 
     copy_v3_v3(mv->origco, v->co);
     copy_v3_v3(mv->origno, v->no);
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h 
b/source/blender/blenkernel/intern/pbvh_intern.h
index 853152c97cf..bce00b79c8c 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -16,10 +16,13 @@
 
 #pragma once
 
+#include "BLI_compiler_compat.h"
 #include "BLI_ghash.h"
 #include "DNA_customdata_types.h"
 #include "DNA_material_types.h"
 
+#include "bmesh.h"
+
 /** \file
  * \ingroup bli
  */
@@ -305,3 +308,16 @@ bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int 
node_index);
 void pbvh_bmesh_check_nodes(PBVH *pbvh);
 void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni);
 void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f);
+void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, 
BMVert *v);
+
+BLI_INLINE bool pbvh_check_vert_boundary(PBVH *pbvh, struct BMVert *v)
+{
+  MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_dyn_vert);
+
+  if (mv->flag & DYNVERT_NEED_BOUNDARY) {
+    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, 
v);
+    return true;
+  }
+
+  return false;
+}
diff --git a/source/blender/editors/interface/interface.c 
b/source/blender/editors/interface/interface.c
index ddde4f5a9dc..9aeb8dc62ad 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -86,8 +86,27 @@
 
 #include "DEG_depsgraph_query.h"
 
+#include "BLI_asan.h"
 #include "interface_intern.h"
 
+void poison_ui_but(struct uiBut *but)
+{
+  BLI_asan_poison(but->poison1, sizeof(but->poison1));
+  BLI_asan_poison(but->poison2, sizeof(but->poison2));
+  BLI_asan_poison(but->poison3, sizeof(but->poison3));
+  BLI_asan_poison(but->poison4, sizeof(but->poison4));
+  BLI_asan_poison(but->poison5, sizeof(but->poison5));
+}
+
+void unpo

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to