[Bf-blender-cvs] [4831b59deb7] temp-trimesh-sculpt: * Added initial support for customdata interpolation. - Edge collapse is still unfinished. - Tried to make the code preserve seams. Hopefully it will work. - Fixed bug with drawing vertex colors with pbvh.
Joseph Eagar
noreply at git.blender.org
Fri Oct 23 08:52:11 CEST 2020
Commit: 4831b59deb78a9c2df27d1c7d068477f432249aa
Author: Joseph Eagar
Date: Thu Oct 22 23:50:28 2020 -0700
Branches: temp-trimesh-sculpt
https://developer.blender.org/rB4831b59deb78a9c2df27d1c7d068477f432249aa
* Added initial support for customdata interpolation.
- Edge collapse is still unfinished.
- Tried to make the code preserve seams. Hopefully it will work.
- Fixed bug with drawing vertex colors with pbvh.
* Began process of ripping out "threadnr" parameter that much of the
trmesh API passes around for no reason.
===================================================================
M source/blender/blenkernel/intern/pbvh_trimesh.c
M source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M source/blender/gpu/intern/gpu_buffers.c
M source/blender/trimesh/intern/trimesh.c
M source/blender/trimesh/intern/trimesh_conv.c
M source/blender/trimesh/intern/trimesh_log.c
M source/blender/trimesh/intern/trimesh_private.h
M source/blender/trimesh/intern/trimesh_thread.c
M source/blender/trimesh/trimesh.h
===================================================================
diff --git a/source/blender/blenkernel/intern/pbvh_trimesh.c b/source/blender/blenkernel/intern/pbvh_trimesh.c
index 2d94ea36a34..191ba7c6bbe 100644
--- a/source/blender/blenkernel/intern/pbvh_trimesh.c
+++ b/source/blender/blenkernel/intern/pbvh_trimesh.c
@@ -46,6 +46,8 @@
#include <assert.h>
+#define DYNTOPO_CD_INTERP
+
#define DYNTOPO_TIME_LIMIT 0.015
#define DYNTOPO_RUN_INTERVAL 0.01
@@ -236,9 +238,9 @@ static TMVert *tm_vert_hash_lookup_chain(GHash *deleted_verts, TMVert *v)
static void tm_edges_from_tri(
TM_TriMesh *tm, TMVert *vs[3], TMEdge *es[3], int threadnr, bool skipcd)
{
- es[0] = TM_get_edge(tm, vs[0], vs[1], threadnr, skipcd);
- es[1] = TM_get_edge(tm, vs[1], vs[2], threadnr, skipcd);
- es[2] = TM_get_edge(tm, vs[2], vs[0], threadnr, skipcd);
+ es[0] = TM_get_edge(tm, vs[0], vs[1], skipcd);
+ es[1] = TM_get_edge(tm, vs[1], vs[2], skipcd);
+ es[2] = TM_get_edge(tm, vs[2], vs[0], skipcd);
}
/* Update node data after splitting */
@@ -541,7 +543,7 @@ static TMVert *pbvh_trimesh_vert_create(
PBVH *bvh, int node_index, const float co[3], const float no[3], const int cd_vert_mask_offset)
{
PBVHNode *node = &bvh->nodes[node_index];
- TMVert *v = TM_make_vert(bvh->tm, co, no, 0, false);
+ TMVert *v = TM_make_vert(bvh->tm, co, no, false);
if (node_index < 0 || node_index >= bvh->totnode) {
printf("eek!\n");
@@ -598,7 +600,7 @@ static TMFace *pbvh_trimesh_face_create(
/* ensure we never add existing face */
// BLI_assert(!BM_face_exists(v_tri, 3));
- TMFace *f = TM_make_tri(bvh->tm, v_tri[0], v_tri[1], v_tri[2], 0, false);
+ TMFace *f = TM_make_tri(bvh->tm, v_tri[0], v_tri[1], v_tri[2], false);
// f->head.hflag = f_example->head.hflag;
if (f_example) {
f->flag = f_example->flag;
@@ -1586,6 +1588,12 @@ static void pbvh_trimesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh, TMEdge
TMVert *v_new = pbvh_trimesh_vert_create(
bvh, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
+# ifdef DYNTOPO_CD_INTERP
+ void *vsrcs[2] = {e->v1->customdata, e->v2->customdata};
+ float vws[2] = {0.5f, 0.5f};
+ CustomData_bmesh_interp(&bvh->tm->vdata, vsrcs, vws, NULL, 2, v_new->customdata);
+# endif
+
// return;
/* update paint mask */
@@ -1599,6 +1607,14 @@ static void pbvh_trimesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh, TMEdge
bool first = true;
+ TMEdge *e1 = TM_get_edge(bvh->tm, e->v1, v_new, false);
+ TMEdge *e2 = TM_get_edge(bvh->tm, v_new, e->v2, false);
+ int eflag = e->flag & ~TM_ELEM_HIDDEN;
+ int vflag = (e->v1->flag | e->v2->flag) & ~TM_ELEM_HIDDEN;
+
+ e1->flag = e2->flag = eflag;
+ v_new->flag = vflag;
+
/* For each face, add two new triangles and delete the original */
for (int i = 0; i < e->tris.length;) {
TMFace *f_adj = e->tris.items[i];
@@ -1665,21 +1681,62 @@ static void pbvh_trimesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh, TMEdge
tm_edges_from_tri(bvh->tm, v_tri, e_tri, 0, false);
f_new = pbvh_trimesh_face_create(bvh, ni, v_tri, e_tri, f_adj);
+# ifdef DYNTOPO_CD_INTERP
+ TMLoopData *l1 = TM_GET_TRI_LOOP_VERTEX(f_adj, v1);
+ TMLoopData *l2 = TM_GET_TRI_LOOP_VERTEX(f_adj, v2);
+ TMLoopData *l3 = TM_GET_TRI_LOOP_VERTEX(f_adj, v_opp);
+
+ void *lsrcs[2] = {l1->customdata, l2->customdata};
+ float lws[2] = {0.5f, 0.5f};
+
+ CustomData_bmesh_interp(&bvh->tm->ldata, lsrcs, lws, lws, 2, f_new->l2->customdata);
+
+ lsrcs[0] = l1->customdata;
+ lws[0] = 1.0f;
+
+ CustomData_bmesh_interp(&bvh->tm->ldata, lsrcs, lws, lws, 1, f_new->l1->customdata);
+
+ lsrcs[0] = l3->customdata;
+ lws[0] = 1.0f;
+
+ CustomData_bmesh_interp(&bvh->tm->ldata, lsrcs, lws, lws, 1, f_new->l3->customdata);
+
+# endif
+
// long_edge_queue_face_add(eq_ctx, f_new);
v_tri[0] = v_new;
v_tri[1] = v2;
/* v_tri[2] = v_opp; */ /* unchanged */
- e_tri[0] = TM_get_edge(bvh->tm, v_tri[0], v_tri[1], 0, false);
+ e_tri[0] = TM_get_edge(bvh->tm, v_tri[0], v_tri[1], false);
e_tri[2] = e_tri[1]; /* switched */
- e_tri[1] = TM_get_edge(bvh->tm, v_tri[1], v_tri[2], 0, false);
+ e_tri[1] = TM_get_edge(bvh->tm, v_tri[1], v_tri[2], false);
f_new = pbvh_trimesh_face_create(bvh, ni, v_tri, e_tri, f_adj);
+# ifdef DYNTOPO_CD_INTERP
+ lsrcs[0] = l1->customdata;
+ lsrcs[1] = l2->customdata;
+ lws[0] = lws[1] = 0.5f;
+
+ CustomData_bmesh_interp(&bvh->tm->ldata, lsrcs, lws, lws, 2, f_new->l1->customdata);
+
+ lsrcs[0] = l2->customdata;
+ lws[0] = 1.0f;
+
+ CustomData_bmesh_interp(&bvh->tm->ldata, lsrcs, lws, lws, 1, f_new->l2->customdata);
+
+ lsrcs[0] = l3->customdata;
+ lws[0] = 1.0f;
+
+ CustomData_bmesh_interp(&bvh->tm->ldata, lsrcs, lws, lws, 1, f_new->l3->customdata);
+
+# endif
+
// long_edge_queue_face_add(eq_ctx, f_new);
/* Delete original */
pbvh_trimesh_face_remove(bvh, f_adj);
- TM_kill_tri(bvh->tm, f_adj, 0, false, false);
+ TM_kill_tri(bvh->tm, f_adj, false, false);
/* Ensure new vertex is in the node */
if (!TMElemSet_has(bvh->nodes[ni].tm_unique_verts, v_new)) {
@@ -1704,7 +1761,7 @@ static void pbvh_trimesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *bvh, TMEdge
}
}
- TM_kill_edge(bvh->tm, e, 0, false);
+ TM_kill_edge(bvh->tm, e, false);
#endif
}
@@ -1775,6 +1832,29 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
{
TMVert *v_del, *v_conn;
+#ifdef DYNTOPO_CD_INTERP
+ if (e->flag & TRIMESH_SEAM) {
+ //return;
+ // only collapse edge if there are two seams in its neighborhood
+ for (int step = 0; step < 2; step++) {
+ int count = 0;
+ TMVert *v = step ? v2 : v1;
+
+ for (int i = 0; i < v->edges.length; i++) {
+ TMEdge *e2 = v->edges.items[i];
+
+ if (e2->flag & TRIMESH_SEAM) {
+ count++;
+ }
+ }
+
+ if (count < 2) {
+ return;
+ }
+ }
+ }
+#endif
+
/* one of the two vertices may be masked, select the correct one for deletion */
if (TM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset) <
TM_ELEM_CD_GET_FLOAT(v2, eq_ctx->cd_vert_mask_offset)) {
@@ -1794,10 +1874,27 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
int lastlen = e->tris.length;
TMFace *f_adj = e->tris.items[0];
+#ifdef DYNTOPO_CD_INTERP
+ int eflag = 0;
+
+ // propegate flags to merged edges
+ for (int i = 0; i < 3; i++) {
+ TMEdge *e2 = TM_GET_TRI_EDGE(f_adj, i);
+
+ if (e2 != e) {
+ eflag |= e2->flag & ~TM_ELEM_HIDDEN;
+ }
+ }
+
+ for (int i = 0; i < 3; i++) {
+ TMEdge *e2 = TM_GET_TRI_EDGE(f_adj, i);
+ e2->flag |= eflag;
+ }
+#endif
pbvh_trimesh_face_remove(bvh, f_adj);
// XXX check threadnr argument!
- TM_kill_tri(bvh->tm, f_adj, 0, false, false);
+ TM_kill_tri(bvh->tm, f_adj, false, false);
if (lastlen == e->tris.length) { // paranoia check
printf("eek! %s %d\n", __FILE__, __LINE__);
@@ -1808,8 +1905,7 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
/* Kill the edge */
BLI_assert(TM_edge_is_wire(e));
- // XXX check threadnr argument!
- TM_kill_edge(bvh->tm, e, 0, false);
+ TM_kill_edge(bvh->tm, e, false);
/* For all remaining faces of v_del, create a new face that is the
* same except it uses v_conn instead of v_del */
@@ -1859,13 +1955,21 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
}
else if (1) {
TMVert *v_tri[3] = {v_conn, TM_nextVertInTri(tri, v_del), TM_prevVertInTri(tri, v_del)};
+ TMVert *v_triold[3] = {v_del, TM_nextVertInTri(tri, v_del), TM_prevVertInTri(tri, v_del)};
// BLI_assert(!BM_face_exists(v_tri, 3));
- TMEdge *e_tri[3];
+ TMEdge *e_tri[3], *e_triold[3];
PBVHNode *n = pbvh_trimesh_node_from_face(bvh, tri);
int ni = (int)(n - bvh->nodes);
tm_edges_from_tri(bvh->tm, v_tri, e_tri, 0, true);
+ tm_edges_from_tri(bvh->tm, v_triold, e_triold, 0, true);
+
+
+ e_tri[0]->flag |= e_triold[0]->flag;
+ e_tri[1]->flag |= e_triold[1]->flag;
+ e_tri[2]->flag |= e_triold[2]->flag;
+
pbvh_trimesh_face_create(bvh, ni, v_tri, e_tri, tri);
/* Ensure that v_conn is in the new face's node */
@@ -1901,13 +2005,13 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
/* Remove the face */
pbvh_trimesh_face_remove(bvh, f_del);
- TM_kill_tri(bvh->tm, f_del, 0, false, false);
+ TM_kill_tri(bvh->tm, f_del, false, false);
/* Check if any of the face's edges are now unused by any
* face, if so delete them */
for (int j = 0; j < 3; j++) {
if (TM_edge_is_wire(e_tri[j])) {
- TM_kill_edge(bvh->tm, e_tri[j], 0, false);
+ TM_kill_edge(bvh->tm, e_tri[j], false);
}
}
@@ -1924,7 +2028,7 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
}
BLI_ghash_insert(deleted_verts, v_tri[j], NULL);
- TM_kill_vert(bvh->tm, v_tri[j], 0); // XXX check threadnr
+ TM_kill_vert(bvh->tm, v_tri[j]); // XXX check threadnr
}
}
}
@@ -1935,13 +2039,13 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
if (e2 != e && TM_edge_is_wire(e2)) {
TMVert *v2 = TM_other_vert(e2, v_del);
- TM_kill_edge(bvh->tm, e2, 0, false);
+ TM_kill_edge(bvh->tm, e2, false);
if (v2 != v_conn && v2->edges.length == 0) {
pbvh_trimesh_vert_remove(bvh, v2);
BLI_trimesh_log_vert_kill(bvh->tm_log, v2);
BLI_ghash_insert(deleted_verts, v2, NULL);
- TM_kill_vert(bvh->tm, v2, 0); // XXX check threadnr
+ TM_kill_vert(bvh->tm, v2); // XXX check threadnr
}
i--;
continue;
@@ -1981,7 +2085,7 @@ static void pbvh_trimesh_collapse_edge(PBVH *bvh,
/* v_conn == NULL is OK */
BLI_ghash_insert(deleted_verts, v_del, v_conn);
- TM_kill_vert(bvh->tm, v_del, 0); // XXX threadnr
+ TM_kill_vert(bvh->tm, v_del); // XXX threadnr
}
static bool pbvh_trimesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
@@ -2647,7 +2751,7 @@ bool BKE_pbvh_trimesh_update_topology(PBVH *bvh,
if (modified) {
for (int i = 0; i < bvh->totnode; i++) {
PBVHNode *node = bvh->nodes + i;
-
+
if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_Upd
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list