[Bf-blender-cvs] [daf119f2a74] functions: initial support for custom particle attributes

Jacques Lucke noreply at git.blender.org
Tue Dec 10 15:32:08 CET 2019


Commit: daf119f2a749a4338351674da7404e6a2e2964e2
Author: Jacques Lucke
Date:   Tue Dec 10 15:30:42 2019 +0100
Branches: functions
https://developer.blender.org/rBdaf119f2a749a4338351674da7404e6a2e2964e2

initial support for custom particle attributes

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

A	release/scripts/startup/nodes/bparticle_nodes/custom_attributes.py
M	release/scripts/startup/nodes/function_nodes/groups.py
M	source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/actions.hpp
M	source/blender/simulations/bparticles/node_frontend.cpp
M	source/blender/simulations/bparticles/particle_function.hpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/custom_attributes.py b/release/scripts/startup/nodes/bparticle_nodes/custom_attributes.py
new file mode 100644
index 00000000000..c1f90fcabff
--- /dev/null
+++ b/release/scripts/startup/nodes/bparticle_nodes/custom_attributes.py
@@ -0,0 +1,58 @@
+import bpy
+from bpy.props import *
+from .. base import SimulationNode, FunctionNode
+from .. node_builder import NodeBuilder
+
+class SetParticleAttributeNode(bpy.types.Node, SimulationNode):
+    bl_idname = "fn_SetParticleAttributeNode"
+    bl_label = "Set Particle Attribute"
+
+    attribute_name: StringProperty(
+        name="Attribute Name",
+        default="My Attribute",
+    )
+
+    attribute_type: StringProperty(
+        name="Attribute Type",
+        default="Float",
+        update=SimulationNode.sync_tree,
+    )
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_input("value", "Value", self.attribute_type)
+        builder.execute_output("execute", "Execute")
+
+    def draw(self, layout):
+        row = layout.row(align=True)
+        row.prop(self, "attribute_name", text="")
+        self.invoke_type_selection(row, "set_type", "", mode="BASE", icon="SETTINGS")
+
+    def set_type(self, data_type):
+        self.attribute_type = data_type
+
+
+class GetParticleAttribute(bpy.types.Node, FunctionNode):
+    bl_idname = "fn_GetParticleAttributeNode"
+    bl_label = "Get Particle Attribute"
+
+    attribute_name: StringProperty(
+        name="Attribute Name",
+        default="My Attribute",
+    )
+
+    attribute_type: StringProperty(
+        name="Attribute Type",
+        default="Float",
+        update=SimulationNode.sync_tree,
+    )
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_output("value", "Value", self.attribute_type)
+
+    def draw(self, layout):
+        row = layout.row(align=True)
+        row.prop(self, "attribute_name", text="")
+        self.invoke_type_selection(row, "set_type", "", mode="BASE", icon="SETTINGS")
+
+    def set_type(self, data_type):
+        self.attribute_type = data_type
diff --git a/release/scripts/startup/nodes/function_nodes/groups.py b/release/scripts/startup/nodes/function_nodes/groups.py
index d712e92bc77..511157c3593 100644
--- a/release/scripts/startup/nodes/function_nodes/groups.py
+++ b/release/scripts/startup/nodes/function_nodes/groups.py
@@ -65,8 +65,8 @@ class GroupInputNode(bpy.types.Node, BaseNode):
 
     def draw_socket(self, layout, socket, text, decl, index):
         row = layout.row(align=True)
-        row.prop(self, "display_settings", text="", icon="SETTINGS")
         row.prop(self, "input_name", text="")
+        row.prop(self, "display_settings", text="", icon="SETTINGS")
 
     def draw_closed_label(self):
         return self.input_name + " (Input)"
@@ -121,8 +121,8 @@ class GroupOutputNode(bpy.types.Node, BaseNode):
 
     def draw_socket(self, layout, socket, text, decl, index):
         row = layout.row(align=True)
-        row.prop(self, "display_settings", text="", icon="SETTINGS")
         row.prop(self, "output_name", text="")
+        row.prop(self, "display_settings", text="", icon="SETTINGS")
 
     def draw_closed_label(self):
         return self.output_name + " (Output)"
@@ -252,7 +252,7 @@ class MoveGroupInterface(bpy.types.Operator):
             nodes = tree.get_input_nodes()
         else:
             nodes = tree.get_output_nodes()
-        
+
         from_index = self.from_index
         to_index = min(max(self.from_index + self.offset, 0), len(nodes) - 1)
 
@@ -279,7 +279,7 @@ class ManageGroupPieMenu(bpy.types.Menu, PieMenuHelper):
 
     @classmethod
     def poll(cls, context):
-        try: 
+        try:
             return isinstance(context.space_data.node_tree, FunctionTree)
         except:
             return False
@@ -293,7 +293,7 @@ class ManageGroupPieMenu(bpy.types.Menu, PieMenuHelper):
             self.empty(layout)
             return
 
-        possible_inputs = [(i, socket) for i, socket in enumerate(node.inputs) 
+        possible_inputs = [(i, socket) for i, socket in enumerate(node.inputs)
                                        if socket_can_become_group_input(socket)]
 
         if len(possible_inputs) == 0:
@@ -375,7 +375,7 @@ class CreateGroupOutputForSocketInvoker(bpy.types.Operator):
 
         layout = menu.layout.column()
         layout.operator_context = "INVOKE_DEFAULT"
-        
+
         for i, socket in enumerate(node.outputs):
             if socket_can_become_group_output(socket):
                 props = layout.operator("fn.create_group_output_for_socket", text=socket.name)
@@ -409,7 +409,7 @@ class CreateGroupInputForSocket(bpy.types.Operator):
             elif socket.bl_idname == "fn_InfluencesSocket":
                 new_node.interface_type = "INFLUENCES"
             new_node.rebuild()
-            
+
             new_node.select = True
             new_node.parent = node.parent
             new_node.location = node.location
@@ -426,7 +426,7 @@ class CreateGroupInputForSocket(bpy.types.Operator):
 class CreateGroupOutputForSocket(bpy.types.Operator):
     bl_idname = "fn.create_group_output_for_socket"
     bl_label = "Create Group Output for Socket"
-    
+
     output_index: IntProperty()
 
     def invoke(self, context, event):
@@ -482,4 +482,4 @@ def register():
 def unregister():
     global keymap
     bpy.context.window_manager.keyconfigs.addon.keymaps.remove(keymap)
-    keymap = None
\ No newline at end of file
+    keymap = None
diff --git a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
index ae9e74c76ab..b5907f55037 100644
--- a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
+++ b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
@@ -396,6 +396,13 @@ static void INSERT_particle_info(VNodeMFNetworkBuilder &builder)
   }
 }
 
+static void INSERT_get_particle_attribute(VNodeMFNetworkBuilder &builder)
+{
+  std::string name = builder.string_from_property("attribute_name");
+  const CPPType &type = builder.cpp_type_from_property("attribute_type");
+  builder.set_constructed_matching_fn<MF_ParticleAttributes>(std::move(name), type);
+}
+
 static void INSERT_closest_location_on_object(VNodeMFNetworkBuilder &builder)
 {
   builder.set_constructed_matching_fn<MF_ClosestSurfaceHookOnObject>();
@@ -442,6 +449,7 @@ void add_inlined_tree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
   mappings.xnode_inserters.add_new("fn_CompareNode", INSERT_compare);
   mappings.xnode_inserters.add_new("fn_PerlinNoiseNode", INSERT_perlin_noise);
   mappings.xnode_inserters.add_new("fn_ParticleInfoNode", INSERT_particle_info);
+  mappings.xnode_inserters.add_new("fn_GetParticleAttributeNode", INSERT_get_particle_attribute);
   mappings.xnode_inserters.add_new("fn_ClosestLocationOnObjectNode",
                                    INSERT_closest_location_on_object);
   mappings.xnode_inserters.add_new("fn_MapRangeNode", INSERT_map_range);
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index d21a54dc066..fa3a5b6f4b6 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -198,4 +198,23 @@ void RemoveFromGroupAction::execute(ActionInterface &interface)
   }
 }
 
+void SetAttributeAction::execute(ActionInterface &interface)
+{
+  Optional<GenericMutableArrayRef> attribute_opt = interface.attributes().try_get(
+      m_attribute_name, m_attribute_type);
+
+  if (!attribute_opt.has_value()) {
+    return;
+  }
+
+  GenericMutableArrayRef attribute = *attribute_opt;
+
+  auto inputs = m_inputs_fn.compute(interface);
+  for (uint pindex : interface.pindices()) {
+    void *value = inputs->get("Value", 0, pindex);
+    void *dst = attribute[pindex];
+    m_attribute_type.copy_to_initialized(value, dst);
+  }
+}
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/actions.hpp b/source/blender/simulations/bparticles/actions.hpp
index e63cbf6fd80..cbe6264e69d 100644
--- a/source/blender/simulations/bparticles/actions.hpp
+++ b/source/blender/simulations/bparticles/actions.hpp
@@ -5,6 +5,8 @@
 
 namespace BParticles {
 
+using FN::CPPType;
+
 class NoneAction : public Action {
   void execute(ActionInterface &UNUSED(interface)) override;
 };
@@ -143,4 +145,23 @@ class RemoveFromGroupAction : public Action {
   void execute(ActionInterface &interface) override;
 };
 
+class SetAttributeAction : public Action {
+ private:
+  std::string m_attribute_name;
+  const CPPType &m_attribute_type;
+  ParticleFunction &m_inputs_fn;
+
+ public:
+  SetAttributeAction(std::string attribute_name,
+                     const CPPType &attribute_type,
+                     ParticleFunction &inputs_fn)
+      : m_attribute_name(std::move(attribute_name)),
+        m_attribute_type(attribute_type),
+        m_inputs_fn(inputs_fn)
+  {
+  }
+
+  void execute(ActionInterface &interface) override;
+};
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 20cfce2d073..a0f89bb545a 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -295,6 +295,19 @@ class XSocketActionBuilder {
     return m_built_action;
   }
 
+  const XSocket &xsocket() const
+  {
+    return m_execute_xsocket;
+  }
+
+  const CPPType &base_type_of(const XInputSocket &xsocket) const
+  {
+    return m_inlined_tree_data.inlined_tree_data_graph()
+        .lookup_dummy_socket(xsocket)
+        .data_type()
+        .single__cpp_type();
+  }
+
   template<typename T, typename... Args> T &construct(Args &&... args)
   {
     return m_inlined_tree_data.construct<T>("construct action", std::forward<Args>(args)...);
@@ -337,9 +350,17 @@ class XSocketActionBuilder {
 
   template<typename T> void add_attribute_to_affected_particles(StringRef name, T default_value)
   {
-    /*

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list