[Bf-blender-cvs] [2a0abf0adf7] functions: initial condition action

Jacques Lucke noreply at git.blender.org
Mon Jul 8 17:57:19 CEST 2019


Commit: 2a0abf0adf765602d1f16810a26cc9a7f3d433d6
Author: Jacques Lucke
Date:   Mon Jul 8 16:09:32 2019 +0200
Branches: functions
https://developer.blender.org/rB2a0abf0adf765602d1f16810a26cc9a7f3d433d6

initial condition action

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

A	release/scripts/startup/nodes/bparticle_nodes/condition.py
M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/actions.hpp
M	source/blender/simulations/bparticles/c_wrapper.cpp
M	source/blender/simulations/bparticles/core.hpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/condition.py b/release/scripts/startup/nodes/bparticle_nodes/condition.py
new file mode 100644
index 00000000000..b2c3335344e
--- /dev/null
+++ b/release/scripts/startup/nodes/bparticle_nodes/condition.py
@@ -0,0 +1,14 @@
+import bpy
+from bpy.props import *
+from .. base import BParticlesNode
+from .. socket_builder import SocketBuilder
+
+class ParticleConditionNode(bpy.types.Node, BParticlesNode):
+    bl_idname = "bp_ParticleConditionNode"
+    bl_label = "Particle Condition"
+
+    def declaration(self, builder : SocketBuilder):
+        builder.control_flow_input("control_in", "(In)")
+        builder.fixed_input("condition", "Condition", "Boolean")
+        builder.control_flow_output("if_true", "If True")
+        builder.control_flow_output("if_false", "If False")
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index 9f14399d001..fb76a1371aa 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -133,6 +133,68 @@ class ExplodeAction : public Action {
   }
 };
 
+class ConditionAction : public Action {
+ private:
+  ParticleFunction m_compute_inputs;
+  std::unique_ptr<Action> m_true_action, m_false_action;
+
+ public:
+  ConditionAction(ParticleFunction &compute_inputs,
+                  std::unique_ptr<Action> true_action,
+                  std::unique_ptr<Action> false_action)
+      : m_compute_inputs(compute_inputs),
+        m_true_action(std::move(true_action)),
+        m_false_action(std::move(false_action))
+  {
+  }
+
+  void execute(EventExecuteInterface &interface, EventInfo &event_info) override
+  {
+    SmallVector<uint> true_indices, false_indices;
+    SmallVector<float> true_times, false_times;
+
+    ParticleSet particles = interface.particles();
+    auto current_times = interface.current_times();
+
+    auto caller = m_compute_inputs.get_caller(particles.attributes(), event_info);
+    FN_TUPLE_CALL_ALLOC_TUPLES(caller.body(), fn_in, fn_out);
+
+    FN::ExecutionStack stack;
+    FN::ExecutionContext execution_context(stack);
+    for (uint i : particles.range()) {
+      uint pindex = particles.get_particle_index(i);
+      caller.call(fn_in, fn_out, execution_context, pindex);
+      bool condition = fn_out.get<bool>(0);
+      if (condition) {
+        true_indices.append(pindex);
+        true_times.append(current_times[i]);
+      }
+      else {
+        false_indices.append(pindex);
+        false_times.append(current_times[i]);
+      }
+    }
+
+    ParticleSet true_particles(particles.block(), true_indices);
+    EventExecuteInterface true_interface(true_particles,
+                                         interface.block_allocator(),
+                                         true_times,
+                                         interface.event_storage(),
+                                         interface.attribute_offsets(),
+                                         interface.step_end_time());
+    m_true_action->execute(true_interface, event_info);
+
+    ParticleSet false_particles(particles.block(), false_indices);
+    EventExecuteInterface false_interface(false_particles,
+                                          interface.block_allocator(),
+                                          false_times,
+                                          interface.event_storage(),
+                                          interface.attribute_offsets(),
+                                          interface.step_end_time());
+    m_false_action->execute(false_interface, event_info);
+  }
+};
+
 Action *ACTION_none()
 {
   return new NoneAction();
@@ -156,4 +218,12 @@ Action *ACTION_explode(StringRef new_particle_name,
       new_particle_name, compute_inputs, std::unique_ptr<Action>(post_action));
 }
 
+Action *ACTION_condition(ParticleFunction &compute_inputs,
+                         Action *true_action,
+                         Action *false_action)
+{
+  return new ConditionAction(
+      compute_inputs, std::unique_ptr<Action>(true_action), std::unique_ptr<Action>(false_action));
+}
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/actions.hpp b/source/blender/simulations/bparticles/actions.hpp
index b92daefc832..d3bad503c51 100644
--- a/source/blender/simulations/bparticles/actions.hpp
+++ b/source/blender/simulations/bparticles/actions.hpp
@@ -103,5 +103,8 @@ Action *ACTION_kill();
 Action *ACTION_explode(StringRef new_particle_name,
                        ParticleFunction &compute_inputs,
                        Action *post_action);
+Action *ACTION_condition(ParticleFunction &compute_inputs,
+                         Action *true_action,
+                         Action *false_action);
 
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/c_wrapper.cpp b/source/blender/simulations/bparticles/c_wrapper.cpp
index 3fd6fc77988..b3658e07884 100644
--- a/source/blender/simulations/bparticles/c_wrapper.cpp
+++ b/source/blender/simulations/bparticles/c_wrapper.cpp
@@ -312,6 +312,7 @@ static Action *build_action(SocketWithNode start,
   BLI_assert(start.socket->in_out == SOCK_IN);
   bNode *bnode = start.node;
   bSocketList node_inputs(bnode->inputs);
+  bSocketList node_outputs(bnode->outputs);
 
   if (STREQ(bnode->idname, "bp_KillParticleNode")) {
     return ACTION_kill();
@@ -320,11 +321,9 @@ static Action *build_action(SocketWithNode start,
     SharedFunction fn = create_function(
         indexed_tree, data_graph, {node_inputs.get(1)}, "Compute Direction");
     ParticleFunction particle_fn(fn);
-    return ACTION_change_direction(particle_fn,
-                                   build_action({bSocketList(bnode->outputs).get(0), bnode},
-                                                indexed_tree,
-                                                data_graph,
-                                                step_description));
+    return ACTION_change_direction(
+        particle_fn,
+        build_action({node_outputs.get(0), bnode}, indexed_tree, data_graph, step_description));
   }
   else if (STREQ(bnode->idname, "bp_ExplodeParticleNode")) {
     SharedFunction fn = create_function(
@@ -336,7 +335,7 @@ static Action *build_action(SocketWithNode start,
     RNA_string_get(&rna, "particle_type_name", name);
 
     Action *post_action = build_action(
-        {bSocketList(bnode->outputs).get(0), bnode}, indexed_tree, data_graph, step_description);
+        {node_outputs.get(0), bnode}, indexed_tree, data_graph, step_description);
 
     if (step_description.m_types.contains(name)) {
       return ACTION_explode(name, particle_fn, post_action);
@@ -345,6 +344,18 @@ static Action *build_action(SocketWithNode start,
       return post_action;
     }
   }
+  else if (STREQ(bnode->idname, "bp_ParticleConditionNode")) {
+    SharedFunction fn = create_function(
+        indexed_tree, data_graph, {node_inputs.get(1)}, bnode->name);
+    ParticleFunction particle_fn(fn);
+
+    Action *true_action = build_action(
+        {node_outputs.get(0), bnode}, indexed_tree, data_graph, step_description);
+    Action *false_action = build_action(
+        {node_outputs.get(1), bnode}, indexed_tree, data_graph, step_description);
+
+    return ACTION_condition(particle_fn, true_action, false_action);
+  }
   else {
     return nullptr;
   }
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index fa01336cce0..fd8d0347066 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -608,9 +608,9 @@ class EventExecuteInterface {
   BlockAllocator &block_allocator();
 
   /**
-   * Get all emit targets created when the event is executed.
+   * Get the entire event storage.
    */
-  ArrayRef<InstantEmitTarget *> emit_targets();
+  EventStorage &event_storage();
 };
 
 /**
@@ -914,6 +914,11 @@ inline BlockAllocator &EventExecuteInterface::block_allocator()
   return m_block_allocator;
 }
 
+inline EventStorage &EventExecuteInterface::event_storage()
+{
+  return m_event_storage;
+}
+
 inline ParticleSet &EventExecuteInterface::particles()
 {
   return m_particles;
@@ -926,11 +931,6 @@ inline void EventExecuteInterface::kill(ArrayRef<uint> particle_indices)
   }
 }
 
-inline ArrayRef<InstantEmitTarget *> EventExecuteInterface::emit_targets()
-{
-  return m_emit_targets;
-}
-
 inline ArrayRef<float> EventExecuteInterface::current_times()
 {
   return m_current_times;



More information about the Bf-blender-cvs mailing list