[Bf-blender-cvs] [8ea7c93a378] temp_bmesh_multires: Sculpt dyntopo: support sharp edge flags

Joseph Eagar noreply at git.blender.org
Fri Aug 27 11:01:26 CEST 2021


Commit: 8ea7c93a3789e4371b896906e90e4c5ac2a5c47c
Author: Joseph Eagar
Date:   Thu Aug 26 18:00:29 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB8ea7c93a3789e4371b896906e90e4c5ac2a5c47c

Sculpt dyntopo: support sharp edge flags

* Sharp edge flags are now supported and are
  treated much the same as face set boundaries:
 + Dyntopo preserves them
 + Interior smoothing treats them as boundaries
 + Corners are detected and pinned in smoothing
 + TODO: add a brush flag to ignore sharp boundaries
   for smoothing.
* Seams are also preserved, but don't affect smoothing.
* BMLog now saves edges.
* The new edge split function is enabled.
* Dyntopo now pushes new combined BMLog entries in
  its top-level function, to avoid scary id reuse
  edge cases.
* SCULPT_vertex_is_boundary/corner now take a bitmask
  of which types of boundaries you wish to query instead
  of check_face_sets.

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/bmesh/bmesh_class.h
M	source/blender/bmesh/intern/bmesh_construct.c
M	source/blender/bmesh/intern/bmesh_core.c
M	source/blender/bmesh/intern/bmesh_interp.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_log.h
M	source/blender/bmesh/intern/bmesh_mesh.c
M	source/blender/bmesh/intern/bmesh_mesh.h
M	source/blender/bmesh/operators/bmo_inset.c
M	source/blender/bmesh/tests/bmesh_core_test.cc
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_automasking.c
M	source/blender/editors/sculpt_paint/sculpt_boundary.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_expand.c
M	source/blender/editors/sculpt_paint/sculpt_face_set.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_smooth.c
M	source/blender/editors/sculpt_paint/sculpt_undo.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 0b2e288cfb5..a63768633e7 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -213,7 +213,8 @@ typedef enum {
 
   /* tri areas are not guaranteed to be up to date, tools should
      update all nodes on first step of brush*/
-  PBVH_UpdateTriAreas = 1 << 19
+  PBVH_UpdateTriAreas = 1 << 19,
+  PBVH_UpdateOtherVerts = 1 << 20
 } PBVHNodeFlags;
 
 typedef struct PBVHFrustumPlanes {
@@ -289,6 +290,10 @@ inside the verts and not in the nodes is to allow splitting of the pbvh during t
 */
 bool BKE_pbvh_bmesh_check_origdata(PBVH *pbvh, struct BMVert *v, int stroke_id);
 
+/** used so pbvh can differentiate between different strokes,
+    see BKE_pbvh_bmesh_check_origdata */
+void BKE_pbvh_set_stroke_id(PBVH *pbvh, int stroke_id);
+
 /* Hierarchical Search in the BVH, two methods:
  * - for each hit calling a callback
  * - gather nodes in an array (easy to multithread) */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 4b75109be3e..15fba14257d 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1978,11 +1978,13 @@ void BKE_brush_sculpt_reset(Brush *br)
       // don't use DYNTOPO_INHERIT_BITMASK, we want to include
       // future bits
 
-      br->flag |= BRUSH_SMOOTH_PRESERVE_FACE_SETS;
+      br->flag |= BRUSH_SMOOTH_PRESERVE_FACE_SETS | BRUSH_SMOOTH_USE_AREA_WEIGHT |
+                  BRUSH_CURVATURE_RAKE;
       br->dyntopo.inherit = 0x7FFFFFFF &
                             ~(DYNTOPO_INHERIT_ALL | DYNTOPO_SUBDIVIDE | DYNTOPO_COLLAPSE);
       br->dyntopo.flag |= DYNTOPO_COLLAPSE | DYNTOPO_SUBDIVIDE;
-      br->autosmooth_factor = 0.02;
+      br->autosmooth_factor = 0.05;
+      br->topology_rake_factor = 0.35;
 
       break;
     case SCULPT_TOOL_VCOL_BOUNDARY:
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 991a01b87e7..45d1cf26fec 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -34,9 +34,13 @@
 
 #define DYNVERT_VALENCE_TEMP (1 << 14)
 
-//#define USE_NEW_SPLIT
-#define DYNVERT_ALL_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY)
-#define DYNVERT_ALL_CORNER (DYNVERT_CORNER | DYNVERT_FSET_CORNER)
+#define USE_NEW_SPLIT
+#define DYNVERT_SMOOTH_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY | DYNVERT_SHARP_BOUNDARY)
+#define DYNVERT_ALL_BOUNDARY \
+  (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY | DYNVERT_SHARP_BOUNDARY | DYNVERT_SEAM_BOUNDARY)
+#define DYNVERT_SMOOTH_CORNER (DYNVERT_CORNER | DYNVERT_FSET_CORNER | DYNVERT_SHARP_CORNER)
+#define DYNVERT_ALL_CORNER \
+  (DYNVERT_CORNER | DYNVERT_FSET_CORNER | DYNVERT_SHARP_CORNER | DYNVERT_SEAM_CORNER)
 
 #define DYNTOPO_MAX_ITER 4096
 
@@ -105,6 +109,9 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
  * Take care since 'break' won't works as expected within these macros!
  */
 
+#define BM_DISK_EDGE(e, v) \
+   &(((&e->v1_disk_link)[v == e->v2])))
+
 #define BM_LOOPS_OF_VERT_ITER_BEGIN(l_iter_radial_, v_) \
   { \
     struct { \
@@ -150,6 +157,26 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
 static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
 static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
 static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge);
+void bm_log_message(const char *fmt, ...);
+
+static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge *e_example)
+{
+  BMEdge *e = BM_edge_exists(v1, v2);
+
+  if (e) {
+    return e;
+  }
+
+  e = BM_edge_create(pbvh->bm, v1, v2, e_example, BM_CREATE_NOP);
+
+  if (e_example) {
+    e->head.hflag |= e_example->head.hflag;
+  }
+
+  BM_log_edge_added(pbvh->bm_log, e);
+
+  return e;
+}
 
 BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
 {
@@ -171,9 +198,9 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *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_ALL_BOUNDARY;
+  const bool bound1 = mv1->flag & DYNVERT_SMOOTH_BOUNDARY;
 
-  if (mv1->flag & DYNVERT_ALL_CORNER) {
+  if (mv1->flag & DYNVERT_SMOOTH_CORNER) {
     return;
   }
 
@@ -184,7 +211,7 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
     // pbvh_check_vert_boundary(pbvh, v2);
 
     MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, v2);
-    const bool bound2 = mv2->flag & DYNVERT_ALL_BOUNDARY;
+    const bool bound2 = mv2->flag & DYNVERT_SMOOTH_BOUNDARY;
 
     if (bound1 != bound2) {
       e = v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
@@ -214,11 +241,44 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
   atomic_cas_float(&v->co[2], z, z + co[2] * DYNTOPO_SAFE_SMOOTH_FAC);
 }
 
-static void bm_edges_from_tri(BMesh *bm, BMVert *v_tri[3], BMEdge *e_tri[3])
+ATTR_NO_OPT static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
+{
+  BMEdge *e = v->e;
+
+  if (e) {
+    do {
+      BM_log_edge_removed(pbvh->bm_log, e);
+      e = BM_DISK_EDGE_NEXT(e, v);
+    } while (e != v->e);
+  }
+
+  BM_vert_kill(pbvh->bm, v);
+}
+
+ATTR_NO_OPT static void pbvh_log_vert_edges_kill(PBVH *pbvh, BMVert *v)
+{
+  BMEdge *e = v->e;
+
+  if (e) {
+    do {
+      BM_log_edge_removed(pbvh->bm_log, e);
+      e = BM_DISK_EDGE_NEXT(e, v);
+    } while (e != v->e);
+  }
+}
+
+static void bm_edges_from_tri(PBVH *pbvh, BMVert *v_tri[3], BMEdge *e_tri[3])
 {
-  e_tri[0] = BM_edge_create(bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
-  e_tri[1] = BM_edge_create(bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
-  e_tri[2] = BM_edge_create(bm, v_tri[2], v_tri[0], NULL, BM_CREATE_NO_DOUBLE);
+  e_tri[0] = bmesh_edge_create_log(pbvh, v_tri[0], v_tri[1], NULL);
+  e_tri[1] = bmesh_edge_create_log(pbvh, v_tri[1], v_tri[2], NULL);
+  e_tri[2] = bmesh_edge_create_log(pbvh, v_tri[2], v_tri[0], NULL);
+}
+
+static void bm_edges_from_tri_example(PBVH *pbvh, BMVert *v_tri[3], BMEdge *e_tri[3])
+{
+  e_tri[0] = bmesh_edge_create_log(pbvh, v_tri[0], v_tri[1], e_tri[0]);
+  e_tri[1] = bmesh_edge_create_log(pbvh, v_tri[1], v_tri[2], e_tri[1]);
+  e_tri[2] = bmesh_edge_create_log(pbvh, v_tri[2], v_tri[0], e_tri[2]);
 }
 
 BLI_INLINE void bm_face_as_array_index_tri(BMFace *f, int r_index[3])
@@ -289,11 +349,16 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
   }
 }
 
-static void pbvh_bmesh_copy_facedata(BMesh *bm, BMFace *dest, BMFace *src)
+static void pbvh_bmesh_copy_facedata(PBVH *pbvh, BMesh *bm, BMFace *dest, BMFace *src)
 {
   dest->head.hflag = src->head.hflag;
   dest->mat_nr = src->mat_nr;
+
+  int ni = BM_ELEM_CD_GET_INT(dest, pbvh->cd_face_node_offset);
+
   CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, src->head.data, &dest->head.data);
+
+  BM_ELEM_CD_SET_INT(dest, pbvh->cd_face_node_offset, ni);
 }
 
 static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
@@ -309,6 +374,9 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
 
   /* avoid initializing customdata because its quite involved */
   BMVert *v = BM_vert_create(pbvh->bm, co, NULL, BM_CREATE_NOP);
+  MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+
+  mv->flag = DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_DISK_SORT | DYNVERT_NEED_VALENCE;
 
   if (v_example) {
     v->head.hflag = v_example->head.hflag;
@@ -336,7 +404,7 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
   BLI_table_gset_insert(node->bm_unique_verts, v);
   BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, node_index);
 
-  node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_UpdateTris;
+  node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_UpdateTris | PBVH_UpdateOtherVerts;
 
   /* Log the new vertex */
   BM_log_vert_added(pbvh->bm_log, v, cd_vert_mask_offset);
@@ -345,6 +413,44 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
   return v;
 }
 
+static BMFace *bmesh_face_create_edge_log(PBVH *pbvh,
+                                          BMVert *v_tri[3],
+                                          BMEdge *e_tri[3],
+                                          const BMFace *f_example)
+{
+  BMFace *f;
+
+  if (!e_tri) {
+    BMEdge *e_tri2[3];
+
+    for (int i = 0; i < 3; i++) {
+      BMVert *v1 = v_tri[i];
+      BMVert *v2 = v_tri[(i + 1) % 3];
+
+      BMEdge *e = BM_edge_exists(v1, v2);
+
+      if (!e) {
+        e = BM_edge_create(pbvh->bm, v1, v2, NULL, BM_CREATE_NOP);
+        BM_log_edge_added(pbvh->bm_log, e);
+      }
+
+      e_tri2[i] = e;
+    }
+
+    // f = BM_face_create_verts(pbvh->bm, v_tri, 3, f_example, BM_CREATE_NOP, true);
+    f = BM_face_create(pbvh->bm, v_tri, e_tri2, 3, f_example, BM_CREATE_NOP);
+  }
+  else {
+    f = BM_face_create(pbvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
+  }
+
+  if (f_example) {
+    f->head.hflag = f_example->head.hflag;
+  }
+
+  return f;
+}
+
 /**
  * \note Callers are responsible for checking if the face exists before adding.
  */
@@ -361,24 +467,14 @@ static BMFace *pbvh_bmesh_face_create(PBVH *pbvh,
   /* ensure we never add existing face */
   BLI_assert(!BM_face_exists(v_tri, 3));
 
-  BMFace *f;
-
-  if (!e_tri) {
-    f = BM_face_create_verts(pbvh->bm, v_tri, 3, f_example, BM_CREATE_NOP, true);
-  }
-  else {
-    f = BM_face_create(pbvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
-  }
-
-  if (f_example) {
-    f->head.hflag = f_example->head.hflag;
-  }
+  BMFace *f = bmesh_face_create_edge_log(pbvh, v_tri, e_tri, f_example);
 
   BLI_table_gset_insert(node->bm_faces, f);
   BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, node_index);
 
   /* mark node for update */
-  node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_UpdateTris;
+  node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_UpdateTris |
+                PBVH_UpdateOtherVerts;
   node->flag &= ~PBVH_FullyHidden;
 
   /* Log the new face */
@@ -397,15 +493,24 @@ static BMFace *pbvh_bmesh_face_create(PBVH *pbvh,
         BLI_table_gset_add(node->bm_unique_verts, l->v);
         BM_ELEM_CD_SET_INT(l->v, cd_vert_node, node_index);
 
-        node->flag |= PBVH_UpdateDrawBuff

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list