Refactor: Mesh: Deduplicate and simplify BVH construction
Currently there are three entry points to building BVH trees for mesh ata: the caches on the mesh, an older set of functions used in the mesh remap code, and a new set of functions used in some geometry nodes sampling nodes. This commit unifies their implementations and switches some functions from bit spans to index masks for representing a selection of geometry.
This commit is contained in:
@@ -9,10 +9,10 @@
|
||||
* This header encapsulates necessary code to build a BVH.
|
||||
*/
|
||||
|
||||
#include "BLI_bit_span.hh"
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
#include "BLI_kdopbvh.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
struct BVHTree;
|
||||
@@ -64,46 +64,26 @@ enum BVHCacheType {
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds a BVH-tree where nodes are the given vertices (NOTE: does not copy given `vert`!).
|
||||
* \param vert_allocated: if true, vert freeing will be done when freeing data.
|
||||
* \param verts_mask: if not null, true elements give which vert to add to BVH-tree.
|
||||
* \param verts_num_active: if >= 0, number of active verts to add to BVH-tree
|
||||
* (else will be computed from `verts_mask`).
|
||||
* Builds a BVH-tree where nodes are the given vertices.
|
||||
*/
|
||||
BVHTreeFromMesh bvhtree_from_mesh_verts_ex(Span<float3> vert_positions,
|
||||
BitSpan verts_mask,
|
||||
int verts_num_active,
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis);
|
||||
const IndexMask &verts_mask);
|
||||
|
||||
/**
|
||||
* Builds a BVH-tree where nodes are the given edges.
|
||||
* \param vert, vert_allocated: if true, elem freeing will be done when freeing data.
|
||||
* \param edge, edge_allocated: if true, elem freeing will be done when freeing data.
|
||||
* \param edges_mask: if not null, true elements give which vert to add to BVH-tree.
|
||||
* \param edges_num_active: if >= 0, number of active edges to add to BVH-tree
|
||||
* (else will be computed from `edges_mask`).
|
||||
*/
|
||||
BVHTreeFromMesh bvhtree_from_mesh_edges_ex(Span<float3> vert_positions,
|
||||
Span<int2> edges,
|
||||
BitSpan edges_mask,
|
||||
int edges_num_active,
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis);
|
||||
const IndexMask &edges_mask);
|
||||
|
||||
/**
|
||||
* Builds a BVH-tree where nodes are the triangle faces (#Mesh::corner_tris()) of the given mesh.
|
||||
*/
|
||||
BVHTreeFromMesh bvhtree_from_mesh_corner_tris_ex(Span<float3> vert_positions,
|
||||
OffsetIndices<int> faces,
|
||||
Span<int> corner_verts,
|
||||
Span<int3> corner_tris,
|
||||
BitSpan corner_tris_mask,
|
||||
int corner_tris_num_active,
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis);
|
||||
const IndexMask &faces_mask);
|
||||
|
||||
/**
|
||||
* Build a bvh tree from the triangles in the mesh that correspond to the faces in the given mask.
|
||||
|
||||
@@ -19,19 +19,6 @@
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name BVHCache
|
||||
* \{ */
|
||||
|
||||
static void bvhtree_balance(BVHTree *tree)
|
||||
{
|
||||
if (tree) {
|
||||
BLI_bvhtree_balance(tree);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Local Callbacks
|
||||
* \{ */
|
||||
@@ -404,66 +391,32 @@ static BVHTreeFromMesh bvhtree_from_mesh_setup_data(BVHTree *tree,
|
||||
return data;
|
||||
}
|
||||
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> bvhtree_new_common(
|
||||
float epsilon, int tree_type, int axis, int elems_num, int &elems_num_active)
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> bvhtree_new_common(int elems_num)
|
||||
{
|
||||
if (elems_num_active != -1) {
|
||||
BLI_assert(IN_RANGE_INCL(elems_num_active, 0, elems_num));
|
||||
}
|
||||
else {
|
||||
elems_num_active = elems_num;
|
||||
}
|
||||
|
||||
if (elems_num_active == 0) {
|
||||
if (elems_num == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::unique_ptr<BVHTree, BVHTreeDeleter>(
|
||||
BLI_bvhtree_new(elems_num, epsilon, tree_type, axis));
|
||||
return std::unique_ptr<BVHTree, BVHTreeDeleter>(BLI_bvhtree_new(elems_num, 0.0f, 2, 6));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Vertex Builder
|
||||
* \{ */
|
||||
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> bvhtree_from_mesh_verts_create_tree(
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis,
|
||||
const Span<float3> positions,
|
||||
const BitSpan verts_mask,
|
||||
int verts_num_active)
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> create_tree_from_verts(
|
||||
const Span<float3> positions, const IndexMask &verts_mask)
|
||||
{
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(
|
||||
epsilon, tree_type, axis, positions.size(), verts_num_active);
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(verts_mask.size());
|
||||
if (!tree) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (const int i : positions.index_range()) {
|
||||
if (!verts_mask.is_empty() && !verts_mask[i]) {
|
||||
continue;
|
||||
}
|
||||
BLI_bvhtree_insert(tree.get(), i, positions[i], 1);
|
||||
}
|
||||
|
||||
verts_mask.foreach_index(
|
||||
[&](const int i) { BLI_bvhtree_insert(tree.get(), i, positions[i], 1); });
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
return tree;
|
||||
}
|
||||
|
||||
BVHTreeFromMesh bvhtree_from_mesh_verts_ex(const Span<float3> vert_positions,
|
||||
const BitSpan verts_mask,
|
||||
int verts_num_active,
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis)
|
||||
const IndexMask &verts_mask)
|
||||
{
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_from_mesh_verts_create_tree(
|
||||
epsilon, tree_type, axis, vert_positions, verts_mask, verts_num_active);
|
||||
|
||||
bvhtree_balance(tree.get());
|
||||
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = create_tree_from_verts(vert_positions,
|
||||
verts_mask);
|
||||
BVHTreeFromMesh data = bvhtree_from_mesh_setup_data(
|
||||
tree.get(), BVHTREE_FROM_VERTS, vert_positions, {}, {}, {}, {});
|
||||
data.owned_tree = std::move(tree);
|
||||
@@ -471,167 +424,117 @@ BVHTreeFromMesh bvhtree_from_mesh_verts_ex(const Span<float3> vert_positions,
|
||||
return data;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Edge Builder
|
||||
* \{ */
|
||||
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> bvhtree_from_mesh_edges_create_tree(
|
||||
const Span<float3> positions,
|
||||
const Span<int2> edges,
|
||||
const BitSpan edges_mask,
|
||||
int edges_num_active,
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis)
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> create_tree_from_edges(
|
||||
const Span<float3> positions, const Span<int2> edges, const IndexMask &edges_mask)
|
||||
{
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(
|
||||
epsilon, tree_type, axis, edges.size(), edges_num_active);
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(edges_mask.size());
|
||||
if (!tree) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (const int i : edges.index_range()) {
|
||||
if (!edges_mask.is_empty() && !edges_mask[i]) {
|
||||
continue;
|
||||
}
|
||||
edges_mask.foreach_index([&](const int edge_i) {
|
||||
const int2 &edge = edges[edge_i];
|
||||
float co[2][3];
|
||||
copy_v3_v3(co[0], positions[edges[i][0]]);
|
||||
copy_v3_v3(co[1], positions[edges[i][1]]);
|
||||
|
||||
BLI_bvhtree_insert(tree.get(), i, co[0], 2);
|
||||
}
|
||||
|
||||
copy_v3_v3(co[0], positions[edge[0]]);
|
||||
copy_v3_v3(co[1], positions[edge[1]]);
|
||||
BLI_bvhtree_insert(tree.get(), edge_i, co[0], 2);
|
||||
});
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
return tree;
|
||||
}
|
||||
|
||||
BVHTreeFromMesh bvhtree_from_mesh_edges_ex(const Span<float3> vert_positions,
|
||||
const Span<int2> edges,
|
||||
const BitSpan edges_mask,
|
||||
int edges_num_active,
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis)
|
||||
const IndexMask &edges_mask)
|
||||
{
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_from_mesh_edges_create_tree(
|
||||
vert_positions, edges, edges_mask, edges_num_active, epsilon, tree_type, axis);
|
||||
|
||||
bvhtree_balance(tree.get());
|
||||
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = create_tree_from_edges(
|
||||
vert_positions, edges, edges_mask);
|
||||
BVHTreeFromMesh data = bvhtree_from_mesh_setup_data(
|
||||
tree.get(), BVHTREE_FROM_EDGES, vert_positions, edges, {}, {}, {});
|
||||
data.owned_tree = std::move(tree);
|
||||
data.tree = data.owned_tree.get();
|
||||
return data;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Tessellated Face Builder
|
||||
* \{ */
|
||||
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> bvhtree_from_mesh_faces_create_tree(
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis,
|
||||
const Span<float3> positions,
|
||||
const MFace *face,
|
||||
const int faces_num,
|
||||
const BitSpan faces_mask,
|
||||
int faces_num_active)
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> create_tree_from_legacy_faces(
|
||||
const Span<float3> positions, const Span<MFace> faces)
|
||||
{
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(
|
||||
epsilon, tree_type, axis, faces_num, faces_num_active);
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(faces.size());
|
||||
if (!tree) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!positions.is_empty() && face) {
|
||||
for (int i = 0; i < faces_num; i++) {
|
||||
float co[4][3];
|
||||
if (!faces_mask.is_empty() && !faces_mask[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
copy_v3_v3(co[0], positions[face[i].v1]);
|
||||
copy_v3_v3(co[1], positions[face[i].v2]);
|
||||
copy_v3_v3(co[2], positions[face[i].v3]);
|
||||
if (face[i].v4) {
|
||||
copy_v3_v3(co[3], positions[face[i].v4]);
|
||||
}
|
||||
|
||||
BLI_bvhtree_insert(tree.get(), i, co[0], face[i].v4 ? 4 : 3);
|
||||
for (const int i : faces.index_range()) {
|
||||
float co[4][3];
|
||||
copy_v3_v3(co[0], positions[faces[i].v1]);
|
||||
copy_v3_v3(co[1], positions[faces[i].v2]);
|
||||
copy_v3_v3(co[2], positions[faces[i].v3]);
|
||||
if (faces[i].v4) {
|
||||
copy_v3_v3(co[3], positions[faces[i].v4]);
|
||||
}
|
||||
BLI_bvhtree_insert(tree.get(), i, co[0], faces[i].v4 ? 4 : 3);
|
||||
}
|
||||
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
return tree;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> create_tree_from_tris(const Span<float3> positions,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris)
|
||||
{
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(corner_tris.size());
|
||||
if (!tree) {
|
||||
return {};
|
||||
}
|
||||
for (const int tri : corner_tris.index_range()) {
|
||||
float co[3][3];
|
||||
copy_v3_v3(co[0], positions[corner_verts[corner_tris[tri][0]]]);
|
||||
copy_v3_v3(co[1], positions[corner_verts[corner_tris[tri][1]]]);
|
||||
copy_v3_v3(co[2], positions[corner_verts[corner_tris[tri][2]]]);
|
||||
BLI_bvhtree_insert(tree.get(), tri, co[0], 3);
|
||||
}
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
return tree;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name corner_tri Face Builder
|
||||
* \{ */
|
||||
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> bvhtree_from_mesh_corner_tris_create_tree(
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis,
|
||||
static std::unique_ptr<BVHTree, BVHTreeDeleter> create_tree_from_tris(
|
||||
const Span<float3> positions,
|
||||
const OffsetIndices<int> faces,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const BitSpan corner_tris_mask,
|
||||
int corner_tris_num_active)
|
||||
const IndexMask &faces_mask)
|
||||
{
|
||||
if (positions.is_empty()) {
|
||||
return nullptr;
|
||||
if (faces_mask.size() == faces.size()) {
|
||||
/* Avoid accessing face offsets if the selection is full. */
|
||||
return create_tree_from_tris(positions, corner_verts, corner_tris);
|
||||
}
|
||||
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(
|
||||
epsilon, tree_type, axis, corner_tris.size(), corner_tris_num_active);
|
||||
int tris_num = 0;
|
||||
faces_mask.foreach_index_optimized<int>(
|
||||
[&](const int i) { tris_num += mesh::face_triangles_num(faces[i].size()); });
|
||||
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(tris_num);
|
||||
if (!tree) {
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
for (const int i : corner_tris.index_range()) {
|
||||
float co[3][3];
|
||||
if (!corner_tris_mask.is_empty() && !corner_tris_mask[i]) {
|
||||
continue;
|
||||
faces_mask.foreach_index([&](const int face) {
|
||||
for (const int tri : mesh::face_triangles_range(faces, face)) {
|
||||
float co[3][3];
|
||||
copy_v3_v3(co[0], positions[corner_verts[corner_tris[tri][0]]]);
|
||||
copy_v3_v3(co[1], positions[corner_verts[corner_tris[tri][1]]]);
|
||||
copy_v3_v3(co[2], positions[corner_verts[corner_tris[tri][2]]]);
|
||||
BLI_bvhtree_insert(tree.get(), tri, co[0], 3);
|
||||
}
|
||||
|
||||
copy_v3_v3(co[0], positions[corner_verts[corner_tris[i][0]]]);
|
||||
copy_v3_v3(co[1], positions[corner_verts[corner_tris[i][1]]]);
|
||||
copy_v3_v3(co[2], positions[corner_verts[corner_tris[i][2]]]);
|
||||
|
||||
BLI_bvhtree_insert(tree.get(), i, co[0], 3);
|
||||
}
|
||||
|
||||
});
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
return tree;
|
||||
}
|
||||
|
||||
BVHTreeFromMesh bvhtree_from_mesh_corner_tris_ex(const Span<float3> vert_positions,
|
||||
const OffsetIndices<int> faces,
|
||||
const Span<int> corner_verts,
|
||||
const Span<int3> corner_tris,
|
||||
const BitSpan corner_tris_mask,
|
||||
int corner_tris_num_active,
|
||||
float epsilon,
|
||||
int tree_type,
|
||||
int axis)
|
||||
const IndexMask &faces_mask)
|
||||
{
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_from_mesh_corner_tris_create_tree(
|
||||
epsilon,
|
||||
tree_type,
|
||||
axis,
|
||||
vert_positions,
|
||||
corner_verts,
|
||||
corner_tris,
|
||||
corner_tris_mask,
|
||||
corner_tris_num_active);
|
||||
|
||||
bvhtree_balance(tree.get());
|
||||
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = create_tree_from_tris(
|
||||
vert_positions, faces, corner_verts, corner_tris, faces_mask);
|
||||
BVHTreeFromMesh data = bvhtree_from_mesh_setup_data(tree.get(),
|
||||
BVHTREE_FROM_CORNER_TRIS,
|
||||
vert_positions,
|
||||
@@ -640,11 +543,10 @@ BVHTreeFromMesh bvhtree_from_mesh_corner_tris_ex(const Span<float3> vert_positio
|
||||
corner_tris,
|
||||
nullptr);
|
||||
data.owned_tree = std::move(tree);
|
||||
data.tree = data.owned_tree.get();
|
||||
return data;
|
||||
}
|
||||
|
||||
static BitVector<> loose_verts_no_hidden_mask_get(const Mesh &mesh, int *r_elem_active_len)
|
||||
static BitVector<> loose_verts_no_hidden_mask_get(const Mesh &mesh)
|
||||
{
|
||||
int count = mesh.verts_num;
|
||||
BitVector<> verts_mask(count, true);
|
||||
@@ -672,17 +574,14 @@ static BitVector<> loose_verts_no_hidden_mask_get(const Mesh &mesh, int *r_elem_
|
||||
for (const int vert : verts_mask.index_range()) {
|
||||
if (verts_mask[vert] && hide_vert[vert]) {
|
||||
verts_mask[vert].reset();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*r_elem_active_len = count;
|
||||
|
||||
return verts_mask;
|
||||
}
|
||||
|
||||
static BitVector<> loose_edges_no_hidden_mask_get(const Mesh &mesh, int *r_elem_active_len)
|
||||
static BitVector<> loose_edges_no_hidden_mask_get(const Mesh &mesh)
|
||||
{
|
||||
int count = mesh.edges_num;
|
||||
BitVector<> edge_mask(count, true);
|
||||
@@ -711,48 +610,13 @@ static BitVector<> loose_edges_no_hidden_mask_get(const Mesh &mesh, int *r_elem_
|
||||
for (const int edge : edge_mask.index_range()) {
|
||||
if (edge_mask[edge] && hide_edge[edge]) {
|
||||
edge_mask[edge].reset();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*r_elem_active_len = count;
|
||||
|
||||
return edge_mask;
|
||||
}
|
||||
|
||||
static BitVector<> corner_tris_no_hidden_map_get(const OffsetIndices<int> faces,
|
||||
const VArray<bool> &hide_poly,
|
||||
const int corner_tris_len,
|
||||
int *r_corner_tris_active_len)
|
||||
{
|
||||
if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
|
||||
return {};
|
||||
}
|
||||
BitVector<> corner_tris_mask(corner_tris_len);
|
||||
|
||||
int corner_tris_no_hidden_len = 0;
|
||||
int tri_index = 0;
|
||||
for (const int64_t i : faces.index_range()) {
|
||||
const int triangles_num = mesh::face_triangles_num(faces[i].size());
|
||||
if (hide_poly[i]) {
|
||||
tri_index += triangles_num;
|
||||
}
|
||||
else {
|
||||
for (const int i : IndexRange(triangles_num)) {
|
||||
UNUSED_VARS(i);
|
||||
corner_tris_mask[tri_index].set();
|
||||
tri_index++;
|
||||
corner_tris_no_hidden_len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*r_corner_tris_active_len = corner_tris_no_hidden_len;
|
||||
|
||||
return corner_tris_mask;
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
blender::bke::BVHTreeFromMesh Mesh::bvh_loose_verts() const
|
||||
@@ -762,11 +626,9 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_loose_verts() const
|
||||
const Span<float3> positions = this->vert_positions();
|
||||
this->runtime->bvh_cache_loose_verts.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
const LooseVertCache &loose_verts = this->loose_verts();
|
||||
data = bvhtree_from_mesh_verts_create_tree(
|
||||
0.0f, 2, 6, positions, loose_verts.is_loose_bits, loose_verts.count);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask mask = IndexMask::from_bits(loose_verts.is_loose_bits, memory);
|
||||
data = create_tree_from_verts(positions, mask);
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree =
|
||||
this->runtime->bvh_cache_loose_verts.data();
|
||||
@@ -781,12 +643,9 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_loose_no_hidden_verts() const
|
||||
const Span<float3> positions = this->vert_positions();
|
||||
this->runtime->bvh_cache_loose_verts_no_hidden.ensure(
|
||||
[&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
int mask_bits_act_len = -1;
|
||||
const BitVector<> mask = loose_verts_no_hidden_mask_get(*this, &mask_bits_act_len);
|
||||
data = bvhtree_from_mesh_verts_create_tree(0.0f, 2, 6, positions, {}, -1);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
const BitVector<> mask = loose_verts_no_hidden_mask_get(*this);
|
||||
IndexMaskMemory memory;
|
||||
data = create_tree_from_verts(positions, IndexMask::from_bits(mask, memory));
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree =
|
||||
this->runtime->bvh_cache_loose_verts_no_hidden.data();
|
||||
@@ -800,10 +659,7 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_verts() const
|
||||
using namespace blender::bke;
|
||||
const Span<float3> positions = this->vert_positions();
|
||||
this->runtime->bvh_cache_verts.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
data = bvhtree_from_mesh_verts_create_tree(0.0f, 2, 6, positions, {}, -1);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
data = create_tree_from_verts(positions, positions.index_range());
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree = this->runtime->bvh_cache_verts.data();
|
||||
return bvhtree_from_mesh_setup_data(
|
||||
@@ -818,11 +674,9 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_loose_edges() const
|
||||
const Span<int2> edges = this->edges();
|
||||
this->runtime->bvh_cache_loose_edges.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
const LooseEdgeCache &loose_edges = this->loose_edges();
|
||||
data = bvhtree_from_mesh_edges_create_tree(
|
||||
positions, edges, loose_edges.is_loose_bits, loose_edges.count, 0.0f, 2, 6);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask mask = IndexMask::from_bits(loose_edges.is_loose_bits, memory);
|
||||
data = create_tree_from_edges(positions, edges, mask);
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree =
|
||||
this->runtime->bvh_cache_loose_edges.data();
|
||||
@@ -839,13 +693,9 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_loose_no_hidden_edges() const
|
||||
const Span<int2> edges = this->edges();
|
||||
this->runtime->bvh_cache_loose_edges_no_hidden.ensure(
|
||||
[&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
int mask_bits_act_len = -1;
|
||||
const BitVector<> mask = loose_edges_no_hidden_mask_get(*this, &mask_bits_act_len);
|
||||
data = bvhtree_from_mesh_edges_create_tree(
|
||||
positions, edges, mask, mask_bits_act_len, 0.0f, 2, 6);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
const BitVector<> mask = loose_edges_no_hidden_mask_get(*this);
|
||||
IndexMaskMemory memory;
|
||||
data = create_tree_from_edges(positions, edges, IndexMask::from_bits(mask, memory));
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree =
|
||||
this->runtime->bvh_cache_loose_edges_no_hidden.data();
|
||||
@@ -860,10 +710,7 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_edges() const
|
||||
const Span<float3> positions = this->vert_positions();
|
||||
const Span<int2> edges = this->edges();
|
||||
this->runtime->bvh_cache_edges.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
data = bvhtree_from_mesh_edges_create_tree(positions, edges, {}, -1, 0.0f, 2, 6);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
data = create_tree_from_edges(positions, edges, edges.index_range());
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree = this->runtime->bvh_cache_edges.data();
|
||||
return bvhtree_from_mesh_setup_data(
|
||||
@@ -877,18 +724,10 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_legacy_faces() const
|
||||
BLI_assert(!(this->totface_legacy == 0 && this->faces_num != 0));
|
||||
const Span<float3> positions = this->vert_positions();
|
||||
this->runtime->bvh_cache_faces.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
data = bvhtree_from_mesh_faces_create_tree(
|
||||
0.0f,
|
||||
2,
|
||||
6,
|
||||
data = create_tree_from_legacy_faces(
|
||||
positions,
|
||||
(const MFace *)CustomData_get_layer(&this->fdata_legacy, CD_MFACE),
|
||||
this->totface_legacy,
|
||||
{},
|
||||
-1);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
{static_cast<const MFace *>(CustomData_get_layer(&this->fdata_legacy, CD_MFACE)),
|
||||
this->totface_legacy});
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree = this->runtime->bvh_cache_faces.data();
|
||||
return bvhtree_from_mesh_setup_data(
|
||||
@@ -902,19 +741,17 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_corner_tris_no_hidden() const
|
||||
const Span<float3> positions = this->vert_positions();
|
||||
const Span<int> corner_verts = this->corner_verts();
|
||||
const Span<int3> corner_tris = this->corner_tris();
|
||||
const AttributeAccessor attributes = this->attributes();
|
||||
const VArray hide_poly = *attributes.lookup<bool>(".hide_poly", AttrDomain::Face);
|
||||
if (!hide_poly) {
|
||||
return this->bvh_corner_tris();
|
||||
}
|
||||
this->runtime->bvh_cache_verts.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
AttributeAccessor attributes = this->attributes();
|
||||
int mask_bits_act_len = -1;
|
||||
const BitVector<> mask = corner_tris_no_hidden_map_get(
|
||||
this->faces(),
|
||||
*attributes.lookup_or_default(".hide_poly", AttrDomain::Face, false),
|
||||
corner_tris.size(),
|
||||
&mask_bits_act_len);
|
||||
data = bvhtree_from_mesh_corner_tris_create_tree(
|
||||
0.0f, 2, 6, positions, corner_verts, corner_tris, mask, mask_bits_act_len);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
const OffsetIndices<int> faces = this->faces();
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask visible_faces = IndexMask::from_bools_inverse(
|
||||
faces.index_range(), VArraySpan(hide_poly), memory);
|
||||
data = create_tree_from_tris(positions, faces, corner_verts, corner_tris, visible_faces);
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree = this->runtime->bvh_cache_verts.data();
|
||||
return bvhtree_from_mesh_setup_data(tree.get(),
|
||||
@@ -934,11 +771,7 @@ blender::bke::BVHTreeFromMesh Mesh::bvh_corner_tris() const
|
||||
const Span<int> corner_verts = this->corner_verts();
|
||||
const Span<int3> corner_tris = this->corner_tris();
|
||||
this->runtime->bvh_cache_corner_tris.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
data = bvhtree_from_mesh_corner_tris_create_tree(
|
||||
0.0f, 2, 6, positions, corner_verts, corner_tris, {}, -1);
|
||||
if (data.get()) {
|
||||
BLI_bvhtree_balance(data.get());
|
||||
}
|
||||
data = create_tree_from_tris(positions, corner_verts, corner_tris);
|
||||
});
|
||||
const std::unique_ptr<BVHTree, BVHTreeDeleter> &tree =
|
||||
this->runtime->bvh_cache_corner_tris.data();
|
||||
@@ -953,42 +786,8 @@ BVHTreeFromMesh bvhtree_from_mesh_tris_init(const Mesh &mesh, const IndexMask &f
|
||||
if (faces_mask.size() == mesh.faces_num) {
|
||||
return mesh.bvh_corner_tris();
|
||||
}
|
||||
|
||||
const Span<float3> positions = mesh.vert_positions();
|
||||
const Span<int2> edges = mesh.edges();
|
||||
const Span<int> corner_verts = mesh.corner_verts();
|
||||
const OffsetIndices faces = mesh.faces();
|
||||
const Span<int3> corner_tris = mesh.corner_tris();
|
||||
BVHTreeFromMesh data = bvhtree_from_mesh_setup_data(
|
||||
nullptr, BVHTREE_FROM_CORNER_TRIS, positions, edges, corner_verts, corner_tris, nullptr);
|
||||
|
||||
int tris_num = 0;
|
||||
faces_mask.foreach_index(
|
||||
[&](const int i) { tris_num += mesh::face_triangles_num(faces[i].size()); });
|
||||
|
||||
int active_num = -1;
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(
|
||||
0.0f, 2, 6, tris_num, active_num);
|
||||
if (tree == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
faces_mask.foreach_index([&](const int face_i) {
|
||||
const IndexRange triangles_range = mesh::face_triangles_range(faces, face_i);
|
||||
for (const int tri_i : triangles_range) {
|
||||
float co[3][3];
|
||||
copy_v3_v3(co[0], positions[corner_verts[corner_tris[tri_i][0]]]);
|
||||
copy_v3_v3(co[1], positions[corner_verts[corner_tris[tri_i][1]]]);
|
||||
copy_v3_v3(co[2], positions[corner_verts[corner_tris[tri_i][2]]]);
|
||||
|
||||
BLI_bvhtree_insert(tree.get(), tri_i, co[0], 3);
|
||||
}
|
||||
});
|
||||
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
data.owned_tree = std::move(tree);
|
||||
data.tree = data.owned_tree.get();
|
||||
return data;
|
||||
return bvhtree_from_mesh_corner_tris_ex(
|
||||
mesh.vert_positions(), mesh.faces(), mesh.corner_verts(), mesh.corner_tris(), faces_mask);
|
||||
}
|
||||
|
||||
BVHTreeFromMesh bvhtree_from_mesh_edges_init(const Mesh &mesh, const IndexMask &edges_mask)
|
||||
@@ -996,31 +795,7 @@ BVHTreeFromMesh bvhtree_from_mesh_edges_init(const Mesh &mesh, const IndexMask &
|
||||
if (edges_mask.size() == mesh.edges_num) {
|
||||
return mesh.bvh_edges();
|
||||
}
|
||||
|
||||
const Span<float3> positions = mesh.vert_positions();
|
||||
const Span<int2> edges = mesh.edges();
|
||||
BVHTreeFromMesh data = bvhtree_from_mesh_setup_data(
|
||||
nullptr, BVHTREE_FROM_EDGES, positions, edges, {}, {}, nullptr);
|
||||
|
||||
int active_num = -1;
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(
|
||||
0.0f, 2, 6, edges_mask.size(), active_num);
|
||||
if (tree == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
edges_mask.foreach_index([&](const int edge_i) {
|
||||
const int2 &edge = edges[edge_i];
|
||||
float co[2][3];
|
||||
copy_v3_v3(co[0], positions[edge[0]]);
|
||||
copy_v3_v3(co[1], positions[edge[1]]);
|
||||
BLI_bvhtree_insert(tree.get(), edge_i, co[0], 2);
|
||||
});
|
||||
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
data.owned_tree = std::move(tree);
|
||||
data.tree = data.owned_tree.get();
|
||||
return data;
|
||||
return bvhtree_from_mesh_edges_ex(mesh.vert_positions(), mesh.edges(), edges_mask);
|
||||
}
|
||||
|
||||
BVHTreeFromMesh bvhtree_from_mesh_verts_init(const Mesh &mesh, const IndexMask &verts_mask)
|
||||
@@ -1028,27 +803,7 @@ BVHTreeFromMesh bvhtree_from_mesh_verts_init(const Mesh &mesh, const IndexMask &
|
||||
if (verts_mask.size() == mesh.verts_num) {
|
||||
return mesh.bvh_verts();
|
||||
}
|
||||
|
||||
const Span<float3> positions = mesh.vert_positions();
|
||||
BVHTreeFromMesh data = bvhtree_from_mesh_setup_data(
|
||||
nullptr, BVHTREE_FROM_VERTS, positions, {}, {}, {}, nullptr);
|
||||
|
||||
int active_num = -1;
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = bvhtree_new_common(
|
||||
0.0f, 2, 6, verts_mask.size(), active_num);
|
||||
if (tree == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
verts_mask.foreach_index([&](const int vert_i) {
|
||||
const float3 &position = positions[vert_i];
|
||||
BLI_bvhtree_insert(tree.get(), vert_i, position, 1);
|
||||
});
|
||||
|
||||
BLI_bvhtree_balance(tree.get());
|
||||
data.owned_tree = std::move(tree);
|
||||
data.tree = data.owned_tree.get();
|
||||
return data;
|
||||
return bvhtree_from_mesh_verts_ex(mesh.vert_positions(), verts_mask);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -1060,17 +815,11 @@ BVHTreeFromMesh bvhtree_from_mesh_verts_init(const Mesh &mesh, const IndexMask &
|
||||
BVHTreeFromPointCloud bvhtree_from_pointcloud_get(const PointCloud &pointcloud,
|
||||
const IndexMask &points_mask)
|
||||
{
|
||||
int active_num = -1;
|
||||
BVHTree *tree = bvhtree_new_common(0.0f, 2, 6, points_mask.size(), active_num).release();
|
||||
const Span<float3> positions = pointcloud.positions();
|
||||
BVHTree *tree = create_tree_from_verts(positions, points_mask).release();
|
||||
if (!tree) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const Span<float3> positions = pointcloud.positions();
|
||||
points_mask.foreach_index([&](const int i) { BLI_bvhtree_insert(tree, i, positions[i], 1); });
|
||||
|
||||
BLI_bvhtree_balance(tree);
|
||||
|
||||
BVHTreeFromPointCloud data{};
|
||||
data.tree = tree;
|
||||
data.nearest_callback = nullptr;
|
||||
|
||||
@@ -1414,18 +1414,17 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
||||
|
||||
for (tindex = 0; tindex < num_trees; tindex++) {
|
||||
MeshElemMap *isld = island_store.islands[tindex];
|
||||
int num_verts_active = 0;
|
||||
verts_active.fill(false);
|
||||
for (int i = 0; i < isld->count; i++) {
|
||||
for (const int vidx_src : corner_verts_src.slice(faces_src[isld->indices[i]])) {
|
||||
if (!verts_active[vidx_src]) {
|
||||
verts_active[vidx_src].set();
|
||||
num_verts_active++;
|
||||
}
|
||||
}
|
||||
}
|
||||
IndexMaskMemory memory;
|
||||
treedata[tindex] = blender::bke::bvhtree_from_mesh_verts_ex(
|
||||
positions_src, verts_active, num_verts_active, 0.0, 2, 6);
|
||||
positions_src, IndexMask::from_bits(verts_active, memory));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1437,26 +1436,23 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
||||
if (use_islands) {
|
||||
corner_tris_src = me_src->corner_tris();
|
||||
tri_faces_src = me_src->corner_tri_faces();
|
||||
blender::BitVector<> corner_tris_active(corner_tris_src.size());
|
||||
blender::BitVector<> faces_active(corner_tris_src.size());
|
||||
|
||||
for (tindex = 0; tindex < num_trees; tindex++) {
|
||||
int corner_tris_num_active = 0;
|
||||
corner_tris_active.fill(false);
|
||||
for (const int64_t i : corner_tris_src.index_range()) {
|
||||
const blender::IndexRange face = faces_src[tri_faces_src[i]];
|
||||
faces_active.fill(false);
|
||||
for (const int64_t i : faces_src.index_range()) {
|
||||
const blender::IndexRange face = faces_src[i];
|
||||
if (island_store.items_to_islands[face.start()] == tindex) {
|
||||
corner_tris_active[i].set();
|
||||
corner_tris_num_active++;
|
||||
faces_active[i].set();
|
||||
}
|
||||
}
|
||||
treedata[tindex] = blender::bke::bvhtree_from_mesh_corner_tris_ex(positions_src,
|
||||
corner_verts_src,
|
||||
corner_tris_src,
|
||||
corner_tris_active,
|
||||
corner_tris_num_active,
|
||||
0.0,
|
||||
2,
|
||||
6);
|
||||
IndexMaskMemory memory;
|
||||
treedata[tindex] = blender::bke::bvhtree_from_mesh_corner_tris_ex(
|
||||
positions_src,
|
||||
faces_src,
|
||||
corner_verts_src,
|
||||
corner_tris_src,
|
||||
IndexMask::from_bits(faces_active, memory));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user