[Bf-blender-cvs] [21ebaf9bc6f] functions: initial Select node

Jacques Lucke noreply at git.blender.org
Sat Dec 14 15:36:29 CET 2019


Commit: 21ebaf9bc6fc9b05da2bfc4c442b851fde78da84
Author: Jacques Lucke
Date:   Sat Dec 14 15:28:13 2019 +0100
Branches: functions
https://developer.blender.org/rB21ebaf9bc6fc9b05da2bfc4c442b851fde78da84

initial Select node

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

M	release/scripts/startup/nodes/function_nodes/switch.py
M	source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
M	source/blender/functions/intern/multi_functions/mixed.cc
M	source/blender/functions/intern/multi_functions/mixed.h

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

diff --git a/release/scripts/startup/nodes/function_nodes/switch.py b/release/scripts/startup/nodes/function_nodes/switch.py
index 2d7ed4d6382..3b1030cf34b 100644
--- a/release/scripts/startup/nodes/function_nodes/switch.py
+++ b/release/scripts/startup/nodes/function_nodes/switch.py
@@ -1,6 +1,8 @@
 import bpy
+import uuid
 from bpy.props import *
 from .. base import FunctionNode
+from .. node_builder import NodeBuilder
 
 class SwitchNode(bpy.types.Node, FunctionNode):
     bl_idname = "fn_SwitchNode"
@@ -11,7 +13,7 @@ class SwitchNode(bpy.types.Node, FunctionNode):
         update=FunctionNode.sync_tree
     )
 
-    def declaration(self, builder):
+    def declaration(self, builder: NodeBuilder):
         builder.fixed_input("condition", "Condition", "Boolean")
         builder.fixed_input("true", "True", self.data_type)
         builder.fixed_input("false", "False", self.data_type)
@@ -22,3 +24,39 @@ class SwitchNode(bpy.types.Node, FunctionNode):
 
     def set_type(self, data_type):
         self.data_type = data_type
+
+
+class SelectNodeItem(bpy.types.PropertyGroup):
+    identifier: StringProperty()
+
+class SelectNode(bpy.types.Node, FunctionNode):
+    bl_idname = "fn_SelectNode"
+    bl_label = "Select"
+
+    data_type: StringProperty(
+        default="Float",
+        update=FunctionNode.sync_tree,
+    )
+
+    input_items: CollectionProperty(
+        type=SelectNodeItem,
+    )
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_input("select", "Select", "Integer")
+        for i, item in enumerate(self.input_items):
+            builder.fixed_input(item.identifier, str(i), self.data_type)
+        builder.fixed_input("fallback", "Fallback", self.data_type)
+        builder.fixed_output("result", "Result", self.data_type)
+
+    def draw(self, layout):
+        self.invoke_type_selection(layout, "set_type", "Change Type")
+        self.invoke_function(layout, "add_input", "Add Input")
+
+    def set_type(self, data_type):
+        self.data_type = data_type
+
+    def add_input(self):
+        item = self.input_items.add()
+        item.identifier = str(uuid.uuid4())
+        self.sync_tree()
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 0cd9edb19e5..7118508f3cf 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
@@ -112,6 +112,22 @@ static void INSERT_switch(VNodeMFNetworkBuilder &builder)
   }
 }
 
+static void INSERT_select(VNodeMFNetworkBuilder &builder)
+{
+  MFDataType type = builder.data_type_from_property("data_type");
+  uint inputs = RNA_collection_length(builder.rna(), "input_items");
+  switch (type.category()) {
+    case MFDataType::Single: {
+      builder.set_constructed_matching_fn<MF_SelectSingle>(type.single__cpp_type(), inputs);
+      break;
+    }
+    case MFDataType::Vector: {
+      builder.set_constructed_matching_fn<MF_SelectVector>(type.vector__cpp_base_type(), inputs);
+      break;
+    }
+  }
+}
+
 static void INSERT_text_length(VNodeMFNetworkBuilder &builder)
 {
   builder.set_constructed_matching_fn<MF_TextLength>();
@@ -492,6 +508,7 @@ void add_inlined_tree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
   mappings.xnode_inserters.add_new("fn_CombineVectorNode", INSERT_combine_vector);
   mappings.xnode_inserters.add_new("fn_SeparateVectorNode", INSERT_separate_vector);
   mappings.xnode_inserters.add_new("fn_SwitchNode", INSERT_switch);
+  mappings.xnode_inserters.add_new("fn_SelectNode", INSERT_select);
   mappings.xnode_inserters.add_new("fn_ListLengthNode", INSERT_list_length);
   mappings.xnode_inserters.add_new("fn_PackListNode", INSERT_pack_list);
   mappings.xnode_inserters.add_new("fn_GetListElementNode", INSERT_get_list_element);
diff --git a/source/blender/functions/intern/multi_functions/mixed.cc b/source/blender/functions/intern/multi_functions/mixed.cc
index 7131c1368ef..19c6569d8c3 100644
--- a/source/blender/functions/intern/multi_functions/mixed.cc
+++ b/source/blender/functions/intern/multi_functions/mixed.cc
@@ -303,6 +303,65 @@ void MF_SwitchVector::call(MFMask mask, MFParams params, MFContext UNUSED(contex
   }
 }
 
+MF_SelectSingle::MF_SelectSingle(const CPPType &type, uint inputs) : m_type(type), m_inputs(inputs)
+{
+  MFSignatureBuilder signature = this->get_builder("Select Single: " + type.name());
+  signature.single_input<int>("Select");
+  for (uint i : IndexRange(inputs)) {
+    signature.single_input(std::to_string(i), type);
+  }
+  signature.single_input("Fallback", type);
+  signature.single_output("Result", type);
+}
+
+void MF_SelectSingle::call(MFMask mask, MFParams params, MFContext UNUSED(context)) const
+{
+  VirtualListRef<int> selects = params.readonly_single_input<int>(0, "Select");
+  GenericVirtualListRef fallbacks = params.readonly_single_input(m_inputs + 1, "Fallback");
+  GenericMutableArrayRef r_results = params.uninitialized_single_output(m_inputs + 2, "Result");
+
+  for (uint i : mask.indices()) {
+    int select = selects[i];
+    if (0 <= select && select < m_inputs) {
+      GenericVirtualListRef selected = params.readonly_single_input(select + 1);
+      r_results.copy_in__uninitialized(i, selected[i]);
+    }
+    else {
+      r_results.copy_in__uninitialized(i, fallbacks[i]);
+    }
+  }
+}
+
+MF_SelectVector::MF_SelectVector(const CPPType &base_type, uint inputs)
+    : m_base_type(base_type), m_inputs(inputs)
+{
+  MFSignatureBuilder signature = this->get_builder("Select Vector: " + base_type.name() + " List");
+  signature.single_input<int>("Select");
+  for (uint i : IndexRange(inputs)) {
+    signature.vector_input(std::to_string(i), base_type);
+  }
+  signature.vector_input("Fallback", base_type);
+  signature.vector_output("Result", base_type);
+}
+
+void MF_SelectVector::call(MFMask mask, MFParams params, MFContext UNUSED(context)) const
+{
+  VirtualListRef<int> selects = params.readonly_single_input<int>(0, "Select");
+  GenericVirtualListListRef fallback = params.readonly_vector_input(m_inputs + 1, "Fallback");
+  GenericVectorArray &r_results = params.vector_output(m_inputs + 2, "Result");
+
+  for (uint i : mask.indices()) {
+    int select = selects[i];
+    if (0 <= select && select < m_inputs) {
+      GenericVirtualListListRef selected = params.readonly_vector_input(select + 1);
+      r_results.extend_single__copy(i, selected[i]);
+    }
+    else {
+      r_results.extend_single__copy(i, fallback[i]);
+    }
+  }
+}
+
 MF_TextLength::MF_TextLength()
 {
   MFSignatureBuilder signature = this->get_builder("Text Length");
diff --git a/source/blender/functions/intern/multi_functions/mixed.h b/source/blender/functions/intern/multi_functions/mixed.h
index 864cbd70570..2887a948083 100644
--- a/source/blender/functions/intern/multi_functions/mixed.h
+++ b/source/blender/functions/intern/multi_functions/mixed.h
@@ -96,6 +96,26 @@ class MF_SwitchVector final : public MultiFunction {
   void call(MFMask mask, MFParams params, MFContext context) const override;
 };
 
+class MF_SelectSingle final : public MultiFunction {
+ private:
+  const CPPType &m_type;
+  uint m_inputs;
+
+ public:
+  MF_SelectSingle(const CPPType &type, uint inputs);
+  void call(MFMask mask, MFParams params, MFContext context) const override;
+};
+
+class MF_SelectVector final : public MultiFunction {
+ private:
+  const CPPType &m_base_type;
+  uint m_inputs;
+
+ public:
+  MF_SelectVector(const CPPType &type, uint inputs);
+  void call(MFMask mask, MFParams params, MFContext context) const override;
+};
+
 class MF_PerlinNoise final : public MultiFunction {
  public:
   MF_PerlinNoise();



More information about the Bf-blender-cvs mailing list