forked from bartvdbraak/blender
bmesh speedup for bvh building, replace SmallHash with BLI_bitmap, using a hash doesn't make much sense since in most cases all vertices are accessed and the hash isn't guaranteed to be small.
gives ~9x speedup to filling 'cagecos' in my own tests on a high poly mesh.
This commit is contained in:
parent
e39ea5f0a3
commit
ea0ad013d3
@ -34,7 +34,7 @@
|
|||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
|
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_smallhash.h"
|
#include "BLI_bitmap.h"
|
||||||
|
|
||||||
#include "BKE_DerivedMesh.h"
|
#include "BKE_DerivedMesh.h"
|
||||||
#include "BKE_editmesh.h"
|
#include "BKE_editmesh.h"
|
||||||
@ -56,21 +56,22 @@ struct BMBVHTree {
|
|||||||
float curw, curd;
|
float curw, curd;
|
||||||
float co[3], (*cagecos)[3], (*cos)[3];
|
float co[3], (*cagecos)[3], (*cos)[3];
|
||||||
int curtag, flag;
|
int curtag, flag;
|
||||||
|
};
|
||||||
|
|
||||||
Object *ob;
|
struct CageUserData {
|
||||||
|
int totvert;
|
||||||
|
float (*cagecos)[3];
|
||||||
|
BLI_bitmap vert_bitmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cage_mapped_verts_callback(void *userData, int index, const float co[3],
|
static void cage_mapped_verts_callback(void *userData, int index, const float co[3],
|
||||||
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
|
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
|
||||||
{
|
{
|
||||||
void **data = userData;
|
struct CageUserData *data = userData;
|
||||||
BMEditMesh *em = data[0];
|
|
||||||
float (*cagecos)[3] = data[1];
|
|
||||||
SmallHash *hash = data[2];
|
|
||||||
|
|
||||||
if (index >= 0 && index < em->bm->totvert && !BLI_smallhash_haskey(hash, index)) {
|
if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_GET(data->vert_bitmap, index))) {
|
||||||
BLI_smallhash_insert(hash, index, NULL);
|
BLI_BITMAP_SET(data->vert_bitmap, index);
|
||||||
copy_v3_v3(cagecos[index], co);
|
copy_v3_v3(data->cagecos[index], co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +80,6 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
|
|||||||
struct BMLoop *(*looptris)[3] = em->looptris;
|
struct BMLoop *(*looptris)[3] = em->looptris;
|
||||||
BMBVHTree *tree = MEM_callocN(sizeof(*tree), "BMBVHTree");
|
BMBVHTree *tree = MEM_callocN(sizeof(*tree), "BMBVHTree");
|
||||||
DerivedMesh *cage, *final;
|
DerivedMesh *cage, *final;
|
||||||
SmallHash shash;
|
|
||||||
float cos[3][3], (*cagecos)[3] = NULL;
|
float cos[3][3], (*cagecos)[3] = NULL;
|
||||||
int i;
|
int i;
|
||||||
int tottri;
|
int tottri;
|
||||||
@ -87,11 +87,9 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
|
|||||||
/* BKE_editmesh_tessface_calc() must be called already */
|
/* BKE_editmesh_tessface_calc() must be called already */
|
||||||
BLI_assert(em->tottri != 0 || em->bm->totface == 0);
|
BLI_assert(em->tottri != 0 || em->bm->totface == 0);
|
||||||
|
|
||||||
/* when initializing cage verts, we only want the first cage coordinate for each vertex,
|
/* cage-flag needs scene */
|
||||||
* so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
|
BLI_assert(scene || !(flag & BMBVH_USE_CAGE));
|
||||||
BLI_smallhash_init(&shash);
|
|
||||||
|
|
||||||
tree->ob = em->ob;
|
|
||||||
tree->em = em;
|
tree->em = em;
|
||||||
tree->bm = em->bm;
|
tree->bm = em->bm;
|
||||||
tree->epsilon = FLT_EPSILON * 2.0f;
|
tree->epsilon = FLT_EPSILON * 2.0f;
|
||||||
@ -120,11 +118,12 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
|
|||||||
tree->tree = BLI_bvhtree_new(tottri, tree->epsilon, 8, 8);
|
tree->tree = BLI_bvhtree_new(tottri, tree->epsilon, 8, 8);
|
||||||
|
|
||||||
if (flag & BMBVH_USE_CAGE) {
|
if (flag & BMBVH_USE_CAGE) {
|
||||||
|
BLI_bitmap vert_bitmap;
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
BMVert *v;
|
BMVert *v;
|
||||||
void *data[3];
|
struct CageUserData data;
|
||||||
|
|
||||||
tree->cos = MEM_callocN(sizeof(float) * 3 * em->bm->totvert, "bmbvh cos");
|
tree->cos = MEM_callocN(sizeof(*tree->cos) * em->bm->totvert, "bmbvh cos");
|
||||||
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
||||||
BM_elem_index_set(v, i); /* set_inline */
|
BM_elem_index_set(v, i); /* set_inline */
|
||||||
copy_v3_v3(tree->cos[i], v->co);
|
copy_v3_v3(tree->cos[i], v->co);
|
||||||
@ -135,11 +134,17 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
|
|||||||
cage = editbmesh_get_derived_cage_and_final(scene, em->ob, em, &final, CD_MASK_DERIVEDMESH);
|
cage = editbmesh_get_derived_cage_and_final(scene, em->ob, em, &final, CD_MASK_DERIVEDMESH);
|
||||||
cagecos = MEM_callocN(sizeof(float) * 3 * em->bm->totvert, "bmbvh cagecos");
|
cagecos = MEM_callocN(sizeof(float) * 3 * em->bm->totvert, "bmbvh cagecos");
|
||||||
|
|
||||||
data[0] = em;
|
/* when initializing cage verts, we only want the first cage coordinate for each vertex,
|
||||||
data[1] = cagecos;
|
* so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
|
||||||
data[2] = &shash;
|
vert_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
|
||||||
|
|
||||||
cage->foreachMappedVert(cage, cage_mapped_verts_callback, data);
|
data.totvert = em->bm->totvert;
|
||||||
|
data.cagecos = cagecos;
|
||||||
|
data.vert_bitmap = vert_bitmap;
|
||||||
|
|
||||||
|
cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data);
|
||||||
|
|
||||||
|
MEM_freeN(vert_bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->cagecos = cagecos;
|
tree->cagecos = cagecos;
|
||||||
@ -175,7 +180,6 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BLI_bvhtree_balance(tree->tree);
|
BLI_bvhtree_balance(tree->tree);
|
||||||
BLI_smallhash_release(&shash);
|
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user