[Bf-blender-cvs] [ab0f8b46a68] functions: use ParticleSets abstraction instead of emitter targets

Jacques Lucke noreply at git.blender.org
Wed Jul 10 17:17:50 CEST 2019


Commit: ab0f8b46a68117ae134d61c3593d6f61ea6ffa8d
Author: Jacques Lucke
Date:   Wed Jul 10 13:54:33 2019 +0200
Branches: functions
https://developer.blender.org/rBab0f8b46a68117ae134d61c3593d6f61ea6ffa8d

use ParticleSets abstraction instead of emitter targets

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

M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/core.cpp
M	source/blender/simulations/bparticles/core.hpp
M	source/blender/simulations/bparticles/emitters.cpp
M	source/blender/simulations/bparticles/simulate.cpp

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

diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index ce4742e028f..f9e314bd3bd 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -118,10 +118,10 @@ class ExplodeAction : public Action {
 
     auto target = interface.particle_allocator().request(m_new_particle_name,
                                                          new_birth_times.size());
-    target->set_float3("Position", new_positions);
-    target->set_float3("Velocity", new_velocities);
-    target->fill_float("Size", 0.1f);
-    target->set_float("Birth Time", new_birth_times);
+    target.set_float3("Position", new_positions);
+    target.set_float3("Velocity", new_velocities);
+    target.fill_float("Size", 0.1f);
+    target.set_float("Birth Time", new_birth_times);
 
     m_post_action->execute(interface);
   }
diff --git a/source/blender/simulations/bparticles/core.cpp b/source/blender/simulations/bparticles/core.cpp
index 69101c8fcf4..e2e9e8a2f3e 100644
--- a/source/blender/simulations/bparticles/core.cpp
+++ b/source/blender/simulations/bparticles/core.cpp
@@ -89,7 +89,7 @@ AttributesInfo &ParticleAllocator::attributes_info(StringRef particle_type_name)
   return m_state.particle_container(particle_type_name).attributes_info();
 }
 
-std::unique_ptr<EmitTargetBase> ParticleAllocator::request(StringRef particle_type_name, uint size)
+ParticleSets ParticleAllocator::request(StringRef particle_type_name, uint size)
 {
   SmallVector<ParticlesBlock *> blocks;
   SmallVector<Range<uint>> ranges;
@@ -97,8 +97,12 @@ std::unique_ptr<EmitTargetBase> ParticleAllocator::request(StringRef particle_ty
 
   AttributesInfo &attributes_info = this->attributes_info(particle_type_name);
 
-  EmitTargetBase *target = new EmitTargetBase(particle_type_name, attributes_info, blocks, ranges);
-  return std::unique_ptr<EmitTargetBase>(target);
+  SmallVector<ParticleSet> sets;
+  for (uint i = 0; i < blocks.size(); i++) {
+    sets.append(ParticleSet(*blocks[i], static_number_range_ref(ranges[i])));
+  }
+
+  return ParticleSets(particle_type_name, attributes_info, sets);
 }
 
 /* Emitter Interface
@@ -109,134 +113,122 @@ EmitterInterface::EmitterInterface(ParticleAllocator &particle_allocator, TimeSp
 {
 }
 
-/* Action Interface
- **************************************/
-
-/* EmitTarget
+/* ParticleSets
  ******************************************/
 
-EmitTargetBase::EmitTargetBase(StringRef particle_type_name,
-                               AttributesInfo &attributes_info,
-                               ArrayRef<ParticlesBlock *> blocks,
-                               ArrayRef<Range<uint>> ranges)
+ParticleSets::ParticleSets(StringRef particle_type_name,
+                           AttributesInfo &attributes_info,
+                           ArrayRef<ParticleSet> sets)
     : m_particle_type_name(particle_type_name.to_std_string()),
       m_attributes_info(attributes_info),
-      m_blocks(blocks),
-      m_ranges(ranges)
+      m_sets(sets)
 {
-  BLI_assert(blocks.size() == ranges.size());
-  for (auto range : ranges) {
-    m_size += range.size();
+  m_size = 0;
+  for (auto &set : sets) {
+    m_size += set.size();
   }
 }
 
-InstantEmitTarget::InstantEmitTarget(StringRef particle_type_name,
-                                     AttributesInfo &attributes_info,
-                                     ArrayRef<ParticlesBlock *> blocks,
-                                     ArrayRef<Range<uint>> ranges)
-    : EmitTargetBase(particle_type_name, attributes_info, blocks, ranges)
-{
-}
-
-void EmitTargetBase::set_elements(uint index, void *data)
+void ParticleSets::set_elements(uint index, void *data)
 {
   AttributeType type = m_attributes_info.type_of(index);
   uint element_size = size_of_attribute_type(type);
 
   void *remaining_data = data;
 
-  for (uint part = 0; part < m_ranges.size(); part++) {
-    ParticlesBlock &block = *m_blocks[part];
-    Range<uint> range = m_ranges[part];
-
-    AttributeArrays attributes = block.attributes_slice(range);
+  for (ParticleSet particles : m_sets) {
+    AttributeArrays attributes = particles.attributes();
     void *dst = attributes.get_ptr(index);
-    uint bytes_to_copy = element_size * attributes.size();
-    memcpy(dst, remaining_data, bytes_to_copy);
 
-    remaining_data = POINTER_OFFSET(remaining_data, bytes_to_copy);
+    for (uint i : particles.range()) {
+      uint pindex = particles.get_particle_index(i);
+      memcpy(POINTER_OFFSET(dst, element_size * pindex),
+             POINTER_OFFSET(remaining_data, element_size * i),
+             element_size);
+    }
+
+    remaining_data = POINTER_OFFSET(remaining_data, particles.size() * element_size);
   }
 }
 
-void EmitTargetBase::fill_elements(uint index, void *value)
+void ParticleSets::fill_elements(uint index, void *value)
 {
   AttributeType type = m_attributes_info.type_of(index);
   uint element_size = size_of_attribute_type(type);
 
-  for (uint part = 0; part < m_ranges.size(); part++) {
-    ParticlesBlock &block = *m_blocks[part];
+  for (ParticleSet particles : m_sets) {
+    AttributeArrays attributes = particles.attributes();
+    void *dst = attributes.get_ptr(index);
 
-    /* TODO(jacques): Check if this is correct. */
-    void *dst = block.attributes_all().get_ptr(index);
-    for (uint i : m_ranges[part]) {
-      memcpy(POINTER_OFFSET(dst, element_size * i), value, element_size);
+    for (uint pindex : particles.indices()) {
+      memcpy(POINTER_OFFSET(dst, element_size * pindex), value, element_size);
     }
   }
 }
 
-void EmitTargetBase::set_byte(uint index, ArrayRef<uint8_t> data)
+void ParticleSets::set_byte(uint index, ArrayRef<uint8_t> data)
 {
   BLI_assert(data.size() == m_size);
   BLI_assert(m_attributes_info.type_of(index) == AttributeType::Byte);
   this->set_elements(index, (void *)data.begin());
 }
-void EmitTargetBase::set_float(uint index, ArrayRef<float> data)
+void ParticleSets::set_float(uint index, ArrayRef<float> data)
 {
   BLI_assert(data.size() == m_size);
   BLI_assert(m_attributes_info.type_of(index) == AttributeType::Float);
   this->set_elements(index, (void *)data.begin());
 }
-void EmitTargetBase::set_float3(uint index, ArrayRef<float3> data)
+void ParticleSets::set_float3(uint index, ArrayRef<float3> data)
 {
   BLI_assert(data.size() == m_size);
   BLI_assert(m_attributes_info.type_of(index) == AttributeType::Float3);
   this->set_elements(index, (void *)data.begin());
 }
 
-void EmitTargetBase::set_byte(StringRef name, ArrayRef<uint8_t> data)
+void ParticleSets::set_byte(StringRef name, ArrayRef<uint8_t> data)
 {
   uint index = m_attributes_info.attribute_index(name);
   this->set_byte(index, data);
 }
-void EmitTargetBase::set_float(StringRef name, ArrayRef<float> data)
+void ParticleSets::set_float(StringRef name, ArrayRef<float> data)
 {
   uint index = m_attributes_info.attribute_index(name);
   this->set_float(index, data);
 }
-void EmitTargetBase::set_float3(StringRef name, ArrayRef<float3> data)
+void ParticleSets::set_float3(StringRef name, ArrayRef<float3> data)
 {
   uint index = m_attributes_info.attribute_index(name);
   this->set_float3(index, data);
 }
 
-void EmitTargetBase::fill_byte(uint index, uint8_t value)
+void ParticleSets::fill_byte(uint index, uint8_t value)
 {
   this->fill_elements(index, (void *)&value);
 }
 
-void EmitTargetBase::fill_byte(StringRef name, uint8_t value)
+void ParticleSets::fill_byte(StringRef name, uint8_t value)
 {
   uint index = m_attributes_info.attribute_index(name);
   this->fill_byte(index, value);
 }
 
-void EmitTargetBase::fill_float(uint index, float value)
+void ParticleSets::fill_float(uint index, float value)
 {
   this->fill_elements(index, (void *)&value);
 }
 
-void EmitTargetBase::fill_float(StringRef name, float value)
+void ParticleSets::fill_float(StringRef name, float value)
 {
   uint index = m_attributes_info.attribute_index(name);
   this->fill_float(index, value);
 }
 
-void EmitTargetBase::fill_float3(uint index, float3 value)
+void ParticleSets::fill_float3(uint index, float3 value)
 {
   this->fill_elements(index, (void *)&value);
 }
 
-void EmitTargetBase::fill_float3(StringRef name, float3 value)
+void ParticleSets::fill_float3(StringRef name, float3 value)
 {
   uint index = m_attributes_info.attribute_index(name);
   this->fill_float3(index, value);
diff --git a/source/blender/simulations/bparticles/core.hpp b/source/blender/simulations/bparticles/core.hpp
index ad3992b3732..adda1a2ef5f 100644
--- a/source/blender/simulations/bparticles/core.hpp
+++ b/source/blender/simulations/bparticles/core.hpp
@@ -10,6 +10,7 @@
 #include "BLI_string_ref.hpp"
 #include "BLI_small_map.hpp"
 #include "BLI_vector_adaptor.hpp"
+#include "BLI_lazy_init.hpp"
 
 #include "attributes.hpp"
 #include "particles_container.hpp"
@@ -209,69 +210,87 @@ class ParticlesState {
 };
 
 /**
- * Base class for different kinds of emitters. It's main purpose is to make it easy to initialize
- * particle attributes.
+ * A set of particles all of which are in the same block.
  */
-class EmitTargetBase {
- protected:
-  std::string m_particle_type_name;
-  AttributesInfo &m_attributes_info;
-  SmallVector<ParticlesBlock *> m_blocks;
-  SmallVector<Range<uint>> m_ranges;
+struct ParticleSet {
+ private:
+  ParticlesBlock *m_block;
 
-  uint m_size = 0;
+  /* Indices into the attribute arrays.
+   * Invariants:
+   *   - Every index must exist at most once.
+   *   - The indices must be sorted. */
+  ArrayRef<uint> m_particle_indices;
 
  public:
-  EmitTargetBase(StringRef particle_type_name,
-                 AttributesInfo &attributes_info,
-                 ArrayRef<ParticlesBlock *> blocks,
-                 ArrayRef<Range<uint>> ranges);
-
-  EmitTargetBase(EmitTargetBase &other) = delete;
+  ParticleSet(ParticlesBlock &block, ArrayRef<uint> particle_indices);
 
   /**
-   * Copy attributes from an array into the particle block ranges referenced by this target.
+   * Return the block that contains the particles of this set.
    */
-  void set_byte(uint index, ArrayRef<uint8_t> data);
-  void set_byte(StringRef name, ArrayRef<uint8_t> data);
-  void set_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list