[Bf-blender-cvs] [5c833190297] functions: new Find Non Close Points node

Jacques Lucke noreply at git.blender.org
Thu Dec 12 18:28:27 CET 2019


Commit: 5c833190297036fd7f86936614507b122fc952f4
Author: Jacques Lucke
Date:   Thu Dec 12 18:28:14 2019 +0100
Branches: functions
https://developer.blender.org/rB5c833190297036fd7f86936614507b122fc952f4

new Find Non Close Points node

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

M	release/scripts/startup/nodes/function_nodes/vector.py
M	source/blender/blenlib/BLI_math_cxx.h
M	source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
M	source/blender/functions/intern/multi_functions/lists.cc
M	source/blender/functions/intern/multi_functions/mixed.cc
M	source/blender/functions/intern/multi_functions/mixed.h

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

diff --git a/release/scripts/startup/nodes/function_nodes/vector.py b/release/scripts/startup/nodes/function_nodes/vector.py
index ced712a6b86..70ccc055964 100644
--- a/release/scripts/startup/nodes/function_nodes/vector.py
+++ b/release/scripts/startup/nodes/function_nodes/vector.py
@@ -48,3 +48,13 @@ class SeparateVectorNode(bpy.types.Node, FunctionNode):
         builder.vectorized_output(
             "z", ["use_list__vector"],
             "Z", "Z", "Float")
+
+
+class FindNonClosePointsNode(bpy.types.Node, FunctionNode):
+    bl_idname = "fn_FindNonClosePointsNode"
+    bl_label = "Find Non Close Point"
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_input("points", "Points", "Vector List")
+        builder.fixed_input("min_distance", "Min Distance", "Float", default=0.1)
+        builder.fixed_output("indices", "Indices", "Integer List")
diff --git a/source/blender/blenlib/BLI_math_cxx.h b/source/blender/blenlib/BLI_math_cxx.h
index 59f1ddd44ec..0c10a87665d 100644
--- a/source/blender/blenlib/BLI_math_cxx.h
+++ b/source/blender/blenlib/BLI_math_cxx.h
@@ -282,6 +282,11 @@ struct float3 {
     return (a - b).length();
   }
 
+  static float distance_squared(float3 a, float3 b)
+  {
+    return float3::dot(a, b);
+  }
+
   static float3 interpolate(float3 a, float3 b, float t)
   {
     return a * (1 - t) + b * t;
diff --git a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
index 9b4d609ec02..b715aafb1d0 100644
--- a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
+++ b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
@@ -493,6 +493,11 @@ static void INSERT_sample_object_surface(VNodeMFNetworkBuilder &builder)
   builder.set_constructed_matching_fn<MF_SampleObjectSurface>(value == 1);
 }
 
+static void INSERT_FindNonClosePointsNode(VNodeMFNetworkBuilder &builder)
+{
+  builder.set_constructed_matching_fn<MF_FindNonClosePoints>();
+}
+
 void add_inlined_tree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
 {
   mappings.xnode_inserters.add_new("fn_CombineColorNode", INSERT_combine_color);
@@ -528,6 +533,7 @@ void add_inlined_tree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
   mappings.xnode_inserters.add_new("fn_ValueNode", INSERT_value);
   mappings.xnode_inserters.add_new("fn_EmitterTimeInfoNode", INSERT_emitter_time_info);
   mappings.xnode_inserters.add_new("fn_SampleObjectSurfaceNode", INSERT_sample_object_surface);
+  mappings.xnode_inserters.add_new("fn_FindNonClosePointsNode", INSERT_FindNonClosePointsNode);
 
   mappings.xnode_inserters.add_new("fn_AddFloatsNode", INSERT_add_floats);
   mappings.xnode_inserters.add_new("fn_MultiplyFloatsNode", INSERT_multiply_floats);
diff --git a/source/blender/functions/intern/multi_functions/lists.cc b/source/blender/functions/intern/multi_functions/lists.cc
index 7d5072c6c05..715b66603e3 100644
--- a/source/blender/functions/intern/multi_functions/lists.cc
+++ b/source/blender/functions/intern/multi_functions/lists.cc
@@ -130,7 +130,7 @@ void MF_GetListElements::call(MFMask mask, MFParams params, MFContext UNUSED(con
     VirtualListRef<int> sub_indices = indices[i];
     GenericMutableArrayRef values = r_output_values.allocate_single(i, sub_indices.size());
     for (uint j = 0; j < sub_indices.size(); j++) {
-      uint index = sub_indices[j];
+      int index = sub_indices[j];
       if (index >= 0 && index < list.size()) {
         values.copy_in__uninitialized(j, list[index]);
       }
diff --git a/source/blender/functions/intern/multi_functions/mixed.cc b/source/blender/functions/intern/multi_functions/mixed.cc
index f1b845d9eb8..0ad55865541 100644
--- a/source/blender/functions/intern/multi_functions/mixed.cc
+++ b/source/blender/functions/intern/multi_functions/mixed.cc
@@ -10,6 +10,8 @@
 #include "BLI_array_cxx.h"
 #include "BLI_noise.h"
 #include "BLI_hash.h"
+#include "BLI_rand.h"
+#include "BLI_kdtree.h"
 
 #include "DNA_object_types.h"
 #include "DNA_mesh_types.h"
@@ -518,4 +520,80 @@ void MF_RandomFloat::call(MFMask mask, MFParams params, MFContext UNUSED(context
   }
 }
 
+MF_FindNonClosePoints::MF_FindNonClosePoints()
+{
+  MFSignatureBuilder signature("Remove Close Points");
+  signature.vector_input<float3>("Points");
+  signature.single_input<float>("Min Distance");
+  signature.vector_output<int>("Indices");
+  this->set_signature(signature);
+}
+
+static BLI_NOINLINE Vector<int> find_non_close_indices(VirtualListRef<float3> points,
+                                                       float min_distance)
+{
+  if (min_distance <= 0.0f) {
+    return IndexRange(points.size()).as_array_ref().cast<int>();
+  }
+
+  KDTree_3d *kdtree = BLI_kdtree_3d_new(points.size());
+  for (uint i : IndexRange(points.size())) {
+    BLI_kdtree_3d_insert(kdtree, i, points[i]);
+  }
+
+  BLI_kdtree_3d_balance(kdtree);
+
+  TemporaryArray<bool> keep_index(points.size());
+  keep_index.fill(true);
+
+  for (uint i : IndexRange(points.size())) {
+    if (!keep_index[i]) {
+      continue;
+    }
+
+    float3 current_point = points[i];
+
+    struct CBData {
+      MutableArrayRef<bool> keep_index_ref;
+      uint current_index;
+    } cb_data = {keep_index, i};
+
+    BLI_kdtree_3d_range_search_cb(
+        kdtree,
+        current_point,
+        min_distance,
+        [](void *user_data, int index, const float *UNUSED(co), float UNUSED(dist_sq)) -> bool {
+          CBData &cb_data = *(CBData *)user_data;
+          if (index != cb_data.current_index) {
+            cb_data.keep_index_ref[index] = false;
+          }
+          return true;
+        },
+        (void *)&cb_data);
+  }
+
+  BLI_kdtree_3d_free(kdtree);
+
+  Vector<int> indices;
+  for (uint i : keep_index.index_iterator()) {
+    if (keep_index[i]) {
+      indices.append(i);
+    }
+  }
+
+  return indices;
+}
+
+void MF_FindNonClosePoints::call(MFMask mask, MFParams params, MFContext UNUSED(context)) const
+{
+  VirtualListListRef<float3> points_list = params.readonly_vector_input<float3>(0, "Points");
+  VirtualListRef<float> min_distances = params.readonly_single_input<float>(1, "Min Distance");
+  GenericVectorArray::MutableTypedRef<int> indices_list = params.vector_output<int>(2, "Indices");
+
+  for (uint i : mask.indices()) {
+    Vector<int> filtered_indices = find_non_close_indices(points_list[i], min_distances[i]);
+    indices_list.extend_single(i, filtered_indices);
+  }
+}
+
 }  // namespace FN
diff --git a/source/blender/functions/intern/multi_functions/mixed.h b/source/blender/functions/intern/multi_functions/mixed.h
index f53c54d5632..864cbd70570 100644
--- a/source/blender/functions/intern/multi_functions/mixed.h
+++ b/source/blender/functions/intern/multi_functions/mixed.h
@@ -120,4 +120,10 @@ class MF_Clamp final : public MultiFunction {
   void call(MFMask mask, MFParams params, MFContext context) const override;
 };
 
+class MF_FindNonClosePoints final : public MultiFunction {
+ public:
+  MF_FindNonClosePoints();
+  void call(MFMask mask, MFParams params, MFContext context) const override;
+};
+
 }  // namespace FN



More information about the Bf-blender-cvs mailing list