Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/node.cc
| Show First 20 Lines • Show All 393 Lines • ▼ Show 20 Lines | static ID *node_owner_get(Main *bmain, ID *id) | ||||
| for (int i = 0; lists[i] != nullptr; i++) { | for (int i = 0; lists[i] != nullptr; i++) { | ||||
| LISTBASE_FOREACH (ID *, id_iter, lists[i]) { | LISTBASE_FOREACH (ID *, id_iter, lists[i]) { | ||||
| if (ntreeFromID(id_iter) == ntree) { | if (ntreeFromID(id_iter) == ntree) { | ||||
| return id_iter; | return id_iter; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(!"Embedded node tree with no owner. Critical Main inconsistency."); | BLI_assert_msg(0, "Embedded node tree with no owner. Critical Main inconsistency."); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *sock) | static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *sock) | ||||
| { | { | ||||
| if (sock->default_value == nullptr) { | if (sock->default_value == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { | ||||
| } | } | ||||
| LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) { | LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) { | ||||
| BLO_write_struct(writer, bNodeLink, link); | BLO_write_struct(writer, bNodeLink, link); | ||||
| } | } | ||||
| if (node->storage) { | if (node->storage) { | ||||
| /* could be handlerized at some point, now only 1 exception still */ | /* could be handlerized at some point, now only 1 exception still */ | ||||
| if ((ELEM(ntree->type, NTREE_SHADER, NTREE_GEOMETRY)) && | if (ELEM(ntree->type, NTREE_SHADER, NTREE_GEOMETRY) && | ||||
| ELEM(node->type, SH_NODE_CURVE_VEC, SH_NODE_CURVE_RGB)) { | ELEM(node->type, SH_NODE_CURVE_VEC, SH_NODE_CURVE_RGB)) { | ||||
| BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage); | BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage); | ||||
| } | } | ||||
| else if ((ntree->type == NTREE_GEOMETRY) && (node->type == GEO_NODE_ATTRIBUTE_CURVE_MAP)) { | else if ((ntree->type == NTREE_GEOMETRY) && (node->type == GEO_NODE_ATTRIBUTE_CURVE_MAP)) { | ||||
| BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage); | BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage); | ||||
| NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage; | NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage; | ||||
| BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_vec); | BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_vec); | ||||
| BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_rgb); | BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_rgb); | ||||
| ▲ Show 20 Lines • Show All 689 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) { | ||||
| if (socktype && STREQ(sock->idname, socktype->idname)) { | if (socktype && STREQ(sock->idname, socktype->idname)) { | ||||
| node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype); | node_socket_set_typeinfo(ntree, sock, unregister ? nullptr : socktype); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| FOREACH_NODETREE_END; | FOREACH_NODETREE_END; | ||||
| } | } | ||||
| /* Try to initialize all typeinfo in a node tree. | /** | ||||
| * NB: In general undefined typeinfo is a perfectly valid case, | * Try to initialize all type-info in a node tree. | ||||
| * | |||||
| * \note In general undefined type-info is a perfectly valid case, | |||||
| * the type may just be registered later. | * the type may just be registered later. | ||||
| * In that case the update_typeinfo function will set typeinfo on registration | * In that case the update_typeinfo function will set type-info on registration | ||||
| * and do necessary updates. | * and do necessary updates. | ||||
| */ | */ | ||||
| void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree) | void ntreeSetTypes(const struct bContext *C, bNodeTree *ntree) | ||||
| { | { | ||||
| ntree->init |= NTREE_TYPE_INIT; | ntree->init |= NTREE_TYPE_INIT; | ||||
| ntree_set_typeinfo(ntree, ntreeTypeFind(ntree->idname)); | ntree_set_typeinfo(ntree, ntreeTypeFind(ntree->idname)); | ||||
| ▲ Show 20 Lines • Show All 1,270 Lines • ▼ Show 20 Lines | void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock) | ||||
| ntree->update |= NTREE_UPDATE_LINKS; | ntree->update |= NTREE_UPDATE_LINKS; | ||||
| } | } | ||||
| bool nodeLinkIsHidden(const bNodeLink *link) | bool nodeLinkIsHidden(const bNodeLink *link) | ||||
| { | { | ||||
| return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock); | return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock); | ||||
| } | } | ||||
| /* Adjust the indices of links connected to the given multi input socket after deleting the link at | |||||
| * `deleted_index`. This function also works if the link has not yet been deleted. */ | |||||
| static void adjust_multi_input_indices_after_removed_link(bNodeTree *ntree, | |||||
| bNodeSocket *sock, | |||||
| int deleted_index) | |||||
| { | |||||
| LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { | |||||
| /* We only need to adjust those with a greater index, because the others will have the same | |||||
| * index. */ | |||||
| if (link->tosock != sock || link->multi_input_socket_index <= deleted_index) { | |||||
| continue; | |||||
| } | |||||
| link->multi_input_socket_index -= 1; | |||||
| } | |||||
| } | |||||
| void nodeInternalRelink(bNodeTree *ntree, bNode *node) | void nodeInternalRelink(bNodeTree *ntree, bNode *node) | ||||
| { | { | ||||
| /* store link pointers in output sockets, for efficient lookup */ | /* store link pointers in output sockets, for efficient lookup */ | ||||
| LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) { | LISTBASE_FOREACH (bNodeLink *, link, &node->internal_links) { | ||||
| link->tosock->link = link; | link->tosock->link = link; | ||||
| } | } | ||||
| /* redirect downstream links */ | /* redirect downstream links */ | ||||
| Show All 17 Lines | if (link->fromnode == node) { | ||||
| if (fromlink->flag & NODE_LINK_MUTED) { | if (fromlink->flag & NODE_LINK_MUTED) { | ||||
| link->flag |= NODE_LINK_MUTED; | link->flag |= NODE_LINK_MUTED; | ||||
| } | } | ||||
| ntree->update |= NTREE_UPDATE_LINKS; | ntree->update |= NTREE_UPDATE_LINKS; | ||||
| } | } | ||||
| else { | else { | ||||
| if (link->tosock->flag & SOCK_MULTI_INPUT) { | |||||
| adjust_multi_input_indices_after_removed_link( | |||||
| ntree, link->tosock, link->multi_input_socket_index); | |||||
| } | |||||
| nodeRemLink(ntree, link); | nodeRemLink(ntree, link); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (link->tosock->flag & SOCK_MULTI_INPUT) { | |||||
| adjust_multi_input_indices_after_removed_link( | |||||
| ntree, link->tosock, link->multi_input_socket_index); | |||||
| }; | |||||
| nodeRemLink(ntree, link); | nodeRemLink(ntree, link); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* remove remaining upstream links */ | /* remove remaining upstream links */ | ||||
| LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { | LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { | ||||
| if (link->tonode == node) { | if (link->tonode == node) { | ||||
| ▲ Show 20 Lines • Show All 434 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { | ||||
| else if (link->tonode == node) { | else if (link->tonode == node) { | ||||
| lb = &node->inputs; | lb = &node->inputs; | ||||
| } | } | ||||
| else { | else { | ||||
| lb = nullptr; | lb = nullptr; | ||||
| } | } | ||||
| if (lb) { | if (lb) { | ||||
| /* Only bother adjusting if the socket is not on the node we're deleting. */ | |||||
| if (link->tonode != node && link->tosock->flag & SOCK_MULTI_INPUT) { | |||||
| adjust_multi_input_indices_after_removed_link( | |||||
| ntree, link->tosock, link->multi_input_socket_index); | |||||
| } | |||||
| LISTBASE_FOREACH (bNodeSocket *, sock, lb) { | LISTBASE_FOREACH (bNodeSocket *, sock, lb) { | ||||
| if (link->fromsock == sock || link->tosock == sock) { | if (link->fromsock == sock || link->tosock == sock) { | ||||
| nodeRemLink(ntree, link); | nodeRemLink(ntree, link); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | static void free_localized_node_groups(bNodeTree *ntree) | ||||
| * since it is a localized copy itself (no risk of accessing free'd | * since it is a localized copy itself (no risk of accessing free'd | ||||
| * data in main, see T37939). | * data in main, see T37939). | ||||
| */ | */ | ||||
| if (!(ntree->id.tag & LIB_TAG_LOCALIZED)) { | if (!(ntree->id.tag & LIB_TAG_LOCALIZED)) { | ||||
| return; | return; | ||||
| } | } | ||||
| LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { | LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { | ||||
| if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) { | if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) { | ||||
| bNodeTree *ngroup = (bNodeTree *)node->id; | bNodeTree *ngroup = (bNodeTree *)node->id; | ||||
| ntreeFreeTree(ngroup); | ntreeFreeTree(ngroup); | ||||
| MEM_freeN(ngroup); | MEM_freeN(ngroup); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Free (or release) any data used by this nodetree. Does not free the | /* Free (or release) any data used by this nodetree. Does not free the | ||||
| ▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | if (ntree) { | ||||
| * NOTE: previews are not copied here. | * NOTE: previews are not copied here. | ||||
| */ | */ | ||||
| bNodeTree *ltree = (bNodeTree *)BKE_id_copy_ex( | bNodeTree *ltree = (bNodeTree *)BKE_id_copy_ex( | ||||
| nullptr, &ntree->id, nullptr, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA)); | nullptr, &ntree->id, nullptr, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA)); | ||||
| ltree->id.tag |= LIB_TAG_LOCALIZED; | ltree->id.tag |= LIB_TAG_LOCALIZED; | ||||
| LISTBASE_FOREACH (bNode *, node, <ree->nodes) { | LISTBASE_FOREACH (bNode *, node, <ree->nodes) { | ||||
| if ((ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) && node->id) { | if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) { | ||||
| node->id = (ID *)ntreeLocalize((bNodeTree *)node->id); | node->id = (ID *)ntreeLocalize((bNodeTree *)node->id); | ||||
| } | } | ||||
| } | } | ||||
| /* ensures only a single output node is enabled */ | /* ensures only a single output node is enabled */ | ||||
| ntreeSetOutput(ntree); | ntreeSetOutput(ntree); | ||||
| bNode *node_src = (bNode *)ntree->nodes.first; | bNode *node_src = (bNode *)ntree->nodes.first; | ||||
| ▲ Show 20 Lines • Show All 1,752 Lines • ▼ Show 20 Lines | static void registerGeometryNodes() | ||||
| register_node_type_geo_attribute_randomize(); | register_node_type_geo_attribute_randomize(); | ||||
| register_node_type_geo_attribute_remove(); | register_node_type_geo_attribute_remove(); | ||||
| register_node_type_geo_attribute_separate_xyz(); | register_node_type_geo_attribute_separate_xyz(); | ||||
| register_node_type_geo_attribute_transfer(); | register_node_type_geo_attribute_transfer(); | ||||
| register_node_type_geo_attribute_vector_math(); | register_node_type_geo_attribute_vector_math(); | ||||
| register_node_type_geo_attribute_vector_rotate(); | register_node_type_geo_attribute_vector_rotate(); | ||||
| register_node_type_geo_boolean(); | register_node_type_geo_boolean(); | ||||
| register_node_type_geo_bounding_box(); | register_node_type_geo_bounding_box(); | ||||
| register_node_type_geo_collapse(); | |||||
| register_node_type_geo_collection_info(); | register_node_type_geo_collection_info(); | ||||
| register_node_type_geo_convex_hull(); | register_node_type_geo_convex_hull(); | ||||
| register_node_type_geo_curve_endpoints(); | register_node_type_geo_curve_endpoints(); | ||||
| register_node_type_geo_curve_length(); | register_node_type_geo_curve_length(); | ||||
| register_node_type_geo_curve_primitive_bezier_segment(); | register_node_type_geo_curve_primitive_bezier_segment(); | ||||
| register_node_type_geo_curve_primitive_circle(); | register_node_type_geo_curve_primitive_circle(); | ||||
| register_node_type_geo_curve_primitive_line(); | register_node_type_geo_curve_primitive_line(); | ||||
| register_node_type_geo_curve_primitive_quadratic_bezier(); | register_node_type_geo_curve_primitive_quadratic_bezier(); | ||||
| register_node_type_geo_curve_primitive_quadrilateral(); | register_node_type_geo_curve_primitive_quadrilateral(); | ||||
| register_node_type_geo_curve_primitive_spiral(); | register_node_type_geo_curve_primitive_spiral(); | ||||
| register_node_type_geo_curve_primitive_star(); | register_node_type_geo_curve_primitive_star(); | ||||
| register_node_type_geo_curve_resample(); | register_node_type_geo_curve_resample(); | ||||
| register_node_type_geo_curve_reverse(); | register_node_type_geo_curve_reverse(); | ||||
| register_node_type_geo_curve_set_handles(); | |||||
| register_node_type_geo_curve_subdivide(); | register_node_type_geo_curve_subdivide(); | ||||
| register_node_type_geo_curve_to_mesh(); | register_node_type_geo_curve_to_mesh(); | ||||
| register_node_type_geo_curve_to_points(); | register_node_type_geo_curve_to_points(); | ||||
| register_node_type_geo_curve_trim(); | |||||
| register_node_type_geo_delete_geometry(); | register_node_type_geo_delete_geometry(); | ||||
| register_node_type_geo_dissolve(); | |||||
| register_node_type_geo_edge_split(); | register_node_type_geo_edge_split(); | ||||
| register_node_type_geo_input_material(); | register_node_type_geo_input_material(); | ||||
| register_node_type_geo_is_viewport(); | register_node_type_geo_is_viewport(); | ||||
| register_node_type_geo_join_geometry(); | register_node_type_geo_join_geometry(); | ||||
| register_node_type_geo_material_assign(); | register_node_type_geo_material_assign(); | ||||
| register_node_type_geo_material_replace(); | register_node_type_geo_material_replace(); | ||||
| register_node_type_geo_mesh_primitive_circle(); | register_node_type_geo_mesh_primitive_circle(); | ||||
| register_node_type_geo_mesh_primitive_cone(); | register_node_type_geo_mesh_primitive_cone(); | ||||
| Show All 16 Lines | static void registerGeometryNodes() | ||||
| register_node_type_geo_raycast(); | register_node_type_geo_raycast(); | ||||
| register_node_type_geo_sample_texture(); | register_node_type_geo_sample_texture(); | ||||
| register_node_type_geo_select_by_material(); | register_node_type_geo_select_by_material(); | ||||
| register_node_type_geo_separate_components(); | register_node_type_geo_separate_components(); | ||||
| register_node_type_geo_subdivision_surface(); | register_node_type_geo_subdivision_surface(); | ||||
| register_node_type_geo_switch(); | register_node_type_geo_switch(); | ||||
| register_node_type_geo_transform(); | register_node_type_geo_transform(); | ||||
| register_node_type_geo_triangulate(); | register_node_type_geo_triangulate(); | ||||
| register_node_type_geo_unsubdivide(); | |||||
| register_node_type_geo_viewer(); | register_node_type_geo_viewer(); | ||||
| register_node_type_geo_volume_to_mesh(); | register_node_type_geo_volume_to_mesh(); | ||||
| } | } | ||||
| static void registerFunctionNodes() | static void registerFunctionNodes() | ||||
| { | { | ||||
| register_node_type_fn_boolean_math(); | register_node_type_fn_boolean_math(); | ||||
| register_node_type_fn_float_compare(); | register_node_type_fn_float_compare(); | ||||
| ▲ Show 20 Lines • Show All 157 Lines • Show Last 20 Lines | |||||