16 root_context_ = &this->construct_context_recursively(
21 const bNode *parent_node,
25 btree.ensure_topology_cache();
27 context.parent_context_ = parent_context;
28 context.parent_node_ = parent_node;
29 context.derived_tree_ =
this;
30 context.btree_ = &btree;
31 context.instance_key_ = instance_key;
32 used_btrees_.
add(context.btree_);
34 for (
const bNode *bnode : context.btree_->all_nodes()) {
35 if (bnode->is_group()) {
37 if (child_btree !=
nullptr) {
39 DTreeContext &child = this->construct_context_recursively(
40 &context, bnode, *child_btree, child_key);
41 context.children_.add_new(bnode, &child);
52 this->destruct_context_recursively(root_context_);
55void DerivedNodeTree::destruct_context_recursively(
DTreeContext *context)
57 for (
DTreeContext *child : context->children_.values()) {
58 this->destruct_context_recursively(child);
60 context->~DTreeContext();
65 for (
const bNodeTree *btree : used_btrees_) {
66 if (btree->has_available_link_cycle()) {
75 for (
const bNodeTree *btree : used_btrees_) {
76 if (btree->has_undefined_nodes_or_sockets()) {
85 this->foreach_node_in_context_recursive(*root_context_, callback);
88void DerivedNodeTree::foreach_node_in_context_recursive(
const DTreeContext &context,
91 for (
const bNode *bnode : context.btree_->all_nodes()) {
92 callback(
DNode(&context, bnode));
94 for (
const DTreeContext *child_context : context.children_.values()) {
95 this->foreach_node_in_context_recursive(*child_context, callback);
115 const int socket_index =
bsocket_->index();
116 return {parent_context, &parent_node->output_socket(socket_index)};
129 const int socket_index =
bsocket_->index();
131 for (
const bNode *group_input_node : group_input_nodes) {
132 sockets.
append(
DOutputSocket(child_context, &group_input_node->output_socket(socket_index)));
148 const int socket_index =
bsocket_->index();
149 return {parent_context, &parent_node->input_socket(socket_index)};
158 if (child_context ==
nullptr) {
166 const int socket_index =
bsocket_->index();
167 for (
const bNode *group_output_node : group_output_nodes) {
169 return {child_context, &group_output_node->input_socket(socket_index)};
179 const bNode &linked_node = linked_socket->owner_node();
182 if (linked_node.is_group_input()) {
185 origin_fn(linked_dsocket);
189 if (socket_in_parent_group->is_logically_linked()) {
196 origin_fn(socket_in_parent_group);
200 else if (linked_node.is_group()) {
202 if (socket_in_group) {
203 if (socket_in_group->is_logically_linked()) {
210 origin_fn(socket_in_group);
216 origin_fn(linked_dsocket);
231 if (link->is_muted()) {
234 const DInputSocket &linked_socket{
context_, link->tosock};
235 if (!linked_socket->is_available()) {
238 const DNode linked_node = linked_socket.node();
239 if (linked_node->is_reroute()) {
240 const DInputSocket reroute_input = linked_socket;
242 path_info.
sockets.append(reroute_input);
243 path_info.
sockets.append(reroute_output);
244 reroute_output.foreach_target_socket(target_fn, path_info);
248 else if (linked_node->is_muted()) {
249 for (
const bNodeLink &internal_link : linked_node->internal_links()) {
250 if (internal_link.fromsock != linked_socket.bsocket()) {
254 if (linked_socket->is_multi_input()) {
255 if (linked_socket->directly_linked_links()[0] != link) {
259 const DInputSocket mute_input = linked_socket;
261 path_info.
sockets.append(mute_input);
262 path_info.
sockets.append(mute_output);
263 mute_output.foreach_target_socket(target_fn, path_info);
268 else if (linked_node->is_group_output()) {
269 if (linked_node.bnode() !=
context_->btree().group_output_node()) {
274 path_info.
sockets.append(linked_socket);
275 target_fn(linked_socket, path_info);
281 linked_socket.get_corresponding_group_node_output();
282 path_info.
sockets.append(linked_socket);
283 path_info.
sockets.append(socket_in_parent_group);
284 socket_in_parent_group.foreach_target_socket(target_fn, path_info);
289 else if (linked_node->is_group()) {
291 path_info.
sockets.append(linked_socket);
292 const Vector<DOutputSocket> sockets_in_group =
293 linked_socket.get_corresponding_group_input_sockets();
294 for (
const DOutputSocket &socket_in_group : sockets_in_group) {
295 path_info.
sockets.append(socket_in_group);
296 socket_in_group.foreach_target_socket(target_fn, path_info);
303 path_info.
sockets.append(linked_socket);
304 target_fn(linked_socket, path_info);
320 if (key.
value == context->derived_tree().root_context().btree().active_viewer_key.value) {
326 for (
const bNode *group_node : context->btree().group_nodes()) {
328 if (!group_node->id) {
331 const DTreeContext *child_context = context->child_context(*group_node);
336 if (!found_context) {
341 return found_context;
358 if (found_context ==
nullptr) {
364 return *found_context;
374 const DTreeContext *parent_context = context->parent_context();
375 if (parent_context ==
nullptr) {
379 digraph, parent_context, dot_clusters);
380 std::string cluster_name =
StringRef(context->btree().id.name + 2) +
" / " +
381 context->parent_node()->name;
401 if (node->is_muted() || node->is_group() || node->is_reroute() || node->is_frame()) {
405 if (node->is_group_input() || node->is_group_output()) {
411 digraph, node.
context(), dot_clusters);
418 for (
const bNodeSocket *socket : node->input_sockets()) {
419 if (socket->is_available()) {
420 dot_node_with_sockets.
add_input(socket->name);
423 for (
const bNodeSocket *socket : node->output_sockets()) {
424 if (socket->is_available()) {
425 dot_node_with_sockets.
add_output(socket->name);
430 dot_node, dot_node_with_sockets);
433 for (
const bNodeSocket *socket : node->input_sockets()) {
434 if (socket->is_available()) {
436 dot_node_with_sockets_ref.
input(input_index));
440 int output_index = 0;
441 for (
const bNodeSocket *socket : node->output_sockets()) {
442 if (socket->is_available()) {
444 dot_node_with_sockets_ref.
output(output_index));
453 for (
const auto item : dot_input_sockets.
items()) {
457 if (from_socket->is_output()) {
460 if (dot_from_port !=
nullptr) {
461 digraph.
new_edge(*dot_from_port, dot_to_port);
465 dot_export::Node &dot_node = *dot_floating_inputs.lookup_or_add_cb(from_socket, [&]() {
473 digraph.
new_edge(dot_node, dot_to_port);
#define BLI_assert_unreachable()
struct bNodeLink bNodeLink
destruct_ptr< T > construct(Args &&...args)
const Value * lookup_ptr(const Key &key) const
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
void add_new(const Key &key, const Value &value)
ItemIterator items() const &
constexpr int64_t size() const
void append(const T &value)
void set_parent_cluster(Cluster *new_parent)
std::string to_dot_string() const
DirectedEdge & new_edge(NodePort from, NodePort to)
Cluster & new_cluster(StringRef label="")
void set_random_cluster_bgcolors()
void set_rankdir(Attr_rankdir rankdir)
Node & new_node(StringRef label)
NodePort output(int index) const
NodePort input(int index) const
void set_shape(Attr_shape shape)
void set_parent_cluster(Cluster *cluster)
void set_background_color(StringRef name)
bNodeInstanceKey instance_key() const
const DTreeContext * context() const
const bNode * bnode() const
FunctionRef< void(DInputSocket, const TargetSocketPathInfo &path_info)> ForeachTargetSocketFn
DInputSocket get_corresponding_group_node_input() const
DInputSocket get_active_corresponding_group_output_socket() const
void foreach_target_socket(ForeachTargetSocketFn target_fn) const
const bNodeSocket * bsocket_
const DTreeContext * context() const
const DTreeContext * context_
const bNodeTree & btree() const
std::string to_dot() const
bool has_link_cycles() const
const DTreeContext & active_context() const
DerivedNodeTree(const bNodeTree &btree)
bool has_undefined_nodes_or_sockets() const
const DTreeContext & root_context() const
void foreach_node(FunctionRef< void(DNode)> callback) const
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
const bNodeInstanceKey NODE_INSTANCE_KEY_BASE
bNodeInstanceKey node_instance_key(bNodeInstanceKey parent_key, const bNodeTree *ntree, const bNode *node)
const bNodeInstanceKey NODE_INSTANCE_KEY_NONE
DOutputSocket::TargetSocketPathInfo TargetSocketPathInfo
int context(const bContext *C, const char *member, bContextDataResult *result)
static const DTreeContext * find_active_context_recursive(const DTreeContext *context)
static dot_export::Cluster * get_dot_cluster_for_context(dot_export::DirectedGraph &digraph, const DTreeContext *context, Map< const DTreeContext *, dot_export::Cluster * > &dot_clusters)
Input & add_input(std::string name)
Output & add_output(std::string name)
Vector< DSocket, 16 > sockets