25 tree_cow.
runtime->geometry_nodes_lazy_function_graph_info_mutex.tag_dirty();
35 for (
const int i :
nodes.index_range()) {
40 if (node.is_group()) {
74 socket->runtime->owner_node = node;
83 socket->runtime->owner_node = node;
104 socket->
runtime->internal_link_input =
nullptr;
117 socket->
runtime->directly_linked_links.clear();
118 socket->
runtime->directly_linked_sockets.clear();
121 socket->
runtime->directly_linked_links.clear();
122 socket->
runtime->directly_linked_sockets.clear();
124 node->
runtime->has_available_linked_inputs =
false;
125 node->
runtime->has_available_linked_outputs =
false;
131 if (link->is_available()) {
140 std::sort(socket->
runtime->directly_linked_links.begin(),
141 socket->
runtime->directly_linked_links.end(),
143 return a->multi_input_sort_id > b->multi_input_sort_id;
157 bool only_follow_first_input_link,
162 if (sockets_in_current_chain.
contains(&input_socket)) {
166 sockets_in_current_chain.
append(&input_socket);
169 if (only_follow_first_input_link) {
170 links_to_check = links_to_check.
take_front(1);
173 if (link->is_muted()) {
176 if (!link->is_available()) {
180 bNode &origin_node = *link->fromnode;
181 if (!origin_socket.is_available()) {
185 if (origin_node.is_reroute()) {
188 r_skipped_origins.
append(&reroute_input);
189 r_skipped_origins.
append(&reroute_output);
191 reroute_input,
false, sockets_in_current_chain, r_logical_origins, r_skipped_origins);
194 if (origin_node.is_muted()) {
196 r_skipped_origins.
append(&origin_socket);
197 r_skipped_origins.
append(mute_input);
199 *mute_input,
true, sockets_in_current_chain, r_logical_origins, r_skipped_origins);
203 r_logical_origins.
append(&origin_socket);
206 sockets_in_current_chain.
pop_last();
215 for (const int i : range) {
216 bNode &node = *nodes[i];
217 for (bNodeSocket *socket : node.runtime->inputs) {
218 Vector<bNodeSocket *, 16> sockets_in_current_chain;
219 socket->runtime->logically_linked_sockets.clear();
220 socket->runtime->logically_linked_skipped_sockets.clear();
221 find_logical_origins_for_socket_recursive(
224 sockets_in_current_chain,
225 socket->runtime->logically_linked_sockets,
226 socket->runtime->logically_linked_skipped_sockets);
233 for (const int i : range) {
234 bNode &node = *nodes[i];
235 for (bNodeSocket *socket : node.runtime->outputs) {
236 socket->runtime->logically_linked_sockets.clear();
246 output_socket->
runtime->logically_linked_sockets.append(input_socket);
266 for (bNode *node : nodes.slice(range)) {
267 node->runtime->inputs_by_identifier.clear();
268 node->runtime->outputs_by_identifier.clear();
269 for (bNodeSocket *socket : node->runtime->inputs) {
270 node->runtime->inputs_by_identifier.add_new(socket->identifier, socket);
272 for (bNodeSocket *socket : node->runtime->outputs) {
273 node->runtime->outputs_by_identifier.add_new(socket->identifier, socket);
296 for (
const bNode *input_node :
300 origin_nodes.
append(input_node);
313 target_nodes.
append(output_node);
324 bool &r_cycle_detected)
328 int socket_index = 0;
330 int implicit_link_index = 0;
334 nodes_to_check.
push({&start_node});
335 node_states[start_node.index()].is_in_stack =
true;
336 while (!nodes_to_check.
is_empty()) {
337 Item &item = nodes_to_check.
peek();
338 bNode &node = *item.node;
339 bool pushed_node =
false;
341 auto handle_linked_node = [&](
bNode &linked_node) {
343 if (linked_node_state.
is_done) {
348 r_cycle_detected =
true;
351 nodes_to_check.
push({&linked_node});
362 if (item.socket_index == sockets.
size()) {
368 if (item.link_index == linked_links.
size()) {
374 bNodeLink &link = *linked_links[item.link_index];
375 if (!link.is_available()) {
380 bNodeSocket &linked_socket = *socket.
runtime->directly_linked_sockets[item.link_index];
381 bNode &linked_node = *linked_socket.
runtime->owner_node;
382 if (handle_linked_node(linked_node)) {
397 if (item.implicit_link_index == implicitly_linked_nodes.
size()) {
401 const bNode &linked_node = *implicitly_linked_nodes[item.implicit_link_index];
402 if (handle_linked_node(
const_cast<bNode &
>(linked_node))) {
404 item.implicit_link_index++;
417 r_sorted_nodes.
append(&node);
418 nodes_to_check.
pop();
426 bool &r_cycle_detected)
429 r_sorted_nodes.
clear();
431 r_cycle_detected =
false;
435 if (node_states[node->index()].is_done) {
440 node->
runtime->has_available_linked_outputs :
441 node->
runtime->has_available_linked_inputs)
447 ntree, direction, *node, node_states, r_sorted_nodes, r_cycle_detected);
451 r_cycle_detected =
true;
453 if (node_states[node->index()].is_done) {
459 ntree, direction, *node, node_states, r_sorted_nodes, r_cycle_detected);
474 if (!node->parent && node->is_frame()) {
486 node->runtime->direct_children_in_frame.clear();
491 frame->runtime->direct_children_in_frame.append(node);
501 if (group_output_nodes.
is_empty()) {
504 else if (group_output_nodes.
size() == 1) {
509 for (
bNode *group_output : group_output_nodes) {
520 for (
const bNode *node : ntree.
runtime->toposort_left_to_right) {
522 if (!node->is_reroute()) {
532 const bNode &source_node = *links.
first()->fromnode;
550 [&]() { update_logically_linked_sockets(ntree); },
551 [&]() { update_sockets_by_identifier(ntree); },
553 update_toposort(ntree,
554 ToposortDirection::LeftToRight,
555 tree_runtime.toposort_left_to_right,
556 tree_runtime.has_available_link_cycle);
557 for (const int i : tree_runtime.toposort_left_to_right.index_range()) {
558 const bNode &node = *tree_runtime.toposort_left_to_right[i];
559 node.runtime->toposort_left_to_right_index = i;
568 node.
runtime->toposort_right_to_left_index =
i;
586 input_socket_index_ = link.
tosock->index();
588 const_cast<const bNodeSocket *
>(link.
tosock)->directly_linked_links().first_index(&link);
598 const bNode *to_node = ntree.node_by_id(to_node_id_);
602 if (input_socket_index_ >= to_node->input_sockets().size()) {
605 const bNodeSocket &input_socket = to_node->input_socket(input_socket_index_);
606 if (input_link_index_ >= input_socket.directly_linked_links().size()) {
609 return input_socket.directly_linked_links()[input_link_index_];
614void bNodeTree::ensure_topology_cache()
const
622 if (ref.id == nested_node_id) {
629const bNestedNodeRef *bNodeTree::nested_node_ref_from_node_id_path(
630 const blender::Span<int32_t> node_ids)
const
636 blender::Vector<int> current_node_ids;
637 if (this->node_id_path_from_nested_node_ref(ref.id, current_node_ids)) {
638 if (current_node_ids.
as_span() == node_ids) {
646bool bNodeTree::node_id_path_from_nested_node_ref(
const int32_t nested_node_id,
647 blender::Vector<int> &r_node_ids)
const
649 const bNestedNodeRef *ref = this->find_nested_node_ref(nested_node_id);
650 if (ref ==
nullptr) {
654 const bNode *node = this->node_by_id(node_id);
655 if (node ==
nullptr) {
658 r_node_ids.
append(node_id);
659 if (!node->is_group()) {
663 if (group ==
nullptr) {
666 return group->node_id_path_from_nested_node_ref(ref->
path.
id_in_node, r_node_ids);
669const bNode *bNodeTree::find_nested_node(
const int32_t nested_node_id,
672 const bNestedNodeRef *ref = this->find_nested_node_ref(nested_node_id);
673 if (ref ==
nullptr) {
677 const bNode *node = this->node_by_id(node_id);
678 if (node ==
nullptr) {
681 if (!node->is_group()) {
688 if (group ==
nullptr) {
694const bNodeSocket &bNode::socket_by_decl(
const blender::nodes::SocketDeclaration &decl)
const
696 return decl.
in_out ==
SOCK_IN ? this->input_socket(decl.
index) : this->output_socket(decl.index);
699bNodeSocket &bNode::socket_by_decl(
const blender::nodes::SocketDeclaration &decl)
701 return decl.
in_out ==
SOCK_IN ? this->input_socket(decl.
index) : this->output_socket(decl.index);
706 tree.runtime->inferenced_input_socket_usage_mutex.ensure([&]() {
707 tree.runtime->inferenced_socket_usage =
712bool bNodeSocket::affects_node_output()
const
718 return tree.runtime->inferenced_socket_usage[this->index_in_tree()].is_used;
721bool bNodeSocket::inferred_socket_visibility()
const
724 const bNode &node = this->owner_node();
725 if (node.
typeinfo->ignore_inferred_input_socket_visibility) {
731 return tree.runtime->inferenced_socket_usage[this->index_in_tree()].is_visible;
#define LISTBASE_FOREACH(type, var, list)
struct bNestedNodeRef bNestedNodeRef
struct bNodeTree bNodeTree
struct bNodeSocket bNodeSocket
int64_t append_and_get_index(const T &value)
void append(const T &value)
IndexRange index_range() const
void ensure(const FunctionRef< void()> compute_cache)
constexpr const T & first() const
constexpr int64_t size() const
constexpr Span take_front(int64_t n) const
constexpr bool is_empty() const
void push(const T &value)
bool contains(const Key &key) const
bool contains(const T &value) const
void append(const T &value)
void reserve(const int64_t min_capacity)
Span< T > as_span() const
Array< bNodePanelRuntime > panels
Vector< bNodeSocket * > outputs
Vector< bNodeSocket * > inputs
Vector< bNode * > root_frames
Vector< bNodeSocket * > output_sockets
Vector< bNode * > toposort_right_to_left
Vector< bNode * > group_nodes
bNode * group_output_node
Vector< bNodeSocket * > sockets
CacheMutex topology_cache_mutex
bool has_undefined_nodes_or_sockets
Vector< bNodeLink * > links
std::atomic< bool > topology_cache_exists
MultiValueMap< const bNodeType *, bNode * > nodes_by_type
NodeIDVectorSet nodes_by_id
Vector< bNodeSocket * > input_sockets
virtual const int & get_corresponding_output_id(const bNode &input_bnode) const =0
const bNode * get_corresponding_output(const bNodeTree &tree, const bNode &input_bnode) const
static void toposort_from_start_node(const bNodeTree &ntree, const ToposortDirection direction, bNode &start_node, MutableSpan< ToposortNodeState > node_states, Vector< bNode * > &r_sorted_nodes, bool &r_cycle_detected)
static void update_dangling_reroute_nodes(const bNodeTree &ntree)
static void update_nodes_by_type(const bNodeTree &ntree)
static void update_direct_frames_childrens(const bNodeTree &ntree)
static Vector< const bNode * > get_implicit_origin_nodes(const bNodeTree &ntree, bNode &node)
static void update_group_output_node(const bNodeTree &ntree)
static void update_link_vector(const bNodeTree &ntree)
static void update_sockets_by_identifier(const bNodeTree &ntree)
static void update_logically_linked_sockets(const bNodeTree &ntree)
static void ensure_topology_cache(const bNodeTree &ntree)
static void find_logical_origins_for_socket_recursive(bNodeSocket &input_socket, bool only_follow_first_input_link, Vector< bNodeSocket *, 16 > &sockets_in_current_chain, Vector< bNodeSocket * > &r_logical_origins, Vector< bNodeSocket * > &r_skipped_origins)
static void update_internal_link_inputs(const bNodeTree &ntree)
bool topology_cache_is_available(const bNodeTree &tree)
static void update_panels(const bNodeTree &ntree)
static void update_node_vector(const bNodeTree &ntree)
static void update_directly_linked_links_and_sockets(const bNodeTree &ntree)
static void update_root_frames(const bNodeTree &ntree)
static void update_toposort(const bNodeTree &ntree, const ToposortDirection direction, Vector< bNode * > &r_sorted_nodes, bool &r_cycle_detected)
void preprocess_geometry_node_tree_for_evaluation(bNodeTree &tree_cow)
static Vector< const bNode * > get_implicit_target_nodes(const bNodeTree &ntree, bNode &node)
static void update_socket_vectors_and_owner_node(const bNodeTree &ntree)
const bNodeZoneType * zone_type_by_node_type(const int node_type)
bNodeSocketType NodeSocketTypeUndefined
Span< int > all_zone_output_node_types()
Span< int > all_zone_input_node_types()
bNodeType * node_type_find(StringRef idname)
Array< SocketUsage > infer_all_sockets_usage(const bNodeTree &tree)
const GeometryNodesLazyFunctionGraphInfo * ensure_geometry_nodes_lazy_function_graph(const bNodeTree &btree)
void parallel_invoke(Functions &&...functions)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
static void ensure_inference_usage_cache(const bNodeTree &tree)
bNodeSocketRuntimeHandle * runtime
bNodeTreeRuntimeHandle * runtime
bNodeTypeHandle * typeinfo
bNodeRuntimeHandle * runtime
bNodeLink * try_find(bNodeTree &ntree) const
NodeLinkKey(const bNodeLink &link)