[Bf-blender-cvs] [ccfe2a2db15] functions: initial Closest Point on Object node

Jacques Lucke noreply at git.blender.org
Wed Nov 13 14:23:42 CET 2019


Commit: ccfe2a2db158e7af45bf65dba63916a178776070
Author: Jacques Lucke
Date:   Wed Nov 13 13:48:03 2019 +0100
Branches: functions
https://developer.blender.org/rBccfe2a2db158e7af45bf65dba63916a178776070

initial Closest Point on Object node

===================================================================

M	release/scripts/startup/nodes/function_nodes/object_mesh.py
M	source/blender/functions/FN_multi_function_common_contexts.h
M	source/blender/functions/intern/multi_functions/mixed.cc
M	source/blender/functions/intern/multi_functions/mixed.h
M	source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
M	source/blender/simulations/bparticles/particle_function.cpp

===================================================================

diff --git a/release/scripts/startup/nodes/function_nodes/object_mesh.py b/release/scripts/startup/nodes/function_nodes/object_mesh.py
index 5250e7ebbad..a42ac8f0a15 100644
--- a/release/scripts/startup/nodes/function_nodes/object_mesh.py
+++ b/release/scripts/startup/nodes/function_nodes/object_mesh.py
@@ -17,3 +17,13 @@ class VertexInfo(bpy.types.Node, FunctionNode):
 
     def declaration(self, builder):
         builder.fixed_output("position", "Position", "Vector")
+
+
+class ClosestPointOnObjectNode(bpy.types.Node, FunctionNode):
+    bl_idname = "fn_ClosestPointOnObjectNode"
+    bl_label = "Closest Point on Object"
+
+    def declaration(self, builder):
+        builder.fixed_input("object", "Object", "Object")
+        builder.fixed_input("position", "Position", "Vector")
+        builder.fixed_output("closest_point", "Closest Point", "Vector")
diff --git a/source/blender/functions/FN_multi_function_common_contexts.h b/source/blender/functions/FN_multi_function_common_contexts.h
index ed66ae64d36..4c6bec7c1a3 100644
--- a/source/blender/functions/FN_multi_function_common_contexts.h
+++ b/source/blender/functions/FN_multi_function_common_contexts.h
@@ -1,16 +1,26 @@
 #ifndef __FN_MULTI_FUNCTION_COMMON_CONTEXTS_H__
 #define __FN_MULTI_FUNCTION_COMMON_CONTEXTS_H__
 
+#include <mutex>
+
 #include "FN_multi_function_context.h"
 #include "FN_attributes_ref.h"
 
 #include "BLI_math_cxx.h"
+#include "BLI_map.h"
+#include "BLI_kdopbvh.h"
+#include "BLI_kdtree.h"
+
+#include "BKE_bvhutils.h"
 
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
 
 namespace FN {
 
+using BLI::Map;
+
 class VertexPositionArray : public MFElementContext {
  public:
   ArrayRef<BLI::float3> positions;
@@ -30,6 +40,41 @@ class ParticleAttributesContext : public MFElementContext {
   }
 };
 
+class ExternalObjectBVHTreesContext : public MFElementContext {
+ private:
+  mutable Map<Object *, BVHTreeFromMesh *> m_bvh_trees;
+  mutable std::mutex m_bvt_trees_mutex;
+
+ public:
+  ExternalObjectBVHTreesContext() = default;
+
+  ~ExternalObjectBVHTreesContext()
+  {
+    for (auto bvhtree : m_bvh_trees.values()) {
+      if (bvhtree != nullptr) {
+        free_bvhtree_from_mesh(bvhtree);
+        delete bvhtree;
+      }
+    }
+  }
+
+  BVHTreeFromMesh *get_bvh_tree(Object *object) const
+  {
+    BLI_assert(object != nullptr);
+
+    std::lock_guard<std::mutex> lock(m_bvt_trees_mutex);
+
+    return m_bvh_trees.lookup_or_add(object, [&]() -> BVHTreeFromMesh * {
+      if (object->type != OB_MESH) {
+        return nullptr;
+      }
+      BVHTreeFromMesh *bvhtree_data = new BVHTreeFromMesh();
+      BKE_bvhtree_from_mesh_get(bvhtree_data, (Mesh *)object->data, BVHTREE_FROM_LOOPTRI, 2);
+      return bvhtree_data;
+    });
+  }
+};
+
 }  // namespace FN
 
 #endif /* __FN_MULTI_FUNCTION_COMMON_CONTEXTS_H__ */
diff --git a/source/blender/functions/intern/multi_functions/mixed.cc b/source/blender/functions/intern/multi_functions/mixed.cc
index a6b27bb7253..97f745b7348 100644
--- a/source/blender/functions/intern/multi_functions/mixed.cc
+++ b/source/blender/functions/intern/multi_functions/mixed.cc
@@ -598,4 +598,56 @@ void MF_ParticleAttribute::call(MFMask mask, MFParams params, MFContext context)
   }
 }
 
+MF_ClosestPointOnObject::MF_ClosestPointOnObject()
+{
+  MFSignatureBuilder signature("Closest Point on Object");
+  signature.readonly_single_input<Object *>("Object");
+  signature.readonly_single_input<float3>("Position");
+  signature.single_output<float3>("Closest Point");
+  this->set_signature(signature);
+}
+
+void MF_ClosestPointOnObject::call(MFMask mask, MFParams params, MFContext context) const
+{
+  auto context_data = context.element_contexts().find_first<ExternalObjectBVHTreesContext>();
+
+  VirtualListRef<Object *> objects = params.readonly_single_input<Object *>(0, "Object");
+  VirtualListRef<float3> positions = params.readonly_single_input<float3>(1, "Position");
+  MutableArrayRef<float3> r_points = params.uninitialized_single_output<float3>(2,
+                                                                                "Closest Point");
+
+  if (!context_data.has_value()) {
+    r_points.fill_indices(mask.indices(), {0, 0, 0});
+    return;
+  }
+
+  for (uint i : mask.indices()) {
+    Object *object = objects[i];
+    if (object == nullptr) {
+      r_points[i] = {0, 0, 0};
+      continue;
+    }
+
+    BVHTreeFromMesh *bvhtree = context_data.value().data->get_bvh_tree(object);
+    if (bvhtree == nullptr) {
+      r_points[i] = {0, 0, 0};
+      continue;
+    }
+
+    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);
+
+    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);
+  }
+}
+
 }  // namespace FN
diff --git a/source/blender/functions/intern/multi_functions/mixed.h b/source/blender/functions/intern/multi_functions/mixed.h
index 48ac412edbd..3d58dcfdd55 100644
--- a/source/blender/functions/intern/multi_functions/mixed.h
+++ b/source/blender/functions/intern/multi_functions/mixed.h
@@ -187,6 +187,12 @@ class MF_ParticleAttribute final : public MultiFunction {
   void call(MFMask mask, MFParams params, MFContext context) const override;
 };
 
+class MF_ClosestPointOnObject final : public MultiFunction {
+ public:
+  MF_ClosestPointOnObject();
+  void call(MFMask mask, MFParams params, MFContext context) const override;
+};
+
 template<typename FromT, typename ToT, ToT (*Compute)(const FromT &)>
 class MF_Mappping final : public MultiFunction {
  public:
diff --git a/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc b/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
index 69552967358..e80c0ccd0b4 100644
--- a/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
+++ b/source/blender/functions/intern/vtree_multi_function_network/mappings_nodes.cc
@@ -489,6 +489,12 @@ static void INSERT_particle_info(VTreeMFNetworkBuilder &builder, const VNode &vn
   }
 }
 
+static void INSERT_closest_point_on_object(VTreeMFNetworkBuilder &builder, const VNode &vnode)
+{
+  const MultiFunction &fn = builder.construct_fn<MF_ClosestPointOnObject>();
+  builder.add_function(fn, {0, 1}, {2}, vnode);
+}
+
 void add_vtree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
 {
   mappings.vnode_inserters.add_new("fn_CombineColorNode", INSERT_combine_color);
@@ -508,6 +514,7 @@ void add_vtree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
   mappings.vnode_inserters.add_new("fn_CompareNode", INSERT_compare);
   mappings.vnode_inserters.add_new("fn_PerlinNoiseNode", INSERT_perlin_noise);
   mappings.vnode_inserters.add_new("fn_ParticleInfoNode", INSERT_particle_info);
+  mappings.vnode_inserters.add_new("fn_ClosestPointOnObjectNode", INSERT_closest_point_on_object);
 
   mappings.vnode_inserters.add_new("fn_AddFloatsNode", INSERT_add_floats);
   mappings.vnode_inserters.add_new("fn_MultiplyFloatsNode", INSERT_multiply_floats);
diff --git a/source/blender/simulations/bparticles/particle_function.cpp b/source/blender/simulations/bparticles/particle_function.cpp
index 70d9cc49479..3aa5187f44e 100644
--- a/source/blender/simulations/bparticles/particle_function.cpp
+++ b/source/blender/simulations/bparticles/particle_function.cpp
@@ -128,6 +128,8 @@ std::unique_ptr<ParticleFunctionResult> ParticleFunction::compute(ArrayRef<uint>
 
   FN::ParticleAttributesContext attributes_context(attributes);
   context_builder.add_element_context(attributes_context, IndexRange(array_size));
+  FN::ExternalObjectBVHTreesContext bvhtree_context;
+  context_builder.add_element_context(bvhtree_context);
 
   m_fn->call(pindices, params_builder, context_builder);



More information about the Bf-blender-cvs mailing list