[Bf-blender-cvs] [3214b1114fc] temp_bmesh_multires: Added support for customdata interpolation to dyntopo. It seems fast enough for simple cases, I make no promises that it will be fast in crazy cases lots if there's lots of vgroup layers.

Joseph Eagar noreply at git.blender.org
Sun Oct 25 09:39:28 CET 2020


Commit: 3214b1114fc1126e5bdb9d550717b8b9bda9d4d7
Author: Joseph Eagar
Date:   Sun Oct 25 01:37:52 2020 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB3214b1114fc1126e5bdb9d550717b8b9bda9d4d7

Added support for customdata interpolation to dyntopo.
It seems fast enough for simple cases, I make no promises that it
will be fast in crazy cases lots if there's lots of vgroup layers.

Note I still need to interface properly with the sculpt colors code.

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 3750e7d14cb..44c3d595988 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -600,6 +600,8 @@ struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh);
 PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
 void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
 
+#define DYNTOPO_CD_INTERP
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index eb8cb81fdb0..88079bb7eba 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1263,6 +1263,12 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
   BMVert *v_new = pbvh_bmesh_vert_create(
       pbvh, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
 
+#ifdef DYNTOPO_CD_INTERP
+  void *vsrcs[2] = {e->v1->head.data, e->v2->head.data};
+  float vws[2] = {0.5f, 0.5f};
+  CustomData_bmesh_interp(&pbvh->bm->vdata, vsrcs, vws, NULL, 2, v_new->head.data);
+#endif
+
   /* update paint mask */
   if (eq_ctx->cd_vert_mask_offset != -1) {
     float mask_v1 = BM_ELEM_CD_GET_FLOAT(e->v1, eq_ctx->cd_vert_mask_offset);
@@ -1331,15 +1337,67 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
     f_new = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f_adj);
     long_edge_queue_face_add(eq_ctx, f_new);
 
+#ifdef DYNTOPO_CD_INTERP
+    BMLoop *lfirst = f_adj->l_first;
+    while (lfirst->v != v1) {
+      lfirst = lfirst->next;
+
+      // paranoia check
+      if (lfirst == f_adj->l_first) {
+        break;
+      }
+    }
+
+    BMLoop *l1 = lfirst;
+    BMLoop *l2 = lfirst->next;
+    BMLoop *l3 = lfirst->next->next;
+
+    void *lsrcs[2] = {l1->head.data, l2->head.data};
+    float lws[2] = {0.5f, 0.5f};
+
+    CustomData_bmesh_interp(&pbvh->bm->ldata, lsrcs, lws, lws, 2, f_new->l_first->next->head.data);
+
+    lsrcs[0] = l1->head.data;
+    lws[0] = 1.0f;
+
+    CustomData_bmesh_interp(&pbvh->bm->ldata, lsrcs, lws, lws, 1, f_new->l_first->head.data);
+
+    lsrcs[0] = l3->head.data;
+    lws[0] = 1.0f;
+
+    CustomData_bmesh_interp(&pbvh->bm->ldata, lsrcs, lws, lws, 1, f_new->l_first->prev->head.data);
+
+#endif
+
     v_tri[0] = v_new;
     v_tri[1] = v2;
     /* v_tri[2] = v_opp; */ /* unchanged */
     e_tri[0] = BM_edge_create(pbvh->bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
     e_tri[2] = e_tri[1]; /* switched */
     e_tri[1] = BM_edge_create(pbvh->bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
+
     f_new = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f_adj);
     long_edge_queue_face_add(eq_ctx, f_new);
 
+#ifdef DYNTOPO_CD_INTERP
+    lsrcs[0] = lfirst->head.data;
+    lsrcs[1] = lfirst->next->head.data;
+    lws[0] = lws[1] = 0.5f;
+
+    CustomData_bmesh_interp(&pbvh->bm->ldata, lsrcs, lws, lws, 2, f_new->l_first->head.data);
+
+    lsrcs[0] = lfirst->next->head.data;
+    ;
+    lws[0] = 1.0f;
+
+    CustomData_bmesh_interp(&pbvh->bm->ldata, lsrcs, lws, lws, 1, f_new->l_first->next->head.data);
+
+    lsrcs[0] = lfirst->prev->head.data;
+    lws[0] = 1.0f;
+
+    CustomData_bmesh_interp(&pbvh->bm->ldata, lsrcs, lws, lws, 1, f_new->l_first->prev->head.data);
+#endif
+
     /* Delete original */
     pbvh_bmesh_face_remove(pbvh, f_adj);
     BM_face_kill(pbvh->bm, f_adj);
@@ -1467,6 +1525,29 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 {
   BMVert *v_del, *v_conn;
 
+#ifdef DYNTOPO_CD_INTERP
+  if (BM_elem_flag_test(e, BM_ELEM_SEAM)) {
+    // return;
+    // only collapse edge if there are two seams in its neighborhood
+    for (int step = 0; step < 2; step++) {
+      int count = 0;
+      BMVert *v = step ? v2 : v1;
+      BMIter iter;
+      BMEdge *e2;
+
+      BM_ITER_ELEM (e2, &iter, v, BM_EDGES_OF_VERT) {
+        if (BM_elem_flag_test(e2, BM_ELEM_SEAM)) {
+          count++;
+        }
+      }
+
+      if (count < 2) {
+        return;
+      }
+    }
+  }
+#endif
+
   /* one of the two vertices may be masked, select the correct one for deletion */
   if (BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset) <
       BM_ELEM_CD_GET_FLOAT(v2, eq_ctx->cd_vert_mask_offset)) {
@@ -1486,6 +1567,29 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   while ((l_adj = e->l)) {
     BMFace *f_adj = l_adj->f;
 
+#ifdef DYNTOPO_CD_INTERP
+    int eflag = 0;
+
+    // propegate flags to merged edges
+    BMLoop *l = f_adj->l_first;
+    do {
+      BMEdge *e2 = l->e;
+
+      if (e2 != e) {
+        eflag |= e2->head.hflag & ~BM_ELEM_HIDDEN;
+      }
+
+      l = l->next;
+    } while (l != f_adj->l_first);
+
+    do {
+      BMEdge *e2 = l->e;
+      e2->head.hflag |= eflag;
+
+      l = l->next;
+    } while (l != f_adj->l_first);
+#endif
+
     pbvh_bmesh_face_remove(pbvh, f_adj);
     BM_face_kill(pbvh->bm, f_adj);
   }
@@ -1540,8 +1644,18 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
       PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f);
       int ni = n - pbvh->nodes;
       bm_edges_from_tri(pbvh->bm, v_tri, e_tri);
-      pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f);
-
+      BMFace *f2 = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f);
+
+#ifdef DYNTOPO_CD_INTERP
+      CustomData_bmesh_copy_data(
+          &pbvh->bm->pdata, &pbvh->bm->pdata, f->head.data, &f2->head.data);
+      CustomData_bmesh_copy_data(
+          &pbvh->bm->ldata, &pbvh->bm->ldata, l->head.data, &f2->l_first->head.data);
+      CustomData_bmesh_copy_data(
+          &pbvh->bm->ldata, &pbvh->bm->ldata, l->next->head.data, &f2->l_first->next->head.data);
+      CustomData_bmesh_copy_data(
+          &pbvh->bm->ldata, &pbvh->bm->ldata, l->prev->head.data, &f2->l_first->prev->head.data);
+#endif
       /* Ensure that v_conn is in the new face's node */
       if (!BLI_table_gset_haskey(n->bm_unique_verts, v_conn)) {
         BLI_table_gset_add(n->bm_other_verts, v_conn);
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index 09b6572d7ce..13b38cf5968 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -431,6 +431,7 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob)
   BLI_assert(ss->bm == NULL);
   UNUSED_VARS_NDEBUG(ss);
 
+#ifndef DYNTOPO_CD_INTERP
   for (int i = 0; i < CD_NUMTYPES; i++) {
     if (!ELEM(i, CD_MVERT, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX)) {
       if (CustomData_has_layer(&me->vdata, i)) {
@@ -444,6 +445,7 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob)
       }
     }
   }
+#endif
 
   {
     VirtualModifierData virtualModifierData;
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index d65cb49bc46..b0ec4399c1c 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -962,7 +962,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
 
   /* TODO, make mask layer optional for bmesh buffer */
   const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
-  const int cd_vcol_offset = CustomData_get_offset(&bm->vdata, CD_MLOOPCOL);
+  const int cd_vcol_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
 
   /* Fill vertex buffer */
   if (!gpu_pbvh_vert_buf_data_set(buffers, totvert)) {



More information about the Bf-blender-cvs mailing list