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>2021-09-20 19:08:47 +0300
committerJacques Lucke <jacques@blender.org>2021-09-20 19:08:47 +0300
commitd26165747eb091898685a6a17cfcaec13070be65 (patch)
treebbf00f6dafb3145055085e4d2bd82da8fc6c476f
parent6dc20450544ac77e225102ae2bca94e19aca7f01 (diff)
initial support for node groupstemp-field-visualization
-rw-r--r--source/blender/blenkernel/intern/node.cc130
-rw-r--r--source/blender/makesdna/DNA_node_types.h2
2 files changed, 121 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 9ef82591b52..a9814964a1b 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -53,10 +53,12 @@
#include "BLI_map.hh"
#include "BLI_math.h"
#include "BLI_path_util.h"
+#include "BLI_set.hh"
#include "BLI_stack.hh"
#include "BLI_string.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
+#include "BLI_vector_set.hh"
#include "BLT_translation.h"
@@ -97,9 +99,11 @@
#define NODE_DEFAULT_MAX_WIDTH 700
using blender::Array;
+using blender::Set;
using blender::Span;
using blender::Stack;
using blender::Vector;
+using blender::VectorSet;
using namespace blender::nodes::node_tree_ref_types;
/* Fallback types for undefined tree, nodes, sockets */
@@ -656,6 +660,8 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
ntree->progress = nullptr;
ntree->execdata = nullptr;
+ ntree->output_field_dependencies = nullptr;
+
BLO_read_data_address(reader, &ntree->adt);
BKE_animdata_blend_read_data(reader, ntree->adt);
@@ -4493,12 +4499,44 @@ static bool sockets_have_links(blender::Span<const SocketRef *> sockets)
return false;
}
+using OutputFieldDependencies = Vector<std::optional<Vector<int>>>;
+
+static const std::optional<Vector<int>> *get_group_output_field_dependencies(
+ const OutputSocketRef &output_socket)
+{
+ const NodeRef &node = output_socket.node();
+ BLI_assert(node.is_group_node());
+ bNodeTree *group = (bNodeTree *)node.bnode()->id;
+ if (group == nullptr) {
+ return nullptr;
+ }
+ if (group->output_field_dependencies == nullptr) {
+ return nullptr;
+ }
+ const OutputFieldDependencies *output_field_dependencies = (const OutputFieldDependencies *)
+ group->output_field_dependencies;
+ if (output_socket.index() >= output_field_dependencies->size()) {
+ return nullptr;
+ }
+ return &(*output_field_dependencies)[output_socket.index()];
+}
+
static Vector<int> get_linked_field_input_indices(const OutputSocketRef &output_socket)
{
Vector<int> indices;
- for (const InputSocketRef *input_socket : output_socket.node().inputs()) {
- if (is_field_socket_type((eNodeSocketDatatype)input_socket->typeinfo()->type)) {
- indices.append(input_socket->index());
+ const NodeRef &node = output_socket.node();
+ if (node.is_group_node()) {
+ const std::optional<Vector<int>> *optional_dependencies = get_group_output_field_dependencies(
+ output_socket);
+ if (optional_dependencies && optional_dependencies->has_value()) {
+ indices.extend(**optional_dependencies);
+ }
+ }
+ else {
+ for (const InputSocketRef *input_socket : output_socket.node().inputs()) {
+ if (is_field_socket_type((eNodeSocketDatatype)input_socket->typeinfo()->type)) {
+ indices.append(input_socket->index());
+ }
}
}
return indices;
@@ -4539,6 +4577,53 @@ static Vector<const NodeRef *> toposort_nodes(const NodeTreeRef &tree, bool left
return toposort;
}
+struct SocketFieldState {
+ bool is_single = true;
+ bool is_field_source = false;
+ bool requires_single = false;
+};
+
+static std::optional<Vector<int>> find_dependent_group_input_indices(
+ const InputSocketRef &group_output_socket,
+ const Span<SocketFieldState> field_state_by_socket_id)
+{
+ Set<const InputSocketRef *> handled_sockets;
+ Stack<const InputSocketRef *> sockets_to_check;
+
+ handled_sockets.add(&group_output_socket);
+ sockets_to_check.push(&group_output_socket);
+
+ Set<int> found_input_indices;
+
+ while (!sockets_to_check.is_empty()) {
+ const InputSocketRef *input_socket = sockets_to_check.pop();
+ for (const OutputSocketRef *origin_socket : input_socket->logically_linked_sockets()) {
+ const NodeRef &origin_node = origin_socket->node();
+ const SocketFieldState &origin_state = field_state_by_socket_id[origin_socket->id()];
+ if (origin_state.is_field_source) {
+ if (origin_node.is_group_input_node()) {
+ found_input_indices.add(origin_socket->index());
+ }
+ else {
+ return std::nullopt;
+ }
+ }
+ else if (!origin_state.is_single) {
+ const Vector<int> input_socket_indices = get_linked_field_input_indices(*origin_socket);
+ for (const int input_index : input_socket_indices) {
+ const InputSocketRef &origin_input_socket = origin_node.input(input_index);
+ if (!field_state_by_socket_id[origin_input_socket.id()].is_single) {
+ if (handled_sockets.add(&origin_input_socket)) {
+ sockets_to_check.push(&origin_input_socket);
+ }
+ }
+ }
+ }
+ }
+ }
+ return Vector<int>(found_input_indices.begin(), found_input_indices.end());
+}
+
static void update_socket_shapes_for_fields(bNodeTree &btree)
{
using namespace blender;
@@ -4551,11 +4636,6 @@ static void update_socket_shapes_for_fields(bNodeTree &btree)
Vector<const NodeRef *> toposort_left_to_right = toposort_nodes(tree, true);
Vector<const NodeRef *> toposort_right_to_left = toposort_nodes(tree, false);
- struct SocketFieldState {
- bool is_single = true;
- bool requires_single = false;
- };
-
Array<SocketFieldState> field_state_by_socket_id(tree.sockets().size());
auto check_if_node_is_adaptive = [](const NodeRef &node) {
@@ -4603,6 +4683,7 @@ static void update_socket_shapes_for_fields(bNodeTree &btree)
SocketFieldState &state = field_state_by_socket_id[output_socket->id()];
if (!state.requires_single) {
state.is_single = false;
+ state.is_field_source = true;
}
}
}
@@ -4630,7 +4711,16 @@ static void update_socket_shapes_for_fields(bNodeTree &btree)
if (node_decl != nullptr) {
const SocketDeclaration &socket_decl = *node_decl->outputs()[output_socket->index()];
if (socket_decl.is_field()) {
- field_state_by_socket_id[output_socket->id()].is_single = false;
+ state.is_single = false;
+ state.is_field_source = true;
+ }
+ }
+ if (output_socket->node().is_group_node()) {
+ const std::optional<Vector<int>> *optional_dependencies =
+ get_group_output_field_dependencies(*output_socket);
+ if (optional_dependencies && !optional_dependencies->has_value()) {
+ state.is_single = false;
+ state.is_field_source = true;
}
}
const Vector<int> input_socket_indices = get_linked_field_input_indices(*output_socket);
@@ -4644,9 +4734,27 @@ static void update_socket_shapes_for_fields(bNodeTree &btree)
}
}
+ for (const NodeRef *group_output_node : tree.nodes_by_type("NodeGroupOutput")) {
+ if (!(group_output_node->bnode()->flag & NODE_DO_OUTPUT)) {
+ continue;
+ }
+
+ OutputFieldDependencies *output_field_dependencies = new OutputFieldDependencies();
+ for (const InputSocketRef *group_output_socket : group_output_node->inputs().drop_back(1)) {
+ std::optional<Vector<int>> dependent_input_indices = find_dependent_group_input_indices(
+ *group_output_socket, field_state_by_socket_id);
+ output_field_dependencies->append(std::move(dependent_input_indices));
+ }
+ if (btree.output_field_dependencies != nullptr) {
+ delete (OutputFieldDependencies *)btree.output_field_dependencies;
+ }
+ btree.output_field_dependencies = output_field_dependencies;
+ break;
+ }
+
for (const InputSocketRef *socket : tree.input_sockets()) {
bNodeSocket *bsocket = socket->bsocket();
- SocketFieldState &state = field_state_by_socket_id[socket->id()];
+ const SocketFieldState &state = field_state_by_socket_id[socket->id()];
if (state.requires_single) {
bsocket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE;
}
@@ -4656,7 +4764,7 @@ static void update_socket_shapes_for_fields(bNodeTree &btree)
}
for (const OutputSocketRef *socket : tree.output_sockets()) {
bNodeSocket *bsocket = socket->bsocket();
- SocketFieldState &state = field_state_by_socket_id[socket->id()];
+ const SocketFieldState &state = field_state_by_socket_id[socket->id()];
if (state.is_single) {
bsocket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE;
}
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index f4c88333528..d3154eaae7b 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -481,6 +481,8 @@ typedef struct bNodeTree {
float view_center[2];
ListBase nodes, links;
+ /* Vector<std::optional<Vector<int>>>. */
+ void *output_field_dependencies;
/** Set init on fileread. */
int type, init;