Sculpt dyntopo: fix nasty node splitting bug
This commit is contained in:
parent
3df335d330
commit
0eeaeb3fc2
|
@ -161,6 +161,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
|
|||
|
||||
struct EdgeQueueContext;
|
||||
|
||||
static bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root);
|
||||
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(struct EdgeQueueContext *eq_ctx,
|
||||
|
@ -3693,7 +3694,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
int totl = 0;
|
||||
|
||||
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
|
||||
MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->v);
|
||||
MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->next->v);
|
||||
mv_l->flag |= mupdateflag;
|
||||
|
||||
BLI_array_append(ls, l);
|
||||
|
@ -3702,7 +3703,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
BM_LOOPS_OF_VERT_ITER_END;
|
||||
|
||||
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
|
||||
MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->v);
|
||||
MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->next->v);
|
||||
mv_l->flag |= mupdateflag;
|
||||
|
||||
BLI_array_append(ls, l);
|
||||
|
@ -3962,6 +3963,16 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
MDynTopoVert *mv3 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_conn);
|
||||
mv3->flag |= mupdateflag;
|
||||
|
||||
if (BM_ELEM_CD_GET_INT(v_conn, pbvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
|
||||
printf("eek!\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (!check_for_fins(pbvh, v_conn)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (wasbad) {
|
||||
fix_mesh(pbvh, pbvh->bm);
|
||||
return;
|
||||
|
|
|
@ -251,7 +251,9 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
|
|||
bool has_visible = false;
|
||||
|
||||
/* Create vert hash sets */
|
||||
n->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
|
||||
if (!n->bm_unique_verts) {
|
||||
n->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
|
||||
}
|
||||
n->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
|
||||
BB_reset(&n->vb);
|
||||
|
@ -356,7 +358,9 @@ static void pbvh_bmesh_node_split(
|
|||
c1->bm_faces = BLI_table_gset_new_ex("bm_faces", BLI_table_gset_len(n->bm_faces) / 2);
|
||||
c2->bm_faces = BLI_table_gset_new_ex("bm_faces", BLI_table_gset_len(n->bm_faces) / 2);
|
||||
|
||||
c1->bm_unique_verts = c2->bm_unique_verts = NULL;
|
||||
c1->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
|
||||
c2->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
|
||||
|
||||
c1->bm_other_verts = c2->bm_other_verts = NULL;
|
||||
|
||||
/* Partition the parent node's faces between the two children */
|
||||
|
@ -389,17 +393,32 @@ static void pbvh_bmesh_node_split(
|
|||
BLI_table_gset_insert(empty, key);
|
||||
BLI_table_gset_remove(other, key, NULL);
|
||||
break;
|
||||
} TGSET_ITER_END
|
||||
}
|
||||
TGSET_ITER_END
|
||||
}
|
||||
#endif
|
||||
/* Clear this node */
|
||||
|
||||
BMVert *v;
|
||||
TableGSet *bm_unique_verts = n->bm_unique_verts;
|
||||
|
||||
/* Mark this node's unique verts as unclaimed */
|
||||
/* Assign verts to c1 and c2. Note that the previous
|
||||
method of simply marking them as untaken and rebuilding
|
||||
unique verts later doesn't work, as it assumes that dyntopo
|
||||
never assigns verts to nodes that don't contain their
|
||||
faces.*/
|
||||
if (n->bm_unique_verts) {
|
||||
TGSET_ITER (v, n->bm_unique_verts) {
|
||||
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
||||
int ni;
|
||||
|
||||
if (v->co[axis] < mid) {
|
||||
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, (c1 - pbvh->nodes));
|
||||
BLI_table_gset_add(c1->bm_unique_verts, v);
|
||||
}
|
||||
else {
|
||||
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, (c2 - pbvh->nodes));
|
||||
BLI_table_gset_add(c2->bm_unique_verts, v);
|
||||
}
|
||||
}
|
||||
TGSET_ITER_END
|
||||
|
||||
|
|
Loading…
Reference in New Issue