25 tree_cow.
runtime->geometry_nodes_lazy_function_graph_info.reset();
37 node.runtime->index_in_tree = i;
40 if (
node.is_group()) {
74 socket->runtime->owner_node =
node;
83 socket->runtime->owner_node =
node;
95 node_runtime.
panels.reinitialize(
node->num_panel_states);
104 socket->runtime->internal_link_input =
nullptr;
107 link.tosock->runtime->internal_link_input = link.fromsock;
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;
128 link->fromsock->runtime->directly_linked_links.append(link);
129 link->fromsock->runtime->directly_linked_sockets.append(link->tosock);
130 link->tosock->runtime->directly_linked_links.append(link);
131 if (link->is_available()) {
132 link->fromnode->runtime->has_available_linked_outputs =
true;
133 link->tonode->runtime->has_available_linked_inputs =
true;
138 std::sort(socket->runtime->directly_linked_links.begin(),
139 socket->runtime->directly_linked_links.end(),
141 return a->multi_input_sort_id > b->multi_input_sort_id;
146 for (
bNodeLink *link : socket->runtime->directly_linked_links) {
148 socket->runtime->directly_linked_sockets.append(link->fromsock);
155 bool only_follow_first_input_link,
160 if (sockets_in_current_chain.
contains(&input_socket)) {
164 sockets_in_current_chain.
append(&input_socket);
167 if (only_follow_first_input_link) {
168 links_to_check = links_to_check.
take_front(1);
171 if (link->is_muted()) {
174 if (!link->is_available()) {
178 bNode &origin_node = *link->fromnode;
179 if (!origin_socket.is_available()) {
183 if (origin_node.is_reroute()) {
186 r_skipped_origins.
append(&reroute_input);
187 r_skipped_origins.
append(&reroute_output);
189 reroute_input,
false, sockets_in_current_chain, r_logical_origins, r_skipped_origins);
192 if (origin_node.is_muted()) {
194 r_skipped_origins.
append(&origin_socket);
195 r_skipped_origins.
append(mute_input);
197 *mute_input,
true, sockets_in_current_chain, r_logical_origins, r_skipped_origins);
201 r_logical_origins.
append(&origin_socket);
204 sockets_in_current_chain.
pop_last();
213 for (const int i : range) {
214 bNode &node = *nodes[i];
215 for (bNodeSocket *socket : node.runtime->inputs) {
216 Vector<bNodeSocket *, 16> sockets_in_current_chain;
217 socket->runtime->logically_linked_sockets.clear();
218 socket->runtime->logically_linked_skipped_sockets.clear();
219 find_logical_origins_for_socket_recursive(
222 sockets_in_current_chain,
223 socket->runtime->logically_linked_sockets,
224 socket->runtime->logically_linked_skipped_sockets);
231 for (const int i : range) {
232 bNode &node = *nodes[i];
233 for (bNodeSocket *socket : node.runtime->outputs) {
234 socket->runtime->logically_linked_sockets.clear();
243 for (
bNodeSocket *output_socket : input_socket->runtime->logically_linked_sockets) {
244 output_socket->runtime->logically_linked_sockets.append(input_socket);
264 for (bNode *node : nodes.slice(range)) {
265 node->runtime->inputs_by_identifier.clear();
266 node->runtime->outputs_by_identifier.clear();
267 for (bNodeSocket *socket : node->runtime->inputs) {
268 node->runtime->inputs_by_identifier.add_new(socket->identifier, socket);
270 for (bNodeSocket *socket : node->runtime->outputs) {
271 node->runtime->outputs_by_identifier.add_new(socket->identifier, socket);
283 bool is_done =
false;
284 bool is_in_stack =
false;
294 for (
const bNode *input_node :
298 origin_nodes.
append(input_node);
311 target_nodes.
append(output_node);
322 bool &r_cycle_detected)
326 int socket_index = 0;
328 int implicit_link_index = 0;
332 nodes_to_check.
push({&start_node});
333 node_states[start_node.index()].is_in_stack =
true;
334 while (!nodes_to_check.
is_empty()) {
335 Item &item = nodes_to_check.
peek();
337 bool pushed_node =
false;
339 auto handle_linked_node = [&](
bNode &linked_node) {
341 if (linked_node_state.
is_done) {
346 r_cycle_detected =
true;
349 nodes_to_check.
push({&linked_node});
357 node.runtime->inputs :
358 node.runtime->outputs;
360 if (item.socket_index == sockets.
size()) {
366 if (item.link_index == linked_links.
size()) {
372 bNodeLink &link = *linked_links[item.link_index];
373 if (!link.is_available()) {
378 bNodeSocket &linked_socket = *socket.
runtime->directly_linked_sockets[item.link_index];
379 bNode &linked_node = *linked_socket.
runtime->owner_node;
380 if (handle_linked_node(linked_node)) {
395 if (item.implicit_link_index == implicitly_linked_nodes.
size()) {
399 const bNode &linked_node = *implicitly_linked_nodes[item.implicit_link_index];
400 if (handle_linked_node(
const_cast<bNode &
>(linked_node))) {
402 item.implicit_link_index++;
416 nodes_to_check.
pop();
424 bool &r_cycle_detected)
427 r_sorted_nodes.
clear();
429 r_cycle_detected =
false;
433 if (node_states[
node->index()].is_done) {
437 if ((direction == ToposortDirection::LeftToRight) ?
438 node->runtime->has_available_linked_outputs :
439 node->runtime->has_available_linked_inputs)
445 ntree, direction, *
node, node_states, r_sorted_nodes, r_cycle_detected);
449 r_cycle_detected =
true;
451 if (node_states[
node->index()].is_done) {
457 ntree, direction, *
node, node_states, r_sorted_nodes, r_cycle_detected);
472 if (!
node->parent &&
node->is_frame()) {
484 node->runtime->direct_children_in_frame.
clear();
489 frame->runtime->direct_children_in_frame.append(
node);
497 const bke::bNodeType *node_type = bke::node_type_find(
"NodeGroupOutput");
499 if (group_output_nodes.
is_empty()) {
502 else if (group_output_nodes.
size() == 1) {
507 for (
bNode *group_output : group_output_nodes) {
520 if (!
node->is_reroute()) {
530 const bNode &source_node = *links.
first()->fromnode;
546 threading::parallel_invoke(
548 [&]() { update_logically_linked_sockets(ntree); },
549 [&]() { update_sockets_by_identifier(ntree); },
551 update_toposort(ntree,
552 ToposortDirection::LeftToRight,
553 tree_runtime.toposort_left_to_right,
554 tree_runtime.has_available_link_cycle);
555 for (const int i : tree_runtime.toposort_left_to_right.index_range()) {
556 const bNode &node = *tree_runtime.toposort_left_to_right[i];
557 node.runtime->toposort_left_to_right_index = i;
566 node.runtime->toposort_right_to_left_index = i;
584 input_socket_index_ = link.
tosock->index();
586 const_cast<const bNodeSocket *
>(link.
tosock)->directly_linked_links().first_index(&link);
596 const bNode *to_node = ntree.node_by_id(to_node_id_);
600 if (input_socket_index_ >= to_node->input_sockets().size()) {
603 const bNodeSocket &input_socket = to_node->input_socket(input_socket_index_);
604 if (input_link_index_ >= input_socket.directly_linked_links().size()) {
607 return input_socket.directly_linked_links()[input_link_index_];
612void bNodeTree::ensure_topology_cache()
const
620 if (ref.id == nested_node_id) {
627const bNestedNodeRef *bNodeTree::nested_node_ref_from_node_id_path(
635 if (this->node_id_path_from_nested_node_ref(ref.id, current_node_ids)) {
636 if (current_node_ids.
as_span() == node_ids) {
644bool bNodeTree::node_id_path_from_nested_node_ref(
const int32_t nested_node_id,
647 const bNestedNodeRef *ref = this->find_nested_node_ref(nested_node_id);
648 if (ref ==
nullptr) {
652 const bNode *
node = this->node_by_id(node_id);
653 if (
node ==
nullptr) {
656 r_node_ids.
append(node_id);
657 if (!
node->is_group()) {
661 if (group ==
nullptr) {
664 return group->node_id_path_from_nested_node_ref(ref->
path.
id_in_node, r_node_ids);
667const bNode *bNodeTree::find_nested_node(
const int32_t nested_node_id,
670 const bNestedNodeRef *ref = this->find_nested_node_ref(nested_node_id);
671 if (ref ==
nullptr) {
675 const bNode *
node = this->node_by_id(node_id);
676 if (
node ==
nullptr) {
679 if (!
node->is_group()) {
686 if (group ==
nullptr) {
704 tree.runtime->inferenced_input_socket_usage_mutex.ensure([&]() {
705 tree.runtime->inferenced_input_socket_usage =
710bool bNodeSocket::affects_node_output()
const
716 return tree.runtime->inferenced_input_socket_usage[this->index_in_all_inputs()].is_used;
719bool bNodeSocket::inferred_input_socket_visibility()
const
724 if (
node.typeinfo->ignore_inferred_input_socket_visibility) {
730 return tree.runtime->inferenced_input_socket_usage[this->index_in_all_inputs()].is_visible;
#define LISTBASE_FOREACH(type, var, list)
void ensure(FunctionRef< void()> compute_cache)
constexpr const T & first() const
constexpr int64_t size() const
constexpr IndexRange index_range() 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
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()
Array< SocketUsage > infer_all_input_sockets_usage(const bNodeTree &tree)
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))
static void ensure_inference_usage_cache(const bNodeTree &tree)
static blender::bke::bNodeSocketTemplate inputs[]
bNodeSocketRuntimeHandle * runtime
bNodeTreeRuntimeHandle * runtime
bNodeRuntimeHandle * runtime
bNodeLink * try_find(bNodeTree &ntree) const
NodeLinkKey(const bNodeLink &link)