Snap: Optimization: Create BVHTree from loose vertices only

Since snapping to endpoints is already done when you snap to edges
together, there is no need to create a bvhtree with all the vertices.

Also use the appropriate endpoint definition for snap to armatures.
This commit is contained in:
Germano Cavalcante
2023-06-23 15:36:57 -03:00
parent fcb2b99f2b
commit 7d54a756b9
5 changed files with 45 additions and 18 deletions

View File

@@ -78,7 +78,7 @@ typedef enum BVHCacheType {
BVHTREE_FROM_LOOSEVERTS,
BVHTREE_FROM_LOOSEEDGES,
BVHTREE_FROM_EM_VERTS,
BVHTREE_FROM_EM_LOOSEVERTS,
BVHTREE_FROM_EM_EDGES,
BVHTREE_FROM_EM_LOOPTRI,

View File

@@ -618,7 +618,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
r_data->nearest_callback = mesh_looptri_nearest_point;
r_data->raycast_callback = mesh_looptri_spherecast;
break;
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM:
@@ -639,7 +639,7 @@ static void bvhtree_from_editmesh_setup_data(BVHTree *tree,
r_data->em = em;
switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
r_data->nearest_callback = nullptr;
r_data->raycast_callback = editmesh_verts_spherecast;
break;
@@ -754,7 +754,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
bvhtree_balance(tree, false);
if (data) {
bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_VERTS, em, data);
bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOSEVERTS, em, data);
}
return tree;
@@ -1223,7 +1223,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
0.0f, tree_type, 6, positions, corner_verts.data(), looptris, {}, -1);
break;
}
case BVHTREE_FROM_EM_VERTS:
case BVHTREE_FROM_EM_LOOSEVERTS:
case BVHTREE_FROM_EM_EDGES:
case BVHTREE_FROM_EM_LOOPTRI:
case BVHTREE_MAX_ITEM:
@@ -1253,6 +1253,25 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
return data->tree;
}
static BitVector<> bmverts_loose_map_get(BMesh *bm, int *r_bmvert_active_len)
{
BitVector<> bmvert_mask(bm->totvert);
int i, bmvert_loose_len = 0;
BMIter iter;
BMVert *v;
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
if (v->e == nullptr) {
bmvert_mask[i].set();
bmvert_loose_len++;
}
}
*r_bmvert_active_len = bmvert_loose_len;
return bmvert_mask;
}
BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
BMEditMesh *em,
const int tree_type,
@@ -1275,9 +1294,13 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
}
switch (bvh_cache_type) {
case BVHTREE_FROM_EM_VERTS:
data->tree = bvhtree_from_editmesh_verts_create_tree(0.0f, tree_type, 6, em, {}, -1);
case BVHTREE_FROM_EM_LOOSEVERTS: {
int mask_bits_act_len = -1;
const BitVector<> mask = bmverts_loose_map_get(em->bm, &mask_bits_act_len);
data->tree = bvhtree_from_editmesh_verts_create_tree(
0.0f, tree_type, 6, em, mask, mask_bits_act_len);
break;
}
case BVHTREE_FROM_EM_EDGES:
data->tree = bvhtree_from_editmesh_edges_create_tree(0.0f, tree_type, 6, em, {}, -1);
break;

View File

@@ -181,7 +181,7 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
/* transform_snap_object_editmesh.cc */
struct SnapCache_EditMesh {
/* Verts, Edges. */
/* Loose Verts, Edges. */
BVHTree *bvhtree[2];
bool cached[2];

View File

@@ -100,11 +100,11 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
nearest2d.nearest_point.index = -2;
}
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_VERTEX) {
if (sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE_ENDPOINT) {
float dist_px_sq_edge = nearest2d.nearest_point.dist_sq;
nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq;
if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) {
retval = SCE_SNAP_TO_POINT;
retval = SCE_SNAP_TO_EDGE_ENDPOINT;
}
else if (retval) {
nearest2d.nearest_point.dist_sq = dist_px_sq_edge;

View File

@@ -474,7 +474,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
} while ((l_iter = l_iter->next) != l_first);
}
else {
elem = SCE_SNAP_TO_VERTEX;
elem = SCE_SNAP_TO_EDGE_ENDPOINT;
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
do {
@@ -534,13 +534,17 @@ static eSnapMode snapEditMesh(SnapCache_EditMesh *em_cache,
if (treedata.tree == nullptr) {
if (sctx->callbacks.edit_mesh.test_vert_fn) {
auto test_looseverts_fn = [](BMElem *elem, void *user_data) {
SnapObjectContext *sctx_ = static_cast<SnapObjectContext *>(user_data);
BMVert *v = reinterpret_cast<BMVert *>(elem);
if (v->e) {
return false;
}
return sctx_->callbacks.edit_mesh.test_vert_fn(v, sctx_->callbacks.edit_mesh.user_data);
};
blender::BitVector<> verts_mask(em->bm->totvert);
const int verts_num_active = BM_iter_mesh_bitmap_from_filter(
BM_VERTS_OF_MESH,
em->bm,
verts_mask,
(bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
sctx->callbacks.edit_mesh.user_data);
BM_VERTS_OF_MESH, em->bm, verts_mask, test_looseverts_fn, sctx);
bvhtree_from_editmesh_verts_ex(&treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6);
}
@@ -548,7 +552,7 @@ static eSnapMode snapEditMesh(SnapCache_EditMesh *em_cache,
BKE_bvhtree_from_editmesh_get(&treedata,
em,
2,
BVHTREE_FROM_EM_VERTS,
BVHTREE_FROM_EM_LOOSEVERTS,
/* WORKAROUND: avoid updating while transforming. */
G.moving ? nullptr : &em_cache->mesh_runtime->bvh_cache,
&em_cache->mesh_runtime->eval_mutex);
@@ -558,7 +562,7 @@ static eSnapMode snapEditMesh(SnapCache_EditMesh *em_cache,
}
}
if (snap_to_flag & SCE_SNAP_TO_EDGE) {
if (snap_to_flag & SNAP_TO_EDGE_ELEMENTS) {
BVHTreeFromEditMesh treedata{};
treedata.tree = em_cache->bvhtree[1];