25 tree_cow.
runtime->geometry_nodes_lazy_function_graph_info.reset();
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()) {
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;
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();
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);
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();
336 bNode &node = *item.node;
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});
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++;
415 r_sorted_nodes.
append(&node);
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) {
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);
499 if (group_output_nodes.
is_empty()) {
502 else if (group_output_nodes.
size() == 1) {
507 for (
bNode *group_output : group_output_nodes) {
518 for (
const bNode *node : ntree.
runtime->toposort_left_to_right) {
520 if (!node->is_reroute()) {
530 const bNode &source_node = *links.
first()->fromnode;
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(
628 const blender::Span<int32_t> node_ids)
const
634 blender::Vector<int> current_node_ids;
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,
645 blender::Vector<int> &r_node_ids)
const
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) {
692const bNodeSocket &bNode::socket_by_decl(
const blender::nodes::SocketDeclaration &decl)
const
697bNodeSocket &bNode::socket_by_decl(
const blender::nodes::SocketDeclaration &decl)
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
723 const bNode &node = this->owner_node();
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)
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(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_input_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)