[Bf-blender-cvs] [2d4f8209a79] functions: optimize Get Nearest Point when the object is the same for every element
Jacques Lucke
noreply at git.blender.org
Fri Nov 15 16:04:13 CET 2019
Commit: 2d4f8209a79777b77ffac4587970eeadb8e0ff00
Author: Jacques Lucke
Date: Fri Nov 15 16:03:54 2019 +0100
Branches: functions
https://developer.blender.org/rB2d4f8209a79777b77ffac4587970eeadb8e0ff00
optimize Get Nearest Point when the object is the same for every element
===================================================================
M source/blender/blenlib/BLI_virtual_list_ref.h
M source/blender/functions/intern/multi_functions/mixed.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_virtual_list_ref.h b/source/blender/blenlib/BLI_virtual_list_ref.h
index 582794ce8e9..0789425f612 100644
--- a/source/blender/blenlib/BLI_virtual_list_ref.h
+++ b/source/blender/blenlib/BLI_virtual_list_ref.h
@@ -102,6 +102,24 @@ template<typename T> class VirtualListRef {
return VirtualListRef::FromRepeatedArray(array.begin(), array.size(), virtual_size);
}
+ bool all_equal(ArrayRef<uint> indices) const
+ {
+ if (indices.size() == 0) {
+ return true;
+ }
+ if (m_category == Category::Single) {
+ return true;
+ }
+
+ const T &first_value = (*this)[indices.first()];
+ for (uint i : indices.drop_front(1)) {
+ if (first_value != (*this)[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
const T &operator[](uint index) const
{
BLI_assert(index < m_virtual_size);
diff --git a/source/blender/functions/intern/multi_functions/mixed.cc b/source/blender/functions/intern/multi_functions/mixed.cc
index d3568ccd536..a684d2a2d5e 100644
--- a/source/blender/functions/intern/multi_functions/mixed.cc
+++ b/source/blender/functions/intern/multi_functions/mixed.cc
@@ -607,6 +607,16 @@ MF_ClosestPointOnObject::MF_ClosestPointOnObject()
this->set_signature(signature);
}
+static BVHTreeNearest get_nearest_point(BVHTreeFromMesh *bvhtree_data, float3 point)
+{
+ BVHTreeNearest nearest = {0};
+ nearest.dist_sq = 10000000.0f;
+ nearest.index = -1;
+ BLI_bvhtree_find_nearest(
+ bvhtree_data->tree, point, &nearest, bvhtree_data->nearest_callback, (void *)bvhtree_data);
+ return nearest;
+}
+
void MF_ClosestPointOnObject::call(MFMask mask, MFParams params, MFContext context) const
{
auto context_data = context.element_contexts().find_first<ExternalDataCacheContext>();
@@ -621,32 +631,53 @@ void MF_ClosestPointOnObject::call(MFMask mask, MFParams params, MFContext conte
return;
}
- for (uint i : mask.indices()) {
- Object *object = objects[i];
+ if (mask.indices().size() > 0 && objects.all_equal(mask.indices())) {
+ Object *object = objects[mask.indices()[0]];
if (object == nullptr) {
- r_points[i] = {0, 0, 0};
- continue;
+ r_points.fill_indices(mask.indices(), {0, 0, 0});
+ return;
}
BVHTreeFromMesh *bvhtree = context_data.value().data->get_bvh_tree(object);
if (bvhtree == nullptr) {
- r_points[i] = {0, 0, 0};
- continue;
+ r_points.fill_indices(mask.indices(), {0, 0, 0});
+ return;
}
- BVHTreeNearest nearest = {0};
- nearest.dist_sq = 10000000.0f;
- nearest.index = -1;
- BLI_bvhtree_find_nearest(
- bvhtree->tree, positions[i], &nearest, bvhtree->nearest_callback, (void *)bvhtree);
+ float4x4 local_to_world_matrix = object->obmat;
+ for (uint i : mask.indices()) {
+ BVHTreeNearest nearest = get_nearest_point(bvhtree, positions[i]);
+ if (nearest.index == -1) {
+ r_points[i] = {0, 0, 0};
+ continue;
+ }
- if (nearest.index == -1) {
- r_points[i] = {0, 0, 0};
- continue;
+ r_points[i] = local_to_world_matrix.transform_position(nearest.co);
}
+ }
+ else {
+ for (uint i : mask.indices()) {
+ Object *object = objects[i];
+ if (object == nullptr) {
+ r_points[i] = {0, 0, 0};
+ continue;
+ }
- float4x4 local_to_world_matrix = object->obmat;
- r_points[i] = local_to_world_matrix.transform_position(nearest.co);
+ BVHTreeFromMesh *bvhtree = context_data.value().data->get_bvh_tree(object);
+ if (bvhtree == nullptr) {
+ r_points[i] = {0, 0, 0};
+ continue;
+ }
+
+ BVHTreeNearest nearest = get_nearest_point(bvhtree, positions[i]);
+ if (nearest.index == -1) {
+ r_points[i] = {0, 0, 0};
+ continue;
+ }
+
+ float4x4 local_to_world_matrix = object->obmat;
+ r_points[i] = local_to_world_matrix.transform_position(nearest.co);
+ }
}
}
More information about the Bf-blender-cvs
mailing list