Point Cloud: Add cached full points BVH tree
Instead of rebuilding the BVH tree every time it's requested.
This commit is contained in:
@@ -93,11 +93,13 @@ float bvhtree_sphereray_tri_intersection(const BVHTreeRay *ray,
|
||||
const float v2[3]);
|
||||
|
||||
struct BVHTreeFromPointCloud {
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree;
|
||||
const BVHTree *tree = nullptr;
|
||||
|
||||
BVHTree_NearestPointCallback nearest_callback;
|
||||
|
||||
const float (*coords)[3];
|
||||
Span<float3> positions;
|
||||
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> owned_tree;
|
||||
};
|
||||
|
||||
BVHTreeFromPointCloud bvhtree_from_pointcloud_get(const PointCloud &pointcloud,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "BLI_bounds_types.hh"
|
||||
#include "BLI_kdopbvh.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_shared_cache.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
@@ -42,6 +43,8 @@ struct PointCloudRuntime {
|
||||
/** Stores weak references to material data blocks. */
|
||||
std::unique_ptr<bake::BakeMaterialsList> bake_materials;
|
||||
|
||||
SharedCache<std::unique_ptr<BVHTree, BVHTreeDeleter>> bvh_cache;
|
||||
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("PointCloudRuntime");
|
||||
};
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "BKE_bvhutils.hh"
|
||||
#include "BKE_editmesh.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_pointcloud.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
@@ -811,21 +812,54 @@ BVHTreeFromMesh bvhtree_from_mesh_verts_init(const Mesh &mesh, const IndexMask &
|
||||
/** \name Point Cloud BVH Building
|
||||
* \{ */
|
||||
|
||||
BVHTreeFromPointCloud bvhtree_from_pointcloud_get(const PointCloud &pointcloud,
|
||||
const IndexMask &points_mask)
|
||||
static BVHTreeFromPointCloud create_points_tree_data(const BVHTree *tree,
|
||||
const Span<float3> positions)
|
||||
{
|
||||
const Span<float3> positions = pointcloud.positions();
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree = create_tree_from_verts(positions, points_mask);
|
||||
if (!tree) {
|
||||
return {};
|
||||
}
|
||||
BVHTreeFromPointCloud data{};
|
||||
data.tree = std::move(tree);
|
||||
data.tree = tree;
|
||||
data.positions = positions;
|
||||
data.nearest_callback = nullptr;
|
||||
data.coords = (const float(*)[3])positions.data();
|
||||
return data;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
static BVHTreeFromPointCloud create_point_cloud_tree_data(const BVHTree *tree,
|
||||
const Span<float3> positions)
|
||||
{
|
||||
BVHTreeFromPointCloud data{};
|
||||
data.tree = tree;
|
||||
data.positions = positions;
|
||||
return data;
|
||||
}
|
||||
|
||||
static BVHTreeFromPointCloud create_point_cloud_tree_data(
|
||||
std::unique_ptr<BVHTree, BVHTreeDeleter> tree, const Span<float3> positions)
|
||||
{
|
||||
BVHTreeFromPointCloud data = create_points_tree_data(tree.get(), positions);
|
||||
data.owned_tree = std::move(tree);
|
||||
return data;
|
||||
}
|
||||
|
||||
BVHTreeFromPointCloud bvhtree_from_pointcloud_get(const PointCloud &pointcloud,
|
||||
const IndexMask &points_mask)
|
||||
{
|
||||
if (points_mask.size() == pointcloud.totpoint) {
|
||||
return pointcloud.bvh_tree();
|
||||
}
|
||||
const Span<float3> positions = pointcloud.positions();
|
||||
return create_point_cloud_tree_data(create_tree_from_verts(positions, points_mask), positions);
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
blender::bke::BVHTreeFromPointCloud PointCloud::bvh_tree() const
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const Span<float3> positions = this->positions();
|
||||
this->runtime->bvh_cache.ensure([&](std::unique_ptr<BVHTree, BVHTreeDeleter> &data) {
|
||||
data = create_tree_from_verts(positions, positions.index_range());
|
||||
});
|
||||
return create_point_cloud_tree_data(this->runtime->bvh_cache.data().get(), positions);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -85,6 +85,7 @@ static void pointcloud_copy_data(Main * /*bmain*/,
|
||||
|
||||
pointcloud_dst->runtime = new blender::bke::PointCloudRuntime();
|
||||
pointcloud_dst->runtime->bounds_cache = pointcloud_src->runtime->bounds_cache;
|
||||
pointcloud_dst->runtime->bvh_cache = pointcloud_src->runtime->bvh_cache;
|
||||
if (pointcloud_src->runtime->bake_materials) {
|
||||
pointcloud_dst->runtime->bake_materials =
|
||||
std::make_unique<blender::bke::bake::BakeMaterialsList>(
|
||||
@@ -457,6 +458,7 @@ void BKE_pointcloud_data_update(Depsgraph *depsgraph, Scene *scene, Object *obje
|
||||
void PointCloud::tag_positions_changed()
|
||||
{
|
||||
this->runtime->bounds_cache.tag_dirty();
|
||||
this->runtime->bvh_cache.tag_dirty();
|
||||
}
|
||||
|
||||
void PointCloud::tag_radii_changed()
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace blender {
|
||||
template<typename T> class Span;
|
||||
namespace bke {
|
||||
class AttributeAccessor;
|
||||
struct BVHTreeFromPointCloud;
|
||||
class MutableAttributeAccessor;
|
||||
struct PointCloudRuntime;
|
||||
} // namespace bke
|
||||
@@ -73,6 +74,8 @@ typedef struct PointCloud {
|
||||
/** Get the largest material index used by the point-cloud or `nullopt` if it is empty. */
|
||||
std::optional<int> material_index_max() const;
|
||||
|
||||
blender::bke::BVHTreeFromPointCloud bvh_tree() const;
|
||||
|
||||
void count_memory(blender::MemoryCounter &memory) const;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ class ProximityFunction : public mf::MultiFunction {
|
||||
const_cast<bke::BVHTreeFromMesh *>(&trees.mesh_bvh));
|
||||
}
|
||||
if (trees.pointcloud_bvh.tree != nullptr) {
|
||||
BLI_bvhtree_find_nearest(trees.pointcloud_bvh.tree.get(),
|
||||
BLI_bvhtree_find_nearest(trees.pointcloud_bvh.tree,
|
||||
sample_position,
|
||||
&nearest,
|
||||
trees.pointcloud_bvh.nearest_callback,
|
||||
|
||||
@@ -91,7 +91,7 @@ static void get_closest_pointcloud_points(const bke::BVHTreeFromPointCloud &tree
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = FLT_MAX;
|
||||
const float3 position = positions[i];
|
||||
BLI_bvhtree_find_nearest(tree_data.tree.get(),
|
||||
BLI_bvhtree_find_nearest(tree_data.tree,
|
||||
position,
|
||||
&nearest,
|
||||
tree_data.nearest_callback,
|
||||
|
||||
Reference in New Issue
Block a user