[Bf-blender-cvs] [37bce7b701f] temp_bmesh_multires: commit working code
Joseph Eagar
noreply at git.blender.org
Wed Sep 8 10:32:25 CEST 2021
Commit: 37bce7b701ff5825409ae9523cafe197b45560a1
Author: Joseph Eagar
Date: Thu Sep 2 23:19:11 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB37bce7b701ff5825409ae9523cafe197b45560a1
commit working code
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/blenkernel/intern/pbvh_intern.h
M source/blender/blenlib/BLI_ghash.h
M source/blender/blenlib/BLI_smallhash.h
M source/blender/blenlib/CMakeLists.txt
M source/blender/blenlib/intern/BLI_ghash_utils.c
A source/blender/blenlib/intern/BLI_table_gset.c
M source/blender/blenlib/intern/smallhash.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index afed28d8120..c017c42aee1 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -29,6 +29,8 @@
#include "BKE_ccg.h"
#include <stdint.h>
+#define DEFRAGMENT_MEMORY
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -74,6 +76,10 @@ BLI_INLINE SculptFaceRef BKE_pbvh_make_fref(intptr_t i)
#define SCULPT_REF_NONE ((intptr_t)-1)
+#ifdef DEFRAGMENT_MEMORY
+# include "BLI_smallhash.h"
+#endif
+
typedef struct PBVHTri {
int v[3]; // references into PBVHTriBuf->verts
intptr_t l[3]; // loops
@@ -90,6 +96,8 @@ typedef struct PBVHTriBuf {
int totvert, totedge, tottri;
int verts_size, edges_size, tris_size;
+ SmallHash vertmap; // maps vertex ptrs to indices within verts
+
// private field
intptr_t *loops;
int totloop, mat_nr;
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 65411abb552..c6f9b8a6437 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -18,6 +18,7 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_rand.h"
+#include "BLI_smallhash.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
#include "PIL_time.h"
@@ -1412,6 +1413,18 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
{
BMLoop *l = f->l_first;
+#if 0
+ float cent[3];
+
+ zero_v3(cent);
+ add_v3_v3(cent, l->v->co);
+ add_v3_v3(cent, l->next->v->co);
+ add_v3_v3(cent, l->prev->v->co);
+
+ mul_v3_fl(cent, 1.0f / 3.0f);
+ return len_squared_v3v3(cent, q->center) < q->radius_squared;
+#endif
+
/* Check if triangle intersects the sphere */
float dis = dist_to_tri_sphere_simple((float *)q->center,
(float *)l->v->co,
@@ -3909,7 +3922,49 @@ typedef struct SwapData {
PBVH *pbvh;
} SwapData;
-static void on_vert_swap(BMVert *v1, BMVert *v2, void *userdata)
+ATTR_NO_OPT void pbvh_tribuf_swap_verts(
+ PBVH *pbvh, PBVHNode *node, PBVHTriBuf *tribuf, BMVert *v1, BMVert *v2)
+{
+
+ void *val;
+
+ bool ok = BLI_smallhash_remove_p(&tribuf->vertmap, (uintptr_t)v1, &val);
+
+ if (!ok) {
+ printf("eek, missing vertex!");
+ // return;
+ }
+
+ int idx = POINTER_AS_INT(val);
+
+ tribuf->verts[idx].i = (intptr_t)v2;
+
+ void **val2;
+ if (BLI_smallhash_ensure_p(&tribuf->vertmap, (intptr_t)v2, &val2)) {
+ // v2 was already in hash? add v1 back in then with v2's index
+
+ int idx2 = POINTER_AS_INT(*val2);
+ BLI_smallhash_insert(&tribuf->vertmap, (intptr_t)v1, POINTER_FROM_INT(idx2));
+ }
+
+ *val2 = POINTER_FROM_INT(idx);
+}
+
+ATTR_NO_OPT void pbvh_node_tribuf_swap_verts(PBVH *pbvh, PBVHNode *node, BMVert *v1, BMVert *v2)
+{
+ BLI_table_gset_remove(node->bm_unique_verts, v1, NULL);
+ BLI_table_gset_add(node->bm_unique_verts, v2);
+
+ if (node->tribuf) {
+ pbvh_tribuf_swap_verts(pbvh, node, node->tribuf, v1, v2);
+ }
+
+ for (int i = 0; i < node->tot_tri_buffers; i++) {
+ pbvh_tribuf_swap_verts(pbvh, node, node->tri_buffers + i, v1, v2);
+ }
+}
+
+ATTR_NO_OPT static void on_vert_swap(BMVert *v1, BMVert *v2, void *userdata)
{
SwapData *sdata = (SwapData *)userdata;
PBVH *pbvh = sdata->pbvh;
@@ -3926,21 +3981,14 @@ static void on_vert_swap(BMVert *v1, BMVert *v2, void *userdata)
printf("node error! %s\n", __func__);
}
- int updateflag = PBVH_UpdateOtherVerts | PBVH_UpdateNormals | PBVH_UpdateTris | PBVH_UpdateTris;
- updateflag |= PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw |
- PBVH_RebuildDrawBuffers | PBVH_UpdateVisibility;
- updateflag |= PBVH_UpdateDrawBuffers;
+ int updateflag = PBVH_UpdateOtherVerts;
if (node1) {
- node1->flag |= updateflag;
- BLI_table_gset_remove(node1->bm_unique_verts, v1, NULL);
- BLI_table_gset_insert(node1->bm_unique_verts, v2);
+ pbvh_node_tribuf_swap_verts(pbvh, node1, v1, v2);
}
- if (node2) {
- node2->flag |= updateflag;
- BLI_table_gset_remove(node2->bm_unique_verts, v2, NULL);
- BLI_table_gset_insert(node2->bm_unique_verts, v1);
+ if (node2 && node2 != node1) {
+ pbvh_node_tribuf_swap_verts(pbvh, node2, v2, v1);
}
if (!node1 || !node2) {
@@ -4183,6 +4231,7 @@ typedef struct EdgeQueueContext {
brusharea = brusharea * brusharea * M_PI;
int max_steps = (int)((float)DYNTOPO_MAX_ITER * ratio);
+ max_steps = MIN2(max_steps, DYNTOPO_MAX_ITER);
printf("max_steps %d\n", max_steps);
@@ -4253,6 +4302,8 @@ typedef struct EdgeQueueContext {
int max_steps = (int)((float)DYNTOPO_MAX_ITER * ratio);
max_steps = (int)(brusharea * ratio * 2.0f);
+ max_steps = MIN2(max_steps, DYNTOPO_MAX_ITER);
+
printf("brusharea: %.2f, ratio: %.2f\n", brusharea, ratio);
printf("subdivide max_steps %d\n", max_steps);
@@ -4278,7 +4329,6 @@ typedef struct EdgeQueueContext {
int dcount = 0;
-//#define DEFRAGMENT_MEMORY
#ifdef DEFRAGMENT_MEMORY
RNG *rng = BLI_rng_new(rseed++);
SwapData swapdata = {.pbvh = pbvh};
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 11f9ae7a616..9da70df13c0 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1885,6 +1885,8 @@ static void pbvh_free_tribuf(PBVHTriBuf *tribuf)
MEM_SAFE_FREE(tribuf->loops);
MEM_SAFE_FREE(tribuf->edges);
+ BLI_smallhash_release(&tribuf->vertmap);
+
tribuf->verts = NULL;
tribuf->tris = NULL;
tribuf->loops = NULL;
@@ -2041,7 +2043,7 @@ static bool pbvh_bmesh_split_tris(PBVH *pbvh, PBVHNode *node)
return true;
}
-BLI_INLINE PBVHTri *pbvh_tribuf_add_tri(PBVHTriBuf *tribuf)
+ATTR_NO_OPT BLI_INLINE PBVHTri *pbvh_tribuf_add_tri(PBVHTriBuf *tribuf)
{
tribuf->tottri++;
@@ -2133,11 +2135,29 @@ void pbvh_bmesh_check_other_verts(PBVHNode *node)
TGSET_ITER_END;
}
+static void pbvh_init_tribuf(PBVHNode *node, PBVHTriBuf *tribuf)
+{
+ tribuf->tottri = 0;
+ tribuf->tris_size = 0;
+ tribuf->verts_size = 0;
+ tribuf->mat_nr = 0;
+ tribuf->tottri = 0;
+ tribuf->totvert = 0;
+ tribuf->totloop = 0;
+ tribuf->totedge = 0;
+
+ tribuf->edges = NULL;
+ tribuf->verts = NULL;
+ tribuf->tris = NULL;
+ tribuf->loops = NULL;
+
+ BLI_smallhash_init_ex(&tribuf->vertmap, node->bm_unique_verts->length);
+}
/* In order to perform operations on the original node coordinates
* (currently just raycast), store the node's triangles and vertices.
*
* Skips triangles that are hidden. */
-bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
+ATTR_NO_OPT bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
{
BMesh *bm = pbvh->bm;
@@ -2147,14 +2167,10 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
node->flag |= PBVH_UpdateOtherVerts;
- GHash *vmap = BLI_ghash_ptr_new("pbvh_bmesh.c vmap");
- GHash *mat_vmaps[MAXMAT];
-
int mat_map[MAXMAT];
for (int i = 0; i < MAXMAT; i++) {
mat_map[i] = -1;
- mat_vmaps[i] = NULL;
}
if (node->tribuf || node->tri_buffers) {
@@ -2162,6 +2178,7 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
}
node->tribuf = MEM_callocN(sizeof(*node->tribuf), "node->tribuf");
+ pbvh_init_tribuf(node, node->tribuf);
BMLoop **loops = NULL;
uint(*loops_idx)[3] = NULL;
@@ -2172,12 +2189,6 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
PBVHTriBuf *tribufs = NULL; // material-specific tribuffers
BLI_array_declare(tribufs);
- node->tribuf->mat_nr = 0;
- node->tribuf->tottri = 0;
- node->tribuf->totvert = 0;
- node->tribuf->totloop = 0;
- node->tribuf->totedge = 0;
-
node->flag &= ~PBVH_UpdateTris;
const int edgeflag = BM_ELEM_TAG_ALT;
@@ -2216,11 +2227,10 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
if (mat_map[mat_nr] == -1) {
PBVHTriBuf _tribuf = {0};
- _tribuf.mat_nr = mat_nr;
-
mat_map[mat_nr] = BLI_array_len(tribufs);
- mat_vmaps[mat_nr] = BLI_ghash_ptr_new("pbvh_bmesh.c vmap");
+ pbvh_init_tribuf(node, &_tribuf);
+ _tribuf.mat_nr = mat_nr;
BLI_array_append(tribufs, _tribuf);
}
@@ -2258,7 +2268,7 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
mat_tri->eflag |= 1 << j;
}
- if (!BLI_ghash_ensure_p(vmap, l->v, &val)) {
+ if (!BLI_smallhash_ensure_p(&node->tribuf->vertmap, l->v, &val)) {
SculptVertRef sv = {(intptr_t)l->v};
minmax_v3v3_v3(min, max, l->v->co);
@@ -2271,7 +2281,7 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
tri->l[j] = (intptr_t)l;
val = NULL;
- if (!BLI_ghash_ensure_p(mat_vmaps[mat_nr], l->v, &val)) {
+ if (!BLI_smallhash_ensure_p(&tribufs[mat_nr].vertmap, l->v, &val)) {
SculptVertRef sv = {(intptr_t)l->v};
minmax_v3v3_v3(min, max, l->v->co);
@@ -2356,13 +2366,13 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
l->e->head.hflag |= edgeflag;
- int v1 = (int)BLI_ghash_lookup(vmap, (void *)l->e->v1);
- int v2 = (int)BLI_ghash_lookup(vmap, (void *)l->e->v2);
+ int v1 = (int)BLI_smallhash_lookup(&node->tribuf->vertmap, (void *)l->e->v1);
+ int v2 = (int)BLI_smallhash_lookup(&node->tribuf->vertmap, (void *)l->e->v2);
pbvh_tribuf_add_edge(node->tribuf, v1, v2);
- v1 = (int)BLI_ghash_lookup(mat_vmaps[mat_nr], (void *)l->e->v1);
- v2 = (int)BLI_ghash_lookup(mat_vmaps[mat_nr], (void *)l->e->v2);
+ v1 = (int)BLI_smallhash_lookup(&tribufs[mat_nr].vertmap, (void *)l->e->v1);
+ v2 = (int)BLI_smallhash_lookup(&tribufs[mat_nr].vertmap, (void *)l->e->v2);
pbvh_tribuf_add_edge(mat_tribuf, v1, v2);
} while ((l = l->next) != f->l_first);
@@ -2386,13 +2396,6 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
zero_v3(node->tribuf->max);
}
- BLI_ghash_free(vmap, NULL, NULL);
- for (int i = 0; i < MAXMAT; i++) {
- if (mat_vmaps[i]) {
- BLI_ghash_free(mat_vmaps[i], NULL, NULL);
- }
- }
-
return true;
}
@@ -4999,6 +5002,91 @@ void pbvh_bmesh_cache_test(CacheParams *params,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list