diff options
Diffstat (limited to 'source/blender/nodes/intern')
-rw-r--r-- | source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 58 | ||||
-rw-r--r-- | source/blender/nodes/intern/geometry_nodes_log.cc | 5 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_common.cc | 150 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_socket.cc | 7 |
4 files changed, 80 insertions, 140 deletions
diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 96c369f2f6b..d9e82c6b4ee 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_cpp_types.hh" #include "BLI_lazy_threading.hh" #include "BLI_map.hh" @@ -53,14 +54,11 @@ static const CPPType *get_socket_cpp_type(const bNodeSocket &socket) static const CPPType *get_vector_type(const CPPType &type) { - /* This could be generalized in the future. For now we only support a small set of vectors. */ - if (type.is<GeometrySet>()) { - return &CPPType::get<Vector<GeometrySet>>(); - } - if (type.is<ValueOrField<std::string>>()) { - return &CPPType::get<Vector<ValueOrField<std::string>>>(); + const VectorCPPType *vector_type = VectorCPPType::get_from_value(type); + if (vector_type == nullptr) { + return nullptr; } - return nullptr; + return &vector_type->self; } /** @@ -296,19 +294,17 @@ static void execute_multi_function_on_value_or_field( for (const int i : input_types.index_range()) { const ValueOrFieldCPPType &type = *input_types[i]; - const CPPType &base_type = type.base_type(); const void *value_or_field = input_values[i]; const void *value = type.get_value_ptr(value_or_field); - params.add_readonly_single_input(GVArray::ForSingleRef(base_type, 1, value)); + params.add_readonly_single_input(GVArray::ForSingleRef(type.value, 1, value)); } for (const int i : output_types.index_range()) { const ValueOrFieldCPPType &type = *output_types[i]; - const CPPType &base_type = type.base_type(); void *value_or_field = output_values[i]; - type.default_construct(value_or_field); + type.self.default_construct(value_or_field); void *value = type.get_value_ptr(value_or_field); - base_type.destruct(value); - params.add_uninitialized_single_output(GMutableSpan{base_type, value, 1}); + type.value.destruct(value); + params.add_uninitialized_single_output(GMutableSpan{type.value, value, 1}); } fn.call(IndexRange(1), params, context); } @@ -380,16 +376,14 @@ class LazyFunctionForMutedNode : public LazyFunction { } /* Perform a type conversion and then format the value. */ const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions(); - const auto *from_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&input_type); - const auto *to_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&output_type); - if (from_field_type != nullptr && to_field_type != nullptr) { - const CPPType &from_base_type = from_field_type->base_type(); - const CPPType &to_base_type = to_field_type->base_type(); - if (conversions.is_convertible(from_base_type, to_base_type)) { + const auto *from_type = ValueOrFieldCPPType::get_from_self(input_type); + const auto *to_type = ValueOrFieldCPPType::get_from_self(output_type); + if (from_type != nullptr && to_type != nullptr) { + if (conversions.is_convertible(from_type->value, to_type->value)) { const MultiFunction &multi_fn = *conversions.get_conversion_multi_function( - MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type)); + MFDataType::ForSingle(from_type->value), MFDataType::ForSingle(to_type->value)); execute_multi_function_on_value_or_field( - multi_fn, {}, {from_field_type}, {to_field_type}, {input_value}, {output_value}); + multi_fn, {}, {from_type}, {to_type}, {input_value}, {output_value}); } params.output_set(output_i); continue; @@ -420,8 +414,8 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction { : fn_(fn), from_type_(from), to_type_(to), target_sockets_(std::move(target_sockets)) { debug_name_ = "Convert"; - inputs_.append({"From", from}); - outputs_.append({"To", to}); + inputs_.append({"From", from.self}); + outputs_.append({"To", to.self}); } void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override @@ -458,10 +452,10 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction { debug_name_ = node.name; lazy_function_interface_from_node(node, r_used_inputs, r_used_outputs, inputs_, outputs_); for (const lf::Input &fn_input : inputs_) { - input_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_input.type)); + input_types_.append(ValueOrFieldCPPType::get_from_self(*fn_input.type)); } for (const lf::Output &fn_output : outputs_) { - output_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_output.type)); + output_types_.append(ValueOrFieldCPPType::get_from_self(*fn_output.type)); } } @@ -552,8 +546,7 @@ class LazyFunctionForViewerNode : public LazyFunction { 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); + const auto &value_or_field_type = *ValueOrFieldCPPType::get_from_self(*inputs_[1].type); GField field = value_or_field_type.as_field(value_or_field); const eAttrDomain domain = eAttrDomain(storage->domain); const StringRefNull viewer_attribute_name = ".viewer"; @@ -1193,14 +1186,13 @@ struct GeometryNodesLazyFunctionGraphBuilder { if (from_type == to_type) { return &from_socket; } - const auto *from_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&from_type); - const auto *to_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&to_type); + const auto *from_field_type = ValueOrFieldCPPType::get_from_self(from_type); + const auto *to_field_type = ValueOrFieldCPPType::get_from_self(to_type); if (from_field_type != nullptr && to_field_type != nullptr) { - const CPPType &from_base_type = from_field_type->base_type(); - const CPPType &to_base_type = to_field_type->base_type(); - if (conversions_->is_convertible(from_base_type, to_base_type)) { + if (conversions_->is_convertible(from_field_type->value, to_field_type->value)) { const MultiFunction &multi_fn = *conversions_->get_conversion_multi_function( - MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type)); + MFDataType::ForSingle(from_field_type->value), + MFDataType::ForSingle(to_field_type->value)); auto fn = std::make_unique<LazyFunctionForMultiFunctionConversion>( multi_fn, *from_field_type, *to_field_type, std::move(target_sockets)); lf::Node &conversion_node = lf_graph_->add_function(*fn); diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index 0f122307328..640296ead66 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -166,10 +166,9 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons const GeometrySet &geometry = *value.get<GeometrySet>(); store_logged_value(this->allocator->construct<GeometryInfoLog>(geometry)); } - else if (const auto *value_or_field_type = dynamic_cast<const fn::ValueOrFieldCPPType *>( - &type)) { + else if (const auto *value_or_field_type = fn::ValueOrFieldCPPType::get_from_self(type)) { const void *value_or_field = value.get(); - const CPPType &base_type = value_or_field_type->base_type(); + const CPPType &base_type = value_or_field_type->value; if (value_or_field_type->is_field(value_or_field)) { const GField *field = value_or_field_type->get_field_ptr(value_or_field); if (field->node().depends_on_input()) { diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc index d7cc0b6065a..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" @@ -86,8 +87,6 @@ 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) */ @@ -106,11 +105,10 @@ bool nodeGroupPoll(const bNodeTree *nodetree, if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance( const_cast<bNode *>(node), const_cast<bNodeTree *>(nodetree), r_disabled_hint)) { - valid = false; - break; + return false; } } - return valid; + return true; } static void add_new_socket_from_interface(bNodeTree &node_tree, @@ -255,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; @@ -285,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); } @@ -381,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; } /** \} */ @@ -460,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); } @@ -527,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); } @@ -552,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); } @@ -617,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_socket.cc b/source/blender/nodes/intern/node_socket.cc index f2f4519625a..6d02ed7d553 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -10,7 +10,6 @@ #include "DNA_node_types.h" #include "BLI_color.hh" -#include "BLI_cpp_type_make.hh" #include "BLI_listbase.h" #include "BLI_math_vec_types.hh" #include "BLI_string.h" @@ -779,12 +778,6 @@ static bNodeSocketType *make_socket_type_string() return socktype; } -BLI_CPP_TYPE_MAKE(Object, Object *, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(Collection, Collection *, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(Texture, Tex *, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(Image, Image *, CPPTypeFlags::BasicType) -BLI_CPP_TYPE_MAKE(Material, Material *, CPPTypeFlags::BasicType) - static bNodeSocketType *make_socket_type_object() { bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE); |