diff options
author | Jacques Lucke <jacques@blender.org> | 2021-09-16 11:22:08 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-09-16 11:22:08 +0300 |
commit | 0bec1f5dadc0a52dcfe895b8fe04a431d52930ab (patch) | |
tree | 4ea998a0a092876316fd462790de06fa6196098d /source | |
parent | a5fbd815107fcd4c797ed7b96667017fa182ee50 (diff) |
progress
Diffstat (limited to 'source')
7 files changed, 104 insertions, 26 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d4bc0245a61..2f099495d02 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -731,7 +731,7 @@ void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available); int nodeSocketLinkLimit(const struct bNodeSocket *sock); -void nodeDeclarationEnsure(struct bNodeTree *ntree, struct bNode *node); +NodeDeclarationHandle *nodeDeclarationEnsure(struct bNodeTree *ntree, struct bNode *node); /* Node Clipboard */ void BKE_node_clipboard_init(const struct bNodeTree *ntree); diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 150b0a99a1f..b2ebab67100 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -29,6 +29,7 @@ #include <cstddef> #include <cstdlib> #include <cstring> +#include <queue> /* Allow using deprecated functionality for .blend file I/O. */ #define DNA_DEPRECATED_ALLOW @@ -52,6 +53,7 @@ #include "BLI_map.hh" #include "BLI_math.h" #include "BLI_path_util.h" +#include "BLI_stack.hh" #include "BLI_string.h" #include "BLI_string_utils.h" #include "BLI_utildefines.h" @@ -80,6 +82,7 @@ #include "NOD_function.h" #include "NOD_geometry.h" #include "NOD_node_declaration.hh" +#include "NOD_node_tree_ref.hh" #include "NOD_shader.h" #include "NOD_socket.h" #include "NOD_texture.h" @@ -1015,8 +1018,8 @@ IDTypeInfo IDType_ID_NT = { static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype) { if (ntype->declare != nullptr) { - nodeDeclarationEnsure(ntree, node); - node->declaration->build(*ntree, *node); + blender::nodes::NodeDeclaration *node_decl = nodeDeclarationEnsure(ntree, node); + node_decl->build(*ntree, *node); return; } bNodeSocketTemplate *sockdef; @@ -3942,15 +3945,16 @@ int nodeSocketLinkLimit(const bNodeSocket *sock) * If the node implements a `declare` function, this function makes sure that `node->declaration` * is up to date. */ -void nodeDeclarationEnsure(bNodeTree *UNUSED(ntree), bNode *node) +NodeDeclarationHandle *nodeDeclarationEnsure(bNodeTree *UNUSED(ntree), bNode *node) { if (node->typeinfo->declare == nullptr) { - return; + return nullptr; } node->declaration = new blender::nodes::NodeDeclaration(); blender::nodes::NodeDeclarationBuilder builder{*node->declaration}; node->typeinfo->declare(builder); + return node->declaration; } /* ************** Node Clipboard *********** */ @@ -4465,28 +4469,102 @@ void ntreeUpdateAllUsers(Main *main, ID *id) } } -static void update_socket_shapes_for_fields(bNodeTree &ntree) +static void update_socket_shapes_for_fields(bNodeTree &btree) { + using namespace blender; using namespace blender::nodes; - if (ntree.type != NTREE_GEOMETRY) { + if (btree.type != NTREE_GEOMETRY) { return; } - LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { - nodeDeclarationEnsure(&ntree, node); - NodeDeclaration *declaration = node->declaration; - if (declaration == nullptr) { - continue; + + NodeTreeRef tree{&btree}; + Vector<const NodeRef *> input_nodes; + Vector<const NodeRef *> output_nodes; + + for (const NodeRef *node : tree.nodes()) { + if (node->inputs().is_empty()) { + input_nodes.append(node); + } + if (node->outputs().is_empty()) { + output_nodes.append(node); } - int input_index; - LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &node->inputs, input_index) { - const SocketDeclaration &socket_decl = *declaration->inputs()[input_index]; - bool is_field = socket_decl.is_field(); - if (is_field) { - socket->display_shape = SOCK_DISPLAY_SHAPE_DIAMOND; + } + + Array<int> field_level_by_node_id(tree.nodes().size(), 0); + Array<int> field_level_by_socket_id(tree.sockets().size(), 0); + Array<bool> node_is_enqueued_by_id(tree.nodes().size(), false); + std::queue<const NodeRef *> nodes_to_check; + + for (const NodeRef *node : input_nodes) { + nodes_to_check.push(node); + node_is_enqueued_by_id[node->id()] = true; + } + + while (!nodes_to_check.empty()) { + const NodeRef &node = *nodes_to_check.front(); + nodes_to_check.pop(); + NodeDeclaration *node_decl = nodeDeclarationEnsure(&btree, node.bnode()); + + int max_node_field_level = 0; + StringRef node_idname = node.idname(); + if (node_idname.startswith("ShaderNode") || node_idname.startswith("FunctionNode")) { + max_node_field_level = 1; + } + + int node_field_level = 0; + for (const SocketRef *input_socket : node.inputs()) { + const int input_index = input_socket->index(); + int normal_input_field_level = 0; + if (node_decl != nullptr) { + const SocketDeclaration &socket_decl = *node_decl->inputs()[input_index]; + normal_input_field_level = socket_decl.is_field(); } - else { - socket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE; + + int input_field_level = normal_input_field_level; + for (const SocketRef *origin_socket : input_socket->directly_linked_sockets()) { + const int origin_field_level = field_level_by_socket_id[origin_socket->id()]; + input_field_level = std::max(input_field_level, origin_field_level); + } + + const int field_level_increase = input_field_level - normal_input_field_level; + node_field_level = std::min(max_node_field_level, + std::max(node_field_level, field_level_increase)); + + field_level_by_socket_id[input_socket->id()] = input_field_level; + } + + for (const SocketRef *output_socket : node.outputs()) { + const int output_index = output_socket->index(); + int normal_output_field_level = 0; + if (node_decl != nullptr) { + const SocketDeclaration &socket_decl = *node_decl->outputs()[output_index]; + normal_output_field_level = socket_decl.is_field(); } + + const int output_field_level = normal_output_field_level + node_field_level; + field_level_by_socket_id[output_socket->id()] = output_field_level; + + for (const SocketRef *target_socket : output_socket->directly_linked_sockets()) { + const NodeRef &target_node = target_socket->node(); + if (!node_is_enqueued_by_id[target_node.id()]) { + nodes_to_check.push(&target_node); + node_is_enqueued_by_id[target_node.id()] = true; + } + } + } + + std::cout << node.name() << ": " << node_field_level << "\n"; + } + std::cout << "\n"; + + for (const SocketRef *socket : tree.sockets()) { + bNodeSocket *bsocket = socket->bsocket(); + const int field_level = field_level_by_socket_id[socket->id()]; + if (field_level == 0) { + bsocket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE; + } + else if (field_level == 1) { + bsocket->display_shape = SOCK_DISPLAY_SHAPE_DIAMOND; } } } diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index e2e4468a219..93eed807731 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -97,7 +97,7 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { return *(Self *)this; } - Self &is_field(bool value) + Self &is_field(bool value = true) { decl_->is_field_ = value; return *(Self *)this; diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_index.cc b/source/blender/nodes/geometry/nodes/node_geo_input_index.cc index c52ff3d448e..b073a3432e5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_index.cc @@ -20,7 +20,7 @@ namespace blender::nodes { static void geo_node_input_index_declare(NodeDeclarationBuilder &b) { - b.add_output<decl::Int>("Index"); + b.add_output<decl::Int>("Index").is_field(); } class IndexFieldInput final : public fn::FieldInput { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc b/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc index 07818f2a3ad..3e0295ced19 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc @@ -25,7 +25,7 @@ namespace blender::nodes { static void geo_node_input_normal_declare(NodeDeclarationBuilder &b) { - b.add_output<decl::Vector>("Normal"); + b.add_output<decl::Vector>("Normal").is_field(); } static GVArrayPtr mesh_face_normals(const Mesh &mesh, diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_position.cc b/source/blender/nodes/geometry/nodes/node_geo_input_position.cc index c6365bf6809..0722ac54e33 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_position.cc @@ -20,7 +20,7 @@ namespace blender::nodes { static void geo_node_input_position_declare(NodeDeclarationBuilder &b) { - b.add_output<decl::Vector>("Position"); + b.add_output<decl::Vector>("Position").is_field(); } static void geo_node_input_position_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 9750a94c3f3..7ea0465bb43 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -23,8 +23,8 @@ namespace blender::nodes { static void geo_node_set_position_declare(NodeDeclarationBuilder &b) { b.add_input<decl::Geometry>("Geometry"); - b.add_input<decl::Vector>("Position").is_field(true); - b.add_input<decl::Bool>("Selection").default_value(true).is_field(true); + b.add_input<decl::Vector>("Position").is_field(); + b.add_input<decl::Bool>("Selection").default_value(true).is_field(); b.add_output<decl::Geometry>("Geometry"); } |