[Bf-blender-cvs] [76bd253be73] temp_bmesh_multires: Dyntopo sculpt: add dev operator to debug memory cache coherency
Joseph Eagar
noreply at git.blender.org
Fri Aug 6 21:51:49 CEST 2021
Commit: 76bd253be73370145404aa4e31139911d9afb579
Author: Joseph Eagar
Date: Fri Aug 6 09:58:46 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB76bd253be73370145404aa4e31139911d9afb579
Dyntopo sculpt: add dev operator to debug memory cache coherency
===================================================================
M source/blender/blenkernel/intern/paint.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/bmesh/intern/bmesh_mesh.c
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/gpu/intern/gpu_node_graph.c
===================================================================
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 800dbaaa1af..fd6c43ece2f 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -82,7 +82,6 @@
// XXX todo: work our bad module cross ref
void SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me);
void SCULPT_on_sculptsession_bmesh_free(SculptSession *ss);
-void SCULPT_reorder_bmesh(SculptSession *ss);
static void palette_init_data(ID *id)
{
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index c7f40d95109..66887e37af9 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -2410,7 +2410,7 @@ static void scan_edge_split(BMesh *bm, BMEdge **edges, int totedge)
BLI_array_free(fmap);
}
-BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
+BMesh *BKE_pbvh_reorder_bmesh2(PBVH *pbvh)
{
if (BKE_pbvh_type(pbvh) != PBVH_BMESH || pbvh->totnode == 0) {
return pbvh->bm;
@@ -2645,3 +2645,210 @@ BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
return bm2;
}
+
+typedef struct SortElem {
+ BMElem *elem;
+ int index;
+ int cd_node_off;
+} SortElem;
+
+static int sort_verts_faces(const void *va, const void *vb)
+{
+ SortElem *a = (SortElem *)va;
+ SortElem *b = (SortElem *)vb;
+ int ni1 = BM_ELEM_CD_GET_INT(a->elem, a->cd_node_off);
+ int ni2 = BM_ELEM_CD_GET_INT(b->elem, b->cd_node_off);
+
+ return ni1 - ni2;
+}
+
+static int sort_edges(const void *va, const void *vb)
+{
+ SortElem *a = (SortElem *)va;
+ SortElem *b = (SortElem *)vb;
+
+ BMEdge *e1 = (BMEdge *)a->elem;
+ BMEdge *e2 = (BMEdge *)b->elem;
+
+ int ni1 = BM_ELEM_CD_GET_INT(e1->v1, a->cd_node_off);
+ int ni2 = BM_ELEM_CD_GET_INT(e1->v2, a->cd_node_off);
+ int ni3 = BM_ELEM_CD_GET_INT(e2->v1, b->cd_node_off);
+ int ni4 = BM_ELEM_CD_GET_INT(e2->v2, b->cd_node_off);
+
+ return (ni1 + ni2) - (ni3 + ni4);
+}
+
+BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
+{
+ BMesh *bm = pbvh->bm;
+
+ int **save_other_vs = MEM_calloc_arrayN(pbvh->totnode, sizeof(int *), __func__);
+ int **save_unique_vs = MEM_calloc_arrayN(pbvh->totnode, sizeof(int *), __func__);
+ int **save_fs = MEM_calloc_arrayN(pbvh->totnode, sizeof(int *), __func__);
+
+ SortElem *verts = MEM_malloc_arrayN(bm->totvert, sizeof(SortElem), __func__);
+ SortElem *edges = MEM_malloc_arrayN(bm->totedge, sizeof(SortElem), __func__);
+ SortElem *faces = MEM_malloc_arrayN(bm->totface, sizeof(SortElem), __func__);
+
+ BMIter iter;
+ BMVert *v;
+ BMEdge *e;
+ BMFace *f;
+
+ int i = 0;
+
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ verts[i].elem = (BMElem *)v;
+ verts[i].cd_node_off = pbvh->cd_vert_node_offset;
+ verts[i].index = i;
+ v->head.index = i;
+ }
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
+ edges[i].elem = (BMElem *)e;
+ edges[i].cd_node_off = pbvh->cd_vert_node_offset;
+ edges[i].index = i;
+ e->head.index = i;
+ }
+ BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
+ faces[i].elem = (BMElem *)f;
+ faces[i].cd_node_off = pbvh->cd_face_node_offset;
+ faces[i].index = i;
+ f->head.index = i;
+ }
+
+ for (i = 0; i < pbvh->totnode; i++) {
+ int *other_vs = NULL;
+ int *unique_vs = NULL;
+ int *fs = NULL;
+
+ BLI_array_declare(other_vs);
+ BLI_array_declare(unique_vs);
+ BLI_array_declare(fs);
+
+ PBVHNode *node = pbvh->nodes + i;
+ if (!(node->flag & PBVH_Leaf)) {
+ continue;
+ }
+
+ BMVert *v;
+ BMFace *f;
+
+ TGSET_ITER (v, node->bm_unique_verts) {
+ BLI_array_append(unique_vs, v->head.index);
+ }
+ TGSET_ITER_END;
+ TGSET_ITER (v, node->bm_other_verts) {
+ BLI_array_append(other_vs, v->head.index);
+ }
+ TGSET_ITER_END;
+ TGSET_ITER (f, node->bm_faces) {
+ BLI_array_append(fs, f->head.index);
+ }
+ TGSET_ITER_END;
+
+ save_unique_vs[i] = unique_vs;
+ save_other_vs[i] = other_vs;
+ save_fs[i] = fs;
+ }
+
+ qsort(verts, bm->totvert, sizeof(SortElem), sort_verts_faces);
+ qsort(edges, bm->totedge, sizeof(SortElem), sort_edges);
+ qsort(faces, bm->totface, sizeof(SortElem), sort_verts_faces);
+
+ uint *vs = MEM_malloc_arrayN(bm->totvert, sizeof(int), __func__);
+ uint *es = MEM_malloc_arrayN(bm->totedge, sizeof(int), __func__);
+ uint *fs = MEM_malloc_arrayN(bm->totface, sizeof(int), __func__);
+
+ for (i = 0; i < bm->totvert; i++) {
+ vs[i] = (uint)verts[i].index;
+ verts[i].elem->head.index = verts[i].index;
+ }
+ for (i = 0; i < bm->totedge; i++) {
+ es[i] = (uint)edges[i].index;
+ edges[i].elem->head.index = edges[i].index;
+ }
+ for (i = 0; i < bm->totface; i++) {
+ fs[i] = (uint)faces[i].index;
+ faces[i].elem->head.index = faces[i].index;
+ }
+
+ BM_mesh_remap(bm, vs, es, fs);
+
+ // create new mappings
+ BMVert **mapvs = MEM_malloc_arrayN(bm->totvert, sizeof(BMVert *), __func__);
+ BMEdge **mapes = MEM_malloc_arrayN(bm->totedge, sizeof(BMEdge *), __func__);
+ BMFace **mapfs = MEM_malloc_arrayN(bm->totface, sizeof(BMFace *), __func__);
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ mapvs[v->head.index] = v;
+ }
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ mapes[e->head.index] = e;
+ }
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ mapfs[f->head.index] = f;
+ }
+
+ // rebuild bm_unique_verts bm_other_verts and bm_faces in pbvh nodes
+ for (i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
+
+ if (!(node->flag & PBVH_Leaf)) {
+ continue;
+ }
+
+ int tot_unique_vs = BLI_table_gset_len(node->bm_unique_verts);
+ int tot_other_vs = BLI_table_gset_len(node->bm_other_verts);
+ int tot_fs = BLI_table_gset_len(node->bm_faces);
+
+ BLI_table_gset_free(node->bm_unique_verts, NULL);
+ BLI_table_gset_free(node->bm_other_verts, NULL);
+ BLI_table_gset_free(node->bm_faces, NULL);
+
+ node->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
+ node->bm_other_verts = BLI_table_gset_new("bm_other_verts");
+ node->bm_faces = BLI_table_gset_new("bm_faces");
+
+ int *unique_vs = save_unique_vs[i];
+ int *other_vs = save_other_vs[i];
+ int *fs = save_fs[i];
+
+ for (int j = 0; j < tot_unique_vs; j++) {
+ BLI_table_gset_add(node->bm_unique_verts, mapvs[unique_vs[j]]);
+ }
+ for (int j = 0; j < tot_other_vs; j++) {
+ BLI_table_gset_add(node->bm_other_verts, mapvs[other_vs[j]]);
+ }
+
+ for (int j = 0; j < tot_fs; j++) {
+ BLI_table_gset_add(node->bm_faces, mapfs[fs[j]]);
+ }
+
+ MEM_SAFE_FREE(save_unique_vs[i]);
+ MEM_SAFE_FREE(save_other_vs[i]);
+ MEM_SAFE_FREE(save_fs[i]);
+
+ node->flag |= PBVH_UpdateTris;
+ }
+
+ MEM_SAFE_FREE(mapvs);
+ MEM_SAFE_FREE(mapes);
+ MEM_SAFE_FREE(mapfs);
+
+ bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE;
+ bm->elem_table_dirty |= BM_VERT | BM_EDGE | BM_FACE;
+
+ MEM_SAFE_FREE(vs);
+ MEM_SAFE_FREE(es);
+ MEM_SAFE_FREE(fs);
+
+ MEM_SAFE_FREE(verts);
+ MEM_SAFE_FREE(edges);
+ MEM_SAFE_FREE(faces);
+
+ MEM_SAFE_FREE(save_other_vs);
+ MEM_SAFE_FREE(save_unique_vs);
+ MEM_SAFE_FREE(save_fs);
+
+ return pbvh->bm;
+}
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 104ae6a349a..06ff1b1df55 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1161,6 +1161,52 @@ void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const
if (fptr_map) {
BLI_ghash_free(fptr_map, NULL, NULL);
}
+
+ // regenerate idmap
+ if ((bm->idmap.flag & BM_HAS_IDS) && (bm->idmap.flag & BM_HAS_ID_MAP) && bm->idmap.map) {
+ memset(bm->idmap.map, 0, sizeof(void *) * bm->idmap.map_size);
+
+ char iters[4] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, 0, BM_FACES_OF_MESH};
+ CustomData *cdatas[4] = {&bm->vdata, &bm->edata, &bm->ldata, &bm->pdata};
+ const bool have_loop = bm->idmap.flag & BM_LOOP;
+
+ for (int i = 0; i < 4; i++) {
+ int type = 1 << i;
+
+ if (type == BM_LOOP) { // handle loops with faces
+ continue;
+ }
+
+ int cd_id = CustomData_get_offset(cdatas[i], CD_MESH_ID);
+ int cd_loop_id = CustomData_get_offset(&bm->ldata, CD_MESH_ID);
+
+ BMIter iter;
+ BMElem *elem;
+
+ if (cd_id < 0 && !(type == BM_FACE && have_loop)) {
+ continue;
+ }
+
+ BM_ITER_MESH (elem, &iter, bm, iters[i]) {
+ if (type == BM_FACE && have_loop) {
+ BMFace *f = (BMFace *)elem;
+ BMLoop *l = f->l_first;
+
+ do {
+ int id_loop = BM_ELEM_CD_GET_INT(l, cd_loop_id);
+ bm->idmap.map[id_loop] = (BMElem *)l;
+ } while ((l = l->next) != f->l_first);
+ }
+
+ if (cd_id < 0) {
+ continue;
+ }
+
+ int id = BM_ELEM_CD_GET_INT(elem, cd_id);
+ bm->idmap.map[id] = elem;
+ }
+ }
+ }
}
/**
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 9da164464c7..cf5bb8b9622 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -9429,6 +9429,67 @@ static bool sculpt_no_multires_poll(bContext *C)
return false;
}
+static bool sculpt_only_bmesh_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ if (SCULPT_mode_poll(C) && ob->sculpt && ob->sculpt->pbvh) {
+ return BKE_pbvh_type(ob->sculpt->pbvh) == PBVH_BMESH;
+ }
+ return false;
+}
+
+static int sculpt_spatial_sort_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
+ const Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss = ob->sculpt;
+ PBVH *pbvh = ss->pbvh;
+
+ if (!pbvh) {
+ return OPERATOR_CANCELLED;
+ }
+
+ switch (BKE_pbvh_type(pbvh)) {
+ case PBVH_BMESH:
+ SCULPT_undo_push_begin(ob, "Dynamic topology symmetrize");
+ SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY);
+
+ BKE_pbvh_reorder_bmesh(ss->pbvh);
+
+ BKE_pbvh_recalc_bmesh_boundary(ss->pbvh);
+ BM_log_full_mesh(ss->bm, ss->bm_log);
+
+ ss->act
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list