commit prior to small cleanup

This commit is contained in:
Joseph Eagar 2021-08-25 03:01:56 -07:00
parent 9680edf77c
commit 12f87d02c6
6 changed files with 542 additions and 19 deletions

View File

@ -2823,11 +2823,12 @@ cleanup_valence_3_4(EdgeQueueContext *ectx,
int ni = BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset);
if (ni >= 0 && BLI_table_gset_haskey(pbvh->nodes[ni].bm_other_verts, v)) {
printf("error! %d\n", (int)BLI_table_gset_haskey(pbvh->nodes[ni].bm_unique_verts, v));
printf("cleanup_valence_3_4 error! %d\n",
(int)BLI_table_gset_haskey(pbvh->nodes[ni].bm_unique_verts, v));
BLI_table_gset_remove(pbvh->nodes[ni].bm_other_verts, v, NULL);
}
else if (ni < 0) {
printf("error!\n");
printf("cleanup_valence_3_4 error!\n");
// attempt to recover
@ -3055,8 +3056,13 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
}
# endif
float brusharea = radius / (pbvh->bm_min_edge_len * 0.5f + pbvh->bm_max_edge_len * 0.5f);
brusharea = brusharea * brusharea * M_PI;
int max_steps = (int)((float)DYNTOPO_MAX_ITER * ratio);
printf("max_steps %d\n", max_steps);
pbvh_bmesh_check_nodes(pbvh);
modified |= pbvh_bmesh_collapse_short_edges(&eq_ctx, pbvh, &deleted_faces, max_steps);
pbvh_bmesh_check_nodes(pbvh);
@ -3078,7 +3084,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
long_edge_queue_create(
&eq_ctx, pbvh, center, view_normal, radius, use_frontface, use_projected);
# ifdef SKINNY_EDGE_FIX
# if 0 /// def SKINNY_EDGE_FIX
// prevent remesher thrashing by throttling edge splitting in pathological case of skinny edges
float avg_elen = eq_ctx.avg_elen;
if (eq_ctx.totedge > 0.0f) {
@ -3091,13 +3097,22 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
if (avg_elen > 0.0f) {
ratio = (pbvh->bm_max_edge_len * 0.5 + emin * 0.5) / avg_elen;
ratio = MAX2(ratio, 0.05f);
ratio = MAX2(ratio, 0.75f);
ratio = MIN2(ratio, 1.0f);
}
}
# else
ratio = 1.0f;
# endif
float brusharea = radius / (pbvh->bm_min_edge_len * 0.5f + pbvh->bm_max_edge_len * 0.5f);
brusharea = brusharea * brusharea * M_PI;
int max_steps = (int)((float)DYNTOPO_MAX_ITER * ratio);
max_steps = (int)(brusharea * ratio * 1.0f);
printf("brusharea: %.2f, ratio: %.2f\n", brusharea, ratio);
printf("max_steps %d\n", max_steps);
pbvh_bmesh_check_nodes(pbvh);
modified |= pbvh_bmesh_subdivide_long_edges(&eq_ctx, pbvh, &edge_loops, max_steps);
@ -3347,7 +3362,7 @@ static const int splitmap[43][16] = {
{6, -1, 3, -1, 5, -1, 1, -1}, // 42
};
static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
ATTR_NO_OPT static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
{
BMFace **faces = NULL;
BLI_array_staticdeclare(faces, 512);
@ -3388,7 +3403,7 @@ static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
l2->v->head.hflag &= ~SPLIT_TAG;
MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l2->v);
mv->flag |= DYNVERT_NEED_VALENCE;
mv->flag |= DYNVERT_NEED_VALENCE | DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_DISK_SORT;
} while ((l2 = l2->next) != l->f->l_first);
l->f->head.hflag &= ~SPLIT_TAG;
@ -3419,7 +3434,8 @@ static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
BMFace *f = faces[i];
BMLoop *l = f->l_first;
pbvh_bmesh_face_remove(pbvh, f, true, false, false);
// pbvh_bmesh_face_remove(pbvh, f, true, false, false);
BM_log_face_removed(pbvh->bm_log, f);
int mask = 0;
int j = 0;
@ -3450,9 +3466,45 @@ static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, newv);
newv->head.hflag |= SPLIT_TAG;
mv->flag |= DYNVERT_NEED_VALENCE;
mv->flag |= DYNVERT_NEED_VALENCE | DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_DISK_SORT;
# if 1
int ni = BM_ELEM_CD_GET_INT(e->v1, pbvh->cd_vert_node_offset);
if (ni == DYNTOPO_NODE_NONE) {
ni = BM_ELEM_CD_GET_INT(e->v2, pbvh->cd_vert_node_offset);
}
if (ni != DYNTOPO_NODE_NONE) {
PBVHNode *node = pbvh->nodes + ni;
BLI_table_gset_add(node->bm_unique_verts, newv);
BMIter iter;
BMFace *f;
# if 0
BM_ITER_ELEM (f, &iter, newv, BM_FACES_OF_VERT) {
int ni2 = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
if (ni != ni2 && ni2 != DYNTOPO_NODE_NONE) {
PBVHNode *node2 = pbvh->nodes + ni2;
BLI_table_gset_add(node2->bm_other_verts, newv);
}
}
# endif
BM_ELEM_CD_SET_INT(newv, pbvh->cd_vert_node_offset, ni);
}
else {
BM_ELEM_CD_SET_INT(newv, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
printf("eek!");
}
# else
BM_ELEM_CD_SET_INT(newv, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
# endif
BM_log_vert_added(pbvh->bm_log, newv, pbvh->cd_vert_mask_offset);
}
@ -3460,6 +3512,8 @@ static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
BMFace *f = faces[i];
int mask = 0;
int ni = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
BMLoop *l = f->l_first;
int j = 0;
do {
@ -3524,6 +3578,20 @@ static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
BMFace *newf = BM_face_split(bm, f2, l1, l2, &rl, NULL, false);
if (newf) {
bool ok = ni != DYNTOPO_NODE_NONE;
ok = ok && BM_ELEM_CD_GET_INT(v1, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE;
ok = ok && BM_ELEM_CD_GET_INT(v2, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE;
if (ok) {
PBVHNode *node = pbvh->nodes + ni;
BLI_table_gset_add(node->bm_faces, newf);
BM_ELEM_CD_SET_INT(newf, pbvh->cd_face_node_offset, ni);
}
else {
BM_ELEM_CD_SET_INT(newf, pbvh->cd_face_node_offset, DYNTOPO_NODE_NONE);
}
newfaces[count++] = newf;
f2 = newf;
}
@ -3534,10 +3602,50 @@ static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
}
for (j = 0; j < count; j++) {
BKE_pbvh_bmesh_add_face(pbvh, newfaces[j], true, false);
if (BM_ELEM_CD_GET_INT(newfaces[j], pbvh->cd_face_node_offset) == DYNTOPO_NODE_NONE) {
BKE_pbvh_bmesh_add_face(pbvh, newfaces[j], false, true);
}
else {
BMFace *f = newfaces[j];
if (f->len != 3) {
printf("eek! f->len was not 3! len: %d\n", f->len);
}
// add face verts to bm_other_verts
int lastni2 = -1;
BMLoop *l = f->l_first;
do {
BMEdge *e = l->v->e;
do {
BMLoop *l2 = e->l;
do {
int ni = BM_ELEM_CD_GET_INT(l->v, pbvh->cd_vert_node_offset);
int ni2 = BM_ELEM_CD_GET_INT(l2->f, pbvh->cd_face_node_offset);
if (ni2 != ni && ni2 != lastni2 && ni2 != DYNTOPO_NODE_NONE) {
PBVHNode *node = pbvh->nodes + ni2;
BLI_table_gset_add(node->bm_other_verts, l->v);
lastni2 = ni2;
}
} while ((l2 = l2->radial_next) != e->l);
e = l->v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
} while (e != l->v->e);
} while ((l = l->next) != f->l_first);
}
BM_log_face_added(pbvh->bm_log, newfaces[j]);
}
BKE_pbvh_bmesh_add_face(pbvh, f, true, false);
if (BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) == DYNTOPO_NODE_NONE) {
BKE_pbvh_bmesh_add_face(pbvh, f, false, true);
}
BM_log_face_added(pbvh->bm_log, f);
}
BLI_array_free(faces);

View File

@ -81,6 +81,27 @@ void BB_reset(BB *bb)
bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
}
void BB_intersect(BB *r_out, BB *a, BB *b)
{
for (int i = 0; i < 3; i++) {
r_out->bmin[i] = max_ff(a->bmin[i], b->bmin[i]);
r_out->bmax[i] = min_ff(a->bmax[i], b->bmax[i]);
if (r_out->bmax[i] < r_out->bmin[i]) {
r_out->bmax[i] = r_out->bmin[i] = 0.0f;
}
}
}
float BB_volume(const BB *bb)
{
float dx = bb->bmax[0] - bb->bmin[0];
float dy = bb->bmax[1] - bb->bmin[1];
float dz = bb->bmax[2] - bb->bmin[2];
return dx * dy * dz;
}
/* Expand the bounding box to include a new coordinate */
void BB_expand(BB *bb, const float co[3])
{

View File

@ -170,6 +170,12 @@ void pbvh_bmesh_check_nodes(PBVH *pbvh)
TGSET_ITER (f, node->bm_faces) {
if (!f || f->head.htype != BM_FACE) {
printf("corruption in pbvh! bm_faces\n");
continue;
}
int ni = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
if (pbvh->nodes + ni != node) {
printf("face in multiple nodes!\n");
}
}
TGSET_ITER_END;
@ -596,7 +602,7 @@ void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f)
}
if (ni < 0 || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
fprintf(stderr, "pbvh error!\n");
fprintf(stderr, "pbvh error! failed to find node to insert face into!\n");
fflush(stderr);
return;
}
@ -1422,10 +1428,7 @@ void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVer
e = e->v1 == v ? e->v1_disk_link.next : e->v2_disk_link.next;
} while (e != v->e);
if (fset1 && fset2) {
mv->flag |= DYNVERT_FSET_BOUNDARY;
}
#if 0
if (fset2 && !fset3) {
int n = MIN2(fset1_count, fset2_count);
float maxth = 0;
@ -1465,10 +1468,17 @@ void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVer
mv->flag |= DYNVERT_FSET_CORNER;
}
}
else if (fset2 && fset3) {
else
#endif
if (fset2 && fset3) {
mv->flag |= DYNVERT_FSET_CORNER;
}
if (fset1 && fset2) {
mv->flag |= DYNVERT_FSET_BOUNDARY;
}
mv->valence = val;
if (val < 4 && (mv->flag & DYNVERT_BOUNDARY)) {
mv->flag |= DYNVERT_CORNER;
@ -2458,6 +2468,374 @@ static void BKE_pbvh_bmesh_correct_tree(PBVH *pbvh, PBVHNode *node, PBVHNode *pa
}
}
// deletes PBVH_Delete marked nodes
static void pbvh_bmesh_compact_tree(PBVH *bvh)
{
// compact nodes
int totnode = 0;
for (int i = 0; i < bvh->totnode; i++) {
PBVHNode *n = bvh->nodes + i;
if (!(n->flag & PBVH_Delete)) {
if (!(n->flag & PBVH_Leaf)) {
PBVHNode *n1 = bvh->nodes + n->children_offset;
PBVHNode *n2 = bvh->nodes + n->children_offset + 1;
if ((n1->flag & PBVH_Delete) != (n2->flag & PBVH_Delete)) {
printf("un-deleting an empty node\n");
PBVHNode *n3 = n1->flag & PBVH_Delete ? n1 : n2;
n3->flag = PBVH_Leaf | PBVH_UpdateTris;
n3->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
n3->bm_other_verts = BLI_table_gset_new("bm_other_verts");
n3->bm_faces = BLI_table_gset_new("bm_faces");
n3->tribuf = NULL;
}
else if ((n1->flag & PBVH_Delete) && (n2->flag & PBVH_Delete)) {
n->children_offset = 0;
n->flag |= PBVH_Leaf | PBVH_UpdateTris;
if (!n->bm_unique_verts) {
// should not happen
n->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
n->bm_other_verts = BLI_table_gset_new("bm_other_verts");
n->bm_faces = BLI_table_gset_new("bm_faces");
n->tribuf = NULL;
}
}
}
totnode++;
}
}
int *map = MEM_callocN(sizeof(int) * bvh->totnode, "bmesh map temp");
// build idx map for child offsets
int j = 0;
for (int i = 0; i < bvh->totnode; i++) {
PBVHNode *n = bvh->nodes + i;
if (!(n->flag & PBVH_Delete)) {
map[i] = j++;
}
else if (1) {
if (n->layer_disp) {
MEM_freeN(n->layer_disp);
n->layer_disp = NULL;
}
pbvh_free_all_draw_buffers(n);
if (n->vert_indices) {
MEM_freeN((void *)n->vert_indices);
n->vert_indices = NULL;
}
if (n->face_vert_indices) {
MEM_freeN((void *)n->face_vert_indices);
n->face_vert_indices = NULL;
}
if (n->tribuf || n->tri_buffers) {
BKE_pbvh_bmesh_free_tris(bvh, n);
}
if (n->bm_unique_verts) {
BLI_table_gset_free(n->bm_unique_verts, NULL);
n->bm_unique_verts = NULL;
}
if (n->bm_other_verts) {
BLI_table_gset_free(n->bm_other_verts, NULL);
n->bm_other_verts = NULL;
}
if (n->bm_faces) {
BLI_table_gset_free(n->bm_faces, NULL);
n->bm_faces = NULL;
}
#ifdef PROXY_ADVANCED
BKE_pbvh_free_proxyarray(bvh, n);
#endif
}
}
// compact node array
j = 0;
for (int i = 0; i < bvh->totnode; i++) {
if (!(bvh->nodes[i].flag & PBVH_Delete)) {
if (bvh->nodes[i].children_offset >= bvh->totnode - 1) {
printf("error %i %i\n", i, bvh->nodes[i].children_offset);
continue;
}
int i1 = map[bvh->nodes[i].children_offset];
int i2 = map[bvh->nodes[i].children_offset + 1];
if (bvh->nodes[i].children_offset >= bvh->totnode) {
printf("bad child node reference %d->%d, totnode: %d\n",
i,
bvh->nodes[i].children_offset,
bvh->totnode);
continue;
}
if (bvh->nodes[i].children_offset && i2 != i1 + 1) {
printf(" pbvh corruption during node join %d %d\n", i1, i2);
}
bvh->nodes[j] = bvh->nodes[i];
bvh->nodes[j].children_offset = i1;
j++;
}
}
if (j != totnode) {
printf("pbvh error: %s", __func__);
}
if (bvh->totnode != j) {
memset(bvh->nodes + j, 0, sizeof(*bvh->nodes) * (bvh->totnode - j));
bvh->node_mem_count = j;
}
bvh->totnode = j;
// set vert/face node indices again
for (int i = 0; i < bvh->totnode; i++) {
PBVHNode *n = bvh->nodes + i;
if (!(n->flag & PBVH_Leaf)) {
continue;
}
if (!n->bm_unique_verts) {
printf("ERROR!\n");
n->bm_unique_verts = BLI_table_gset_new("bleh");
n->bm_other_verts = BLI_table_gset_new("bleh");
n->bm_faces = BLI_table_gset_new("bleh");
}
BMVert *v;
TGSET_ITER (v, n->bm_unique_verts) {
BM_ELEM_CD_SET_INT(v, bvh->cd_vert_node_offset, i);
}
TGSET_ITER_END
BMFace *f;
TGSET_ITER (f, n->bm_faces) {
BM_ELEM_CD_SET_INT(f, bvh->cd_face_node_offset, i);
}
TGSET_ITER_END
}
BMVert **scratch = NULL;
BLI_array_declare(scratch);
for (int i = 0; i < bvh->totnode; i++) {
PBVHNode *n = bvh->nodes + i;
if (!(n->flag & PBVH_Leaf)) {
continue;
}
BLI_array_clear(scratch);
BMVert *v;
TGSET_ITER (v, n->bm_other_verts) {
int ni = BM_ELEM_CD_GET_INT(v, bvh->cd_vert_node_offset);
if (ni == DYNTOPO_NODE_NONE) {
BLI_array_append(scratch, v);
}
// BM_ELEM_CD_SET_INT(v, bvh->cd_vert_node_offset, i);
}
TGSET_ITER_END
int slen = BLI_array_len(scratch);
for (int j = 0; j < slen; j++) {
BMVert *v = scratch[j];
BLI_table_gset_remove(n->bm_other_verts, v, NULL);
BLI_table_gset_add(n->bm_unique_verts, v);
BM_ELEM_CD_SET_INT(v, bvh->cd_vert_node_offset, i);
}
}
BLI_array_free(scratch);
MEM_freeN(map);
}
static void recursive_delete_nodes(PBVH *pbvh, int ni)
{
PBVHNode *node = pbvh->nodes + ni;
node->flag |= PBVH_Delete;
if (!(node->flag & PBVH_Leaf) && node->children_offset) {
if (node->children_offset < pbvh->totnode) {
recursive_delete_nodes(pbvh, node->children_offset);
}
if (node->children_offset + 1 < pbvh->totnode) {
recursive_delete_nodes(pbvh, node->children_offset + 1);
}
}
}
// static float bbox_overlap()
/* works by detect overlay of leaf nodes, destroying them
and then re-inserting them*/
ATTR_NO_OPT static void pbvh_bmesh_balance_tree(PBVH *pbvh)
{
PBVHNode **stack = NULL;
float *overlaps = MEM_calloc_arrayN(pbvh->totnode, sizeof(float), "overlaps");
PBVHNode **parentmap = MEM_calloc_arrayN(pbvh->totnode, sizeof(*parentmap), "parentmap");
int *depthmap = MEM_calloc_arrayN(pbvh->totnode, sizeof(*depthmap), "depthmap");
BLI_array_declare(stack);
BMFace **faces = NULL;
BLI_array_declare(faces);
PBVHNode **substack = NULL;
BLI_array_declare(substack);
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *node = pbvh->nodes + i;
if ((node->flag & PBVH_Leaf) || node->children_offset == 0) {
continue;
}
if (node->children_offset < pbvh->totnode) {
parentmap[node->children_offset] = node;
}
if (node->children_offset + 1 < pbvh->totnode) {
parentmap[node->children_offset + 1] = node;
}
}
#if 0
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *node = pbvh->nodes + i;
PBVHNode *parent = parentmap[i];
int depth = 0;
while (parent) {
parent = parentmap[parent - pbvh->nodes];
depth++;
}
depthmap[i] = depth;
}
#endif
const int cd_vert_node = pbvh->cd_vert_node_offset;
const int cd_face_node = pbvh->cd_face_node_offset;
bool modified = false;
BLI_array_append(stack, pbvh->nodes);
while (BLI_array_len(stack) > 0) {
PBVHNode *node = BLI_array_pop(stack);
BB clip;
if (!(node->flag & PBVH_Leaf) && node->children_offset > 0) {
PBVHNode *child1 = pbvh->nodes + node->children_offset;
PBVHNode *child2 = pbvh->nodes + node->children_offset + 1;
float volume = BB_volume(&child1->vb) + BB_volume(&child2->vb);
BB_intersect(&clip, &child1->vb, &child2->vb);
float overlap = BB_volume(&clip);
// for (int i = 0; i < depthmap[node - pbvh->nodes]; i++) {
// printf("-");
//}
// printf("volume: %.4f overlap: %.4f ratio: %.3f\n", volume, overlap, overlap / volume);
if (overlap > volume * 0.25) {
modified = true;
// printf(" DELETE!\n");
BLI_array_clear(substack);
BLI_array_append(substack, child1);
BLI_array_append(substack, child2);
while (BLI_array_len(substack) > 0) {
PBVHNode *node2 = BLI_array_pop(substack);
node2->flag |= PBVH_Delete;
if (node2->flag & PBVH_Leaf) {
BMFace *f;
BMVert *v;
TGSET_ITER (f, node2->bm_faces) {
if (BM_ELEM_CD_GET_INT(f, cd_face_node) == -1) {
// eek!
continue;
}
BM_ELEM_CD_SET_INT(f, cd_face_node, DYNTOPO_NODE_NONE);
BLI_array_append(faces, f);
}
TGSET_ITER_END;
TGSET_ITER (v, node2->bm_unique_verts) {
BM_ELEM_CD_SET_INT(v, cd_vert_node, DYNTOPO_NODE_NONE);
}
TGSET_ITER_END;
}
else if (node2->children_offset > 0 && node2->children_offset < pbvh->totnode) {
BLI_array_append(substack, pbvh->nodes + node2->children_offset);
if (node2->children_offset + 1 < pbvh->totnode) {
BLI_array_append(substack, pbvh->nodes + node2->children_offset + 1);
}
}
}
}
if (node->children_offset < pbvh->totnode) {
BLI_array_append(stack, child1);
}
if (node->children_offset + 1 < pbvh->totnode) {
BLI_array_append(stack, child2);
}
}
}
if (modified) {
pbvh_bmesh_compact_tree(pbvh);
printf("joined nodes; %d faces\n", BLI_array_len(faces));
for (int i = 0; i < BLI_array_len(faces); i++) {
if (BM_ELEM_CD_GET_INT(faces[i], cd_face_node) != DYNTOPO_NODE_NONE) {
// printf("duplicate faces in pbvh_bmesh_balance_tree!\n");
continue;
}
bke_pbvh_insert_face(pbvh, faces[i]);
}
}
BLI_array_free(faces);
MEM_SAFE_FREE(parentmap);
MEM_SAFE_FREE(overlaps);
BLI_array_free(stack);
BLI_array_free(substack);
}
static void pbvh_bmesh_join_nodes(PBVH *bvh)
{
if (bvh->totnode < 2) {
@ -2669,12 +3047,20 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
{
int totnode = pbvh->totnode;
BKE_pbvh_update_bounds(pbvh, (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw));
pbvh_bmesh_check_nodes(pbvh);
pbvh_bmesh_join_nodes(pbvh);
pbvh_bmesh_check_nodes(pbvh);
BKE_pbvh_update_bounds(pbvh, (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw));
if (1 || pbvh->balance_counter++ == 5) {
pbvh_bmesh_balance_tree(pbvh);
pbvh_bmesh_check_nodes(pbvh);
pbvh->balance_counter = 0;
}
totnode = pbvh->totnode;
for (int i = 0; i < totnode; i++) {

View File

@ -208,6 +208,8 @@ struct PBVH {
bool flat_vcol_shading;
bool need_full_render; // used by pbvh drawing for PBVH_BMESH
int balance_counter;
};
/* pbvh.c */
@ -216,6 +218,9 @@ void BB_expand(BB *bb, const float co[3]);
void BB_expand_with_bb(BB *bb, BB *bb2);
void BBC_update_centroid(BBC *bbc);
int BB_widest_axis(const BB *bb);
void BB_intersect(BB *r_out, BB *a, BB *b);
float BB_volume(const BB *bb);
void pbvh_grow_nodes(PBVH *bvh, int totnode);
bool ray_face_intersection_quad(const float ray_start[3],
struct IsectRayPrecalc *isect_precalc,

View File

@ -1542,8 +1542,7 @@ void SCULPT_dyntopo_save_persistent_base(SculptSession *ss);
#define SCULPT_LAYER_DISP "__dyntopo_layer_disp"
// these tools don't support dynamic pbvh splitting during the stroke
#define DYNTOPO_HAS_DYNAMIC_SPLIT(tool) \
(ELEM(tool, SCULPT_TOOL_DRAW_SHARP, SCULPT_TOOL_LAYER) == 0)
#define DYNTOPO_HAS_DYNAMIC_SPLIT(tool) (ELEM(tool, SCULPT_TOOL_LAYER) == 0)
/*get current symmetry pass index inclusive of both
mirror and radial symmetry*/

View File

@ -1060,6 +1060,8 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hid
/** \name BMesh PBVH
* \{ */
static int debug_pass = 0;
/* Output a BMVert into a VertexBufferFormat array at v_index. */
static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
GPUVertBuf *vert_buf,
@ -1099,7 +1101,7 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
if (G.debug_value == 889) {
int ni = BM_ELEM_CD_GET_INT(v, cd_vert_node_offset);
effective_mask = ni == -1 ? 0.0f : (float)((ni * 50) % 32) / 32.0f;
effective_mask = ni == -1 ? 0.0f : (float)(((ni + debug_pass) * 511) % 64) / 64;
}
uchar cmask = (uchar)(effective_mask * 255);
@ -1267,6 +1269,8 @@ void GPU_pbvh_update_attribute_names(CustomData *vdata,
{
const bool active_only = !need_full_render;
debug_pass++;
GPU_vertformat_clear(&g_vbo_id.format);
g_vbo_id.fast_mode = fast_mode;