Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/intern/node_socket.cc
| Show All 13 Lines | |||||
| #include "BLI_math_vector_types.hh" | #include "BLI_math_vector_types.hh" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_geometry_set.hh" | #include "BKE_geometry_set.hh" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_node_runtime.hh" | #include "BKE_node_runtime.hh" | ||||
| #include "BKE_node_tree_update.h" | |||||
| #include "DNA_collection_types.h" | #include "DNA_collection_types.h" | ||||
| #include "DNA_material_types.h" | #include "DNA_material_types.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_types.h" | #include "RNA_types.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| ▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | else { | ||||
| while (stemp->type != -1) { | while (stemp->type != -1) { | ||||
| BLI_addtail(socklist, stemp->sock); | BLI_addtail(socklist, stemp->sock); | ||||
| stemp++; | stemp++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| namespace blender::nodes { | |||||
| static void refresh_socket_list(bNodeTree &ntree, | static void refresh_socket_list(bNodeTree &ntree, | ||||
| bNode &node, | bNode &node, | ||||
| ListBase &sockets, | ListBase &sockets, | ||||
| Span<SocketDeclarationPtr> socket_decls, | Span<SocketDeclarationPtr> socket_decls, | ||||
| const bool do_id_user) | const bool do_id_user) | ||||
| { | { | ||||
| Vector<bNodeSocket *> old_sockets = sockets; | Vector<bNodeSocket *> old_sockets = sockets; | ||||
| VectorSet<bNodeSocket *> new_sockets; | VectorSet<bNodeSocket *> new_sockets; | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | else { | ||||
| else if (internal_link.tosock == old_socket_with_same_identifier) { | else if (internal_link.tosock == old_socket_with_same_identifier) { | ||||
| internal_link.tosock = new_socket; | internal_link.tosock = new_socket; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| new_sockets.add_new(new_socket); | new_sockets.add_new(new_socket); | ||||
| BKE_ntree_update_tag_socket_new(&ntree, new_socket); | |||||
| } | } | ||||
| LISTBASE_FOREACH_MUTABLE (bNodeSocket *, old_socket, &sockets) { | LISTBASE_FOREACH_MUTABLE (bNodeSocket *, old_socket, &sockets) { | ||||
| if (!new_sockets.contains(old_socket)) { | if (!new_sockets.contains(old_socket)) { | ||||
| nodeRemoveSocketEx(&ntree, &node, old_socket, do_id_user); | nodeRemoveSocketEx(&ntree, &node, old_socket, do_id_user); | ||||
| } | } | ||||
| } | } | ||||
| BLI_listbase_clear(&sockets); | BLI_listbase_clear(&sockets); | ||||
| for (bNodeSocket *socket : new_sockets) { | for (bNodeSocket *socket : new_sockets) { | ||||
| BLI_addtail(&sockets, socket); | BLI_addtail(&sockets, socket); | ||||
| } | } | ||||
| } | } | ||||
| static void refresh_node(bNodeTree &ntree, | static void refresh_node(bNodeTree &ntree, | ||||
| bNode &node, | bNode &node, | ||||
| blender::nodes::NodeDeclaration &node_decl, | blender::nodes::NodeDeclaration &node_decl, | ||||
| bool do_id_user) | bool do_id_user) | ||||
| { | { | ||||
| if (node_decl.skip_updating_sockets) { | |||||
| return; | |||||
| } | |||||
| if (!node_decl.matches(node)) { | |||||
| refresh_socket_list(ntree, node, node.inputs, node_decl.inputs, do_id_user); | refresh_socket_list(ntree, node, node.inputs, node_decl.inputs, do_id_user); | ||||
| refresh_socket_list(ntree, node, node.outputs, node_decl.outputs, do_id_user); | refresh_socket_list(ntree, node, node.outputs, node_decl.outputs, do_id_user); | ||||
| } | } | ||||
| nodeSocketDeclarationsUpdate(&node); | |||||
| } | |||||
| void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node) | |||||
| { | |||||
| if (node.typeinfo->declare_dynamic) { | |||||
| if (!node.runtime->declaration) { | |||||
| node.runtime->declaration = new NodeDeclaration(); | |||||
| } | |||||
| build_node_declaration_dynamic(ntree, node, *node.runtime->declaration); | |||||
| } | |||||
| refresh_node(ntree, node, *node.runtime->declaration, true); | |||||
| } | |||||
| } // namespace blender::nodes | |||||
| void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user) | void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user) | ||||
| { | { | ||||
| bNodeType *ntype = node->typeinfo; | bNodeType *ntype = node->typeinfo; | ||||
| if (ntype == nullptr) { | if (ntype == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (ntype->declare != nullptr) { | if (ntype->declare != nullptr) { | ||||
| nodeDeclarationEnsureOnOutdatedNode(ntree, node); | nodeDeclarationEnsureOnOutdatedNode(ntree, node); | ||||
| if (!node->runtime->declaration->matches(*node)) { | |||||
| refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user); | refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user); | ||||
| } | |||||
| nodeSocketDeclarationsUpdate(node); | |||||
| return; | return; | ||||
| } | } | ||||
| /* Don't try to match socket lists when there are no templates. | /* Don't try to match socket lists when there are no templates. | ||||
| * This prevents dynamically generated sockets to be removed, like for | * This prevents dynamically generated sockets to be removed, like for | ||||
| * group, image or render layer nodes. We have an explicit check for the | * group, image or render layer nodes. We have an explicit check for the | ||||
| * render layer node since it still has fixed sockets too. | * render layer node since it still has fixed sockets too. | ||||
| */ | */ | ||||
| if (ntype) { | if (ntype) { | ||||
| ▲ Show 20 Lines • Show All 218 Lines • ▼ Show 20 Lines | static void standard_node_socket_interface_init_socket(bNodeTree * /*ntree*/, | ||||
| /* XXX socket interface 'type' value is not used really, | /* XXX socket interface 'type' value is not used really, | ||||
| * but has to match or the copy function will bail out | * but has to match or the copy function will bail out | ||||
| */ | */ | ||||
| const_cast<bNodeSocket *>(interface_socket)->type = interface_socket->typeinfo->type; | const_cast<bNodeSocket *>(interface_socket)->type = interface_socket->typeinfo->type; | ||||
| /* copy default_value settings */ | /* copy default_value settings */ | ||||
| node_socket_copy_default_value(sock, interface_socket); | node_socket_copy_default_value(sock, interface_socket); | ||||
| } | } | ||||
| /* copies settings that are not changed for each socket instance */ | |||||
| static void standard_node_socket_interface_verify_socket(bNodeTree * /*ntree*/, | |||||
| const bNodeSocket *interface_socket, | |||||
| bNode * /*node*/, | |||||
| bNodeSocket *sock, | |||||
| const char * /*data_path*/) | |||||
| { | |||||
| /* sanity check */ | |||||
| if (sock->type != interface_socket->typeinfo->type) { | |||||
| return; | |||||
| } | |||||
| /* make sure both exist */ | |||||
| if (!interface_socket->default_value) { | |||||
| return; | |||||
| } | |||||
| node_socket_init_default_value(sock); | |||||
| switch (interface_socket->typeinfo->type) { | |||||
| case SOCK_FLOAT: { | |||||
| bNodeSocketValueFloat *toval = (bNodeSocketValueFloat *)sock->default_value; | |||||
| const bNodeSocketValueFloat *fromval = (const bNodeSocketValueFloat *) | |||||
| interface_socket->default_value; | |||||
| toval->min = fromval->min; | |||||
| toval->max = fromval->max; | |||||
| break; | |||||
| } | |||||
| case SOCK_INT: { | |||||
| bNodeSocketValueInt *toval = (bNodeSocketValueInt *)sock->default_value; | |||||
| const bNodeSocketValueInt *fromval = (const bNodeSocketValueInt *) | |||||
| interface_socket->default_value; | |||||
| toval->min = fromval->min; | |||||
| toval->max = fromval->max; | |||||
| break; | |||||
| } | |||||
| case SOCK_VECTOR: { | |||||
| bNodeSocketValueVector *toval = (bNodeSocketValueVector *)sock->default_value; | |||||
| const bNodeSocketValueVector *fromval = (const bNodeSocketValueVector *) | |||||
| interface_socket->default_value; | |||||
| toval->min = fromval->min; | |||||
| toval->max = fromval->max; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| static void standard_node_socket_interface_from_socket(bNodeTree * /*ntree*/, | static void standard_node_socket_interface_from_socket(bNodeTree * /*ntree*/, | ||||
| bNodeSocket *stemp, | bNodeSocket *stemp, | ||||
| const bNode * /*node*/, | const bNode * /*node*/, | ||||
| const bNodeSocket *sock) | const bNodeSocket *sock) | ||||
| { | { | ||||
| /* initialize settings */ | /* initialize settings */ | ||||
| stemp->type = stemp->typeinfo->type; | stemp->type = stemp->typeinfo->type; | ||||
| node_socket_copy_default_value(stemp, sock); | node_socket_copy_default_value(stemp, sock); | ||||
| Show All 31 Lines | static bNodeSocketType *make_standard_socket_type(int type, int subtype) | ||||
| stype->type = type; | stype->type = type; | ||||
| stype->subtype = subtype; | stype->subtype = subtype; | ||||
| /* XXX bad-level call! needed for setting draw callbacks */ | /* XXX bad-level call! needed for setting draw callbacks */ | ||||
| ED_init_standard_node_socket_type(stype); | ED_init_standard_node_socket_type(stype); | ||||
| stype->interface_init_socket = standard_node_socket_interface_init_socket; | stype->interface_init_socket = standard_node_socket_interface_init_socket; | ||||
| stype->interface_from_socket = standard_node_socket_interface_from_socket; | stype->interface_from_socket = standard_node_socket_interface_from_socket; | ||||
| stype->interface_verify_socket = standard_node_socket_interface_verify_socket; | |||||
| stype->use_link_limits_of_type = true; | stype->use_link_limits_of_type = true; | ||||
| stype->input_link_limit = 1; | stype->input_link_limit = 1; | ||||
| stype->output_link_limit = 0xFFF; | stype->output_link_limit = 0xFFF; | ||||
| return stype; | return stype; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 249 Lines • Show Last 20 Lines | |||||