[Bf-blender-cvs] [a2b128a4513] functions: experimental Close By Points event

Jacques Lucke noreply at git.blender.org
Wed Jul 17 18:03:09 CEST 2019


Commit: a2b128a4513067c08dbd6ef7b94ba474b8fd7fca
Author: Jacques Lucke
Date:   Wed Jul 17 16:46:13 2019 +0200
Branches: functions
https://developer.blender.org/rBa2b128a4513067c08dbd6ef7b94ba474b8fd7fca

experimental Close By Points event

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

A	release/scripts/startup/nodes/bparticle_nodes/close_by_points.py
M	source/blender/simulations/bparticles/events.cpp
M	source/blender/simulations/bparticles/events.hpp
M	source/blender/simulations/bparticles/inserters.cpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/close_by_points.py b/release/scripts/startup/nodes/bparticle_nodes/close_by_points.py
new file mode 100644
index 00000000000..9b499566730
--- /dev/null
+++ b/release/scripts/startup/nodes/bparticle_nodes/close_by_points.py
@@ -0,0 +1,14 @@
+import bpy
+from bpy.props import *
+from .. base import BParticlesNode
+from .. socket_builder import SocketBuilder
+
+class CloseByPointsEventNode(bpy.types.Node, BParticlesNode):
+    bl_idname = "bp_CloseByPointsEventNode"
+    bl_label = "Close By Points Event"
+
+    def declaration(self, builder : SocketBuilder):
+        builder.event_input("event", "Event")
+        builder.fixed_input("points", "Points", "Vector List")
+        builder.fixed_input("distance", "Distance", "Float", default=1)
+        builder.control_flow_output("on_event", "On Event")
diff --git a/source/blender/simulations/bparticles/events.cpp b/source/blender/simulations/bparticles/events.cpp
index 4993ad158e5..3613aa8fd08 100644
--- a/source/blender/simulations/bparticles/events.cpp
+++ b/source/blender/simulations/bparticles/events.cpp
@@ -129,4 +129,24 @@ void MeshCollisionEvent::execute(EventExecuteInterface &interface)
   ActionInterface::RunFromEvent(m_action, interface, &event_info);
 }
 
+void CloseByPointsEvent::filter(EventFilterInterface &interface)
+{
+  ParticleSet &particles = interface.particles();
+  auto positions = particles.attributes().get_float3("Position");
+
+  for (uint pindex : particles.pindices()) {
+    KDTreeNearest_3d nearest;
+    if (BLI_kdtree_3d_find_nearest(m_kdtree, positions[pindex], &nearest) != -1) {
+      if (float3::distance(positions[pindex], nearest.co) < m_distance) {
+        interface.trigger_particle(pindex, 0.5f);
+      }
+    }
+  }
+}
+
+void CloseByPointsEvent::execute(EventExecuteInterface &interface)
+{
+  ActionInterface::RunFromEvent(m_action, interface);
+}
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/events.hpp b/source/blender/simulations/bparticles/events.hpp
index 52121c54bb2..831b8110f7f 100644
--- a/source/blender/simulations/bparticles/events.hpp
+++ b/source/blender/simulations/bparticles/events.hpp
@@ -6,6 +6,7 @@
 #include "BKE_bvhutils.h"
 
 #include "BLI_kdopbvh.h"
+#include "BLI_kdtree.h"
 
 #include "DNA_object_types.h"
 
@@ -98,4 +99,32 @@ class MeshCollisionEvent : public Event {
   RayCastResult ray_cast(float3 start, float3 normalized_direction, float max_distance);
 };
 
+class CloseByPointsEvent : public Event {
+ private:
+  std::string m_identifier;
+  KDTree_3d *m_kdtree;
+  float m_distance;
+  std::unique_ptr<Action> m_action;
+
+ public:
+  CloseByPointsEvent(StringRef identifier,
+                     KDTree_3d *kdtree,
+                     float distance,
+                     std::unique_ptr<Action> action)
+      : m_identifier(identifier.to_std_string()),
+        m_kdtree(kdtree),
+        m_distance(distance),
+        m_action(std::move(action))
+  {
+  }
+
+  ~CloseByPointsEvent()
+  {
+    BLI_kdtree_3d_free(m_kdtree);
+  }
+
+  void filter(EventFilterInterface &interface) override;
+  void execute(EventExecuteInterface &interface) override;
+};
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/inserters.cpp b/source/blender/simulations/bparticles/inserters.cpp
index bdf52b890aa..0cca7d12d71 100644
--- a/source/blender/simulations/bparticles/inserters.cpp
+++ b/source/blender/simulations/bparticles/inserters.cpp
@@ -222,11 +222,33 @@ static std::unique_ptr<Event> BUILD_EVENT_mesh_collision(BuildContext &ctx, bNod
 
 static std::unique_ptr<Event> BUILD_EVENT_age_reached(BuildContext &ctx, bNode *bnode)
 {
-  FN::SharedFunction fn = create_function_for_data_inputs(bnode, ctx.indexed_tree, ctx.data_graph);
+  SharedFunction fn = create_function_for_data_inputs(bnode, ctx.indexed_tree, ctx.data_graph);
   auto action = build_action(ctx, {bSocketList(bnode->outputs).get(0), bnode});
   return std::unique_ptr<Event>(new AgeReachedEvent(bnode->name, fn, std::move(action)));
 }
 
+static std::unique_ptr<Event> BUILD_EVENT_close_by_points(BuildContext &ctx, bNode *bnode)
+{
+  SharedFunction fn = create_function_for_data_inputs(bnode, ctx.indexed_tree, ctx.data_graph);
+  auto action = build_action(ctx, {bSocketList(bnode->outputs).get(0), bnode});
+
+  TupleCallBody *body = fn->body<TupleCallBody>();
+  FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out);
+  body->call__setup_execution_context(fn_in, fn_out);
+
+  auto vectors = fn_out.relocate_out<FN::Types::SharedFloat3List>(0);
+  float distance = body->get_output<float>(fn_out, 1, "Distance");
+
+  KDTree_3d *kdtree = BLI_kdtree_3d_new(vectors->size());
+  for (float3 vector : *vectors.ptr()) {
+    BLI_kdtree_3d_insert(kdtree, 0, vector);
+  }
+  BLI_kdtree_3d_balance(kdtree);
+
+  return std::unique_ptr<Event>(
+      new CloseByPointsEvent(bnode->name, kdtree, distance, std::move(action)));
+}
+
 static std::unique_ptr<Emitter> BUILD_EMITTER_mesh_surface(BuildContext &ctx,
                                                            bNode *bnode,
                                                            StringRef particle_type_name)
@@ -241,6 +263,9 @@ static std::unique_ptr<Emitter> BUILD_EMITTER_mesh_surface(BuildContext &ctx,
   auto on_birth_action = build_action(ctx, {bSocketList(bnode->outputs).get(0), bnode});
 
   Object *object = body->get_output<Object *>(fn_out, 0, "Object");
+  if (object == nullptr) {
+    return {};
+  }
   InterpolatedFloat4x4 transform = ctx.world_state.get_interpolated_value(bnode->name,
                                                                           object->obmat);
 
@@ -366,6 +391,7 @@ BLI_LAZY_INIT(StringMap<EventFromNodeCallback>, get_event_builders)
   StringMap<EventFromNodeCallback> map;
   map.add_new("bp_MeshCollisionEventNode", BUILD_EVENT_mesh_collision);
   map.add_new("bp_AgeReachedEventNode", BUILD_EVENT_age_reached);
+  map.add_new("bp_CloseByPointsEventNode", BUILD_EVENT_close_by_points);
   return map;
 }



More information about the Bf-blender-cvs mailing list