[Bf-blender-cvs] [ccc8d664fca] functions: initial Spawn Action node

Jacques Lucke noreply at git.blender.org
Tue Dec 17 13:54:06 CET 2019


Commit: ccc8d664fca0e4d5318b1a6a14445d74650811c9
Author: Jacques Lucke
Date:   Tue Dec 17 13:28:38 2019 +0100
Branches: functions
https://developer.blender.org/rBccc8d664fca0e4d5318b1a6a14445d74650811c9

initial Spawn Action node

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

M	source/blender/simulations/bparticles/action_interface.hpp
M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/actions.hpp
M	source/blender/simulations/bparticles/emitters.cpp
M	source/blender/simulations/bparticles/node_frontend.cpp

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

diff --git a/source/blender/simulations/bparticles/action_interface.hpp b/source/blender/simulations/bparticles/action_interface.hpp
index 7fdfc23e916..693044e663b 100644
--- a/source/blender/simulations/bparticles/action_interface.hpp
+++ b/source/blender/simulations/bparticles/action_interface.hpp
@@ -17,34 +17,6 @@ class ActionContext {
   virtual ~ActionContext();
 };
 
-class SourceParticleActionContext : public ActionContext {
- private:
-  ArrayRef<uint> m_all_source_indices;
-  ArrayRef<uint> m_current_source_indices;
-  ActionContext *m_source_context;
-
- public:
-  SourceParticleActionContext(ArrayRef<uint> source_indices, ActionContext *source_context)
-      : m_all_source_indices(source_indices), m_source_context(source_context)
-  {
-  }
-
-  void update(IndexRange slice)
-  {
-    m_current_source_indices = m_all_source_indices.slice(slice.start(), slice.size());
-  }
-
-  ArrayRef<uint> source_indices()
-  {
-    return m_current_source_indices;
-  }
-
-  ActionContext *source_context()
-  {
-    return m_source_context;
-  }
-};
-
 class ActionInterface {
  private:
   ParticleAllocator &m_particle_allocator;
@@ -94,8 +66,7 @@ class Action {
                                    ActionContext *action_context = nullptr);
   void execute_for_subset(ArrayRef<uint> pindices, ActionInterface &action_interface);
   void execute_for_new_particles(AttributesRefGroup &new_particles,
-                                 ActionInterface &action_interface,
-                                 SourceParticleActionContext *action_context);
+                                 ActionInterface &action_interface);
   void execute_for_new_particles(AttributesRefGroup &new_particles,
                                  OffsetHandlerInterface &offset_handler_interface);
 };
@@ -219,8 +190,7 @@ inline void Action::execute_for_subset(ArrayRef<uint> pindices, ActionInterface
 }
 
 inline void Action::execute_for_new_particles(AttributesRefGroup &new_particles,
-                                              ActionInterface &action_interface,
-                                              SourceParticleActionContext *action_context)
+                                              ActionInterface &action_interface)
 {
   AttributesInfo info;
   std::array<void *, 0> buffers;
@@ -228,20 +198,21 @@ inline void Action::execute_for_new_particles(AttributesRefGroup &new_particles,
   uint offset = 0;
   for (AttributesRef attributes : new_particles) {
     uint range_size = attributes.size();
-    action_context->update(IndexRange(offset, range_size));
     offset += range_size;
 
     AttributesRef offsets(info, buffers, range_size);
     LargeScopedArray<float> durations(range_size);
     durations.fill(0);
 
+    EmptyActionContext empty_context;
+
     ActionInterface new_interface(action_interface.particle_allocator(),
                                   IndexRange(range_size).as_array_ref(),
                                   attributes,
                                   offsets,
                                   attributes.get<float>("Birth Time"),
                                   durations,
-                                  *action_context);
+                                  empty_context);
     this->execute(new_interface);
   }
 }
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index fa3a5b6f4b6..84cc606ca00 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -128,7 +128,6 @@ void ExplodeAction::execute(ActionInterface &interface)
   Vector<float3> new_positions;
   Vector<float3> new_velocities;
   Vector<float> new_birth_times;
-  Vector<uint> source_particles;
 
   auto inputs = m_inputs_fn->compute(interface);
 
@@ -136,7 +135,6 @@ void ExplodeAction::execute(ActionInterface &interface)
     uint parts_amount = std::max(0, inputs->get<int>("Amount", 0, pindex));
     float speed = inputs->get<float>("Speed", 1, pindex);
 
-    source_particles.append_n_times(pindex, parts_amount);
     new_positions.append_n_times(positions[pindex], parts_amount);
     new_birth_times.append_n_times(interface.current_times()[pindex], parts_amount);
 
@@ -153,9 +151,7 @@ void ExplodeAction::execute(ActionInterface &interface)
     new_particles.fill<float>("Size", 0.1f);
     new_particles.set<float>("Birth Time", new_birth_times);
 
-    SourceParticleActionContext source_context(source_particles, &interface.context());
-
-    m_on_birth_action.execute_for_new_particles(new_particles, interface, &source_context);
+    m_on_birth_action.execute_for_new_particles(new_particles, interface);
   }
 }
 
@@ -217,4 +213,162 @@ void SetAttributeAction::execute(ActionInterface &interface)
   }
 }
 
+using FN::MFDataType;
+using FN::MFParamType;
+
+void SpawnParticlesAction::execute(ActionInterface &interface)
+{
+  FN::MFMask mask(interface.pindices());
+  uint min_array_size = mask.min_array_size();
+  FN::MFParamsBuilder params_builder{m_spawn_function, min_array_size};
+
+  for (uint param_index : m_spawn_function.param_indices()) {
+    MFParamType param_type = m_spawn_function.param_type(param_index);
+    MFDataType data_type = param_type.data_type();
+    BLI_assert(param_type.is_output());
+    switch (param_type.data_type().category()) {
+      case MFDataType::Single: {
+        const FN::CPPType &type = data_type.single__cpp_type();
+        void *buffer = MEM_malloc_arrayN(min_array_size, type.size(), __func__);
+        FN::GenericMutableArrayRef array{type, buffer, min_array_size};
+        params_builder.add_single_output(array);
+        break;
+      }
+      case MFDataType::Vector: {
+        const FN::CPPType &base_type = data_type.vector__cpp_base_type();
+        FN::GenericVectorArray *vector_array = new FN::GenericVectorArray(base_type,
+                                                                          min_array_size);
+        params_builder.add_vector_output(*vector_array);
+        break;
+      }
+    }
+  }
+
+  FN::ParticleAttributesContext attributes_context = {interface.attributes()};
+
+  FN::MFContextBuilder context_builder;
+  context_builder.add_global_context(m_id_data_cache);
+  context_builder.add_global_context(m_id_handle_lookup);
+  context_builder.add_element_context(attributes_context, IndexRange(min_array_size));
+
+  m_spawn_function.call(mask, params_builder, context_builder);
+
+  LargeScopedArray<int> particle_counts(min_array_size, -1);
+
+  for (uint param_index : m_spawn_function.param_indices()) {
+    MFParamType param_type = m_spawn_function.param_type(param_index);
+    if (param_type.is_vector_output()) {
+      FN::GenericVectorArray &vector_array = params_builder.computed_vector_array(param_index);
+      for (uint i : interface.pindices()) {
+        FN::GenericArrayRef array = vector_array[i];
+        particle_counts[i] = std::max<int>(particle_counts[i], array.size());
+      }
+    }
+  }
+
+  for (uint i : interface.pindices()) {
+    if (particle_counts[i] == -1) {
+      particle_counts[i] = 1;
+    }
+  }
+
+  uint total_spawn_amount = 0;
+  for (uint i : interface.pindices()) {
+    total_spawn_amount += particle_counts[i];
+  }
+
+  StringMap<GenericMutableArrayRef> attribute_arrays;
+
+  Vector<float> new_birth_times;
+  for (uint i : interface.pindices()) {
+    new_birth_times.append_n_times(interface.current_times()[i], particle_counts[i]);
+  }
+  attribute_arrays.add_new("Birth Time", new_birth_times.as_mutable_ref());
+
+  for (uint param_index : m_spawn_function.param_indices()) {
+    MFParamType param_type = m_spawn_function.param_type(param_index);
+    MFDataType data_type = param_type.data_type();
+    StringRef attribute_name = m_attribute_names[param_index];
+
+    switch (data_type.category()) {
+      case MFDataType::Single: {
+        const FN::CPPType &type = data_type.single__cpp_type();
+        void *buffer = MEM_malloc_arrayN(total_spawn_amount, type.size(), __func__);
+        GenericMutableArrayRef array(type, buffer, total_spawn_amount);
+        GenericMutableArrayRef computed_array = params_builder.computed_array(param_index);
+
+        uint current = 0;
+        for (uint i : interface.pindices()) {
+          uint amount = particle_counts[i];
+          array.slice(current, amount).fill__uninitialized(computed_array[i]);
+          current += amount;
+        }
+
+        attribute_arrays.add(attribute_name, array);
+
+        computed_array.destruct_indices(interface.pindices());
+        MEM_freeN(computed_array.buffer());
+        break;
+      }
+      case MFDataType::Vector: {
+        const FN::CPPType &base_type = data_type.vector__cpp_base_type();
+        void *buffer = MEM_malloc_arrayN(total_spawn_amount, base_type.size(), __func__);
+        GenericMutableArrayRef array(base_type, buffer, total_spawn_amount);
+        FN::GenericVectorArray &computed_vector_array = params_builder.computed_vector_array(
+            param_index);
+
+        uint current = 0;
+        for (uint pindex : interface.pindices()) {
+          uint amount = particle_counts[pindex];
+          GenericMutableArrayRef array_slice = array.slice(current, amount);
+          GenericArrayRef computed_array = computed_vector_array[pindex];
+
+          if (computed_array.size() == 0) {
+            const void *default_buffer = interface.attributes().info().default_of(attribute_name);
+            array_slice.fill__uninitialized(default_buffer);
+          }
+          else if (computed_array.size() == amount) {
+            base_type.copy_to_uninitialized_n(
+                computed_array.buffer(), array_slice.buffer(), amount);
+          }
+          else {
+            for (uint i : IndexRange(amount)) {
+              base_type.copy_to_uninitialized(computed_array[i % computed_array.size()],
+                                              array_slice[i]);
+            }
+          }
+
+          current += amount;
+        }
+
+        attribute_arrays.add(attribute_name, array);
+
+        delete &computed_vector_array;
+        break;
+      }
+    }
+  }
+
+  for (StringRef system_name : m_systems_to_emit) {
+    auto new_particles = interface.parti

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list