22 tree_cow.
runtime->geometry_nodes_lazy_function_graph_info.reset();
32 for (
const int i : nodes.index_range()) {
33 bNode &node = *nodes[i];
34 node.
runtime->index_in_tree = i;
35 node.runtime->owner_tree =
const_cast<bNodeTree *
>(&ntree);
37 if (node.is_group()) {
71 socket->runtime->owner_node =
node;
80 socket->runtime->owner_node =
node;
92 node_runtime.
panels.reinitialize(node->num_panel_states);
100 for (
bNodeSocket *socket : node->runtime->outputs) {
101 socket->runtime->internal_link_input =
nullptr;
103 for (
bNodeLink &link : node->runtime->internal_links) {
104 link.tosock->runtime->internal_link_input = link.fromsock;
113 for (
bNodeSocket *socket : node->runtime->inputs) {
114 socket->runtime->directly_linked_links.clear();
115 socket->runtime->directly_linked_sockets.clear();
117 for (
bNodeSocket *socket : node->runtime->outputs) {
118 socket->runtime->directly_linked_links.clear();
119 socket->runtime->directly_linked_sockets.clear();
121 node->runtime->has_available_linked_inputs =
false;
122 node->runtime->has_available_linked_outputs =
false;
125 link->fromsock->runtime->directly_linked_links.append(link);
126 link->fromsock->runtime->directly_linked_sockets.append(link->tosock);
127 link->tosock->runtime->directly_linked_links.append(link);
128 if (link->is_available()) {
129 link->fromnode->runtime->has_available_linked_outputs =
true;
130 link->tonode->runtime->has_available_linked_inputs =
true;
135 std::sort(socket->runtime->directly_linked_links.begin(),
136 socket->runtime->directly_linked_links.end(),
138 return a->multi_input_sort_id > b->multi_input_sort_id;
143 for (
bNodeLink *link : socket->runtime->directly_linked_links) {
145 socket->runtime->directly_linked_sockets.append(link->fromsock);
152 bool only_follow_first_input_link,
157 if (sockets_in_current_chain.
contains(&input_socket)) {
161 sockets_in_current_chain.
append(&input_socket);
164 if (only_follow_first_input_link) {
165 links_to_check = links_to_check.
take_front(1);
168 if (link->is_muted()) {
171 if (!link->is_available()) {
175 bNode &origin_node = *link->fromnode;
176 if (!origin_socket.is_available()) {
183 r_skipped_origins.
append(&reroute_input);
184 r_skipped_origins.
append(&reroute_output);
186 reroute_input,
false, sockets_in_current_chain, r_logical_origins, r_skipped_origins);
189 if (origin_node.is_muted()) {
191 r_skipped_origins.
append(&origin_socket);
192 r_skipped_origins.
append(mute_input);
194 *mute_input,
true, sockets_in_current_chain, r_logical_origins, r_skipped_origins);
198 r_logical_origins.
append(&origin_socket);
201 sockets_in_current_chain.
pop_last();
210 for (const int i : range) {
211 bNode &node = *nodes[i];
212 for (bNodeSocket *socket : node.runtime->inputs) {
213 Vector<bNodeSocket *, 16> sockets_in_current_chain;
214 socket->runtime->logically_linked_sockets.clear();
215 socket->runtime->logically_linked_skipped_sockets.clear();
216 find_logical_origins_for_socket_recursive(
219 sockets_in_current_chain,
220 socket->runtime->logically_linked_sockets,
221 socket->runtime->logically_linked_skipped_sockets);
228 for (const int i : range) {
229 bNode &node = *nodes[i];
230 for (bNodeSocket *socket : node.runtime->outputs) {
231 socket->runtime->logically_linked_sockets.clear();
238 for (
const bNode *node : nodes) {
239 for (
bNodeSocket *input_socket : node->runtime->inputs) {
240 for (
bNodeSocket *output_socket : input_socket->runtime->logically_linked_sockets) {
241 output_socket->runtime->logically_linked_sockets.append(input_socket);
260 threading::parallel_for(nodes.index_range(), 128, [&](
const IndexRange range) {
261 for (bNode *node : nodes.slice(range)) {
262 node->runtime->inputs_by_identifier.clear();
263 node->runtime->outputs_by_identifier.clear();
264 for (bNodeSocket *socket : node->runtime->inputs) {
265 node->runtime->inputs_by_identifier.add_new(socket->identifier, socket);
267 for (bNodeSocket *socket : node->runtime->outputs) {
268 node->runtime->outputs_by_identifier.add_new(socket->identifier, socket);
280 bool is_done =
false;
281 bool is_in_stack =
false;
291 for (
const bNode *input_node :
295 origin_nodes.
append(input_node);
308 target_nodes.
append(output_node);
319 bool &r_cycle_detected)
323 int socket_index = 0;
325 int implicit_link_index = 0;
329 nodes_to_check.
push({&start_node});
330 node_states[start_node.index()].is_in_stack =
true;
331 while (!nodes_to_check.
is_empty()) {
332 Item &item = nodes_to_check.
peek();
333 bNode &node = *item.node;
334 bool pushed_node =
false;
336 auto handle_linked_node = [&](
bNode &linked_node) {
338 if (linked_node_state.
is_done) {
343 r_cycle_detected =
true;
346 nodes_to_check.
push({&linked_node});
354 node.runtime->inputs :
355 node.runtime->outputs;
357 if (item.socket_index == sockets.
size()) {
363 if (item.link_index == linked_links.
size()) {
369 bNodeLink &link = *linked_links[item.link_index];
370 if (!link.is_available()) {
375 bNodeSocket &linked_socket = *socket.
runtime->directly_linked_sockets[item.link_index];
376 bNode &linked_node = *linked_socket.
runtime->owner_node;
377 if (handle_linked_node(linked_node)) {
392 if (item.implicit_link_index == implicitly_linked_nodes.
size()) {
396 const bNode &linked_node = *implicitly_linked_nodes[item.implicit_link_index];
397 if (handle_linked_node(
const_cast<bNode &
>(linked_node))) {
399 item.implicit_link_index++;
412 r_sorted_nodes.
append(&node);
413 nodes_to_check.
pop();
421 bool &r_cycle_detected)
424 r_sorted_nodes.
clear();
426 r_cycle_detected =
false;
430 if (node_states[node->index()].is_done) {
434 if ((direction == ToposortDirection::LeftToRight) ?
435 node->runtime->has_available_linked_outputs :
436 node->runtime->has_available_linked_inputs)
442 ntree, direction, *node, node_states, r_sorted_nodes, r_cycle_detected);
446 r_cycle_detected =
true;
448 if (node_states[node->index()].is_done) {
454 ntree, direction, *node, node_states, r_sorted_nodes, r_cycle_detected);
468 for (
bNode *node : nodes) {
469 if (!node->parent && node->is_frame()) {
480 for (
bNode *node : nodes) {
481 node->runtime->direct_children_in_frame.
clear();
484 for (
bNode *node : nodes) {
486 frame->runtime->direct_children_in_frame.append(node);
494 const bke::bNodeType *node_type = bke::node_type_find(
"NodeGroupOutput");
496 if (group_output_nodes.
is_empty()) {
499 else if (group_output_nodes.
size() == 1) {
503 for (
bNode *group_output : group_output_nodes) {
514 for (
const bNode *node : ntree.
runtime->toposort_left_to_right) {
516 if (!node->is_reroute()) {
526 const bNode &source_node = *links.
first()->fromnode;
542 threading::parallel_invoke(
544 [&]() { update_logically_linked_sockets(ntree); },
545 [&]() { update_sockets_by_identifier(ntree); },
547 update_toposort(ntree,
548 ToposortDirection::LeftToRight,
549 tree_runtime.toposort_left_to_right,
550 tree_runtime.has_available_link_cycle);
551 for (const int i : tree_runtime.toposort_left_to_right.index_range()) {
552 const bNode &node = *tree_runtime.toposort_left_to_right[i];
553 node.runtime->toposort_left_to_right_index = i;
562 node.runtime->toposort_right_to_left_index = i;
575void bNodeTree::ensure_topology_cache()
const
583 if (ref.id == nested_node_id) {
590const bNestedNodeRef *bNodeTree::nested_node_ref_from_node_id_path(
598 if (this->node_id_path_from_nested_node_ref(ref.id, current_node_ids)) {
599 if (current_node_ids.
as_span() == node_ids) {
607bool bNodeTree::node_id_path_from_nested_node_ref(
const int32_t nested_node_id,
610 const bNestedNodeRef *ref = this->find_nested_node_ref(nested_node_id);
611 if (ref ==
nullptr) {
615 const bNode *node = this->node_by_id(node_id);
616 if (node ==
nullptr) {
619 r_node_ids.
append(node_id);
620 if (!node->is_group()) {
624 if (group ==
nullptr) {
627 return group->node_id_path_from_nested_node_ref(ref->
path.
id_in_node, r_node_ids);
630const bNode *bNodeTree::find_nested_node(
const int32_t nested_node_id,
633 const bNestedNodeRef *ref = this->find_nested_node_ref(nested_node_id);
634 if (ref ==
nullptr) {
638 const bNode *node = this->node_by_id(node_id);
639 if (node ==
nullptr) {
642 if (!node->is_group()) {
649 if (group ==
nullptr) {
#define LISTBASE_FOREACH(type, var, list)
void ensure(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
int64_t append_and_get_index(const T &value)
bool contains(const T &value) const
void append(const T &value)
IndexRange index_range() const
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
local_group_size(16, 16) .push_constant(Type b
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)
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()
bNodeType NodeTypeUndefined
Span< int > all_zone_input_node_types()
const GeometryNodesLazyFunctionGraphInfo * ensure_geometry_nodes_lazy_function_graph(const bNodeTree &btree)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
bNodeSocketRuntimeHandle * runtime
bNodeTreeRuntimeHandle * runtime
bNodeRuntimeHandle * runtime