[Bf-blender-cvs] [be738fa181c] functions-experimental-refactor: make Pack List node work again

Jacques Lucke noreply at git.blender.org
Wed Oct 30 16:35:03 CET 2019


Commit: be738fa181c3f7958205279935af90a37330671e
Author: Jacques Lucke
Date:   Wed Oct 30 16:27:53 2019 +0100
Branches: functions-experimental-refactor
https://developer.blender.org/rBbe738fa181c3f7958205279935af90a37330671e

make Pack List node work again

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

M	source/blender/blenkernel/BKE_multi_functions.h
M	source/blender/blenkernel/intern/multi_functions.cc
M	source/blender/modifiers/intern/MOD_functiondeform_cxx.cc

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

diff --git a/source/blender/blenkernel/BKE_multi_functions.h b/source/blender/blenkernel/BKE_multi_functions.h
index 1c614d4a24d..f10e2e34ab5 100644
--- a/source/blender/blenkernel/BKE_multi_functions.h
+++ b/source/blender/blenkernel/BKE_multi_functions.h
@@ -83,6 +83,19 @@ class MultiFunction_CombineLists final : public MultiFunction {
   void call(ArrayRef<uint> mask_indices, MFParams &params, MFContext &context) const override;
 };
 
+class MultiFunction_PackList final : public MultiFunction {
+ private:
+  const CPPType &m_base_type;
+  Vector<bool> m_input_list_status;
+
+ public:
+  MultiFunction_PackList(const CPPType &base_type, ArrayRef<bool> input_list_status);
+  void call(ArrayRef<uint> mask_indices, MFParams &params, MFContext &context) const override;
+
+ private:
+  bool input_is_list(uint index) const;
+};
+
 template<typename T> class MultiFunction_ConstantValue : public MultiFunction {
  private:
   T m_value;
diff --git a/source/blender/blenkernel/intern/multi_functions.cc b/source/blender/blenkernel/intern/multi_functions.cc
index 109221f9933..7dd9088075f 100644
--- a/source/blender/blenkernel/intern/multi_functions.cc
+++ b/source/blender/blenkernel/intern/multi_functions.cc
@@ -200,6 +200,83 @@ void MultiFunction_AppendToList::call(ArrayRef<uint> mask_indices,
   }
 }
 
+MultiFunction_PackList::MultiFunction_PackList(const CPPType &base_type,
+                                               ArrayRef<bool> input_list_status)
+    : m_base_type(base_type), m_input_list_status(input_list_status)
+{
+  MFSignatureBuilder signature;
+  if (m_input_list_status.size() == 0) {
+    /* Output just an empty list. */
+    signature.vector_output("List", m_base_type);
+  }
+  else if (this->input_is_list(0)) {
+    /* Extend the first incoming list. */
+    signature.mutable_vector("List", m_base_type);
+    for (uint i = 1; i < m_input_list_status.size(); i++) {
+      if (this->input_is_list(i)) {
+        signature.readonly_vector_input("List", m_base_type);
+      }
+      else {
+        signature.readonly_single_input("Value", m_base_type);
+      }
+    }
+  }
+  else {
+    /* Create a new list and append everything. */
+    for (uint i = 0; i < m_input_list_status.size(); i++) {
+      if (this->input_is_list(i)) {
+        signature.readonly_vector_input("List", m_base_type);
+      }
+      else {
+        signature.readonly_single_input("Value", m_base_type);
+      }
+    }
+    signature.vector_output("List", m_base_type);
+  }
+  this->set_signature(signature);
+}
+
+void MultiFunction_PackList::call(ArrayRef<uint> mask_indices,
+                                  MFParams &params,
+                                  MFContext &UNUSED(context)) const
+{
+  GenericVectorArray *vector_array;
+  bool is_mutating_first_list;
+  if (m_input_list_status.size() == 0) {
+    vector_array = &params.vector_output(0, "List");
+    is_mutating_first_list = false;
+  }
+  else if (this->input_is_list(0)) {
+    vector_array = &params.mutable_vector(0, "List");
+    is_mutating_first_list = true;
+  }
+  else {
+    vector_array = &params.vector_output(m_input_list_status.size(), "List");
+    is_mutating_first_list = false;
+  }
+
+  uint first_index = is_mutating_first_list ? 1 : 0;
+  for (uint input_index = first_index; input_index < m_input_list_status.size(); input_index++) {
+    if (this->input_is_list(input_index)) {
+      GenericVirtualListListRef list = params.readonly_vector_input(input_index, "List");
+      for (uint i : mask_indices) {
+        vector_array->extend_single__copy(i, list[i]);
+      }
+    }
+    else {
+      GenericVirtualListRef list = params.readonly_single_input(input_index, "Value");
+      for (uint i : mask_indices) {
+        vector_array->append_single__copy(i, list[i]);
+      }
+    }
+  }
+}
+
+bool MultiFunction_PackList::input_is_list(uint index) const
+{
+  return m_input_list_status[index];
+}
+
 MultiFunction_GetListElement::MultiFunction_GetListElement(const CPPType &base_type)
     : m_base_type(base_type)
 {
diff --git a/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc b/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
index 699798aa31d..9693647a0c0 100644
--- a/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
+++ b/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
@@ -424,6 +424,61 @@ static void INSERT_list_length(VTreeMFNetworkBuilder &builder,
   resources.add(std::move(function), "list length function");
 }
 
+static MFBuilderOutputSocket &build_pack_list_node(VTreeMFNetworkBuilder &builder,
+                                                   OwnedResources &resources,
+                                                   const VirtualNode &vnode,
+                                                   const CPPType &base_type,
+                                                   const char *prop_name,
+                                                   uint start_index)
+{
+  PointerRNA rna = vnode.rna();
+
+  Vector<bool> input_is_list;
+  RNA_BEGIN (&rna, itemptr, prop_name) {
+    int state = RNA_enum_get(&itemptr, "state");
+    if (state == 0) {
+      /* single value case */
+      input_is_list.append(false);
+    }
+    else if (state == 1) {
+      /* list case */
+      input_is_list.append(true);
+    }
+    else {
+      BLI_assert(false);
+    }
+  }
+  RNA_END;
+
+  uint input_amount = input_is_list.size();
+  uint output_param_index = (input_amount > 0 && input_is_list[0]) ? 0 : input_amount;
+
+  auto function = BLI::make_unique<BKE::MultiFunction_PackList>(base_type, input_is_list);
+  MFBuilderFunctionNode &node = builder.add_function(
+      *function, IndexRange(input_amount).as_array_ref(), {output_param_index});
+  resources.add(std::move(function), "pack list function");
+
+  for (uint i = 0; i < input_amount; i++) {
+    builder.map_sockets(vnode.input(start_index + i), *node.inputs()[i]);
+  }
+
+  return *node.outputs()[0];
+}
+
+static void INSERT_pack_list(VTreeMFNetworkBuilder &builder,
+                             OwnedResources &resources,
+                             const VirtualNode &vnode)
+{
+  PointerRNA rna = vnode.rna();
+  char *type_name = RNA_string_get_alloc(&rna, "active_type", nullptr, 0);
+  const CPPType &type = get_cpp_type_by_name(type_name);
+  MEM_freeN(type_name);
+
+  MFBuilderOutputSocket &packed_list_socket = build_pack_list_node(
+      builder, resources, vnode, type, "variadic", 0);
+  builder.map_sockets(vnode.output(0), packed_list_socket);
+}
+
 static StringMap<InsertVNodeFunction> get_node_inserters()
 {
   StringMap<InsertVNodeFunction> inserters;
@@ -433,6 +488,7 @@ static StringMap<InsertVNodeFunction> get_node_inserters()
   inserters.add_new("fn_SeparateVectorNode", INSERT_separate_vector);
   inserters.add_new("fn_AppendToListNode", INSERT_append_to_list);
   inserters.add_new("fn_ListLengthNode", INSERT_list_length);
+  inserters.add_new("fn_PackListNode", INSERT_pack_list);
   return inserters;
 }
 
@@ -820,11 +876,6 @@ class MultiFunction_FunctionTree : public BKE::MultiFunction {
     }
 
     while (!sockets_to_compute.empty()) {
-      for (const MFSocket *socket : sockets_to_compute) {
-        std::cout << socket->id() << ", ";
-      }
-      std::cout << "\n";
-
       const MFSocket &socket = *sockets_to_compute.peek();
 
       if (socket.is_input()) {



More information about the Bf-blender-cvs mailing list