[Bf-blender-cvs] [8a41c15bf9d] functions: prevent trails and explosion in a the same particle system

Jacques Lucke noreply at git.blender.org
Sat Dec 14 13:15:38 CET 2019


Commit: 8a41c15bf9d8eeeade87b545e001ad22425b577e
Author: Jacques Lucke
Date:   Sat Dec 14 11:29:49 2019 +0100
Branches: functions
https://developer.blender.org/rB8a41c15bf9d8eeeade87b545e001ad22425b577e

prevent trails and explosion in a the same particle system

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

M	source/blender/blenlib/BLI_array_ref.h
M	source/blender/simulations/bparticles/node_frontend.cpp

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

diff --git a/source/blender/blenlib/BLI_array_ref.h b/source/blender/blenlib/BLI_array_ref.h
index 5af421066aa..5428bba6e70 100644
--- a/source/blender/blenlib/BLI_array_ref.h
+++ b/source/blender/blenlib/BLI_array_ref.h
@@ -278,6 +278,21 @@ template<typename T> class ArrayRef {
     return false;
   }
 
+  bool intersects__linear_search(ArrayRef other) const
+  {
+    /* The size should really be smaller than that. If it is not, the calling code should be
+     * changed. */
+    BLI_assert(m_size < 1000);
+
+    for (uint i = 0; i < m_size; i++) {
+      const T &value = m_start[i];
+      if (other.contains(value)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   uint first_index(const T &search_value) const
   {
     int index = this->first_index_try(search_value);
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 3d6593de83f..055a49a395e 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -201,16 +201,19 @@ class InlinedTreeData {
     return system_names;
   }
 
-  Action *build_action(InfluencesCollector &collector, const XInputSocket &start);
+  Action *build_action(InfluencesCollector &collector,
+                       const XInputSocket &start,
+                       ArrayRef<std::string> system_names);
 
   Action &build_action_list(InfluencesCollector &collector,
                             const XNode &start_xnode,
-                            StringRef name)
+                            StringRef name,
+                            ArrayRef<std::string> system_names)
   {
     Vector<const XInputSocket *> execute_sockets = this->find_execute_sockets(start_xnode, name);
     Vector<Action *> actions;
     for (const XInputSocket *socket : execute_sockets) {
-      Action *action = this->build_action(collector, *socket);
+      Action *action = this->build_action(collector, *socket, system_names);
       if (action != nullptr) {
         actions.append(action);
       }
@@ -311,15 +314,18 @@ class XSocketActionBuilder {
   InfluencesCollector &m_influences_collector;
   InlinedTreeData &m_inlined_tree_data;
   const XSocket &m_execute_xsocket;
+  ArrayRef<std::string> m_system_names;
   Action *m_built_action = nullptr;
 
  public:
   XSocketActionBuilder(InfluencesCollector &influences_collector,
                        InlinedTreeData &inlined_tree_data,
-                       const XSocket &execute_xsocket)
+                       const XSocket &execute_xsocket,
+                       ArrayRef<std::string> system_names)
       : m_influences_collector(influences_collector),
         m_inlined_tree_data(inlined_tree_data),
-        m_execute_xsocket(execute_xsocket)
+        m_execute_xsocket(execute_xsocket),
+        m_system_names(system_names)
   {
   }
 
@@ -333,6 +339,11 @@ class XSocketActionBuilder {
     return m_execute_xsocket;
   }
 
+  ArrayRef<std::string> system_names() const
+  {
+    return m_system_names;
+  }
+
   const CPPType &base_type_of(const XInputSocket &xsocket) const
   {
     return m_inlined_tree_data.inlined_tree_data_graph()
@@ -364,10 +375,10 @@ class XSocketActionBuilder {
     return m_execute_xsocket.node().rna();
   }
 
-  Action &build_input_action_list(StringRef name)
+  Action &build_input_action_list(StringRef name, ArrayRef<std::string> system_names)
   {
     return m_inlined_tree_data.build_action_list(
-        m_influences_collector, m_execute_xsocket.node(), name);
+        m_influences_collector, m_execute_xsocket.node(), name, system_names);
   }
 
   ArrayRef<std::string> find_system_target_names(uint output_index, StringRef expected_name)
@@ -402,7 +413,9 @@ class XSocketActionBuilder {
   }
 };
 
-Action *InlinedTreeData::build_action(InfluencesCollector &collector, const XInputSocket &start)
+Action *InlinedTreeData::build_action(InfluencesCollector &collector,
+                                      const XInputSocket &start,
+                                      ArrayRef<std::string> system_names)
 {
   if (start.linked_sockets().size() != 1) {
     return nullptr;
@@ -416,7 +429,7 @@ Action *InlinedTreeData::build_action(InfluencesCollector &collector, const XInp
   StringMap<ActionParserCallback> &parsers = get_action_parsers();
   ActionParserCallback &parser = parsers.lookup(execute_socket.node().idname());
 
-  XSocketActionBuilder builder{collector, *this, execute_socket};
+  XSocketActionBuilder builder{collector, *this, execute_socket, system_names};
   parser(builder);
 
   return builder.built_action();
@@ -455,8 +468,12 @@ static void ACTION_explode(XSocketActionBuilder &builder)
     return;
   }
 
-  Action &on_birth_action = builder.build_input_action_list("Execute on Birth");
   ArrayRef<std::string> system_names = builder.find_system_target_names(1, "Explode System");
+  if (builder.system_names().intersects__linear_search(system_names)) {
+    return;
+  }
+
+  Action &on_birth_action = builder.build_input_action_list("Execute on Birth", system_names);
   builder.set_constructed<ExplodeAction>(system_names, inputs_fn, on_birth_action);
 }
 
@@ -467,8 +484,9 @@ static void ACTION_condition(XSocketActionBuilder &builder)
     return;
   }
 
-  Action &action_true = builder.build_input_action_list("Execute If True");
-  Action &action_false = builder.build_input_action_list("Execute If False");
+  Action &action_true = builder.build_input_action_list("Execute If True", builder.system_names());
+  Action &action_false = builder.build_input_action_list("Execute If False",
+                                                         builder.system_names());
   builder.set_constructed<ConditionAction>(inputs_fn, action_true, action_false);
 }
 
@@ -611,9 +629,10 @@ class XNodeInfluencesBuilder {
     return m_inlined_tree_data.function_for_inputs(m_xnode, input_indices);
   }
 
-  Action &build_action_list(StringRef name)
+  Action &build_action_list(StringRef name, ArrayRef<std::string> system_names)
   {
-    return m_inlined_tree_data.build_action_list(m_influences_collector, m_xnode, name);
+    return m_inlined_tree_data.build_action_list(
+        m_influences_collector, m_xnode, name, system_names);
   }
 
   ArrayRef<std::string> find_target_system_names(uint output_index, StringRef expected_name)
@@ -722,9 +741,9 @@ static void PARSE_point_emitter(XNodeInfluencesBuilder &builder)
     return;
   }
 
-  Action &action = builder.build_action_list("Execute on Birth");
-
   ArrayRef<std::string> system_names = builder.find_target_system_names(0, "Emitter");
+  Action &action = builder.build_action_list("Execute on Birth", system_names);
+
   std::string identifier = builder.node_identifier();
 
   WorldTransition &world_transition = builder.world_transition();
@@ -774,7 +793,7 @@ static void PARSE_custom_emitter(XNodeInfluencesBuilder &builder)
     builder.try_add_attribute(system_names, attribute_name, *attribute_type);
   }
 
-  Action &action = builder.build_action_list("Execute on Birth");
+  Action &action = builder.build_action_list("Execute on Birth", system_names);
   BirthTimeModes::Enum birth_time_mode = (BirthTimeModes::Enum)RNA_enum_get(builder.node_rna(),
                                                                             "birth_time_mode");
 
@@ -827,8 +846,6 @@ static void PARSE_mesh_emitter(XNodeInfluencesBuilder &builder)
     return;
   }
 
-  Action &on_birth_action = builder.build_action_list("Execute on Birth");
-
   ObjectIDHandle object_handle = inputs->relocate_out<ObjectIDHandle>(0, "Object");
   Object *object = builder.id_handle_lookup().lookup(object_handle);
   if (object == nullptr || object->type != OB_MESH) {
@@ -841,6 +858,8 @@ static void PARSE_mesh_emitter(XNodeInfluencesBuilder &builder)
       object->id.name, "obmat", object->obmat);
 
   ArrayRef<std::string> system_names = builder.find_target_system_names(0, "Emitter");
+  Action &on_birth_action = builder.build_action_list("Execute on Birth", system_names);
+
   Emitter &emitter = builder.construct<SurfaceEmitter>(system_names,
                                                        on_birth_action,
                                                        object,
@@ -878,7 +897,7 @@ static void PARSE_age_reached_event(XNodeInfluencesBuilder &builder)
     return;
   }
 
-  Action &action = builder.build_action_list("Execute on Event");
+  Action &action = builder.build_action_list("Execute on Event", system_names);
   Event &event = builder.construct<AgeReachedEvent>(is_triggered_attribute, inputs_fn, action);
   builder.add_event(system_names, event);
 }
@@ -892,8 +911,11 @@ static void PARSE_trails(XNodeInfluencesBuilder &builder)
   if (inputs_fn == nullptr) {
     return;
   }
+  if (main_system_names.intersects__linear_search(trail_system_names)) {
+    return;
+  }
 
-  Action &action = builder.build_action_list("Execute on Birth");
+  Action &action = builder.build_action_list("Execute on Birth", trail_system_names);
   OffsetHandler &offset_handler = builder.construct<CreateTrailHandler>(
       trail_system_names, inputs_fn, action);
   builder.add_offset_handler(main_system_names, offset_handler);
@@ -906,9 +928,9 @@ static void PARSE_initial_grid_emitter(XNodeInfluencesBuilder &builder)
     return;
   }
 
-  Action &action = builder.build_action_list("Execute on Birth");
-
   ArrayRef<std::string> system_names = builder.find_target_system_names(0, "Emitter");
+  Action &action = builder.build_action_list("Execute on Birth", system_names);
+
   Emitter &emitter = builder.construct<InitialGridEmitter>(
       std::move(system_names),
       std::max(0, inputs->get<int>(0, "Amount X")),
@@ -939,7 +961,7 @@ static void PARSE_mesh_collision(XNodeInfluencesBuilder &builder)
   }
 
   ArrayRef<std::string> system_names = builder.find_target_system_names(0, "Event");
-  Action &action = builder.build_action_list("Execute on Event");
+  Action &action = builder.build_action_list("Execute on Event", system_names);
 
   float4x4 local_to_world_end = object->obmat;
   float4x4 local_to_world_begin =
@@ -985,7 +1007,7 @@ static void PARSE_custom_event(XNodeInfluencesBuilder &builde

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list