Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/intern/node_declaration.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| #include "NOD_node_declaration.hh" | #include "NOD_node_declaration.hh" | ||||
| #include "NOD_socket_declarations.hh" | |||||
| #include "NOD_socket_declarations_geometry.hh" | |||||
| #include "BKE_geometry_fields.hh" | #include "BKE_geometry_fields.hh" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| namespace blender::nodes { | namespace blender::nodes { | ||||
| void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration) | void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration) | ||||
| { | { | ||||
| NodeDeclarationBuilder node_decl_builder{r_declaration}; | NodeDeclarationBuilder node_decl_builder{r_declaration}; | ||||
| typeinfo.declare(node_decl_builder); | typeinfo.declare(node_decl_builder); | ||||
| node_decl_builder.finalize(); | node_decl_builder.finalize(); | ||||
| } | } | ||||
| void NodeDeclarationBuilder::finalize() | void NodeDeclarationBuilder::finalize() | ||||
| { | { | ||||
| if (is_function_node_) { | if (is_function_node_) { | ||||
| for (SocketDeclarationPtr &socket_decl : declaration_.inputs) { | for (std::unique_ptr<BaseSocketDeclarationBuilder> &socket_builder : input_builders_) { | ||||
| if (socket_decl->input_field_type != InputSocketFieldType::Implicit) { | SocketDeclaration &socket_decl = *socket_builder->declaration(); | ||||
| socket_decl->input_field_type = InputSocketFieldType::IsSupported; | if (socket_decl.input_field_type != InputSocketFieldType::Implicit) { | ||||
| socket_decl.input_field_type = InputSocketFieldType::IsSupported; | |||||
| } | } | ||||
| } | } | ||||
| for (SocketDeclarationPtr &socket_decl : declaration_.outputs) { | for (std::unique_ptr<BaseSocketDeclarationBuilder> &socket_builder : output_builders_) { | ||||
| socket_decl->output_field_dependency = OutputFieldDependency::ForDependentField(); | SocketDeclaration &socket_decl = *socket_builder->declaration(); | ||||
| socket_decl.output_field_dependency = OutputFieldDependency::ForDependentField(); | |||||
| socket_builder->reference_pass_all_ = true; | |||||
| } | |||||
| } | |||||
| Vector<int> geometry_inputs; | |||||
| for (const int i : declaration_.inputs.index_range()) { | |||||
| if (dynamic_cast<decl::Geometry *>(declaration_.inputs[i].get())) { | |||||
| geometry_inputs.append(i); | |||||
| } | |||||
| } | |||||
| Vector<int> geometry_outputs; | |||||
| for (const int i : declaration_.outputs.index_range()) { | |||||
| if (dynamic_cast<decl::Geometry *>(declaration_.outputs[i].get())) { | |||||
| geometry_outputs.append(i); | |||||
| } | |||||
| } | |||||
| for (std::unique_ptr<BaseSocketDeclarationBuilder> &socket_builder : input_builders_) { | |||||
| if (socket_builder->reference_on_auto_) { | |||||
| aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); | |||||
| const int field_input = socket_builder->index_; | |||||
| for (const int geometry_input : geometry_inputs) { | |||||
| relations.eval_relations.append({field_input, geometry_input}); | |||||
| } | |||||
| } | |||||
| } | |||||
| for (std::unique_ptr<BaseSocketDeclarationBuilder> &socket_builder : output_builders_) { | |||||
| if (socket_builder->reference_on_auto_) { | |||||
| aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); | |||||
| const int field_output = socket_builder->index_; | |||||
| for (const int geometry_output : geometry_outputs) { | |||||
| relations.available_relations.append({field_output, geometry_output}); | |||||
| } | |||||
| } | |||||
| if (socket_builder->reference_pass_all_) { | |||||
| aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); | |||||
| const int field_output = socket_builder->index_; | |||||
| for (const int input_i : declaration_.inputs.index_range()) { | |||||
| SocketDeclaration &input_socket_decl = *declaration_.inputs[input_i]; | |||||
| if (input_socket_decl.input_field_type != InputSocketFieldType::None) { | |||||
| relations.reference_relations.append({input_i, field_output}); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (socket_builder->propagate_from_auto_) { | |||||
| aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); | |||||
| const int geometry_output = socket_builder->index_; | |||||
| for (const int geometry_input : geometry_inputs) { | |||||
| relations.propagate_relations.append({geometry_input, geometry_output}); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| namespace anonymous_attribute_lifetime { | |||||
| bool operator==(const RelationsInNode &a, const RelationsInNode &b) | |||||
| { | |||||
| return a.propagate_relations == b.propagate_relations && | |||||
| a.reference_relations == b.reference_relations && a.eval_relations == b.eval_relations && | |||||
| a.available_relations == b.available_relations && | |||||
| a.available_on_none == b.available_on_none; | |||||
| } | |||||
| bool operator!=(const RelationsInNode &a, const RelationsInNode &b) | |||||
| { | |||||
| return !(a == b); | |||||
| } | |||||
| std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations) | |||||
| { | |||||
| stream << "Propagate Relations: " << relations.propagate_relations.size() << "\n"; | |||||
| for (const PropagateRelation &relation : relations.propagate_relations) { | |||||
| stream << " " << relation.from_geometry_input << " -> " << relation.to_geometry_output | |||||
| << "\n"; | |||||
| } | |||||
| stream << "Reference Relations: " << relations.reference_relations.size() << "\n"; | |||||
| for (const ReferenceRelation &relation : relations.reference_relations) { | |||||
| stream << " " << relation.from_field_input << " -> " << relation.to_field_output << "\n"; | |||||
| } | |||||
| stream << "Eval Relations: " << relations.eval_relations.size() << "\n"; | |||||
| for (const EvalRelation &relation : relations.eval_relations) { | |||||
| stream << " eval " << relation.field_input << " on " << relation.geometry_input << "\n"; | |||||
| } | |||||
| stream << "Available Relations: " << relations.available_relations.size() << "\n"; | |||||
| for (const AvailableRelation &relation : relations.available_relations) { | |||||
| stream << " " << relation.field_output << " available on " << relation.geometry_output | |||||
| << "\n"; | |||||
| } | |||||
| stream << "Available on None: " << relations.available_on_none.size() << "\n"; | |||||
| for (const int i : relations.available_on_none) { | |||||
| stream << " output " << i << " available on none\n"; | |||||
| } | |||||
| return stream; | |||||
| } | |||||
| } // namespace anonymous_attribute_lifetime | |||||
| bool NodeDeclaration::matches(const bNode &node) const | bool NodeDeclaration::matches(const bNode &node) const | ||||
| { | { | ||||
| auto check_sockets = [&](ListBase sockets, Span<SocketDeclarationPtr> socket_decls) { | auto check_sockets = [&](ListBase sockets, Span<SocketDeclarationPtr> socket_decls) { | ||||
| const int tot_sockets = BLI_listbase_count(&sockets); | const int tot_sockets = BLI_listbase_count(&sockets); | ||||
| if (tot_sockets != socket_decls.size()) { | if (tot_sockets != socket_decls.size()) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| int i; | int i; | ||||
| ▲ Show 20 Lines • Show All 94 Lines • Show Last 20 Lines | |||||