20 if (zone.
depth >= 0) {
41 zone_output_nodes.
extend(
tree.nodes_by_type(zone_type->output_idname));
43 for (
const bNode *node : zone_output_nodes) {
44 auto zone = std::make_unique<bNodeTreeZone>();
46 zone->index = zones.
size();
47 zone->output_node_id = node->identifier;
48 r_zone_by_inout_node.
add(node, zone.get());
52 for (
const bNode *input_node :
tree.nodes_by_type(zone_type->input_idname)) {
53 if (
const bNode *output_node = zone_type->get_corresponding_output(
tree, *input_node)) {
55 zone->input_node_id = input_node->identifier;
56 r_zone_by_inout_node.
add(input_node, zone);
83 const int zone_i = zone->index;
84 for (
const bNode *node : {zone->output_node()}) {
85 if (node ==
nullptr) {
88 const BoundedBitSpan depend_on_input_flags = depend_on_input_flag_array[node->index()];
90 if (parent_zone_i != zone_i) {
91 all_zone_relations.
add_new({all_zones[parent_zone_i], zone});
97 for (
const ZoneRelation &relation : all_zone_relations) {
98 const ZoneRelation reverse_relation{relation.child, relation.parent};
99 if (all_zone_relations.
contains(reverse_relation)) {
107 for (
const int a : all_zone_relations.
index_range()) {
118 const int transitive_relation_i = all_zone_relations.
index_of_try(transitive_relation);
119 if (transitive_relation_i != -1) {
124 std::sort(transitive_relations.
begin(), transitive_relations.
end(), std::greater<>());
127 for (
const int i : transitive_relations) {
131 return zone_relations;
141 bool found_node_in_multiple_zones =
false;
143 const bNode &node = *all_nodes[node_i];
144 const BoundedBitSpan depend_on_input_flags = depend_on_input_flag_array[node_i];
151 if (parent_zone ==
nullptr) {
158 if (iter_zone == parent_zone) {
167 if (iter_zone == zone) {
172 found_node_in_multiple_zones =
true;
174 if (parent_zone ==
nullptr) {
175 if (!zone_by_inout_node.
contains(&node)) {
184 r_zone_by_node_id.
add_overwrite(item.key->identifier, item.value->index);
186 return found_node_in_multiple_zones;
191 tree.ensure_topology_cache();
193 if (!link->is_available()) {
196 if (link->is_muted()) {
199 if (link->fromnode->is_dangling_reroute()) {
206 if (from_zone == to_zone) {
211 zone->border_links.append(link);
218 tree.ensure_topology_cache();
219 if (
tree.has_available_link_cycle()) {
226 std::unique_ptr<bNodeTreeZones> tree_zones = std::make_unique<bNodeTreeZones>();
227 tree_zones->tree = &
tree;
232 for (
const std::unique_ptr<bNodeTreeZone> &zone : tree_zones->zones_ptrs) {
233 tree_zones->zones.append(zone.get());
236 const int zones_num = tree_zones->zones.size();
237 const int nodes_num = all_nodes.
size();
244 for (
const bNode *node : sorted_nodes) {
245 const int node_i = node->index();
250 for (
const bNodeSocket *input_socket : node->input_sockets()) {
251 if (!input_socket->is_available()) {
254 for (
const bNodeLink *link : input_socket->directly_linked_links()) {
255 if (link->is_muted()) {
258 const bNode &from_node = *link->fromnode;
259 const int from_node_i = from_node.index();
260 depend_on_input_flags |= depend_on_input_flag_array[from_node_i];
261 depend_on_output_flags |= depend_on_output_flag_array[from_node_i];
264 if (input_types.
contains(node->type_legacy)) {
267 depend_on_input_flags[zone->index].set();
270 else if (output_types.
contains(node->type_legacy)) {
273 if (
const bNode *zone_input_node = zone->input_node()) {
274 const int input_node_i = zone_input_node->index();
275 depend_on_input_flags |= depend_on_input_flag_array[input_node_i];
276 depend_on_output_flags |= depend_on_output_flag_array[input_node_i];
279 depend_on_input_flags[zone->index].reset();
280 depend_on_output_flags[zone->index].set();
291 tree_zones->zones, depend_on_input_flag_array);
292 if (!zone_relations) {
299 relation.parent->child_zones.append(relation.child);
300 BLI_assert(relation.child->parent_zone ==
nullptr);
301 relation.child->parent_zone = relation.parent;
307 for (
bNodeTreeZone *zone = main_zone; zone; zone = zone->parent_zone) {
308 if (!found_zones.
add(zone)) {
321 if (zone->depth == 0) {
322 tree_zones->root_zones.append(zone);
329 depend_on_input_flag_array,
331 tree_zones->zone_by_node_id,
332 tree_zones->node_ids_outside_zones);
333 if (found_node_in_multiple_zones) {
337 for (
const bNode *node :
tree.nodes_by_type(
"NodeGroupOutput")) {
338 if (tree_zones->zone_by_node_id.contains(node->identifier)) {
345 const bNode *node = all_nodes[node_i];
346 const int zone_i = tree_zones->zone_by_node_id.lookup_default(node->
identifier, -1);
365 tree.ensure_topology_cache();
366 tree.runtime->tree_zones_cache_mutex.ensure([&]() {
368 if (
tree.runtime->tree_zones) {
369 tree.runtime->last_valid_zones =
tree.runtime->tree_zones;
372 return tree.runtime->tree_zones.get();
382 for (
const bNodeTreeZone *zone = zones->
zones[zone_i]; zone; zone = zone->parent_zone) {
402 const bNode &node = socket.owner_node();
404 if (zone ==
nullptr) {
408 if (socket.is_input()) {
413 if (socket.is_output()) {
426 return this->
zones[zone_i];
432 if (from_zone == to_zone) {
463 zones_to_enter.
append(zone);
465 std::reverse(zones_to_enter.
begin(), zones_to_enter.
end());
466 return zones_to_enter;
476 const bNode &output_bnode)
const
478 for (
const bNode *node :
tree.nodes_by_type(
this->input_idname)) {
487 const bNode &input_bnode)
const
494 return const_cast<bNode *
>(
500 return const_cast<bNode *
>(
525 node_types.
append(zone_type->input_type);
526 node_types.
append(zone_type->output_type);
538 node_types.
append(zone_type->input_type);
550 node_types.
append(zone_type->output_type);
560 if (
ELEM(node_type, zone_type->input_type, zone_type->output_type)) {
586 for (
const int i :
nodes.index_range()) {
606 if (
zones.zones.last() != zone) {
615 stream << zone.
index <<
": Parent index: ";
626 stream <<
"; Border Links: {\n";
#define BLI_STRUCT_EQUALITY_OPERATORS_2(Type, m1, m2)
unsigned long long int uint64_t
Value lookup_default(const Key &key, const Value &default_value) const
bool add_overwrite(const Key &key, const Value &value)
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
bool contains(const Key &key) const
ItemIterator items() const &
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool contains(const T &value) const
int64_t index_of_try(const Key &key) const
IndexRange index_range() const
bool contains(const Key &key) const
Span< Key > as_span() const
void add_new(const Key &key)
void remove_and_reorder(const int64_t index)
int64_t append_and_get_index(const T &value)
void append(const T &value)
void extend(Span< T > array)
void append_non_duplicates(const T &value)
bool contains_zone_recursively(const bNodeTreeZone &other_zone) const
Vector< int > child_node_ids
Vector< const bNode * > child_nodes() const
bNodeTreeZone * parent_zone
std::optional< int > output_node_id
const bNode * output_node() const
Vector< const bNodeLink * > border_links
bool contains_node_recursively(const bNode &node) const
std::optional< int > input_node_id
const bNode * input_node() const
Vector< const bNodeTreeZone * > get_zones_to_enter_from_root(const bNodeTreeZone *zone) const
Vector< const bNodeTreeZone * > get_zones_to_enter(const bNodeTreeZone *outer_zone, const bNodeTreeZone *inner_zone) const
bool link_between_zones_is_allowed(const bNodeTreeZone *from_zone, const bNodeTreeZone *to_zone) const
Vector< int > node_ids_outside_zones
Vector< const bNode * > nodes_outside_zones() const
Vector< bNodeTreeZone * > zones
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
Map< int, int > zone_by_node_id
const bNodeTreeZone * get_zone_by_socket(const bNodeSocket &socket) const
bool link_between_sockets_is_allowed(const bNodeSocket &from, const bNodeSocket &to) const
const bNode * get_corresponding_input(const bNodeTree &tree, const bNode &output_bnode) const
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
bool has_common_set_bits(const BitSpanT &...args)
void foreach_1_index(const BitSpanT &data, Fn &&fn)
const bNodeZoneType * zone_type_by_node_type(const int node_type)
static void update_zone_depths(bNodeTreeZone &zone)
static std::optional< Vector< ZoneRelation > > get_direct_zone_relations(const Span< bNodeTreeZone * > all_zones, const BitGroupVector<> &depend_on_input_flag_array)
static Vector< const bNodeZoneType * > & get_zone_types_vector()
static Vector< std::unique_ptr< bNodeTreeZone > > find_zone_nodes(const bNodeTree &tree, bNodeTreeZones &owner, Map< const bNode *, bNodeTreeZone * > &r_zone_by_inout_node)
Span< int > all_zone_output_node_types()
static void update_zone_border_links(const bNodeTree &tree, bNodeTreeZones &tree_zones)
Span< const bNodeZoneType * > all_zone_types()
static Vector< const bNode * > node_ids_to_vector(const bNodeTree &tree, const Vector< int > &node_ids)
Span< int > all_zone_node_types()
void register_node_zone_type(const bNodeZoneType &zone_type)
Span< int > all_zone_input_node_types()
static std::unique_ptr< bNodeTreeZones > discover_tree_zones(const bNodeTree &tree)
std::ostream & operator<<(std::ostream &stream, const GeometrySet &geometry_set)
const bNodeTreeZones * get_tree_zones(const bNodeTree &tree)
static bool update_zone_per_node(const Span< const bNode * > all_nodes, const Span< bNodeTreeZone * > all_zones, const BitGroupVector<> &depend_on_input_flag_array, const Map< const bNode *, bNodeTreeZone * > &zone_by_inout_node, Map< int, int > &r_zone_by_node_id, Vector< int > &r_node_outside_zones)
uint64_t get_default_hash(const T &v, const Args &...args)