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());
49 zones.
append(std::move(zone));
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);
62 for (
const std::unique_ptr<bNodeTreeZone> &zone : zones) {
63 if (!zone->input_node_id || !zone->output_node_id) {
64 r_zone_by_inout_node.
clear();
90 const int zone_i = zone->index;
91 for (
const bNode *node : {zone->output_node()}) {
92 if (node ==
nullptr) {
95 const BoundedBitSpan depend_on_input_flags = depend_on_input_flag_array[node->index()];
97 if (parent_zone_i != zone_i) {
98 all_zone_relations.
add_new({all_zones[parent_zone_i], zone});
104 for (
const ZoneRelation &relation : all_zone_relations) {
105 const ZoneRelation reverse_relation{relation.child, relation.parent};
106 if (all_zone_relations.
contains(reverse_relation)) {
114 for (
const int a : all_zone_relations.
index_range()) {
125 const int transitive_relation_i = all_zone_relations.
index_of_try(transitive_relation);
126 if (transitive_relation_i != -1) {
131 std::sort(transitive_relations.
begin(), transitive_relations.
end(), std::greater<>());
134 for (
const int i : transitive_relations) {
138 return zone_relations;
148 bool found_node_in_multiple_zones =
false;
150 const bNode &node = *all_nodes[node_i];
151 const BoundedBitSpan depend_on_input_flags = depend_on_input_flag_array[node_i];
158 if (parent_zone ==
nullptr) {
165 if (iter_zone == parent_zone) {
174 if (iter_zone == zone) {
179 found_node_in_multiple_zones =
true;
181 if (parent_zone ==
nullptr) {
182 if (!zone_by_inout_node.
contains(&node)) {
191 r_zone_by_node_id.
add_overwrite(item.key->identifier, item.value->index);
193 return found_node_in_multiple_zones;
198 tree.ensure_topology_cache();
200 if (!link->is_available()) {
203 if (link->is_muted()) {
206 if (link->fromnode->is_dangling_reroute()) {
213 if (from_zone == to_zone) {
218 zone->border_links.append(link);
225 tree.ensure_topology_cache();
226 if (
tree.has_available_link_cycle()) {
233 std::unique_ptr<bNodeTreeZones> tree_zones = std::make_unique<bNodeTreeZones>();
234 tree_zones->tree = &
tree;
239 for (
const std::unique_ptr<bNodeTreeZone> &zone : tree_zones->zones_ptrs) {
240 tree_zones->zones.append(zone.get());
243 const int zones_num = tree_zones->zones.size();
244 const int nodes_num = all_nodes.
size();
251 for (
const bNode *node : sorted_nodes) {
252 const int node_i = node->index();
257 for (
const bNodeSocket *input_socket : node->input_sockets()) {
258 if (!input_socket->is_available()) {
261 for (
const bNodeLink *link : input_socket->directly_linked_links()) {
262 if (link->is_muted()) {
265 const bNode &from_node = *link->fromnode;
266 const int from_node_i = from_node.index();
267 depend_on_input_flags |= depend_on_input_flag_array[from_node_i];
268 depend_on_output_flags |= depend_on_output_flag_array[from_node_i];
271 if (input_types.
contains(node->type_legacy)) {
274 depend_on_input_flags[zone->index].set();
277 else if (output_types.
contains(node->type_legacy)) {
280 if (
const bNode *zone_input_node = zone->input_node()) {
281 const int input_node_i = zone_input_node->index();
282 depend_on_input_flags |= depend_on_input_flag_array[input_node_i];
283 depend_on_output_flags |= depend_on_output_flag_array[input_node_i];
286 depend_on_input_flags[zone->index].reset();
287 depend_on_output_flags[zone->index].set();
298 tree_zones->zones, depend_on_input_flag_array);
299 if (!zone_relations) {
306 relation.parent->child_zones.append(relation.child);
307 BLI_assert(relation.child->parent_zone ==
nullptr);
308 relation.child->parent_zone = relation.parent;
314 for (
bNodeTreeZone *zone = main_zone; zone; zone = zone->parent_zone) {
315 if (!found_zones.
add(zone)) {
328 if (zone->depth == 0) {
329 tree_zones->root_zones.append(zone);
336 depend_on_input_flag_array,
338 tree_zones->zone_by_node_id,
339 tree_zones->node_ids_outside_zones);
340 if (found_node_in_multiple_zones) {
345 "ShaderNodeOutputMaterial",
346 "ShaderNodeOutputLight",
347 "ShaderNodeOutputWorld",
348 "ShaderNodeOutputAOV"})
350 for (
const bNode *node :
tree.nodes_by_type(output_idname)) {
351 if (tree_zones->zone_by_node_id.contains(node->identifier)) {
359 const bNode *node = all_nodes[node_i];
360 const int zone_i = tree_zones->zone_by_node_id.lookup_default(node->
identifier, -1);
379 tree.ensure_topology_cache();
380 tree.runtime->tree_zones_cache_mutex.ensure([&]() {
382 if (
tree.runtime->tree_zones) {
383 tree.runtime->last_valid_zones =
tree.runtime->tree_zones;
386 return tree.runtime->tree_zones.get();
396 for (
const bNodeTreeZone *zone = zones->
zones[zone_i]; zone; zone = zone->parent_zone) {
416 const bNode &node = socket.owner_node();
418 if (zone ==
nullptr) {
422 if (socket.is_input()) {
427 if (socket.is_output()) {
440 return this->
zones[zone_i];
446 if (from_zone == to_zone) {
477 zones_to_enter.
append(zone);
479 std::reverse(zones_to_enter.
begin(), zones_to_enter.
end());
480 return zones_to_enter;
490 const bNode &output_bnode)
const
492 for (
const bNode *node :
tree.nodes_by_type(this->input_idname)) {
501 const bNode &input_bnode)
const
508 return const_cast<bNode *
>(
514 return const_cast<bNode *
>(
539 node_types.
append(zone_type->input_type);
540 node_types.
append(zone_type->output_type);
552 node_types.
append(zone_type->input_type);
564 node_types.
append(zone_type->output_type);
574 if (
ELEM(node_type, zone_type->input_type, zone_type->output_type)) {
600 for (
const int i :
nodes.index_range()) {
620 if (
zones.zones.last() != zone) {
629 stream << zone.
index <<
": Parent index: ";
640 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)
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)