Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-07-17 12:36:59 +0300
committerJacques Lucke <jacques@blender.org>2020-07-17 12:36:59 +0300
commit5910dbdbf7dc7999597a680f81c261fa7bbcf011 (patch)
treeedc962ebd6b11d89d3c29e571caeee0dcbe4ad79 /source/blender/blenkernel/intern
parent0a40c671b0b5a6735bd0137ebcb3ab7568ae4481 (diff)
Nodes: move some code from blenkernel directory to nodes
This also introduces the `blender::nodes` namespace. Eventually, we want to move most/all of the node implementation files into this namespace. The reason for this file-move is that the code fits much better into the `nodes` directory than in the `blenkernel` directory.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/derived_node_tree.cc441
-rw-r--r--source/blender/blenkernel/intern/node_tree_multi_function.cc346
-rw-r--r--source/blender/blenkernel/intern/node_tree_ref.cc177
-rw-r--r--source/blender/blenkernel/intern/simulation.cc44
4 files changed, 25 insertions, 983 deletions
diff --git a/source/blender/blenkernel/intern/derived_node_tree.cc b/source/blender/blenkernel/intern/derived_node_tree.cc
deleted file mode 100644
index 01317eeb5ce..00000000000
--- a/source/blender/blenkernel/intern/derived_node_tree.cc
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "BKE_derived_node_tree.hh"
-
-#include "BLI_dot_export.hh"
-
-#define UNINITIALIZED_ID UINT32_MAX
-
-namespace blender::bke {
-
-static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree *btree)
-{
- return *node_tree_refs.lookup_or_add_cb(btree,
- [&]() { return std::make_unique<NodeTreeRef>(btree); });
-}
-
-DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) : btree_(btree)
-{
- const NodeTreeRef &main_tree_ref = get_tree_ref(node_tree_refs, btree);
-
- Vector<DNode *> all_nodes;
- Vector<DGroupInput *> all_group_inputs;
- Vector<DParentNode *> all_parent_nodes;
-
- this->insert_nodes_and_links_in_id_order(main_tree_ref, nullptr, all_nodes);
- this->expand_groups(all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
- this->remove_expanded_group_interfaces(all_nodes);
- this->remove_unused_group_inputs(all_group_inputs);
- this->store_in_this_and_init_ids(
- std::move(all_nodes), std::move(all_group_inputs), std::move(all_parent_nodes));
-}
-
-BLI_NOINLINE void DerivedNodeTree::insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref,
- DParentNode *parent,
- Vector<DNode *> &all_nodes)
-{
- Array<DSocket *, 64> sockets_map(tree_ref.sockets().size());
-
- /* Insert nodes. */
- for (const NodeRef *node_ref : tree_ref.nodes()) {
- DNode &node = this->create_node(*node_ref, parent, sockets_map);
- all_nodes.append(&node);
- }
-
- /* Insert links. */
- for (const NodeRef *node_ref : tree_ref.nodes()) {
- for (const InputSocketRef *to_socket_ref : node_ref->inputs()) {
- DInputSocket *to_socket = (DInputSocket *)sockets_map[to_socket_ref->id()];
- for (const OutputSocketRef *from_socket_ref : to_socket_ref->linked_sockets()) {
- DOutputSocket *from_socket = (DOutputSocket *)sockets_map[from_socket_ref->id()];
- to_socket->linked_sockets_.append(from_socket);
- from_socket->linked_sockets_.append(to_socket);
- }
- }
- }
-}
-
-DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
- DParentNode *parent,
- MutableSpan<DSocket *> r_sockets_map)
-{
- DNode &node = *allocator_.construct<DNode>();
- node.node_ref_ = &node_ref;
- node.parent_ = parent;
- node.id_ = UNINITIALIZED_ID;
-
- node.inputs_ = allocator_.construct_elements_and_pointer_array<DInputSocket>(
- node_ref.inputs().size());
- node.outputs_ = allocator_.construct_elements_and_pointer_array<DOutputSocket>(
- node_ref.outputs().size());
-
- for (uint i : node.inputs_.index_range()) {
- const InputSocketRef &socket_ref = node_ref.input(i);
- DInputSocket &socket = *node.inputs_[i];
-
- socket.id_ = UNINITIALIZED_ID;
- socket.node_ = &node;
- socket.socket_ref_ = &socket_ref;
-
- r_sockets_map[socket_ref.id()] = &socket;
- }
-
- for (uint i : node.outputs_.index_range()) {
- const OutputSocketRef &socket_ref = node_ref.output(i);
- DOutputSocket &socket = *node.outputs_[i];
-
- socket.id_ = UNINITIALIZED_ID;
- socket.node_ = &node;
- socket.socket_ref_ = &socket_ref;
-
- r_sockets_map[socket_ref.id()] = &socket;
- }
-
- return node;
-}
-
-BLI_NOINLINE void DerivedNodeTree::expand_groups(Vector<DNode *> &all_nodes,
- Vector<DGroupInput *> &all_group_inputs,
- Vector<DParentNode *> &all_parent_nodes,
- NodeTreeRefMap &node_tree_refs)
-{
- for (uint i = 0; i < all_nodes.size(); i++) {
- DNode &node = *all_nodes[i];
- if (node.node_ref_->is_group_node()) {
- this->expand_group_node(node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
- }
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::expand_group_node(DNode &group_node,
- Vector<DNode *> &all_nodes,
- Vector<DGroupInput *> &all_group_inputs,
- Vector<DParentNode *> &all_parent_nodes,
- NodeTreeRefMap &node_tree_refs)
-{
- const NodeRef &group_node_ref = *group_node.node_ref_;
- BLI_assert(group_node_ref.is_group_node());
-
- bNodeTree *btree = (bNodeTree *)group_node_ref.bnode()->id;
- if (btree == nullptr) {
- return;
- }
-
- const NodeTreeRef &group_ref = get_tree_ref(node_tree_refs, btree);
-
- DParentNode &parent = *allocator_.construct<DParentNode>();
- parent.id_ = all_parent_nodes.append_and_get_index(&parent);
- parent.parent_ = group_node.parent_;
- parent.node_ref_ = &group_node_ref;
-
- this->insert_nodes_and_links_in_id_order(group_ref, &parent, all_nodes);
- Span<DNode *> new_nodes_by_id = all_nodes.as_span().take_back(group_ref.nodes().size());
-
- this->create_group_inputs_for_unlinked_inputs(group_node, all_group_inputs);
- this->relink_group_inputs(group_ref, new_nodes_by_id, group_node);
- this->relink_group_outputs(group_ref, new_nodes_by_id, group_node);
-}
-
-BLI_NOINLINE void DerivedNodeTree::create_group_inputs_for_unlinked_inputs(
- DNode &node, Vector<DGroupInput *> &all_group_inputs)
-{
- for (DInputSocket *input_socket : node.inputs_) {
- if (input_socket->is_linked()) {
- continue;
- }
-
- DGroupInput &group_input = *allocator_.construct<DGroupInput>();
- group_input.id_ = UNINITIALIZED_ID;
- group_input.socket_ref_ = &input_socket->socket_ref();
- group_input.parent_ = node.parent_;
-
- group_input.linked_sockets_.append(input_socket);
- input_socket->linked_group_inputs_.append(&group_input);
- all_group_inputs.append(&group_input);
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::relink_group_inputs(const NodeTreeRef &group_ref,
- Span<DNode *> nodes_by_id,
- DNode &group_node)
-{
- Span<const NodeRef *> node_refs = group_ref.nodes_by_type("NodeGroupInput");
- if (node_refs.size() == 0) {
- return;
- }
- /* TODO: Pick correct group input node if there are more than one. */
- const NodeRef &input_node_ref = *node_refs[0];
- DNode &input_node = *nodes_by_id[input_node_ref.id()];
-
- uint input_amount = group_node.inputs().size();
- BLI_assert(input_amount == input_node_ref.outputs().size() - 1);
-
- for (uint input_index : IndexRange(input_amount)) {
- DInputSocket *outside_group = group_node.inputs_[input_index];
- DOutputSocket *inside_group = input_node.outputs_[input_index];
-
- for (DOutputSocket *outside_connected : outside_group->linked_sockets_) {
- outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
- }
-
- for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) {
- outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
- }
-
- for (DInputSocket *inside_connected : inside_group->linked_sockets_) {
- inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
-
- for (DOutputSocket *outside_connected : outside_group->linked_sockets_) {
- inside_connected->linked_sockets_.append(outside_connected);
- outside_connected->linked_sockets_.append(inside_connected);
- }
-
- for (DGroupInput *outside_connected : outside_group->linked_group_inputs_) {
- inside_connected->linked_group_inputs_.append(outside_connected);
- outside_connected->linked_sockets_.append(inside_connected);
- }
- }
-
- inside_group->linked_sockets_.clear();
- outside_group->linked_sockets_.clear();
- outside_group->linked_group_inputs_.clear();
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::relink_group_outputs(const NodeTreeRef &group_ref,
- Span<DNode *> nodes_by_id,
- DNode &group_node)
-{
- Span<const NodeRef *> node_refs = group_ref.nodes_by_type("NodeGroupOutput");
- if (node_refs.size() == 0) {
- return;
- }
- /* TODO: Pick correct group output node if there are more than one. */
- const NodeRef &output_node_ref = *node_refs[0];
- DNode &output_node = *nodes_by_id[output_node_ref.id()];
-
- uint output_amount = group_node.outputs().size();
- BLI_assert(output_amount == output_node_ref.inputs().size() - 1);
-
- for (uint output_index : IndexRange(output_amount)) {
- DOutputSocket *outside_group = group_node.outputs_[output_index];
- DInputSocket *inside_group = output_node.inputs_[output_index];
-
- for (DInputSocket *outside_connected : outside_group->linked_sockets_) {
- outside_connected->linked_sockets_.remove_first_occurrence_and_reorder(outside_group);
- }
-
- for (DOutputSocket *inside_connected : inside_group->linked_sockets_) {
- inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
-
- for (DInputSocket *outside_connected : outside_group->linked_sockets_) {
- inside_connected->linked_sockets_.append(outside_connected);
- outside_connected->linked_sockets_.append(inside_connected);
- }
- }
-
- for (DGroupInput *inside_connected : inside_group->linked_group_inputs_) {
- inside_connected->linked_sockets_.remove_first_occurrence_and_reorder(inside_group);
-
- for (DInputSocket *outside_connected : outside_group->linked_sockets_) {
- inside_connected->linked_sockets_.append(outside_connected);
- outside_connected->linked_group_inputs_.append(inside_connected);
- }
- }
-
- outside_group->linked_sockets_.clear();
- inside_group->linked_sockets_.clear();
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::remove_expanded_group_interfaces(Vector<DNode *> &all_nodes)
-{
- int index = 0;
- while (index < all_nodes.size()) {
- DNode &node = *all_nodes[index];
- const NodeRef &node_ref = *node.node_ref_;
- if (node_ref.is_group_node() ||
- (node.parent_ != nullptr &&
- (node_ref.is_group_input_node() || node_ref.is_group_output_node()))) {
- all_nodes.remove_and_reorder(index);
- node.destruct_with_sockets();
- }
- else {
- index++;
- }
- }
-}
-
-BLI_NOINLINE void DerivedNodeTree::remove_unused_group_inputs(
- Vector<DGroupInput *> &all_group_inputs)
-{
- int index = 0;
- while (index < all_group_inputs.size()) {
- DGroupInput &group_input = *all_group_inputs[index];
- if (group_input.linked_sockets_.is_empty()) {
- all_group_inputs.remove_and_reorder(index);
- group_input.~DGroupInput();
- }
- else {
- index++;
- }
- }
-}
-
-void DNode::destruct_with_sockets()
-{
- for (DInputSocket *socket : inputs_) {
- socket->~DInputSocket();
- }
- for (DOutputSocket *socket : outputs_) {
- socket->~DOutputSocket();
- }
- this->~DNode();
-}
-
-BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids(
- Vector<DNode *> &&all_nodes,
- Vector<DGroupInput *> &&all_group_inputs,
- Vector<DParentNode *> &&all_parent_nodes)
-{
- nodes_by_id_ = std::move(all_nodes);
- group_inputs_ = std::move(all_group_inputs);
- parent_nodes_ = std::move(all_parent_nodes);
-
- for (uint node_index : nodes_by_id_.index_range()) {
- DNode *node = nodes_by_id_[node_index];
- node->id_ = node_index;
-
- const bNodeType *nodetype = node->node_ref_->bnode()->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
-
- for (DInputSocket *socket : node->inputs_) {
- socket->id_ = sockets_by_id_.append_and_get_index(socket);
- input_sockets_.append(socket);
- }
- for (DOutputSocket *socket : node->outputs_) {
- socket->id_ = sockets_by_id_.append_and_get_index(socket);
- output_sockets_.append(socket);
- }
- }
-
- for (uint i : group_inputs_.index_range()) {
- group_inputs_[i]->id_ = i;
- }
-}
-
-DerivedNodeTree::~DerivedNodeTree()
-{
- for (DInputSocket *socket : input_sockets_) {
- socket->~DInputSocket();
- }
- for (DOutputSocket *socket : output_sockets_) {
- socket->~DOutputSocket();
- }
- for (DNode *node : nodes_by_id_) {
- node->~DNode();
- }
- for (DGroupInput *group_input : group_inputs_) {
- group_input->~DGroupInput();
- }
- for (DParentNode *parent : parent_nodes_) {
- parent->~DParentNode();
- }
-}
-
-static dot::Cluster *get_cluster_for_parent(dot::DirectedGraph &graph,
- Map<const DParentNode *, dot::Cluster *> &clusters,
- const DParentNode *parent)
-{
- if (parent == nullptr) {
- return nullptr;
- }
- return clusters.lookup_or_add_cb(parent, [&]() {
- dot::Cluster *parent_cluster = get_cluster_for_parent(graph, clusters, parent->parent());
- bNodeTree *btree = (bNodeTree *)parent->node_ref().bnode()->id;
- dot::Cluster *new_cluster = &graph.new_cluster(parent->node_ref().name() + " / " +
- StringRef(btree->id.name + 2));
- new_cluster->set_parent_cluster(parent_cluster);
- return new_cluster;
- });
-}
-
-std::string DerivedNodeTree::to_dot() const
-{
- dot::DirectedGraph digraph;
- digraph.set_rankdir(dot::Attr_rankdir::LeftToRight);
-
- Map<const DNode *, dot::NodeWithSocketsRef> dot_nodes;
- Map<const DGroupInput *, dot::NodeWithSocketsRef> dot_group_inputs;
- Map<const DParentNode *, dot::Cluster *> dot_clusters;
-
- for (const DNode *node : nodes_by_id_) {
- dot::Node &dot_node = digraph.new_node("");
- dot_node.set_background_color("white");
-
- Vector<std::string> input_names;
- for (const DInputSocket *socket : node->inputs()) {
- input_names.append(socket->name());
- }
- Vector<std::string> output_names;
- for (const DOutputSocket *socket : node->outputs()) {
- output_names.append(socket->name());
- }
-
- dot_nodes.add_new(node,
- dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names));
-
- dot::Cluster *cluster = get_cluster_for_parent(digraph, dot_clusters, node->parent());
- dot_node.set_parent_cluster(cluster);
- }
-
- for (const DGroupInput *group_input : group_inputs_) {
- dot::Node &dot_node = digraph.new_node("");
- dot_node.set_background_color("white");
-
- std::string group_input_name = group_input->name();
- dot_group_inputs.add_new(
- group_input, dot::NodeWithSocketsRef(dot_node, "Group Input", {}, {group_input_name}));
-
- dot::Cluster *cluster = get_cluster_for_parent(digraph, dot_clusters, group_input->parent());
- dot_node.set_parent_cluster(cluster);
- }
-
- for (const DNode *to_node : nodes_by_id_) {
- dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(to_node);
-
- for (const DInputSocket *to_socket : to_node->inputs()) {
- for (const DOutputSocket *from_socket : to_socket->linked_sockets()) {
- const DNode *from_node = &from_socket->node();
- dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(from_node);
-
- digraph.new_edge(from_dot_node.output(from_socket->index()),
- to_dot_node.input(to_socket->index()));
- }
- for (const DGroupInput *group_input : to_socket->linked_group_inputs()) {
- dot::NodeWithSocketsRef &from_dot_node = dot_group_inputs.lookup(group_input);
-
- digraph.new_edge(from_dot_node.output(0), to_dot_node.input(to_socket->index()));
- }
- }
- }
-
- digraph.set_random_cluster_bgcolors();
- return digraph.to_dot_string();
-}
-
-} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/node_tree_multi_function.cc b/source/blender/blenkernel/intern/node_tree_multi_function.cc
deleted file mode 100644
index 537ec056126..00000000000
--- a/source/blender/blenkernel/intern/node_tree_multi_function.cc
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "BKE_node_tree_multi_function.hh"
-
-#include "BLI_color.hh"
-#include "BLI_float3.hh"
-
-namespace blender {
-namespace bke {
-
-/* Maybe this should be moved to BKE_node.h. */
-static std::optional<fn::MFDataType> try_get_multi_function_data_type_of_socket(
- const bNodeSocket *bsocket)
-{
- if (bsocket->typeinfo->get_mf_data_type == nullptr) {
- return {};
- }
- return bsocket->typeinfo->get_mf_data_type();
-}
-
-const fn::MultiFunction &NodeMFNetworkBuilder::get_default_fn(StringRef name)
-{
- Vector<fn::MFDataType, 10> input_types;
- Vector<fn::MFDataType, 10> output_types;
-
- for (const DInputSocket *dsocket : dnode_.inputs()) {
- if (dsocket->is_available()) {
- std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
- dsocket->bsocket());
- if (data_type.has_value()) {
- input_types.append(*data_type);
- }
- }
- }
- for (const DOutputSocket *dsocket : dnode_.outputs()) {
- if (dsocket->is_available()) {
- std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
- dsocket->bsocket());
- if (data_type.has_value()) {
- output_types.append(*data_type);
- }
- }
- }
-
- const fn::MultiFunction &fn = this->construct_fn<fn::CustomMF_DefaultOutput>(
- name, input_types, output_types);
- return fn;
-}
-
-static void insert_dummy_node(CommonMFNetworkBuilderData &common, const DNode &dnode)
-{
- constexpr uint stack_capacity = 10;
-
- Vector<fn::MFDataType, stack_capacity> input_types;
- Vector<StringRef, stack_capacity> input_names;
- Vector<const DInputSocket *, stack_capacity> input_dsockets;
-
- for (const DInputSocket *dsocket : dnode.inputs()) {
- if (dsocket->is_available()) {
- std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
- dsocket->bsocket());
- if (data_type.has_value()) {
- input_types.append(*data_type);
- input_names.append(dsocket->name());
- input_dsockets.append(dsocket);
- }
- }
- }
-
- Vector<fn::MFDataType, stack_capacity> output_types;
- Vector<StringRef, stack_capacity> output_names;
- Vector<const DOutputSocket *, stack_capacity> output_dsockets;
-
- for (const DOutputSocket *dsocket : dnode.outputs()) {
- if (dsocket->is_available()) {
- std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
- dsocket->bsocket());
- if (data_type.has_value()) {
- output_types.append(*data_type);
- output_names.append(dsocket->name());
- output_dsockets.append(dsocket);
- }
- }
- }
-
- fn::MFDummyNode &dummy_node = common.network.add_dummy(
- dnode.name(), input_types, output_types, input_names, output_names);
-
- common.network_map.add(input_dsockets, dummy_node.inputs());
- common.network_map.add(output_dsockets, dummy_node.outputs());
-}
-
-static bool has_data_sockets(const DNode &dnode)
-{
- for (const DInputSocket *socket : dnode.inputs()) {
- if (is_multi_function_data_socket(socket->bsocket())) {
- return true;
- }
- }
- for (const DOutputSocket *socket : dnode.outputs()) {
- if (is_multi_function_data_socket(socket->bsocket())) {
- return true;
- }
- }
- return false;
-}
-
-/**
- * Expands all function nodes in the multi-function network. Nodes that don't have an expand
- * function, but do have data sockets, will get corresponding dummy nodes.
- */
-static void insert_nodes(CommonMFNetworkBuilderData &common)
-{
- for (const DNode *dnode : common.tree.nodes()) {
- const bNodeType *node_type = dnode->node_ref().bnode()->typeinfo;
- if (node_type->expand_in_mf_network != nullptr) {
- NodeMFNetworkBuilder builder{common, *dnode};
- node_type->expand_in_mf_network(builder);
- }
- else if (has_data_sockets(*dnode)) {
- insert_dummy_node(common, *dnode);
- }
- }
-}
-
-static void insert_group_inputs(CommonMFNetworkBuilderData &common)
-{
- for (const DGroupInput *group_input : common.tree.group_inputs()) {
- bNodeSocket *bsocket = group_input->bsocket();
- if (is_multi_function_data_socket(bsocket)) {
- bNodeSocketType *socktype = bsocket->typeinfo;
- BLI_assert(socktype->expand_in_mf_network != nullptr);
-
- SocketMFNetworkBuilder builder{common, *group_input};
- socktype->expand_in_mf_network(builder);
-
- fn::MFOutputSocket *from_socket = builder.built_socket();
- BLI_assert(from_socket != nullptr);
- common.network_map.add(*group_input, *from_socket);
- }
- }
-}
-
-static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common,
- const DInputSocket &to_dsocket)
-{
- Span<const DOutputSocket *> from_dsockets = to_dsocket.linked_sockets();
- Span<const DGroupInput *> from_group_inputs = to_dsocket.linked_group_inputs();
- uint total_linked_amount = from_dsockets.size() + from_group_inputs.size();
- BLI_assert(total_linked_amount <= 1);
-
- if (total_linked_amount == 0) {
- return nullptr;
- }
-
- if (from_dsockets.size() == 1) {
- const DOutputSocket &from_dsocket = *from_dsockets[0];
- if (!from_dsocket.is_available()) {
- return nullptr;
- }
- if (is_multi_function_data_socket(from_dsocket.bsocket())) {
- return &common.network_map.lookup(from_dsocket);
- }
- return nullptr;
- }
- else {
- const DGroupInput &from_group_input = *from_group_inputs[0];
- if (is_multi_function_data_socket(from_group_input.bsocket())) {
- return &common.network_map.lookup(from_group_input);
- }
- return nullptr;
- }
-}
-
-using ImplicitConversionsMap =
- Map<std::pair<fn::MFDataType, fn::MFDataType>, const fn::MultiFunction *>;
-
-template<typename From, typename To>
-static void add_implicit_conversion(ImplicitConversionsMap &map)
-{
- static fn::CustomMF_Convert<From, To> function;
- map.add({fn::MFDataType::ForSingle<From>(), fn::MFDataType::ForSingle<To>()}, &function);
-}
-
-template<typename From, typename To, typename ConversionF>
-static void add_implicit_conversion(ImplicitConversionsMap &map,
- StringRef name,
- ConversionF conversion)
-{
- static fn::CustomMF_SI_SO<From, To> function{name, conversion};
- map.add({fn::MFDataType::ForSingle<From>(), fn::MFDataType::ForSingle<To>()}, &function);
-}
-
-static ImplicitConversionsMap get_implicit_conversions()
-{
- ImplicitConversionsMap conversions;
- add_implicit_conversion<float, int32_t>(conversions);
- add_implicit_conversion<float, float3>(conversions);
- add_implicit_conversion<int32_t, float>(conversions);
- add_implicit_conversion<float3, float>(
- conversions, "Vector Length", [](float3 a) { return a.length(); });
- add_implicit_conversion<int32_t, float3>(
- conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
- add_implicit_conversion<float3, Color4f>(
- conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
- add_implicit_conversion<Color4f, float3>(
- conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
- return conversions;
-}
-
-static const fn::MultiFunction *try_get_conversion_function(fn::MFDataType from, fn::MFDataType to)
-{
- static const ImplicitConversionsMap conversions = get_implicit_conversions();
- const fn::MultiFunction *function = conversions.lookup_default({from, to}, nullptr);
- return function;
-}
-
-static fn::MFOutputSocket &insert_default_value_for_type(CommonMFNetworkBuilderData &common,
- fn::MFDataType type)
-{
- const fn::MultiFunction *default_fn;
- if (type.is_single()) {
- default_fn = &common.resources.construct<fn::CustomMF_GenericConstant>(
- AT, type.single_type(), type.single_type().default_value());
- }
- else {
- default_fn = &common.resources.construct<fn::CustomMF_GenericConstantArray>(
- AT, fn::GSpan(type.vector_base_type()));
- }
-
- fn::MFNode &node = common.network.add_function(*default_fn);
- return node.output(0);
-}
-
-static void insert_links(CommonMFNetworkBuilderData &common)
-{
- for (const DInputSocket *to_dsocket : common.tree.input_sockets()) {
- if (!to_dsocket->is_available()) {
- continue;
- }
- if (!to_dsocket->is_linked()) {
- continue;
- }
- if (!is_multi_function_data_socket(to_dsocket->bsocket())) {
- continue;
- }
-
- Span<fn::MFInputSocket *> to_sockets = common.network_map.lookup(*to_dsocket);
- BLI_assert(to_sockets.size() >= 1);
- fn::MFDataType to_type = to_sockets[0]->data_type();
-
- fn::MFOutputSocket *from_socket = try_find_origin(common, *to_dsocket);
- if (from_socket == nullptr) {
- from_socket = &insert_default_value_for_type(common, to_type);
- }
-
- fn::MFDataType from_type = from_socket->data_type();
-
- if (from_type != to_type) {
- const fn::MultiFunction *conversion_fn = try_get_conversion_function(from_type, to_type);
- if (conversion_fn != nullptr) {
- fn::MFNode &node = common.network.add_function(*conversion_fn);
- common.network.add_link(*from_socket, node.input(0));
- from_socket = &node.output(0);
- }
- else {
- from_socket = &insert_default_value_for_type(common, to_type);
- }
- }
-
- for (fn::MFInputSocket *to_socket : to_sockets) {
- common.network.add_link(*from_socket, *to_socket);
- }
- }
-}
-
-static void insert_unlinked_input(CommonMFNetworkBuilderData &common, const DInputSocket &dsocket)
-{
- bNodeSocket *bsocket = dsocket.bsocket();
- bNodeSocketType *socktype = bsocket->typeinfo;
- BLI_assert(socktype->expand_in_mf_network != nullptr);
-
- SocketMFNetworkBuilder builder{common, dsocket};
- socktype->expand_in_mf_network(builder);
-
- fn::MFOutputSocket *from_socket = builder.built_socket();
- BLI_assert(from_socket != nullptr);
-
- for (fn::MFInputSocket *to_socket : common.network_map.lookup(dsocket)) {
- common.network.add_link(*from_socket, *to_socket);
- }
-}
-
-static void insert_unlinked_inputs(CommonMFNetworkBuilderData &common)
-{
- Vector<const DInputSocket *> unlinked_data_inputs;
- for (const DInputSocket *dsocket : common.tree.input_sockets()) {
- if (dsocket->is_available()) {
- if (is_multi_function_data_socket(dsocket->bsocket())) {
- if (!dsocket->is_linked()) {
- insert_unlinked_input(common, *dsocket);
- }
- }
- }
- }
-}
-
-/**
- * Expands all function nodes contained in the given node tree within the given multi-function
- * network.
- *
- * Returns a mapping between the original node tree and the generated nodes/sockets for further
- * processing.
- */
-MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network,
- const DerivedNodeTree &tree,
- ResourceCollector &resources)
-{
- MFNetworkTreeMap network_map{tree, network};
-
- CommonMFNetworkBuilderData common{resources, network, network_map, tree};
-
- insert_nodes(common);
- insert_group_inputs(common);
- insert_links(common);
- insert_unlinked_inputs(common);
-
- return network_map;
-}
-
-} // namespace bke
-} // namespace blender
diff --git a/source/blender/blenkernel/intern/node_tree_ref.cc b/source/blender/blenkernel/intern/node_tree_ref.cc
deleted file mode 100644
index 5c998a06cb5..00000000000
--- a/source/blender/blenkernel/intern/node_tree_ref.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "BKE_node_tree_ref.hh"
-
-#include "BLI_dot_export.hh"
-
-namespace blender::bke {
-
-NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
-{
- Map<bNode *, NodeRef *> node_mapping;
-
- LISTBASE_FOREACH (bNode *, bnode, &btree->nodes) {
- NodeRef &node = *allocator_.construct<NodeRef>();
-
- node.tree_ = this;
- node.bnode_ = bnode;
- node.id_ = nodes_by_id_.append_and_get_index(&node);
- RNA_pointer_create(&btree->id, &RNA_Node, bnode, &node.rna_);
-
- LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->inputs) {
- InputSocketRef &socket = *allocator_.construct<InputSocketRef>();
- socket.node_ = &node;
- socket.index_ = node.inputs_.append_and_get_index(&socket);
- socket.is_input_ = true;
- socket.bsocket_ = bsocket;
- socket.id_ = sockets_by_id_.append_and_get_index(&socket);
- RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.rna_);
- }
-
- LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->outputs) {
- OutputSocketRef &socket = *allocator_.construct<OutputSocketRef>();
- socket.node_ = &node;
- socket.index_ = node.outputs_.append_and_get_index(&socket);
- socket.is_input_ = false;
- socket.bsocket_ = bsocket;
- socket.id_ = sockets_by_id_.append_and_get_index(&socket);
- RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.rna_);
- }
-
- input_sockets_.extend(node.inputs_.as_span());
- output_sockets_.extend(node.outputs_.as_span());
-
- node_mapping.add_new(bnode, &node);
- }
-
- LISTBASE_FOREACH (bNodeLink *, blink, &btree->links) {
- OutputSocketRef &from_socket = this->find_output_socket(
- node_mapping, blink->fromnode, blink->fromsock);
- InputSocketRef &to_socket = this->find_input_socket(
- node_mapping, blink->tonode, blink->tosock);
-
- from_socket.directly_linked_sockets_.append(&to_socket);
- to_socket.directly_linked_sockets_.append(&from_socket);
- }
-
- for (OutputSocketRef *socket : output_sockets_) {
- if (!socket->node_->is_reroute_node()) {
- this->find_targets_skipping_reroutes(*socket, socket->linked_sockets_);
- for (SocketRef *target : socket->linked_sockets_) {
- target->linked_sockets_.append(socket);
- }
- }
- }
-
- for (NodeRef *node : nodes_by_id_) {
- const bNodeType *nodetype = node->bnode_->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
- }
-}
-
-NodeTreeRef::~NodeTreeRef()
-{
- for (NodeRef *node : nodes_by_id_) {
- node->~NodeRef();
- }
- for (InputSocketRef *socket : input_sockets_) {
- socket->~InputSocketRef();
- }
- for (OutputSocketRef *socket : output_sockets_) {
- socket->~OutputSocketRef();
- }
-}
-
-InputSocketRef &NodeTreeRef::find_input_socket(Map<bNode *, NodeRef *> &node_mapping,
- bNode *bnode,
- bNodeSocket *bsocket)
-{
- NodeRef *node = node_mapping.lookup(bnode);
- for (SocketRef *socket : node->inputs_) {
- if (socket->bsocket_ == bsocket) {
- return *(InputSocketRef *)socket;
- }
- }
- BLI_assert(false);
- return *node->inputs_[0];
-}
-
-OutputSocketRef &NodeTreeRef::find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
- bNode *bnode,
- bNodeSocket *bsocket)
-{
- NodeRef *node = node_mapping.lookup(bnode);
- for (SocketRef *socket : node->outputs_) {
- if (socket->bsocket_ == bsocket) {
- return *(OutputSocketRef *)socket;
- }
- }
- BLI_assert(false);
- return *node->outputs_[0];
-}
-
-void NodeTreeRef::find_targets_skipping_reroutes(OutputSocketRef &socket,
- Vector<SocketRef *> &r_targets)
-{
- for (SocketRef *direct_target : socket.directly_linked_sockets_) {
- if (direct_target->node_->is_reroute_node()) {
- this->find_targets_skipping_reroutes(*direct_target->node_->outputs_[0], r_targets);
- }
- else {
- r_targets.append_non_duplicates(direct_target);
- }
- }
-}
-
-std::string NodeTreeRef::to_dot() const
-{
- dot::DirectedGraph digraph;
- digraph.set_rankdir(dot::Attr_rankdir::LeftToRight);
-
- Map<const NodeRef *, dot::NodeWithSocketsRef> dot_nodes;
-
- for (const NodeRef *node : nodes_by_id_) {
- dot::Node &dot_node = digraph.new_node("");
- dot_node.set_background_color("white");
-
- Vector<std::string> input_names;
- Vector<std::string> output_names;
- for (const InputSocketRef *socket : node->inputs()) {
- input_names.append(socket->name());
- }
- for (const OutputSocketRef *socket : node->outputs()) {
- output_names.append(socket->name());
- }
-
- dot_nodes.add_new(node,
- dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names));
- }
-
- for (const OutputSocketRef *from_socket : output_sockets_) {
- for (const InputSocketRef *to_socket : from_socket->directly_linked_sockets()) {
- dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(&from_socket->node());
- dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(&to_socket->node());
-
- digraph.new_edge(from_dot_node.output(from_socket->index()),
- to_dot_node.input(to_socket->index()));
- }
- }
-
- return digraph.to_dot_string();
-}
-
-} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 831de084500..f38001bf69f 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -45,10 +45,10 @@
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_node_tree_multi_function.hh"
#include "BKE_pointcache.h"
#include "BKE_simulation.h"
+#include "NOD_node_tree_multi_function.hh"
#include "NOD_simulation.h"
#include "BLT_translation.h"
@@ -216,16 +216,19 @@ static void copy_states_to_cow(Simulation *simulation_orig, Simulation *simulati
}
static Map<const fn::MFOutputSocket *, std::string> deduplicate_attribute_nodes(
- fn::MFNetwork &network, MFNetworkTreeMap &network_map, const DerivedNodeTree &tree)
+ fn::MFNetwork &network,
+ nodes::MFNetworkTreeMap &network_map,
+ const nodes::DerivedNodeTree &tree)
{
- Span<const DNode *> attribute_dnodes = tree.nodes_by_type("SimulationNodeParticleAttribute");
+ Span<const nodes::DNode *> attribute_dnodes = tree.nodes_by_type(
+ "SimulationNodeParticleAttribute");
uint amount = attribute_dnodes.size();
if (amount == 0) {
return {};
}
Vector<fn::MFInputSocket *> name_sockets;
- for (const DNode *dnode : attribute_dnodes) {
+ for (const nodes::DNode *dnode : attribute_dnodes) {
fn::MFInputSocket &name_socket = network_map.lookup_dummy(dnode->input(0));
name_sockets.append(&name_socket);
}
@@ -309,10 +312,10 @@ class CustomDataAttributesRef {
}
};
-static std::string dnode_to_path(const DNode &dnode)
+static std::string dnode_to_path(const nodes::DNode &dnode)
{
std::string path;
- for (const DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) {
+ for (const nodes::DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) {
path = parent->node_ref().name() + "/" + path;
}
path = path + dnode.name();
@@ -373,10 +376,10 @@ static void add_missing_particle_states(Simulation *simulation, Span<std::string
}
static void reinitialize_empty_simulation_states(Simulation *simulation,
- const DerivedNodeTree &tree)
+ const nodes::DerivedNodeTree &tree)
{
VectorSet<std::string> state_names;
- for (const DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) {
+ for (const nodes::DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) {
state_names.add(dnode_to_path(*dnode));
}
@@ -385,10 +388,11 @@ static void reinitialize_empty_simulation_states(Simulation *simulation,
add_missing_particle_states(simulation, state_names);
}
-static void update_simulation_state_list(Simulation *simulation, const DerivedNodeTree &tree)
+static void update_simulation_state_list(Simulation *simulation,
+ const nodes::DerivedNodeTree &tree)
{
VectorSet<std::string> state_names;
- for (const DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) {
+ for (const nodes::DNode *dnode : tree.nodes_by_type("SimulationNodeParticleSimulation")) {
state_names.add(dnode_to_path(*dnode));
}
@@ -672,14 +676,15 @@ class ParticleFunctionForce : public ParticleForce {
};
static Vector<const ParticleForce *> create_forces_for_particle_simulation(
- const DNode &simulation_node,
- MFNetworkTreeMap &network_map,
+ const nodes::DNode &simulation_node,
+ nodes::MFNetworkTreeMap &network_map,
ResourceCollector &resources,
const Map<const fn::MFOutputSocket *, std::string> &attribute_inputs)
{
Vector<const ParticleForce *> forces;
- for (const DOutputSocket *origin_socket : simulation_node.input(2, "Forces").linked_sockets()) {
- const DNode &origin_node = origin_socket->node();
+ for (const nodes::DOutputSocket *origin_socket :
+ simulation_node.input(2, "Forces").linked_sockets()) {
+ const nodes::DNode &origin_node = origin_socket->node();
if (origin_node.idname() != "SimulationNodeForce") {
continue;
}
@@ -701,12 +706,13 @@ static Vector<const ParticleForce *> create_forces_for_particle_simulation(
}
static Map<std::string, Vector<const ParticleForce *>> collect_forces(
- MFNetworkTreeMap &network_map,
+ nodes::MFNetworkTreeMap &network_map,
ResourceCollector &resources,
const Map<const fn::MFOutputSocket *, std::string> &attribute_inputs)
{
Map<std::string, Vector<const ParticleForce *>> forces_by_simulation;
- for (const DNode *dnode : network_map.tree().nodes_by_type("SimulationNodeParticleSimulation")) {
+ for (const nodes::DNode *dnode :
+ network_map.tree().nodes_by_type("SimulationNodeParticleSimulation")) {
std::string name = dnode_to_path(*dnode);
Vector<const ParticleForce *> forces = create_forces_for_particle_simulation(
*dnode, network_map, resources, attribute_inputs);
@@ -729,12 +735,12 @@ static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulatio
Simulation *simulation_orig = (Simulation *)DEG_get_original_id(&simulation_cow->id);
- NodeTreeRefMap tree_refs;
+ nodes::NodeTreeRefMap tree_refs;
/* TODO: Use simulation_cow, but need to add depsgraph relations before that. */
- const DerivedNodeTree tree{simulation_orig->nodetree, tree_refs};
+ const nodes::DerivedNodeTree tree{simulation_orig->nodetree, tree_refs};
fn::MFNetwork network;
ResourceCollector resources;
- MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources);
+ nodes::MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources);
Map<const fn::MFOutputSocket *, std::string> attribute_inputs = deduplicate_attribute_nodes(
network, network_map, tree);
fn::mf_network_optimization::constant_folding(network, resources);