[Bf-blender-cvs] [4df45d1c4ce] functions: initial Custom Emitter node

Jacques Lucke noreply at git.blender.org
Tue Dec 10 18:13:02 CET 2019


Commit: 4df45d1c4cebe693a05bff312ba57f0edff6c16e
Author: Jacques Lucke
Date:   Tue Dec 10 18:12:51 2019 +0100
Branches: functions
https://developer.blender.org/rB4df45d1c4cebe693a05bff312ba57f0edff6c16e

initial Custom Emitter node

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

A	release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
M	source/blender/blenkernel/BKE_inlined_node_tree.h
M	source/blender/blenkernel/intern/inlined_node_tree.cc
M	source/blender/functions/FN_attributes_ref.h
M	source/blender/functions/FN_generic_array_ref.h
M	source/blender/simulations/bparticles/emitters.cpp
M	source/blender/simulations/bparticles/emitters.hpp
M	source/blender/simulations/bparticles/node_frontend.cpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py b/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
new file mode 100644
index 00000000000..54f099e8f2f
--- /dev/null
+++ b/release/scripts/startup/nodes/bparticle_nodes/custom_emitter.py
@@ -0,0 +1,48 @@
+import bpy
+import uuid
+from bpy.props import *
+from .. base import SimulationNode
+from .. node_builder import NodeBuilder
+from .. types import type_infos
+
+
+class CustomEmitterAttribute(bpy.types.PropertyGroup):
+    attribute_name: StringProperty()
+    attribute_type: StringProperty()
+    identifier: StringProperty()
+    is_list: NodeBuilder.VectorizedProperty()
+
+
+class CustomEmitter(bpy.types.Node, SimulationNode):
+    bl_idname = "fn_CustomEmitterNode"
+    bl_label = "Custom Emitter"
+
+    execute_on_birth__prop: NodeBuilder.ExecuteInputProperty()
+
+    attributes: CollectionProperty(
+        type=CustomEmitterAttribute,
+    )
+
+    new_attribute_name: StringProperty(default="My Attribute")
+
+    def declaration(self, builder: NodeBuilder):
+        for i, item in enumerate(self.attributes):
+            builder.vectorized_input(
+                item.identifier,
+                f"attributes[{i}].is_list",
+                item.attribute_name,
+                item.attribute_name,
+                item.attribute_type)
+        builder.execute_input("execute_on_birth", "Execute on Birth", "execute_on_birth__prop")
+        builder.influences_output("emitter", "Emitter")
+
+    def draw(self, layout):
+        layout.prop(self, "new_attribute_name")
+        self.invoke_type_selection(layout, "add_attribute", "Add Attribute", mode="BASE")
+
+    def add_attribute(self, data_type):
+        item = self.attributes.add()
+        item.identifier = str(uuid.uuid4())
+        item.attribute_name = self.new_attribute_name
+        item.attribute_type = data_type
+        self.sync_tree()
diff --git a/source/blender/blenkernel/BKE_inlined_node_tree.h b/source/blender/blenkernel/BKE_inlined_node_tree.h
index 40bc039b7b7..a7dab0d008a 100644
--- a/source/blender/blenkernel/BKE_inlined_node_tree.h
+++ b/source/blender/blenkernel/BKE_inlined_node_tree.h
@@ -44,6 +44,8 @@ class XSocket : BLI::NonCopyable, BLI::NonMovable {
   PointerRNA *rna() const;
   StringRefNull idname() const;
   StringRefNull name() const;
+
+  uint index() const;
 };
 
 class XInputSocket : public XSocket {
@@ -120,6 +122,8 @@ class XNode : BLI::NonCopyable, BLI::NonMovable {
   PointerRNA *rna() const;
   StringRefNull idname() const;
   StringRefNull name() const;
+
+  const XInputSocket *input_with_name_prefix(StringRef name_prefix) const;
 };
 
 class XParentNode : BLI::NonCopyable, BLI::NonMovable {
@@ -334,6 +338,11 @@ inline StringRefNull XSocket::name() const
   return m_vsocket->name();
 }
 
+inline uint XSocket::index() const
+{
+  return m_vsocket->index();
+}
+
 inline const VInputSocket &XInputSocket::vsocket() const
 {
   return m_vsocket->as_input();
diff --git a/source/blender/blenkernel/intern/inlined_node_tree.cc b/source/blender/blenkernel/intern/inlined_node_tree.cc
index 7ce8c89fed3..341e842bc47 100644
--- a/source/blender/blenkernel/intern/inlined_node_tree.cc
+++ b/source/blender/blenkernel/intern/inlined_node_tree.cc
@@ -471,4 +471,14 @@ void InlinedNodeTree::to_dot__clipboard() const
   WM_clipboard_text_set(dot.c_str(), false);
 }
 
+const XInputSocket *XNode::input_with_name_prefix(StringRef name_prefix) const
+{
+  for (const XInputSocket *xsocket : m_inputs) {
+    if (xsocket->name().startswith(name_prefix)) {
+      return xsocket;
+    }
+  }
+  return nullptr;
+}
+
 }  // namespace BKE
diff --git a/source/blender/functions/FN_attributes_ref.h b/source/blender/functions/FN_attributes_ref.h
index 43a950ef6e4..89042f9bca5 100644
--- a/source/blender/functions/FN_attributes_ref.h
+++ b/source/blender/functions/FN_attributes_ref.h
@@ -41,12 +41,17 @@ class AttributesInfoBuilder : BLI::NonCopyable, BLI::NonMovable {
     this->add(name, CPP_TYPE<T>(), (const void *)&default_value);
   }
 
-  void add(StringRef name, const CPPType &type, const void *default_value)
+  void add(StringRef name, const CPPType &type, const void *default_value = nullptr)
   {
     if (m_names.add(name)) {
       m_types.append(&type);
       void *dst = m_allocator.allocate(type.size(), type.alignment());
-      type.copy_to_uninitialized(default_value, dst);
+      if (default_value == nullptr) {
+        type.construct_default(dst);
+      }
+      else {
+        type.copy_to_uninitialized(default_value, dst);
+      }
       m_defaults.append(dst);
     }
     else {
@@ -312,6 +317,30 @@ class AttributesRefGroup {
     this->set_repeated(m_info->index_of(name), data);
   }
 
+  void set_repeated(uint index, GenericArrayRef data)
+  {
+    BLI_assert(m_total_size == 0 || data.size() > 0);
+    BLI_assert(m_info->type_of(index) == data.type());
+
+    uint src_index = 0;
+    for (AttributesRef attributes : *this) {
+      GenericMutableArrayRef array = attributes.get(index);
+
+      for (uint i = 0; i < attributes.size(); i++) {
+        array.copy_in__initialized(i, data[src_index]);
+        src_index++;
+        if (src_index == data.size()) {
+          src_index = 0;
+        }
+      }
+    }
+  }
+
+  void set_repeated(StringRef name, GenericArrayRef data)
+  {
+    this->set_repeated(m_info->index_of(name), data);
+  }
+
   template<typename T> void fill(uint index, const T &value)
   {
     BLI_assert(m_info->type_of(index) == CPP_TYPE<T>());
@@ -327,6 +356,22 @@ class AttributesRefGroup {
     this->fill(m_info->index_of(name), value);
   }
 
+  void fill(uint index, const CPPType &type, const void *value)
+  {
+    BLI_assert(m_info->type_of(index) == type);
+    UNUSED_VARS_NDEBUG(type);
+
+    for (AttributesRef attributes : *this) {
+      GenericMutableArrayRef array = attributes.get(index);
+      array.fill__initialized(value);
+    }
+  }
+
+  void fill(StringRef name, const CPPType &type, const void *value)
+  {
+    this->fill(m_info->index_of(name), type, value);
+  }
+
   class Iterator {
    private:
     AttributesRefGroup *m_group;
diff --git a/source/blender/functions/FN_generic_array_ref.h b/source/blender/functions/FN_generic_array_ref.h
index 4bf9d417e71..1b51233d306 100644
--- a/source/blender/functions/FN_generic_array_ref.h
+++ b/source/blender/functions/FN_generic_array_ref.h
@@ -133,6 +133,13 @@ class GenericMutableArrayRef {
     }
   }
 
+  void fill__initialized(const void *value)
+  {
+    for (uint i = 0; i < m_size; i++) {
+      m_type->copy_to_initialized(value, (*this)[i]);
+    }
+  }
+
   void copy_in__uninitialized(uint index, const void *src)
   {
     BLI_assert(index < m_size);
@@ -140,6 +147,13 @@ class GenericMutableArrayRef {
     m_type->copy_to_uninitialized(src, dst);
   }
 
+  void copy_in__initialized(uint index, const void *src)
+  {
+    BLI_assert(index < m_size);
+    void *dst = POINTER_OFFSET(m_buffer, m_type->size() * index);
+    m_type->copy_to_initialized(src, dst);
+  }
+
   static void RelocateUninitialized(GenericMutableArrayRef from, GenericMutableArrayRef to);
 
   void *operator[](uint index)
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index 7b3ba4e83cd..8b906b31fe8 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -357,4 +357,87 @@ void InitialGridEmitter::emit(EmitterInterface &interface)
   }
 }
 
+using FN::MFParamType;
+
+void CustomEmitter::emit(EmitterInterface &interface)
+{
+  FN::MFParamsBuilder params_builder{m_emitter_function, 1};
+
+  for (uint param_index : m_emitter_function.param_indices()) {
+    MFParamType param_type = m_emitter_function.param_type(param_index);
+    switch (param_type.type()) {
+      case MFParamType::SingleInput:
+      case MFParamType::VectorInput:
+      case MFParamType::MutableSingle:
+      case MFParamType::MutableVector:
+        BLI_assert(false);
+        break;
+      case MFParamType::SingleOutput: {
+        const FN::CPPType &type = param_type.data_type().single__cpp_type();
+        void *buffer = MEM_mallocN(type.size(), __func__);
+        FN::GenericMutableArrayRef array{type, buffer, 1};
+        params_builder.add_single_output(array);
+        break;
+      }
+      case MFParamType::VectorOutput: {
+        const FN::CPPType &base_type = param_type.data_type().vector__cpp_base_type();
+        FN::GenericVectorArray *vector_array = new FN::GenericVectorArray(base_type, 1);
+        params_builder.add_vector_output(*vector_array);
+        break;
+      }
+    }
+  }
+
+  FN::MFContextBuilder context_builder;
+  m_emitter_function.call({0}, params_builder, context_builder);
+
+  int particle_count = -1;
+
+  for (uint param_index : m_emitter_function.param_indices()) {
+    MFParamType param_type = m_emitter_function.param_type(param_index);
+    if (param_type.is_vector_output()) {
+      FN::GenericVectorArray &vector_array = params_builder.computed_vector_array(param_index);
+      FN::GenericArrayRef array = vector_array[0];
+      particle_count = std::max<int>(particle_count, array.size());
+    }
+  }
+
+  if (particle_count == -1) {
+    particle_count = 1;
+  }
+
+  for (StringRef system_name : m_systems_to_emit) {
+    auto new_particles = interface.particle_allocator().request(system_name, particle_count);
+    new_particles.fill<float>("Birth Time", interface.time_span().end());
+
+    for (uint param_index : m_emitter_function.param_indices()) {
+      MFParamType param_type = m_emitter_function.param_type(param_index);
+      StringRef attribute_name = m_attribute_names[param_index];
+      if (param_type.is_vector_output()) {
+        FN::GenericVectorArray &vector_array = params_builder.computed_vector_array(param_index);
+        FN::GenericArrayRef array = vector_array[0];
+        const FN::CPPType &base_type = array.type();
+        if (array.size() == 0) {
+          void *default_buffer = alloca(base_type.size());
+          base_type.construct_default(default_buffer);
+          new_particles.fill(attribute_name, base_type, default_buffer);
+        }
+        els

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list