[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