[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 ¶ms) 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