[Bf-blender-cvs] [3df335d330a] temp_bmesh_multires: Sculpt dyntopo:

Joseph Eagar noreply at git.blender.org
Tue Sep 14 04:28:08 CEST 2021


Commit: 3df335d330a694269a9ceefb7234a00c69ca4be9
Author: Joseph Eagar
Date:   Mon Sep 13 19:24:21 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB3df335d330a694269a9ceefb7234a00c69ca4be9

Sculpt dyntopo:

* Fixed noise on using autosmooth with tools that use original
  coorinates.  While this was most prominent with DynTopo,
  it did happen with other tools.
* The solution is to smooth the original coordinates as well
  as the explicit coordinates if the active tool requires
  original data.

* I decided to replace the original coordinates system for
  PBVH_FACES and PBVH_GRIDS with the same MDynTopoVert structure
  DynTopo uses.  The alternative would have been extremely messy
  code.

* Todo: Rename MDynTopoVert to. . .SculptInfoVert?
* Todo: Cache boundary flag and corner info in MDynTopoVert->flag
        for PBVH_FACES/GRIDS similar to PBVH_BMESH.

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/paint.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/editors/sculpt_paint/sculpt.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_filter_color.c
M	source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_paint_color.c
M	source/blender/editors/sculpt_paint/sculpt_pose.c
M	source/blender/editors/sculpt_paint/sculpt_smooth.c
M	source/blender/editors/sculpt_paint/sculpt_transform.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 53d59c42a81..22362b34548 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -34,6 +34,7 @@
 extern "C" {
 #endif
 
+struct MDynTopoVert;
 struct BMFace;
 struct BMesh;
 struct BlendDataReader;
@@ -658,6 +659,8 @@ typedef struct SculptSession {
   int stroke_id, boundary_symmetry;
 
   bool fast_draw;  // hides facesets/masks and forces smooth to save GPU bandwidth
+  struct MDynTopoVert *mdyntopo_verts;  // for non-bmesh
+  int mdyntopo_verts_size;
 } SculptSession;
 
 void BKE_sculptsession_free(struct Object *ob);
@@ -665,6 +668,7 @@ void BKE_sculptsession_free_deformMats(struct SculptSession *ss);
 void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss);
 void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
 void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
+bool BKE_sculptsession_check_mdyntopo(SculptSession *ss, int totvert);
 
 /* Create new color layer on object if it doesn't have one and if experimental feature set has
  * sculpt vertex color enabled. Returns truth if new layer has been added, false otherwise. */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 77da0616b69..72c48d21af7 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -269,6 +269,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
                          const struct MPoly *mpoly,
                          const struct MLoop *mloop,
                          struct MVert *verts,
+                         struct MDynTopoVert *mdyntopo_verts,
                          int totvert,
                          struct CustomData *vdata,
                          struct CustomData *ldata,
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 0ac6c9a42ce..b53ed71070c 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1552,7 +1552,8 @@ static void layerDynTopoVert_interp(
   float mul = 1.0f / totweight;
 
   mul_v3_fl(co, mul);
-  mul_v3_fl(no, mul);
+  normalize_v3(no);
+
   mul_v4_fl(color, mul);
   origmask *= mul;
 
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 2585959bdae..7e02131d2c6 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -560,10 +560,26 @@ static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge
 BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
 {
   float co[3];
+  float origco[3], origco1[3];
+  float origno1[3];
   float tan[3];
   float tot = 0.0;
 
+  MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+
+  if (mv1->stroke_id != pbvh->stroke_id) {
+    copy_v3_v3(origco1, v->co);
+    copy_v3_v3(origno1, v->no);
+  }
+  else {
+    copy_v3_v3(origco1, mv1->origco);
+    copy_v3_v3(origno1, dot_v3v3(mv1->origno, mv1->origno) == 0.0f ? v->no : mv1->origno);
+  }
+
+  // BKE_pbvh_bmesh_check_origdata(pbvh, v, pbvh->stroke_id);
+
   zero_v3(co);
+  zero_v3(origco);
 
   // this is a manual edge walk
 
@@ -572,11 +588,14 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
     return;
   }
 
-  pbvh_check_vert_boundary(pbvh, v);
+  if (mv1->flag & DYNVERT_NEED_BOUNDARY) {
+    return;  // can't update boundary in thread
+  }
+
+  // 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_SMOOTH_BOUNDARY;
 
   if (mv1->flag & DYNVERT_SMOOTH_CORNER) {
@@ -601,6 +620,18 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
 
     madd_v3_v3fl(tan, v->no, -d * 0.99f);
     add_v3_v3(co, tan);
+
+    if (mv2->stroke_id == pbvh->stroke_id) {
+      sub_v3_v3v3(tan, mv2->origco, origco1);
+    }
+    else {
+      sub_v3_v3v3(tan, v2->co, origco1);
+    }
+
+    d = dot_v3v3(tan, origno1);
+    madd_v3_v3fl(tan, origno1, -d * 0.99f);
+    add_v3_v3(origco, tan);
+
     tot += 1.0f;
 
   } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
@@ -610,12 +641,32 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
   }
 
   mul_v3_fl(co, 1.0f / tot);
-  float x = v->co[0], y = v->co[1], z = v->co[2];
+  mul_v3_fl(origco, 1.0f / tot);
+
+  volatile float x = v->co[0], y = v->co[1], z = v->co[2];
+  volatile float nx = x + co[0] * fac, ny = y + co[1] * fac, nz = z + co[2] * fac;
 
   // conflicts here should be pretty rare.
-  atomic_cas_float(&v->co[0], x, x + co[0] * fac);
-  atomic_cas_float(&v->co[1], y, y + co[1] * fac);
-  atomic_cas_float(&v->co[2], z, z + co[2] * fac);
+  atomic_cas_float(&v->co[0], x, nx);
+  atomic_cas_float(&v->co[1], y, ny);
+  atomic_cas_float(&v->co[2], z, nz);
+
+  // conflicts here should be pretty rare.
+  x = mv1->origco[0];
+  y = mv1->origco[1];
+  z = mv1->origco[2];
+
+  nx = x + origco[0] * fac;
+  ny = y + origco[1] * fac;
+  nz = z + origco[2] * fac;
+
+  atomic_cas_float(&mv1->origco[0], x, nx);
+  atomic_cas_float(&mv1->origco[1], y, ny);
+  atomic_cas_float(&mv1->origco[2], z, nz);
+
+  volatile int stroke_id = mv1->stroke_id;
+
+  // atomic_cas_int32(&mv1->stroke_id, stroke_id, pbvh->stroke_id);
 }
 
 static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
@@ -3624,8 +3675,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   // snap customdata
   if (snap) {
     int ni_conn = BM_ELEM_CD_GET_INT(v_conn, pbvh->cd_vert_node_offset);
+
     const float v_ws[2] = {0.5f, 0.5f};
     const void *v_blocks[2] = {v_del->head.data, v_conn->head.data};
+
     CustomData_bmesh_interp(&pbvh->bm->vdata, v_blocks, v_ws, NULL, 2, v_conn->head.data);
     BM_ELEM_CD_SET_INT(v_conn, pbvh->cd_vert_node_offset, ni_conn);
 
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 3ed146c38a8..45abd6a96c6 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -85,6 +85,8 @@ void SCULPT_on_sculptsession_bmesh_free(SculptSession *ss);
 void SCULPT_dyntopo_node_layers_add(SculptSession *ss);
 BMesh *SCULPT_dyntopo_empty_bmesh();
 
+static void init_mdyntopo_layer(SculptSession *ss, int totvert);
+
 static void palette_init_data(ID *id)
 {
   Palette *palette = (Palette *)id;
@@ -1483,6 +1485,11 @@ void BKE_sculptsession_free(Object *ob)
   if (ob && ob->sculpt) {
     SculptSession *ss = ob->sculpt;
 
+    if (ss->mdyntopo_verts) {
+      MEM_freeN(ss->mdyntopo_verts);
+      ss->mdyntopo_verts = NULL;
+    }
+
     if (ss->bm_log && BM_log_free(ss->bm_log, true)) {
       ss->bm_log = NULL;
     }
@@ -1671,7 +1678,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
   }
 
   ss->shapekey_active = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
-
   ss->boundary_symmetry = (int)BKE_get_fset_boundary_symflag(ob);
 
   /* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
@@ -1724,6 +1730,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
   ss->fast_draw = (scene->toolsettings->sculpt->flags & SCULPT_FAST_DRAW) != 0;
 
   PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
+
   BLI_assert(pbvh == ss->pbvh);
   UNUSED_VARS_NDEBUG(pbvh);
 
@@ -2190,11 +2197,14 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
 
   BKE_sculpt_sync_face_set_visibility(me, NULL);
 
+  BKE_sculptsession_check_mdyntopo(ob->sculpt, me->totvert);
+
   BKE_pbvh_build_mesh(pbvh,
                       me,
                       me->mpoly,
                       me->mloop,
                       me->mvert,
+                      ob->sculpt->mdyntopo_verts,
                       me->totvert,
                       &me->vdata,
                       &me->ldata,
@@ -2235,11 +2245,40 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
                        subdiv_ccg->grid_flag_mats,
                        subdiv_ccg->grid_hidden,
                        ob->sculpt->fast_draw);
+
+  BKE_sculptsession_check_mdyntopo(ob->sculpt, BKE_pbvh_get_grid_num_vertices(pbvh));
+
   pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
   pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets);
   return pbvh;
 }
 
+bool BKE_sculptsession_check_mdyntopo(SculptSession *ss, int totvert)
+{
+  if (!ss->bm && (!ss->mdyntopo_verts || totvert != ss->mdyntopo_verts_size)) {
+    init_mdyntopo_layer(ss, totvert);
+    return true;
+  }
+
+  return false;
+}
+
+static void init_mdyntopo_layer(SculptSession *ss, int totvert)
+{
+  if (ss->mdyntopo_verts) {
+    MEM_freeN(ss->mdyntopo_verts);
+  }
+
+  ss->mdyntopo_verts = MEM_calloc_arrayN(totvert, sizeof(*ss->mdyntopo_verts), "mdyntopo_verts");
+  ss->mdyntopo_verts_size = totvert;
+
+  MDynTopoVert *mv = ss->mdyntopo_verts;
+
+  for (int i = 0; i < totvert; i++, mv++) {
+    mv->flag = DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_VALENCE | DYNVERT_NEED_DISK_SORT;
+    mv->stroke_id = -1;
+  }
+}
 PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
 {
   if (ob == NULL || ob->sculpt == NULL) {
@@ -2331,6 +2370,9 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
     }
     else if (ob->type == OB_MESH) {
       Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
+
+      BKE_sculptsession_check_mdyntopo(ob->sculpt, me_eval_deform->totvert);
+
       pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
     }
 #endif
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 313e01ca1a1..fc25826e731 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -607,6 +607,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
                          const MPoly *mpoly,
                          const MLoop *mloop,
                          MVert *verts,
+                         MDynTopoVert *mdyntopo_verts,
+
                          int totvert,
             

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list