[Bf-blender-cvs] [9952cbc7151] functions-experimental-refactor: initial multi function node tree evaluation

Jacques Lucke noreply at git.blender.org
Tue Oct 15 15:57:40 CEST 2019


Commit: 9952cbc7151ca8205c39f4cf08426cf9759cdbe9
Author: Jacques Lucke
Date:   Tue Oct 15 15:12:48 2019 +0200
Branches: functions-experimental-refactor
https://developer.blender.org/rB9952cbc7151ca8205c39f4cf08426cf9759cdbe9

initial multi function node tree evaluation

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

M	source/blender/blenkernel/BKE_generic_array_ref.h
M	source/blender/blenkernel/BKE_multi_function.h
M	source/blender/blenkernel/BKE_virtual_node_tree_cxx.h
M	source/blender/modifiers/intern/MOD_functiondeform_cxx.cc

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

diff --git a/source/blender/blenkernel/BKE_generic_array_ref.h b/source/blender/blenkernel/BKE_generic_array_ref.h
index 3822a3fd468..99c3369b43a 100644
--- a/source/blender/blenkernel/BKE_generic_array_ref.h
+++ b/source/blender/blenkernel/BKE_generic_array_ref.h
@@ -31,6 +31,11 @@ class GenericArrayRef {
     BLI_assert(type.pointer_has_valid_alignment(buffer));
   }
 
+  const CPPType &type() const
+  {
+    return *m_type;
+  }
+
   uint size() const
   {
     return m_size;
@@ -136,11 +141,28 @@ class GenericMutableArrayRef {
   {
   }
 
+  const CPPType &type() const
+  {
+    return *m_type;
+  }
+
+  void *buffer()
+  {
+    return m_buffer;
+  }
+
   uint size() const
   {
     return m_size;
   }
 
+  void copy_in__uninitialized(uint index, const void *src)
+  {
+    BLI_assert(index < m_size);
+    void *dst = POINTER_OFFSET(m_buffer, m_type->size() * index);
+    m_type->copy_to_uninitialized(src, dst);
+  }
+
   void *operator[](uint index)
   {
     BLI_assert(index < m_size);
diff --git a/source/blender/blenkernel/BKE_multi_function.h b/source/blender/blenkernel/BKE_multi_function.h
index 24a9578362a..4f29497a8ed 100644
--- a/source/blender/blenkernel/BKE_multi_function.h
+++ b/source/blender/blenkernel/BKE_multi_function.h
@@ -3,6 +3,7 @@
 
 #include "BKE_generic_array_ref.h"
 #include "BKE_generic_vector_array.h"
+#include "BKE_tuple.h"
 
 #include "BLI_vector.h"
 
@@ -312,12 +313,31 @@ class MultiFunction {
           GenericArrayOrSingleRef::FromSingle(GET_TYPE<T>(), (void *)value, m_min_array_size));
     }
 
+    void add_readonly_array_ref(GenericMutableArrayRef array)
+    {
+      BLI_assert(array.size() >= m_min_array_size);
+      m_array_or_single_refs.append(
+          GenericArrayOrSingleRef::FromArray(array.type(), array.buffer(), array.size()));
+    }
+
+    void add_readonly_single_ref(TupleRef tuple, uint index)
+    {
+      m_array_or_single_refs.append(GenericArrayOrSingleRef::FromSingle(
+          tuple.info().type_at_index(index), tuple.element_ptr(index), m_min_array_size));
+    }
+
     template<typename T> void add_mutable_array_ref(ArrayRef<T> array)
     {
       BLI_assert(array.size() >= m_min_array_size);
       m_mutable_array_refs.append(GenericMutableArrayRef(array));
     }
 
+    void add_mutable_array_ref(GenericMutableArrayRef array)
+    {
+      BLI_assert(array.size() >= m_min_array_size);
+      m_mutable_array_refs.append(array);
+    }
+
     Params &build()
     {
       BLI_assert(m_signature != nullptr);
diff --git a/source/blender/blenkernel/BKE_virtual_node_tree_cxx.h b/source/blender/blenkernel/BKE_virtual_node_tree_cxx.h
index 3bb9da4b00e..02b3069822c 100644
--- a/source/blender/blenkernel/BKE_virtual_node_tree_cxx.h
+++ b/source/blender/blenkernel/BKE_virtual_node_tree_cxx.h
@@ -254,6 +254,11 @@ class VirtualSocket {
     return m_links;
   }
 
+  bool is_linked() const
+  {
+    return m_links.size() > 0;
+  }
+
   PointerRNA rna()
   {
     PointerRNA rna;
diff --git a/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc b/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
index 9faea130606..14582af0bb8 100644
--- a/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
+++ b/source/blender/modifiers/intern/MOD_functiondeform_cxx.cc
@@ -2,9 +2,12 @@
 
 #include "BKE_virtual_node_tree_cxx.h"
 #include "BKE_multi_functions.h"
+#include "BKE_tuple.h"
 
 #include "BLI_math_cxx.h"
 
+using BKE::CPPType;
+using BKE::TupleRef;
 using BKE::VirtualLink;
 using BKE::VirtualNode;
 using BKE::VirtualNodeTree;
@@ -12,6 +15,7 @@ using BKE::VirtualSocket;
 using BLI::ArrayRef;
 using BLI::float3;
 using BLI::IndexRange;
+using BLI::StringRef;
 using BLI::TemporaryVector;
 using BLI::Vector;
 
@@ -19,6 +23,213 @@ extern "C" {
 void MOD_functiondeform_do(FunctionDeformModifierData *fdmd, float (*vertexCos)[3], int numVerts);
 }
 
+static CPPType &get_type_by_socket(VirtualSocket *vsocket)
+{
+  StringRef idname = vsocket->idname();
+
+  if (idname == "fn_FloatSocket") {
+    return BKE::GET_TYPE<float>();
+  }
+  else if (idname == "fn_IntegerSocket") {
+    return BKE::GET_TYPE<int>();
+  }
+  else if (idname == "fn_VectorSocket") {
+    return BKE::GET_TYPE<float3>();
+  }
+  BLI_assert(false);
+  return BKE::GET_TYPE<float>();
+}
+
+static std::unique_ptr<BKE::MultiFunction> get_multi_function_by_node(VirtualNode *vnode)
+{
+  StringRef idname = vnode->idname();
+
+  if (idname == "fn_VectorMathNode") {
+    return BLI::make_unique<BKE::MultiFunction_AddFloat3s>();
+  }
+  else {
+    BLI_assert(false);
+    return {};
+  }
+}
+
+static void load_socket_value(VirtualSocket *vsocket, TupleRef tuple, uint index)
+{
+  StringRef idname = vsocket->idname();
+  PointerRNA rna = vsocket->rna();
+
+  if (idname == "fn_FloatSocket") {
+    float value = RNA_float_get(&rna, "value");
+    tuple.set<float>(index, value);
+  }
+  else if (idname == "fn_IntegerSocket") {
+    int value = RNA_int_get(&rna, "value");
+    tuple.set<int>(index, value);
+  }
+  else if (idname == "fn_VectorSocket") {
+    float3 value;
+    RNA_float_get_array(&rna, "value", value);
+    tuple.set<float3>(index, value);
+  }
+  else {
+    BLI_assert(false);
+  }
+}
+
+class MultiFunction_FunctionTree : public BKE::MultiFunction {
+ private:
+  VirtualNode &m_input_vnode;
+  VirtualNode &m_output_vnode;
+
+ public:
+  MultiFunction_FunctionTree(VirtualNode &input_vnode, VirtualNode &output_vnode)
+      : m_input_vnode(input_vnode), m_output_vnode(output_vnode)
+  {
+    SignatureBuilder signature;
+    for (VirtualSocket *vsocket : input_vnode.outputs().drop_back(1)) {
+      CPPType &type = get_type_by_socket(vsocket);
+      signature.readonly_single_input(vsocket->name(), type);
+    }
+    for (VirtualSocket *vsocket : output_vnode.inputs().drop_back(1)) {
+      CPPType &type = get_type_by_socket(vsocket);
+      signature.single_output(vsocket->name(), type);
+    }
+    this->set_signature(signature);
+  }
+
+  void call(ArrayRef<uint> mask_indices, Params &params) const override
+  {
+    if (mask_indices.size() == 0) {
+      return;
+    }
+
+    for (uint output_index = 0; output_index < m_output_vnode.inputs().size() - 1;
+         output_index++) {
+      uint param_index = output_index + m_input_vnode.outputs().size() - 1;
+      VirtualSocket *vsocket = m_output_vnode.input(output_index);
+      BKE::GenericMutableArrayRef output_array = params.single_output(param_index,
+                                                                      vsocket->name());
+
+      if (vsocket->is_linked()) {
+        this->compute_output(mask_indices, params, vsocket->links()[0], output_array);
+      }
+      else {
+        CPPType &type = get_type_by_socket(vsocket);
+        BKE::TupleInfo value_info{{&type}};
+        BKE_TUPLE_STACK_ALLOC(value_tuple, value_info);
+        load_socket_value(vsocket, value_tuple, 0);
+        for (uint i : mask_indices) {
+          output_array.copy_in__uninitialized(i, value_tuple->element_ptr(0));
+        }
+      }
+    }
+  }
+
+  void compute_output(ArrayRef<uint> mask_indices,
+                      Params &global_params,
+                      VirtualSocket *vsocket,
+                      BKE::GenericMutableArrayRef result) const
+  {
+    VirtualNode *vnode = vsocket->vnode();
+
+    uint output_index = 0;
+    while (vnode->outputs()[output_index] != vsocket) {
+      output_index++;
+    }
+
+    if (vnode == &m_input_vnode) {
+      auto input_values = global_params.readonly_single_input(output_index, vsocket->name());
+
+      for (uint i : mask_indices) {
+        result.copy_in__uninitialized(i, input_values[i]);
+      }
+
+      return;
+    }
+
+    auto node_function = get_multi_function_by_node(vnode);
+
+    ParamsBuilder params;
+    uint array_size = result.size();
+    params.start_new(node_function->signature(), array_size);
+
+    Vector<void *> linked_buffers;
+    Vector<CPPType *> unlinked_types;
+
+    for (VirtualSocket *input_vsocket : vnode->inputs()) {
+      CPPType &type = get_type_by_socket(input_vsocket);
+      if (input_vsocket->is_linked()) {
+        void *buffer = MEM_mallocN_aligned(array_size * type.size(), type.alignment(), __func__);
+        linked_buffers.append(buffer);
+      }
+      else {
+        unlinked_types.append(&type);
+      }
+    }
+
+    BKE::TupleInfo unlinked_info{unlinked_types};
+    BKE_TUPLE_STACK_ALLOC(unlinked_values, unlinked_info);
+
+    {
+      uint linked_index = 0;
+      uint unlinked_index = 0;
+      for (VirtualSocket *input_vsocket : vnode->inputs()) {
+        if (input_vsocket->is_linked()) {
+          CPPType &type = get_type_by_socket(input_vsocket);
+          BKE::GenericMutableArrayRef array_ref{&type, linked_buffers[linked_index], array_size};
+          VirtualSocket *origin = input_vsocket->links()[0];
+          this->compute_output(mask_indices, global_params, origin, array_ref);
+          params.add_readonly_array_ref(array_ref);
+          linked_index++;
+        }
+        else {
+          load_socket_value(input_vsocket, unlinked_values, unlinked_index);
+          params.add_readonly_single_ref(unlinked_values, unlinked_index);
+          unlinked_index++;
+        }
+      }
+    }
+
+    Vector<BKE::GenericMutableArrayRef> temporary_output_buffers;
+    {
+      for (VirtualSocket *output_vsocket : vnode->outputs()) {
+        if (output_vsocket == vsocket) {
+          params.add_mutable_array_ref(result);
+        }
+        else {
+          CPPType &type = get_type_by_socket(output_vsocket);
+          void *buffer = MEM_mallocN_aligned(type.size() * array_size, type.alignment(), __func__);
+          BKE::GenericMutableArrayRef array_ref{&type, buffer, array_size};
+          params.add_mutable_array_ref(array_ref);
+          temporary_output_buffers.append(array_ref);
+        }
+      }
+    }
+
+    node_function->call(mask_indices, params.build());
+
+    {
+      uint linked_index = 0;
+      for (VirtualSocket *input_vsocket : vnode->inputs()) {
+        if (input_vsocket->is_linked()) {
+          CPPType &type = get_type_by_socket(input_vsocket);
+          void *buffer = linked_buffers[linked_index];
+          for (uint i : mask_indices) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list