diff options
Diffstat (limited to 'source/blender/nodes/intern')
-rw-r--r-- | source/blender/nodes/intern/derived_node_tree.cc | 2 | ||||
-rw-r--r-- | source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 279 | ||||
-rw-r--r-- | source/blender/nodes/intern/geometry_nodes_log.cc | 77 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_common.cc | 169 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_declaration.cc | 27 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_exec.cc | 2 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_exec.h | 4 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_geometry_exec.cc | 12 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_socket.cc | 26 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_socket_declarations.cc | 2 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_util.cc (renamed from source/blender/nodes/intern/node_util.c) | 16 | ||||
-rw-r--r-- | source/blender/nodes/intern/socket_search_link.cc | 63 |
12 files changed, 363 insertions, 316 deletions
diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index e8e0f0fa61c..2ea80008af8 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -58,7 +58,7 @@ void DerivedNodeTree::destruct_context_recursively(DTreeContext *context) bool DerivedNodeTree::has_link_cycles() const { for (const bNodeTree *btree : used_btrees_) { - if (btree->has_link_cycle()) { + if (btree->has_available_link_cycle()) { return true; } } diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index e4d476e6374..197f0997160 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -16,6 +16,7 @@ #include "NOD_multi_function.hh" #include "NOD_node_declaration.hh" +#include "BLI_lazy_threading.hh" #include "BLI_map.hh" #include "DNA_ID.h" @@ -27,6 +28,8 @@ #include "FN_field_cpp_type.hh" #include "FN_lazy_function_graph_executor.hh" +#include "DEG_depsgraph_query.h" + namespace blender::nodes { using fn::ValueOrField; @@ -134,13 +137,14 @@ class LazyFunctionForGeometryNode : public LazyFunction { if (geo_eval_log::GeoModifierLog *modifier_log = user_data->modifier_data->eval_log) { geo_eval_log::GeoTreeLogger &tree_logger = modifier_log->get_local_tree_logger( *user_data->compute_context); - tree_logger.node_execution_times.append({node_.name, start_time, end_time}); + tree_logger.node_execution_times.append( + {tree_logger.allocator->copy_string(node_.name), start_time, end_time}); } } }; /** - * Used to gather all inputs of a multi-input socket. A separate node is necessary, because + * Used to gather all inputs of a multi-input socket. A separate node is necessary because * multi-inputs are not supported in lazy-function graphs. */ class LazyFunctionForMultiInput : public LazyFunction { @@ -154,8 +158,9 @@ class LazyFunctionForMultiInput : public LazyFunction { base_type_ = get_socket_cpp_type(socket); BLI_assert(base_type_ != nullptr); BLI_assert(socket.is_multi_input()); + const bNodeTree &btree = socket.owner_tree(); for (const bNodeLink *link : socket.directly_linked_links()) { - if (!link->is_muted()) { + if (!(link->is_muted() || nodeIsDanglingReroute(&btree, link->fromnode))) { inputs_.append({"Input", *base_type_}); } } @@ -164,14 +169,14 @@ class LazyFunctionForMultiInput : public LazyFunction { outputs_.append({"Output", *vector_type}); } - void execute_impl(lf::Params ¶ms, const lf::Context &UNUSED(context)) const override + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override { /* Currently we only have multi-inputs for geometry and string sockets. This could be * generalized in the future. */ base_type_->to_static_type_tag<GeometrySet, ValueOrField<std::string>>([&](auto type_tag) { using T = typename decltype(type_tag)::type; if constexpr (std::is_void_v<T>) { - /* This type is not support in this node for now. */ + /* This type is not supported in this node for now. */ BLI_assert_unreachable(); } else { @@ -198,7 +203,7 @@ class LazyFunctionForRerouteNode : public LazyFunction { outputs_.append({"Output", type}); } - void execute_impl(lf::Params ¶ms, const lf::Context &UNUSED(context)) const override + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override { void *input_value = params.try_get_input_data_ptr(0); void *output_value = params.get_output_data_ptr(0); @@ -211,6 +216,28 @@ class LazyFunctionForRerouteNode : public LazyFunction { }; /** + * Lazy functions for nodes whose type cannot be found. An undefined function just outputs default + * values. It's useful to have so other parts of the conversion don't have to care about undefined + * nodes. + */ +class LazyFunctionForUndefinedNode : public LazyFunction { + public: + LazyFunctionForUndefinedNode(const bNode &node, Vector<const bNodeSocket *> &r_used_outputs) + { + debug_name_ = "Undefined"; + Vector<const bNodeSocket *> dummy_used_inputs; + Vector<lf::Input> dummy_inputs; + lazy_function_interface_from_node( + node, dummy_used_inputs, r_used_outputs, dummy_inputs, outputs_); + } + + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override + { + params.set_default_remaining_outputs(); + } +}; + +/** * Executes a multi-function. If all inputs are single values, the results will also be single * values. If any input is a field, the outputs will also be fields. */ @@ -325,7 +352,7 @@ class LazyFunctionForMutedNode : public LazyFunction { } } - void execute_impl(lf::Params ¶ms, const lf::Context &UNUSED(context)) const override + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override { for (const int output_i : outputs_.index_range()) { if (params.output_was_set(output_i)) { @@ -397,7 +424,7 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction { outputs_.append({"To", to}); } - void execute_impl(lf::Params ¶ms, const lf::Context &UNUSED(context)) const override + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override { const void *from_value = params.try_get_input_data_ptr(0); void *to_value = params.get_output_data_ptr(0); @@ -416,18 +443,16 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction { */ class LazyFunctionForMultiFunctionNode : public LazyFunction { private: - const bNode &node_; const NodeMultiFunctions::Item fn_item_; Vector<const ValueOrFieldCPPType *> input_types_; Vector<const ValueOrFieldCPPType *> output_types_; - Vector<const bNodeSocket *> output_sockets_; public: LazyFunctionForMultiFunctionNode(const bNode &node, NodeMultiFunctions::Item fn_item, Vector<const bNodeSocket *> &r_used_inputs, Vector<const bNodeSocket *> &r_used_outputs) - : node_(node), fn_item_(std::move(fn_item)) + : fn_item_(std::move(fn_item)) { BLI_assert(fn_item_.fn != nullptr); debug_name_ = node.name; @@ -438,10 +463,9 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction { for (const lf::Output &fn_output : outputs_) { output_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_output.type)); } - output_sockets_ = r_used_outputs; } - void execute_impl(lf::Params ¶ms, const lf::Context &UNUSED(context)) const override + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override { Vector<const void *> input_values(inputs_.size()); Vector<void *> output_values(outputs_.size()); @@ -478,7 +502,7 @@ class LazyFunctionForImplicitInput : public LazyFunction { outputs_.append({"Output", type}); } - void execute_impl(lf::Params ¶ms, const lf::Context &UNUSED(context)) const override + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override { void *value = params.get_output_data_ptr(0); init_fn_(value); @@ -514,21 +538,61 @@ class LazyFunctionForViewerNode : public LazyFunction { { GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data); BLI_assert(user_data != nullptr); + if (user_data->modifier_data == nullptr) { + return; + } + if (user_data->modifier_data->eval_log == nullptr) { + return; + } GeometrySet geometry = params.extract_input<GeometrySet>(0); + const NodeGeometryViewer *storage = static_cast<NodeGeometryViewer *>(bnode_.storage); - GField field; if (use_field_input_) { const void *value_or_field = params.try_get_input_data_ptr(1); BLI_assert(value_or_field != nullptr); const ValueOrFieldCPPType &value_or_field_type = static_cast<const ValueOrFieldCPPType &>( *inputs_[1].type); - field = value_or_field_type.as_field(value_or_field); + GField field = value_or_field_type.as_field(value_or_field); + const eAttrDomain domain = eAttrDomain(storage->domain); + const StringRefNull viewer_attribute_name = ".viewer"; + if (domain == ATTR_DOMAIN_INSTANCE) { + if (geometry.has_instances()) { + GeometryComponent &component = geometry.get_component_for_write( + GEO_COMPONENT_TYPE_INSTANCES); + bke::try_capture_field_on_geometry( + component, viewer_attribute_name, ATTR_DOMAIN_INSTANCE, field); + } + } + else { + geometry.modify_geometry_sets([&](GeometrySet &geometry) { + for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH, + GEO_COMPONENT_TYPE_POINT_CLOUD, + GEO_COMPONENT_TYPE_CURVE}) { + if (geometry.has(type)) { + GeometryComponent &component = geometry.get_component_for_write(type); + eAttrDomain used_domain = domain; + if (used_domain == ATTR_DOMAIN_AUTO) { + if (const std::optional<eAttrDomain> detected_domain = + bke::try_detect_field_domain(component, field)) { + used_domain = *detected_domain; + } + else { + used_domain = type == GEO_COMPONENT_TYPE_MESH ? ATTR_DOMAIN_CORNER : + ATTR_DOMAIN_POINT; + } + } + bke::try_capture_field_on_geometry( + component, viewer_attribute_name, used_domain, field); + } + } + }); + } } geo_eval_log::GeoTreeLogger &tree_logger = user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context); - tree_logger.log_viewer_node(bnode_, geometry, field); + tree_logger.log_viewer_node(bnode_, std::move(geometry)); } }; @@ -539,6 +603,8 @@ class LazyFunctionForViewerNode : public LazyFunction { class LazyFunctionForGroupNode : public LazyFunction { private: const bNode &group_node_; + bool has_many_nodes_ = false; + bool use_fallback_outputs_ = false; std::optional<GeometryNodesLazyFunctionLogger> lf_logger_; std::optional<GeometryNodesLazyFunctionSideEffectProvider> lf_side_effect_provider_; std::optional<lf::GraphExecutor> graph_executor_; @@ -557,6 +623,8 @@ class LazyFunctionForGroupNode : public LazyFunction { bNodeTree *group_btree = reinterpret_cast<bNodeTree *>(group_node_.id); BLI_assert(group_btree != nullptr); + has_many_nodes_ = lf_graph_info.num_inline_nodes_approximate > 1000; + Vector<const lf::OutputSocket *> graph_inputs; for (const lf::OutputSocket *socket : lf_graph_info.mapping.group_input_sockets) { if (socket != nullptr) { @@ -573,9 +641,12 @@ class LazyFunctionForGroupNode : public LazyFunction { } } } + else { + use_fallback_outputs_ = true; + } lf_logger_.emplace(lf_graph_info); - lf_side_effect_provider_.emplace(lf_graph_info); + lf_side_effect_provider_.emplace(); graph_executor_.emplace(lf_graph_info.graph, std::move(graph_inputs), std::move(graph_outputs), @@ -588,6 +659,17 @@ class LazyFunctionForGroupNode : public LazyFunction { GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data); BLI_assert(user_data != nullptr); + if (has_many_nodes_) { + /* If the called node group has many nodes, it's likely that executing it takes a while even + * if every individual node is very small. */ + lazy_threading::send_hint(); + } + if (use_fallback_outputs_) { + /* The node group itself does not have an output node, so use default values as outputs. + * The group should still be executed in case it has side effects. */ + params.set_default_remaining_outputs(); + } + /* The compute context changes when entering a node group. */ bke::NodeGroupComputeContext compute_context{user_data->compute_context, group_node_.name}; GeoNodesLFUserData group_user_data = *user_data; @@ -599,12 +681,12 @@ class LazyFunctionForGroupNode : public LazyFunction { graph_executor_->execute(params, group_context); } - void *init_storage(LinearAllocator<> &allocator) const + void *init_storage(LinearAllocator<> &allocator) const override { return graph_executor_->init_storage(allocator); } - void destruct_storage(void *storage) const + void destruct_storage(void *storage) const override { graph_executor_->destruct_storage(storage); } @@ -679,6 +761,7 @@ struct GeometryNodesLazyFunctionGraphBuilder { this->add_default_inputs(); lf_graph_->update_node_indices(); + lf_graph_info_->num_inline_nodes_approximate += lf_graph_->nodes().size(); } private: @@ -776,6 +859,11 @@ struct GeometryNodesLazyFunctionGraphBuilder { *bnode); if (fn_item.fn != nullptr) { this->handle_multi_function_node(*bnode, fn_item); + break; + } + if (node_type == &NodeTypeUndefined) { + this->handle_undefined_node(*bnode); + break; } /* Nodes that don't match any of the criteria above are just ignored. */ break; @@ -890,6 +978,8 @@ struct GeometryNodesLazyFunctionGraphBuilder { mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); } mapping_->group_node_map.add(&bnode, &lf_node); + lf_graph_info_->num_inline_nodes_approximate += + group_lf_graph_info->num_inline_nodes_approximate; } void handle_geometry_node(const bNode &bnode) @@ -969,6 +1059,21 @@ struct GeometryNodesLazyFunctionGraphBuilder { mapping_->viewer_node_map.add(&bnode, &lf_node); } + void handle_undefined_node(const bNode &bnode) + { + Vector<const bNodeSocket *> used_outputs; + auto lazy_function = std::make_unique<LazyFunctionForUndefinedNode>(bnode, used_outputs); + lf::FunctionNode &lf_node = lf_graph_->add_function(*lazy_function); + lf_graph_info_->functions.append(std::move(lazy_function)); + + for (const int i : used_outputs.index_range()) { + const bNodeSocket &bsocket = *used_outputs[i]; + lf::OutputSocket &lf_socket = lf_node.output(i); + output_socket_map_.add(&bsocket, &lf_socket); + mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); + } + } + void handle_links() { for (const auto item : output_socket_map_.items()) { @@ -978,6 +1083,10 @@ struct GeometryNodesLazyFunctionGraphBuilder { void insert_links_from_socket(const bNodeSocket &from_bsocket, lf::OutputSocket &from_lf_socket) { + if (nodeIsDanglingReroute(&btree_, &from_bsocket.owner_node())) { + return; + } + const Span<const bNodeLink *> links_from_bsocket = from_bsocket.directly_linked_links(); struct TypeWithLinks { @@ -991,10 +1100,10 @@ struct GeometryNodesLazyFunctionGraphBuilder { if (link->is_muted()) { continue; } - const bNodeSocket &to_bsocket = *link->tosock; - if (!to_bsocket.is_available()) { + if (!link->is_available()) { continue; } + const bNodeSocket &to_bsocket = *link->tosock; const CPPType *to_type = get_socket_cpp_type(to_bsocket); if (to_type == nullptr) { continue; @@ -1044,7 +1153,8 @@ struct GeometryNodesLazyFunctionGraphBuilder { if (multi_input_link == link) { break; } - if (!multi_input_link->is_muted()) { + if (!(multi_input_link->is_muted() || + nodeIsDanglingReroute(&btree_, multi_input_link->fromnode))) { link_index++; } } @@ -1135,79 +1245,41 @@ struct GeometryNodesLazyFunctionGraphBuilder { bool try_add_implicit_input(const bNodeSocket &input_bsocket, lf::InputSocket &input_lf_socket) { const bNode &bnode = input_bsocket.owner_node(); - const NodeDeclaration *node_declaration = bnode.declaration(); - if (node_declaration == nullptr) { + const SocketDeclaration *socket_decl = input_bsocket.runtime->declaration; + if (socket_decl == nullptr) { return false; } - const SocketDeclaration &socket_declaration = - *node_declaration->inputs()[input_bsocket.index()]; - if (socket_declaration.input_field_type() != InputSocketFieldType::Implicit) { + if (socket_decl->input_field_type() != InputSocketFieldType::Implicit) { return false; } - const CPPType &type = input_lf_socket.type(); - std::function<void(void *)> init_fn = this->get_implicit_input_init_function(bnode, - input_bsocket); - if (!init_fn) { + const ImplicitInputValueFn *implicit_input_fn = socket_decl->implicit_input_fn(); + if (implicit_input_fn == nullptr) { return false; } - + std::function<void(void *)> init_fn = [&bnode, implicit_input_fn](void *r_value) { + (*implicit_input_fn)(bnode, r_value); + }; + const CPPType &type = input_lf_socket.type(); auto lazy_function = std::make_unique<LazyFunctionForImplicitInput>(type, std::move(init_fn)); lf::Node &lf_node = lf_graph_->add_function(*lazy_function); lf_graph_info_->functions.append(std::move(lazy_function)); lf_graph_->add_link(lf_node.output(0), input_lf_socket); return true; } - - std::function<void(void *)> get_implicit_input_init_function(const bNode &bnode, - const bNodeSocket &bsocket) - { - const bNodeSocketType &socket_type = *bsocket.typeinfo; - if (socket_type.type == SOCK_VECTOR) { - if (bnode.type == GEO_NODE_SET_CURVE_HANDLES) { - StringRef side = ((NodeGeometrySetCurveHandlePositions *)bnode.storage)->mode == - GEO_NODE_CURVE_HANDLE_LEFT ? - "handle_left" : - "handle_right"; - return [side](void *r_value) { - new (r_value) ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>(side)); - }; - } - else if (bnode.type == GEO_NODE_EXTRUDE_MESH) { - return [](void *r_value) { - new (r_value) - ValueOrField<float3>(Field<float3>(std::make_shared<bke::NormalFieldInput>())); - }; - } - else { - return [](void *r_value) { - new (r_value) ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>("position")); - }; - } - } - else if (socket_type.type == SOCK_INT) { - if (ELEM(bnode.type, FN_NODE_RANDOM_VALUE, GEO_NODE_INSTANCE_ON_POINTS)) { - return [](void *r_value) { - new (r_value) - ValueOrField<int>(Field<int>(std::make_shared<bke::IDAttributeFieldInput>())); - }; - } - else { - return [](void *r_value) { - new (r_value) ValueOrField<int>(Field<int>(std::make_shared<fn::IndexFieldInput>())); - }; - } - } - return {}; - } }; const GeometryNodesLazyFunctionGraphInfo *ensure_geometry_nodes_lazy_function_graph( const bNodeTree &btree) { btree.ensure_topology_cache(); - if (btree.has_link_cycle()) { + if (btree.has_available_link_cycle()) { return nullptr; } + if (const ID *id_orig = DEG_get_original_id(const_cast<ID *>(&btree.id))) { + if (id_orig->tag & LIB_TAG_MISSING) { + return nullptr; + } + } std::unique_ptr<GeometryNodesLazyFunctionGraphInfo> &lf_graph_info_ptr = btree.runtime->geometry_nodes_lazy_function_graph_info; @@ -1300,12 +1372,6 @@ void GeometryNodesLazyFunctionLogger::dump_when_input_is_set_twice( user_data->compute_context->print_stack(std::cout, ss.str()); } -GeometryNodesLazyFunctionSideEffectProvider::GeometryNodesLazyFunctionSideEffectProvider( - const GeometryNodesLazyFunctionGraphInfo &lf_graph_info) - : lf_graph_info_(lf_graph_info) -{ -} - Vector<const lf::FunctionNode *> GeometryNodesLazyFunctionSideEffectProvider:: get_nodes_with_side_effects(const lf::Context &context) const { @@ -1324,4 +1390,53 @@ GeometryNodesLazyFunctionGraphInfo::~GeometryNodesLazyFunctionGraphInfo() } } +[[maybe_unused]] static void add_thread_id_debug_message( + const GeometryNodesLazyFunctionGraphInfo &lf_graph_info, + const lf::FunctionNode &node, + const lf::Context &context) +{ + static std::atomic<int> thread_id_source = 0; + static thread_local const int thread_id = thread_id_source.fetch_add(1); + static thread_local const std::string thread_id_str = "Thread: " + std::to_string(thread_id); + + GeoNodesLFUserData *user_data = dynamic_cast<GeoNodesLFUserData *>(context.user_data); + BLI_assert(user_data != nullptr); + if (user_data->modifier_data->eval_log == nullptr) { + return; + } + geo_eval_log::GeoTreeLogger &tree_logger = + user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context); + + /* Find corresponding node based on the socket mapping. */ + auto check_sockets = [&](const Span<const lf::Socket *> lf_sockets) { + for (const lf::Socket *lf_socket : lf_sockets) { + const Span<const bNodeSocket *> bsockets = + lf_graph_info.mapping.bsockets_by_lf_socket_map.lookup(lf_socket); + if (!bsockets.is_empty()) { + const bNodeSocket &bsocket = *bsockets[0]; + const bNode &bnode = bsocket.owner_node(); + tree_logger.debug_messages.append( + {tree_logger.allocator->copy_string(bnode.name), thread_id_str}); + return true; + } + } + return false; + }; + + if (check_sockets(node.inputs().cast<const lf::Socket *>())) { + return; + } + check_sockets(node.outputs().cast<const lf::Socket *>()); +} + +void GeometryNodesLazyFunctionLogger::log_before_node_execute(const lf::FunctionNode &node, + const lf::Params & /*params*/, + const lf::Context &context) const +{ + /* Enable this to see the threads that invoked a node. */ + if constexpr (false) { + add_thread_id_debug_message(lf_graph_info_, node, context); + } +} + } // namespace blender::nodes diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index 350b199cd60..0f122307328 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -6,12 +6,15 @@ #include "BKE_compute_contexts.hh" #include "BKE_curves.hh" #include "BKE_node_runtime.hh" +#include "BKE_viewer_path.h" #include "FN_field_cpp_type.hh" #include "DNA_modifier_types.h" #include "DNA_space_types.h" +#include "ED_viewer_path.hh" + namespace blender::nodes::geo_eval_log { using fn::FieldInput; @@ -35,8 +38,8 @@ FieldInfoLog::FieldInfoLog(const GField &field) : type(field.cpp_type()) std::sort( field_inputs.begin(), field_inputs.end(), [](const FieldInput &a, const FieldInput &b) { - const int index_a = (int)a.category(); - const int index_b = (int)b.category(); + const int index_a = int(a.category()); + const int index_b = int(b.category()); if (index_a == index_b) { return a.socket_inspection_name().size() < b.socket_inspection_name().size(); } @@ -66,7 +69,7 @@ GeometryInfoLog::GeometryInfoLog(const GeometrySet &geometry_set) true, [&](const bke::AttributeIDRef &attribute_id, const bke::AttributeMetaData &meta_data, - const GeometryComponent &UNUSED(component)) { + const GeometryComponent & /*component*/) { if (attribute_id.is_named() && names.add(attribute_id.name())) { this->attributes.append({attribute_id.name(), meta_data.domain, meta_data.data_type}); } @@ -98,7 +101,7 @@ GeometryInfoLog::GeometryInfoLog(const GeometrySet &geometry_set) case GEO_COMPONENT_TYPE_INSTANCES: { const InstancesComponent &instances_component = *(const InstancesComponent *)component; InstancesInfo &info = this->instances_info.emplace(); - info.instances_num = instances_component.instances_num(); + info.instances_num = instances_component.attribute_domain_size(ATTR_DOMAIN_INSTANCE); break; } case GEO_COMPONENT_TYPE_EDIT: { @@ -148,7 +151,9 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons auto store_logged_value = [&](destruct_ptr<ValueLog> value_log) { auto &socket_values = socket.in_out == SOCK_IN ? this->input_socket_values : this->output_socket_values; - socket_values.append({node.name, socket.identifier, std::move(value_log)}); + socket_values.append({this->allocator->copy_string(node.name), + this->allocator->copy_string(socket.identifier), + std::move(value_log)}); }; auto log_generic_value = [&](const CPPType &type, const void *value) { @@ -186,15 +191,12 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons } } -void GeoTreeLogger::log_viewer_node(const bNode &viewer_node, - const GeometrySet &geometry, - const GField &field) +void GeoTreeLogger::log_viewer_node(const bNode &viewer_node, GeometrySet geometry) { destruct_ptr<ViewerNodeLog> log = this->allocator->construct<ViewerNodeLog>(); - log->geometry = geometry; - log->field = field; + log->geometry = std::move(geometry); log->geometry.ensure_owns_direct_data(); - this->viewer_node_logs.append({viewer_node.name, std::move(log)}); + this->viewer_node_logs.append({this->allocator->copy_string(viewer_node.name), std::move(log)}); } void GeoTreeLog::ensure_node_warnings() @@ -315,11 +317,11 @@ void GeoTreeLog::ensure_used_named_attributes() return; } - auto add_attribute = [&](const StringRef node_name, - const StringRef attribute_name, + auto add_attribute = [&](const StringRefNull node_name, + const StringRefNull attribute_name, const NamedAttributeUsage &usage) { - this->nodes.lookup_or_add_as(node_name).used_named_attributes.lookup_or_add_as(attribute_name, - usage) |= usage; + this->nodes.lookup_or_add_default(node_name).used_named_attributes.lookup_or_add( + attribute_name, usage) |= usage; this->used_named_attributes.lookup_or_add_as(attribute_name, usage) |= usage; }; @@ -543,29 +545,17 @@ GeoTreeLog *GeoModifierLog::get_tree_log_for_node_editor(const SpaceNode &snode) return &modifier_log->get_tree_log(compute_context_builder.hash()); } -const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_spreadsheet( - const SpaceSpreadsheet &sspreadsheet) +const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_path(const ViewerPath &viewer_path) { - Vector<const SpreadsheetContext *> context_path = sspreadsheet.context_path; - if (context_path.size() < 3) { - return nullptr; - } - if (context_path[0]->type != SPREADSHEET_CONTEXT_OBJECT) { - return nullptr; - } - if (context_path[1]->type != SPREADSHEET_CONTEXT_MODIFIER) { - return nullptr; - } - const SpreadsheetContextObject *object_context = - reinterpret_cast<const SpreadsheetContextObject *>(context_path[0]); - const SpreadsheetContextModifier *modifier_context = - reinterpret_cast<const SpreadsheetContextModifier *>(context_path[1]); - if (object_context->object == nullptr) { + const std::optional<ed::viewer_path::ViewerPathForGeometryNodesViewer> parsed_path = + ed::viewer_path::parse_geometry_nodes_viewer(viewer_path); + if (!parsed_path.has_value()) { return nullptr; } + const Object *object = parsed_path->object; NodesModifierData *nmd = nullptr; - LISTBASE_FOREACH (ModifierData *, md, &object_context->object->modifiers) { - if (STREQ(md->name, modifier_context->modifier_name)) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { + if (md->name == parsed_path->modifier_name) { if (md->type == eModifierType_Nodes) { nmd = reinterpret_cast<NodesModifierData *>(md); } @@ -581,27 +571,16 @@ const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_spreadsheet( static_cast<nodes::geo_eval_log::GeoModifierLog *>(nmd->runtime_eval_log); ComputeContextBuilder compute_context_builder; - compute_context_builder.push<bke::ModifierComputeContext>(modifier_context->modifier_name); - for (const SpreadsheetContext *context : context_path.as_span().drop_front(2).drop_back(1)) { - if (context->type != SPREADSHEET_CONTEXT_NODE) { - return nullptr; - } - const SpreadsheetContextNode &node_context = *reinterpret_cast<const SpreadsheetContextNode *>( - context); - compute_context_builder.push<bke::NodeGroupComputeContext>(node_context.node_name); + compute_context_builder.push<bke::ModifierComputeContext>(parsed_path->modifier_name); + for (const StringRef group_node_name : parsed_path->group_node_names) { + compute_context_builder.push<bke::NodeGroupComputeContext>(group_node_name); } const ComputeContextHash context_hash = compute_context_builder.hash(); nodes::geo_eval_log::GeoTreeLog &tree_log = modifier_log->get_tree_log(context_hash); tree_log.ensure_viewer_node_logs(); - const SpreadsheetContext *last_context = context_path.last(); - if (last_context->type != SPREADSHEET_CONTEXT_NODE) { - return nullptr; - } - const SpreadsheetContextNode &last_node_context = - *reinterpret_cast<const SpreadsheetContextNode *>(last_context); const ViewerNodeLog *viewer_log = tree_log.viewer_node_logs.lookup_default( - last_node_context.node_name, nullptr); + parsed_path->viewer_node_name, nullptr); return viewer_log; } diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc index 6402ec3f3d6..975bf0c01ca 100644 --- a/source/blender/nodes/intern/node_common.cc +++ b/source/blender/nodes/intern/node_common.cc @@ -22,6 +22,7 @@ #include "BLT_translation.h" #include "BKE_node.h" +#include "BKE_node_runtime.hh" #include "BKE_node_tree_update.h" #include "RNA_types.h" @@ -63,7 +64,7 @@ bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identif return find_matching_socket(groupnode->outputs, identifier); } -void node_group_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen) +void node_group_label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen) { BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen); } @@ -82,10 +83,10 @@ bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **dis return false; } -bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_disabled_hint) +bool nodeGroupPoll(const bNodeTree *nodetree, + const bNodeTree *grouptree, + const char **r_disabled_hint) { - bool valid = true; - /* unspecified node group, generally allowed * (if anything, should be avoided on operator level) */ @@ -94,18 +95,20 @@ bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_dis } if (nodetree == grouptree) { - *r_disabled_hint = TIP_("Nesting a node group inside of itself is not allowed"); + if (r_disabled_hint) { + *r_disabled_hint = TIP_("Nesting a node group inside of itself is not allowed"); + } return false; } - LISTBASE_FOREACH (bNode *, node, &grouptree->nodes) { + LISTBASE_FOREACH (const bNode *, node, &grouptree->nodes) { if (node->typeinfo->poll_instance && - !node->typeinfo->poll_instance(node, nodetree, r_disabled_hint)) { - valid = false; - break; + !node->typeinfo->poll_instance( + const_cast<bNode *>(node), const_cast<bNodeTree *>(nodetree), r_disabled_hint)) { + return false; } } - return valid; + return true; } static void add_new_socket_from_interface(bNodeTree &node_tree, @@ -216,7 +219,7 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node) if (node->id == nullptr) { nodeRemoveAllSockets(ntree, node); } - else if ((ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING))) { + else if (ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING)) { /* Missing data-block, leave sockets unchanged so that when it comes back * the links remain valid. */ } @@ -233,7 +236,7 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node) /** \name Node Frame * \{ */ -static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node) +static void node_frame_init(bNodeTree * /*ntree*/, bNode *node) { NodeFrame *data = MEM_cnew<NodeFrame>("frame node storage"); node->storage = data; @@ -250,7 +253,7 @@ void register_node_type_frame() ntype->free_self = (void (*)(bNodeType *))MEM_freeN; node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT); - node_type_init(ntype, node_frame_init); + ntype->initfunc = node_frame_init; node_type_storage(ntype, "NodeFrame", node_free_standard_storage, node_copy_standard_storage); node_type_size(ntype, 150, 100, 0); ntype->flag |= NODE_BACKGROUND; @@ -280,7 +283,7 @@ void register_node_type_reroute() ntype->free_self = (void (*)(bNodeType *))MEM_freeN; node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT); - node_type_init(ntype, node_reroute_init); + ntype->initfunc = node_reroute_init; nodeRegisterType(ntype); } @@ -376,53 +379,29 @@ void ntree_update_reroute_nodes(bNodeTree *ntree) } } -static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node) +bool BKE_node_is_connected_to_output(const bNodeTree *ntree, const bNode *node) { - bNodeLink *link; - - /* avoid redundant checks, and infinite loops in case of cyclic node links */ - if (node->done) { - return false; - } - node->done = 1; - - /* main test, done before child loop so it catches output nodes themselves as well */ - if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) { - return true; + ntree->ensure_topology_cache(); + Stack<const bNode *> nodes_to_check; + for (const bNodeSocket *socket : node->output_sockets()) { + for (const bNodeLink *link : socket->directly_linked_links()) { + nodes_to_check.push(link->tonode); + } } - - /* test all connected nodes, first positive find is sufficient to return true */ - for (link = (bNodeLink *)ntree->links.first; link; link = link->next) { - if (link->fromnode == node) { - if (node_is_connected_to_output_recursive(ntree, link->tonode)) { - return true; + while (!nodes_to_check.is_empty()) { + const bNode *next_node = nodes_to_check.pop(); + for (const bNodeSocket *socket : next_node->output_sockets()) { + for (const bNodeLink *link : socket->directly_linked_links()) { + if (link->tonode->typeinfo->nclass == NODE_CLASS_OUTPUT && + link->tonode->flag & NODE_DO_OUTPUT) { + return true; + } + nodes_to_check.push(link->tonode); } } } - return false; -} - -bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node) -{ - bNode *tnode; - - /* clear flags */ - for (tnode = (bNode *)ntree->nodes.first; tnode; tnode = tnode->next) { - tnode->done = 0; - } - - return node_is_connected_to_output_recursive(ntree, node); -} - -void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree) -{ - bNode *node; - for (node = (bNode *)ntree->nodes.first; node; node = node->next) { - if (node->id == id) { - node->id = nullptr; - } - } + return false; } /** \} */ @@ -455,62 +434,53 @@ bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier) void node_group_input_update(bNodeTree *ntree, bNode *node) { bNodeSocket *extsock = (bNodeSocket *)node->outputs.last; - bNodeLink *link, *linknext, *exposelink; /* Adding a tree socket and verifying will remove the extension socket! * This list caches the existing links from the extension socket - * so they can be recreated after verification. - */ - ListBase tmplinks; + * so they can be recreated after verification. */ + Vector<bNodeLink> temp_links; /* find links from the extension socket and store them */ - BLI_listbase_clear(&tmplinks); - for (link = (bNodeLink *)ntree->links.first; link; link = linknext) { - linknext = link->next; + LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { if (nodeLinkIsHidden(link)) { continue; } if (link->fromsock == extsock) { - bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link"); - *tlink = *link; - BLI_addtail(&tmplinks, tlink); - + temp_links.append(*link); nodeRemLink(ntree, link); } } /* find valid link to expose */ - exposelink = nullptr; - for (link = (bNodeLink *)tmplinks.first; link; link = link->next) { + bNodeLink *exposelink = nullptr; + for (bNodeLink &link : temp_links) { /* XXX Multiple sockets can be connected to the extension socket at once, * in that case the arbitrary first link determines name and type. * This could be improved by choosing the "best" type among all links, * whatever that means. */ - if (!is_group_extension_socket(link->tonode, link->tosock)) { - exposelink = link; + if (!is_group_extension_socket(link.tonode, link.tosock)) { + exposelink = &link; break; } } if (exposelink) { - bNodeSocket *gsock, *newsock; - - gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock); + bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket( + ntree, exposelink->tonode, exposelink->tosock); node_group_input_update(ntree, node); - newsock = node_group_input_find_socket(node, gsock->identifier); + bNodeSocket *newsock = node_group_input_find_socket(node, gsock->identifier); /* redirect links from the extension socket */ - for (link = (bNodeLink *)tmplinks.first; link; link = link->next) { - bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link->tonode, link->tosock); + for (bNodeLink &link : temp_links) { + bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link.tonode, link.tosock); if (newlink->tosock->flag & SOCK_MULTI_INPUT) { - newlink->multi_input_socket_index = link->multi_input_socket_index; + newlink->multi_input_socket_index = link.multi_input_socket_index; } } } - BLI_freelistN(&tmplinks); group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT, true); } @@ -522,8 +492,8 @@ void register_node_type_group_input() node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE); node_type_size(ntype, 140, 80, 400); - node_type_init(ntype, node_group_input_init); - node_type_update(ntype, node_group_input_update); + ntype->initfunc = node_group_input_init; + ntype->updatefunc = node_group_input_update; nodeRegisterType(ntype); } @@ -547,60 +517,51 @@ bNodeSocket *node_group_output_find_socket(bNode *node, const char *identifier) void node_group_output_update(bNodeTree *ntree, bNode *node) { bNodeSocket *extsock = (bNodeSocket *)node->inputs.last; - bNodeLink *link, *linknext, *exposelink; /* Adding a tree socket and verifying will remove the extension socket! * This list caches the existing links to the extension socket - * so they can be recreated after verification. - */ - ListBase tmplinks; + * so they can be recreated after verification. */ + Vector<bNodeLink> temp_links; /* find links to the extension socket and store them */ - BLI_listbase_clear(&tmplinks); - for (link = (bNodeLink *)ntree->links.first; link; link = linknext) { - linknext = link->next; + LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { if (nodeLinkIsHidden(link)) { continue; } if (link->tosock == extsock) { - bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link"); - *tlink = *link; - BLI_addtail(&tmplinks, tlink); - + temp_links.append(*link); nodeRemLink(ntree, link); } } /* find valid link to expose */ - exposelink = nullptr; - for (link = (bNodeLink *)tmplinks.first; link; link = link->next) { + bNodeLink *exposelink = nullptr; + for (bNodeLink &link : temp_links) { /* XXX Multiple sockets can be connected to the extension socket at once, * in that case the arbitrary first link determines name and type. * This could be improved by choosing the "best" type among all links, * whatever that means. */ - if (!is_group_extension_socket(link->fromnode, link->fromsock)) { - exposelink = link; + if (!is_group_extension_socket(link.fromnode, link.fromsock)) { + exposelink = &link; break; } } if (exposelink) { - bNodeSocket *gsock, *newsock; - /* XXX what if connecting virtual to virtual socket?? */ - gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock); + bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket( + ntree, exposelink->fromnode, exposelink->fromsock); node_group_output_update(ntree, node); - newsock = node_group_output_find_socket(node, gsock->identifier); + bNodeSocket *newsock = node_group_output_find_socket(node, gsock->identifier); /* redirect links to the extension socket */ - for (link = (bNodeLink *)tmplinks.first; link; link = link->next) { - nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock); + for (bNodeLink &link : temp_links) { + nodeAddLink(ntree, link.fromnode, link.fromsock, node, newsock); } } - BLI_freelistN(&tmplinks); group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN, true); } @@ -612,8 +573,8 @@ void register_node_type_group_output() node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE); node_type_size(ntype, 140, 80, 400); - node_type_init(ntype, node_group_output_init); - node_type_update(ntype, node_group_output_update); + ntype->initfunc = node_group_output_init; + ntype->updatefunc = node_group_output_update; ntype->no_muting = true; diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index 2cd9c6000c0..f323d035668 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -2,6 +2,7 @@ #include "NOD_node_declaration.hh" +#include "BKE_geometry_fields.hh" #include "BKE_node.h" namespace blender::nodes { @@ -81,4 +82,30 @@ bool SocketDeclaration::matches_common_data(const bNodeSocket &socket) const return true; } +namespace implicit_field_inputs { + +void position(const bNode & /*node*/, void *r_value) +{ + new (r_value) fn::ValueOrField<float3>(bke::AttributeFieldInput::Create<float3>("position")); +} + +void normal(const bNode & /*node*/, void *r_value) +{ + new (r_value) + fn::ValueOrField<float3>(fn::Field<float3>(std::make_shared<bke::NormalFieldInput>())); +} + +void index(const bNode & /*node*/, void *r_value) +{ + new (r_value) fn::ValueOrField<int>(fn::Field<int>(std::make_shared<fn::IndexFieldInput>())); +} + +void id_or_index(const bNode & /*node*/, void *r_value) +{ + new (r_value) + fn::ValueOrField<int>(fn::Field<int>(std::make_shared<bke::IDAttributeFieldInput>())); +} + +} // namespace implicit_field_inputs + } // namespace blender::nodes diff --git a/source/blender/nodes/intern/node_exec.cc b/source/blender/nodes/intern/node_exec.cc index 724d6f1a1e1..af783ca391f 100644 --- a/source/blender/nodes/intern/node_exec.cc +++ b/source/blender/nodes/intern/node_exec.cc @@ -162,7 +162,7 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, /* XXX could let callbacks do this for specialized data */ exec = MEM_cnew<bNodeTreeExec>("node tree execution data"); - /* backpointer to node tree */ + /* Back-pointer to node tree. */ exec->nodetree = ntree; /* set stack indices */ diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h index dc07f52e23f..55bf409444e 100644 --- a/source/blender/nodes/intern/node_exec.h +++ b/source/blender/nodes/intern/node_exec.h @@ -27,7 +27,7 @@ struct bNodeTree; /* Node execution data */ typedef struct bNodeExec { - /** Backpointer to node. */ + /** Back-pointer to node. */ struct bNode *node; bNodeExecData data; @@ -37,7 +37,7 @@ typedef struct bNodeExec { /* Execution Data for each instance of node tree execution */ typedef struct bNodeTreeExec { - struct bNodeTree *nodetree; /* backpointer to node tree */ + struct bNodeTree *nodetree; /* Back-pointer to node tree. */ int totnodes; /* total node count */ struct bNodeExec *nodeexec; /* per-node execution data */ diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc index 1833774fe33..1de92fa8409 100644 --- a/source/blender/nodes/intern/node_geometry_exec.cc +++ b/source/blender/nodes/intern/node_geometry_exec.cc @@ -13,18 +13,22 @@ namespace blender::nodes { -void GeoNodeExecParams::error_message_add(const NodeWarningType type, std::string message) const +void GeoNodeExecParams::error_message_add(const NodeWarningType type, + const StringRef message) const { if (geo_eval_log::GeoTreeLogger *tree_logger = this->get_local_tree_logger()) { - tree_logger->node_warnings.append({node_.name, {type, std::move(message)}}); + tree_logger->node_warnings.append({tree_logger->allocator->copy_string(node_.name), + {type, tree_logger->allocator->copy_string(message)}}); } } -void GeoNodeExecParams::used_named_attribute(std::string attribute_name, +void GeoNodeExecParams::used_named_attribute(const StringRef attribute_name, const NamedAttributeUsage usage) { if (geo_eval_log::GeoTreeLogger *tree_logger = this->get_local_tree_logger()) { - tree_logger->used_named_attributes.append({node_.name, std::move(attribute_name), usage}); + tree_logger->used_named_attributes.append({tree_logger->allocator->copy_string(node_.name), + tree_logger->allocator->copy_string(attribute_name), + usage}); } } diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 098f766589d..f2f4519625a 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -59,14 +59,14 @@ struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, } case SOCK_INT: { bNodeSocketValueInt *dval = (bNodeSocketValueInt *)sock->default_value; - dval->value = (int)stemp->val1; - dval->min = (int)stemp->min; - dval->max = (int)stemp->max; + dval->value = int(stemp->val1); + dval->min = int(stemp->min); + dval->max = int(stemp->max); break; } case SOCK_BOOLEAN: { bNodeSocketValueBoolean *dval = (bNodeSocketValueBoolean *)sock->default_value; - dval->value = (int)stemp->val1; + dval->value = int(stemp->val1); break; } case SOCK_VECTOR: { @@ -531,11 +531,11 @@ void node_socket_skip_reroutes( } } -static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree), +static void standard_node_socket_interface_init_socket(bNodeTree * /*ntree*/, const bNodeSocket *interface_socket, - bNode *UNUSED(node), + bNode * /*node*/, bNodeSocket *sock, - const char *UNUSED(data_path)) + const char * /*data_path*/) { /* initialize the type value */ sock->type = sock->typeinfo->type; @@ -549,11 +549,11 @@ static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree), } /* copies settings that are not changed for each socket instance */ -static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree), +static void standard_node_socket_interface_verify_socket(bNodeTree * /*ntree*/, const bNodeSocket *interface_socket, - bNode *UNUSED(node), + bNode * /*node*/, bNodeSocket *sock, - const char *UNUSED(data_path)) + const char * /*data_path*/) { /* sanity check */ if (sock->type != interface_socket->typeinfo->type) { @@ -594,9 +594,9 @@ static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree } } -static void standard_node_socket_interface_from_socket(bNodeTree *UNUSED(ntree), +static void standard_node_socket_interface_from_socket(bNodeTree * /*ntree*/, bNodeSocket *stemp, - bNode *UNUSED(node), + bNode * /*node*/, bNodeSocket *sock) { /* initialize settings */ @@ -801,7 +801,7 @@ static bNodeSocketType *make_socket_type_geometry() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_GEOMETRY, PROP_NONE); socktype->base_cpp_type = &blender::CPPType::get<GeometrySet>(); - socktype->get_base_cpp_value = [](const bNodeSocket &UNUSED(socket), void *r_value) { + socktype->get_base_cpp_value = [](const bNodeSocket & /*socket*/, void *r_value) { new (r_value) GeometrySet(); }; socktype->geometry_nodes_cpp_type = socktype->base_cpp_type; diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc index b9fb75f30c7..a7d281bcf52 100644 --- a/source/blender/nodes/intern/node_socket_declarations.cc +++ b/source/blender/nodes/intern/node_socket_declarations.cc @@ -50,7 +50,7 @@ static bool sockets_can_connect(const SocketDeclaration &socket_decl, return true; } -static bool basic_types_can_connect(const SocketDeclaration &UNUSED(socket_decl), +static bool basic_types_can_connect(const SocketDeclaration & /*socket_decl*/, const bNodeSocket &other_socket) { return ELEM(other_socket.type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA); diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.cc index ddab455509d..17be20b4e4b 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.cc @@ -37,7 +37,7 @@ void node_free_curves(bNode *node) { - BKE_curvemapping_free(node->storage); + BKE_curvemapping_free(static_cast<CurveMapping *>(node->storage)); } void node_free_standard_storage(bNode *node) @@ -49,7 +49,7 @@ void node_free_standard_storage(bNode *node) void node_copy_curves(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node) { - dest_node->storage = BKE_curvemapping_copy(src_node->storage); + dest_node->storage = BKE_curvemapping_copy(static_cast<CurveMapping *>(src_node->storage)); } void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), @@ -63,7 +63,7 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context), bNode *node, bNodeInstanceKey UNUSED(key)) { - BKE_curvemapping_init(node->storage); + BKE_curvemapping_init(static_cast<CurveMapping *>(node->storage)); return NULL; /* unused return */ } @@ -87,9 +87,9 @@ void node_sock_label_clear(bNodeSocket *sock) void node_math_update(bNodeTree *ntree, bNode *node) { - bNodeSocket *sock1 = BLI_findlink(&node->inputs, 0); - bNodeSocket *sock2 = BLI_findlink(&node->inputs, 1); - bNodeSocket *sock3 = BLI_findlink(&node->inputs, 2); + bNodeSocket *sock1 = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 0)); + bNodeSocket *sock2 = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1)); + bNodeSocket *sock3 = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 2)); nodeSetSocketAvailability(ntree, sock2, !ELEM(node->custom1, @@ -305,7 +305,9 @@ static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNodeSocket *to_socket) { - bNodeSocket *first = to_socket->in_out == SOCK_IN ? node->inputs.first : node->outputs.first; + bNodeSocket *first = to_socket->in_out == SOCK_IN ? + static_cast<bNodeSocket *>(node->inputs.first) : + static_cast<bNodeSocket *>((node->outputs.first)); /* Wrap around the list end. */ bNodeSocket *socket_iter = to_socket->next ? to_socket->next : first; diff --git a/source/blender/nodes/intern/socket_search_link.cc b/source/blender/nodes/intern/socket_search_link.cc index 0bd838ff002..b440952b503 100644 --- a/source/blender/nodes/intern/socket_search_link.cc +++ b/source/blender/nodes/intern/socket_search_link.cc @@ -125,64 +125,23 @@ void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms, } } -static void search_link_ops_for_socket_templates(GatherLinkSearchOpParams ¶ms, - const bNodeSocketTemplate *templates, - const eNodeSocketInOut in_out) -{ - const bNodeType &node_type = params.node_type(); - const bNodeTreeType &node_tree_type = *params.node_tree().typeinfo; - - Set<StringRef> socket_names; - for (const bNodeSocketTemplate *socket_template = templates; socket_template->type != -1; - socket_template++) { - eNodeSocketDatatype from = (eNodeSocketDatatype)socket_template->type; - eNodeSocketDatatype to = (eNodeSocketDatatype)params.other_socket().type; - if (in_out == SOCK_IN) { - std::swap(from, to); - } - if (node_tree_type.validate_link && !node_tree_type.validate_link(from, to)) { - continue; - } - if (!socket_names.add(socket_template->name)) { - /* See comment in #search_link_ops_for_declarations. */ - continue; - } - - params.add_item( - socket_template->name, [socket_template, node_type, in_out](LinkSearchOpParams ¶ms) { - bNode &node = params.add_node(node_type); - bNodeSocket *new_node_socket = bke::node_find_enabled_socket( - node, in_out, socket_template->name); - if (new_node_socket != nullptr) { - /* Rely on the way #nodeAddLink switches in/out if necessary. */ - nodeAddLink(¶ms.node_tree, ¶ms.node, ¶ms.socket, &node, new_node_socket); - } - }); - } -} - void search_link_ops_for_basic_node(GatherLinkSearchOpParams ¶ms) { const bNodeType &node_type = params.node_type(); + if (!node_type.declare) { + return; + } - if (node_type.declare) { - if (node_type.declaration_is_dynamic) { - /* Dynamic declarations (whatever they end up being) aren't supported - * by this function, but still avoid a crash in release builds. */ - BLI_assert_unreachable(); - return; - } + if (node_type.declaration_is_dynamic) { + /* Dynamic declarations (whatever they end up being) aren't supported + * by this function, but still avoid a crash in release builds. */ + BLI_assert_unreachable(); + return; + } - const NodeDeclaration &declaration = *node_type.fixed_declaration; + const NodeDeclaration &declaration = *node_type.fixed_declaration; - search_link_ops_for_declarations(params, declaration.sockets(params.in_out())); - } - else if (node_type.inputs && params.in_out() == SOCK_IN) { - search_link_ops_for_socket_templates(params, node_type.inputs, SOCK_IN); - } - else if (node_type.outputs && params.in_out() == SOCK_OUT) { - search_link_ops_for_socket_templates(params, node_type.outputs, SOCK_OUT); - } + search_link_ops_for_declarations(params, declaration.sockets(params.in_out())); } } // namespace blender::nodes |