/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ /** \file * \ingroup RNA */ #include "DNA_node_types.h" #include "RNA_define.hh" #include "RNA_enum_types.hh" #include "RNA_types.hh" #include "rna_internal.hh" #include "WM_api.hh" const EnumPropertyItem rna_enum_node_socket_type_items[] = { {SOCK_CUSTOM, "CUSTOM", 0, "Custom", ""}, {SOCK_FLOAT, "VALUE", ICON_NODE_SOCKET_FLOAT, "Value", ""}, {SOCK_INT, "INT", ICON_NODE_SOCKET_INT, "Integer", ""}, {SOCK_BOOLEAN, "BOOLEAN", ICON_NODE_SOCKET_BOOLEAN, "Boolean", ""}, {SOCK_VECTOR, "VECTOR", ICON_NODE_SOCKET_VECTOR, "Vector", ""}, {SOCK_ROTATION, "ROTATION", ICON_NODE_SOCKET_ROTATION, "Rotation", ""}, {SOCK_MATRIX, "MATRIX", ICON_NODE_SOCKET_MATRIX, "Matrix", ""}, {SOCK_STRING, "STRING", ICON_NODE_SOCKET_STRING, "String", ""}, {SOCK_RGBA, "RGBA", ICON_NODE_SOCKET_RGBA, "RGBA", ""}, {SOCK_SHADER, "SHADER", ICON_NODE_SOCKET_SHADER, "Shader", ""}, {SOCK_OBJECT, "OBJECT", ICON_NODE_SOCKET_OBJECT, "Object", ""}, {SOCK_IMAGE, "IMAGE", ICON_NODE_SOCKET_IMAGE, "Image", ""}, {SOCK_GEOMETRY, "GEOMETRY", ICON_NODE_SOCKET_GEOMETRY, "Geometry", ""}, {SOCK_COLLECTION, "COLLECTION", ICON_NODE_SOCKET_COLLECTION, "Collection", ""}, {SOCK_TEXTURE, "TEXTURE", ICON_NODE_SOCKET_TEXTURE, "Texture", ""}, {SOCK_MATERIAL, "MATERIAL", ICON_NODE_SOCKET_MATERIAL, "Material", ""}, {SOCK_MENU, "MENU", ICON_NODE_SOCKET_MENU, "Menu", ""}, {SOCK_BUNDLE, "BUNDLE", ICON_NODE_SOCKET_BUNDLE, "Bundle", ""}, {SOCK_CLOSURE, "CLOSURE", ICON_NODE_SOCKET_CLOSURE, "Closure", ""}, {0, nullptr, 0, nullptr, nullptr}, }; #ifdef RNA_RUNTIME # include # include "DNA_material_types.h" # include "BLI_math_vector.h" # include "BLI_string_ref.hh" # include "BKE_main_invariants.hh" # include "BKE_node.hh" # include "BKE_node_enum.hh" # include "BKE_node_runtime.hh" # include "BKE_node_tree_update.hh" # include "DEG_depsgraph_build.hh" # include "NOD_socket_declarations.hh" # include "ED_node.hh" extern FunctionRNA rna_NodeSocket_draw_func; extern FunctionRNA rna_NodeSocket_draw_color_func; extern FunctionRNA rna_NodeSocket_draw_color_simple_func; /* ******** Node Socket ******** */ static void rna_NodeSocket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr, const blender::StringRefNull text) { bNodeSocket *sock = static_cast(ptr->data); ParameterList list; FunctionRNA *func; func = &rna_NodeSocket_draw_func; /* RNA_struct_find_function(&ptr, "draw"); */ RNA_parameter_list_create(&list, ptr, func); RNA_parameter_set_lookup(&list, "context", &C); RNA_parameter_set_lookup(&list, "layout", &layout); RNA_parameter_set_lookup(&list, "node", node_ptr); RNA_parameter_set_lookup(&list, "text", &text); sock->typeinfo->ext_socket.call(C, ptr, func, &list); RNA_parameter_list_free(&list); } static void rna_NodeSocket_draw_color(bContext *C, PointerRNA *ptr, PointerRNA *node_ptr, float *r_color) { bNodeSocket *sock = static_cast(ptr->data); ParameterList list; FunctionRNA *func; void *ret; func = &rna_NodeSocket_draw_color_func; /* RNA_struct_find_function(&ptr, "draw_color"); */ RNA_parameter_list_create(&list, ptr, func); RNA_parameter_set_lookup(&list, "context", &C); RNA_parameter_set_lookup(&list, "node", node_ptr); sock->typeinfo->ext_socket.call(C, ptr, func, &list); RNA_parameter_get_lookup(&list, "color", &ret); copy_v4_v4(r_color, static_cast(ret)); RNA_parameter_list_free(&list); } static void rna_NodeSocket_draw_color_simple(const blender::bke::bNodeSocketType *socket_type, float *r_color) { ParameterList list; FunctionRNA *func; void *ret; func = &rna_NodeSocket_draw_color_simple_func; /* RNA_struct_find_function(&ptr, * "draw_color_simple"); */ PointerRNA ptr = RNA_pointer_create_discrete(nullptr, socket_type->ext_socket.srna, nullptr); RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "type", socket_type); socket_type->ext_socket.call(nullptr, &ptr, func, &list); RNA_parameter_get_lookup(&list, "color", &ret); copy_v4_v4(r_color, static_cast(ret)); RNA_parameter_list_free(&list); } static bool rna_NodeSocket_unregister(Main *bmain, StructRNA *type) { blender::bke::bNodeSocketType *st = static_cast( RNA_struct_blender_type_get(type)); if (!st) { return false; } RNA_struct_free_extension(type, &st->ext_socket); RNA_struct_free(&BLENDER_RNA, type); blender::bke::node_unregister_socket_type(*st); /* update while blender is running */ WM_main_add_notifier(NC_NODE | NA_EDITED, nullptr); BKE_main_ensure_invariants(*bmain); return true; } static StructRNA *rna_NodeSocket_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { blender::bke::bNodeSocketType *st; bNodeSocket dummy_sock; bool have_function[3]; /* setup dummy socket & socket type to store static properties in */ blender::bke::bNodeSocketType dummy_st = {}; dummy_st.type = SOCK_CUSTOM; memset(&dummy_sock, 0, sizeof(bNodeSocket)); dummy_sock.typeinfo = &dummy_st; PointerRNA dummy_sock_ptr = RNA_pointer_create_discrete(nullptr, &RNA_NodeSocket, &dummy_sock); /* validate the python class */ if (validate(&dummy_sock_ptr, data, have_function) != 0) { return nullptr; } if (strlen(identifier) >= sizeof(dummy_sock.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering node socket class: '%s' is too long, maximum length is %d", identifier, int(sizeof(dummy_sock.idname))); return nullptr; } /* check if we have registered this socket type before */ st = blender::bke::node_socket_type_find(dummy_st.idname); if (!st) { /* create a new node socket type */ st = MEM_new(__func__, dummy_st); blender::bke::node_register_socket_type(*st); } st->free_self = [](blender::bke::bNodeSocketType *stype) { MEM_delete(stype); }; /* if RNA type is already registered, unregister first */ if (st->ext_socket.srna) { StructRNA *srna = st->ext_socket.srna; RNA_struct_free_extension(srna, &st->ext_socket); RNA_struct_free(&BLENDER_RNA, srna); } st->ext_socket.srna = RNA_def_struct_ptr(&BLENDER_RNA, st->idname.c_str(), &RNA_NodeSocket); st->ext_socket.data = data; st->ext_socket.call = call; st->ext_socket.free = free; RNA_struct_blender_type_set(st->ext_socket.srna, st); /* XXX bad level call! needed to initialize the basic draw functions ... */ ED_init_custom_node_socket_type(st); st->draw = (have_function[0]) ? rna_NodeSocket_draw : nullptr; st->draw_color = (have_function[1]) ? rna_NodeSocket_draw_color : nullptr; st->draw_color_simple = (have_function[2]) ? rna_NodeSocket_draw_color_simple : nullptr; /* update while blender is running */ WM_main_add_notifier(NC_NODE | NA_EDITED, nullptr); BKE_main_ensure_invariants(*bmain); return st->ext_socket.srna; } static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr) { bNodeSocket *sock = static_cast(ptr->data); if (sock->typeinfo->ext_socket.srna) { return sock->typeinfo->ext_socket.srna; } else { return &RNA_NodeSocket; } } static std::optional rna_NodeSocket_path(const PointerRNA *ptr) { const bNodeTree *ntree = reinterpret_cast(ptr->owner_id); const bNodeSocket *sock = static_cast(ptr->data); const bNode &node = blender::bke::node_find_node(*ntree, *sock); const ListBase *sockets = (sock->in_out == SOCK_IN) ? &node.inputs : &node.outputs; const int socketindex = BLI_findindex(sockets, sock); char name_esc[sizeof(node.name) * 2]; BLI_str_escape(name_esc, node.name, sizeof(name_esc)); if (sock->in_out == SOCK_IN) { return fmt::format("nodes[\"{}\"].inputs[{}]", name_esc, socketindex); } return fmt::format("nodes[\"{}\"].outputs[{}]", name_esc, socketindex); } static IDProperty **rna_NodeSocket_idprops(PointerRNA *ptr) { bNodeSocket *sock = static_cast(ptr->data); return &sock->prop; } static PointerRNA rna_NodeSocket_node_get(PointerRNA *ptr) { bNodeTree *ntree = reinterpret_cast(ptr->owner_id); bNodeSocket *sock = static_cast(ptr->data); bNode &node = blender::bke::node_find_node(*ntree, *sock); return RNA_pointer_create_discrete(&ntree->id, &RNA_Node, &node); } static void rna_NodeSocket_type_set(PointerRNA *ptr, int value) { bNodeTree *ntree = reinterpret_cast(ptr->owner_id); bNodeSocket *sock = static_cast(ptr->data); bNode &node = blender::bke::node_find_node(*ntree, *sock); if (node.type_legacy != NODE_CUSTOM) { /* Can't change the socket type on built-in nodes like this. */ return; } blender::bke::node_modify_socket_type_static(ntree, &node, sock, value, 0); } static void rna_NodeSocket_bl_idname_get(PointerRNA *ptr, char *value) { const bNodeSocket *node = static_cast(ptr->data); const blender::bke::bNodeSocketType *ntype = node->typeinfo; blender::StringRef(ntype->idname).copy_unsafe(value); } static int rna_NodeSocket_bl_idname_length(PointerRNA *ptr) { const bNodeSocket *node = static_cast(ptr->data); const blender::bke::bNodeSocketType *ntype = node->typeinfo; return ntype->idname.size(); } static void rna_NodeSocket_bl_idname_set(PointerRNA *ptr, const char *value) { bNodeSocket *node = static_cast(ptr->data); blender::bke::bNodeSocketType *ntype = node->typeinfo; ntype->idname = value; } static void rna_NodeSocket_bl_label_get(PointerRNA *ptr, char *value) { const bNodeSocket *node = static_cast(ptr->data); const blender::bke::bNodeSocketType *ntype = node->typeinfo; blender::StringRef(ntype->label).copy_unsafe(value); } static int rna_NodeSocket_bl_label_length(PointerRNA *ptr) { const bNodeSocket *node = static_cast(ptr->data); const blender::bke::bNodeSocketType *ntype = node->typeinfo; return ntype->label.size(); } static void rna_NodeSocket_bl_label_set(PointerRNA *ptr, const char *value) { bNodeSocket *node = static_cast(ptr->data); blender::bke::bNodeSocketType *ntype = node->typeinfo; ntype->label = value; } static void rna_NodeSocket_bl_subtype_label_get(PointerRNA *ptr, char *value) { const bNodeSocket *node = static_cast(ptr->data); const blender::bke::bNodeSocketType *ntype = node->typeinfo; blender::StringRef(ntype->subtype_label).copy_unsafe(value); } static int rna_NodeSocket_bl_subtype_label_length(PointerRNA *ptr) { const bNodeSocket *node = static_cast(ptr->data); const blender::bke::bNodeSocketType *ntype = node->typeinfo; return ntype->subtype_label.size(); } static void rna_NodeSocket_bl_subtype_label_set(PointerRNA *ptr, const char *value) { bNodeSocket *node = static_cast(ptr->data); blender::bke::bNodeSocketType *ntype = node->typeinfo; ntype->subtype_label = value; } static bool rna_NodeSocket_is_linked_get(PointerRNA *ptr) { bNodeTree *ntree = reinterpret_cast(ptr->owner_id); bNodeSocket *sock = static_cast(ptr->data); ntree->ensure_topology_cache(); return sock->is_directly_linked(); } static void rna_NodeSocket_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr) { bNodeTree *ntree = reinterpret_cast(ptr->owner_id); bNodeSocket *sock = static_cast(ptr->data); BKE_ntree_update_tag_socket_property(ntree, sock); BKE_main_ensure_invariants(*bmain, ntree->id); } static void rna_NodeSocket_enabled_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr) { bNodeTree *ntree = reinterpret_cast(ptr->owner_id); bNodeSocket *sock = static_cast(ptr->data); BKE_ntree_update_tag_socket_availability(ntree, sock); BKE_main_ensure_invariants(*bmain, ntree->id); } static bool rna_NodeSocket_is_output_get(PointerRNA *ptr) { bNodeSocket *sock = static_cast(ptr->data); return sock->in_out == SOCK_OUT; } static int rna_NodeSocket_link_limit_get(PointerRNA *ptr) { bNodeSocket *sock = static_cast(ptr->data); return blender::bke::node_socket_link_limit(*sock); } static void rna_NodeSocket_link_limit_set(PointerRNA *ptr, int value) { bNodeSocket *sock = static_cast(ptr->data); sock->limit = (value == 0 ? 0xFFF : value); } static void rna_NodeSocket_hide_set(PointerRNA *ptr, bool value) { bNodeSocket *sock = static_cast(ptr->data); /* don't hide linked sockets */ if (sock->flag & SOCK_IS_LINKED) { return; } bNodeTree *ntree = reinterpret_cast(ptr->owner_id); bNode &node = blender::bke::node_find_node(*ntree, *sock); /* The Reroute node is the socket itself, do not hide this. */ if (node.is_reroute()) { return; } if (value) { sock->flag |= SOCK_HIDDEN; } else { sock->flag &= ~SOCK_HIDDEN; } } /* ******** Standard Node Socket Base Types ******** */ static void rna_NodeSocketStandard_draw(ID *id, bNodeSocket *sock, bContext *C, uiLayout *layout, PointerRNA *nodeptr, const char *text) { PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_NodeSocket, sock); sock->typeinfo->draw(C, layout, &ptr, nodeptr, text); } static void rna_NodeSocketStandard_draw_color( ID *id, bNodeSocket *sock, bContext *C, PointerRNA *nodeptr, float r_color[4]) { PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_NodeSocket, sock); sock->typeinfo->draw_color(C, &ptr, nodeptr, r_color); } static void rna_NodeSocketStandard_draw_color_simple(StructRNA *type, float r_color[4]) { const blender::bke::bNodeSocketType *typeinfo = static_cast(RNA_struct_blender_type_get(type)); typeinfo->draw_color_simple(typeinfo, r_color); } /* ******** Node Socket Subtypes ******** */ void rna_NodeSocketStandard_float_range( PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax) { bNodeSocket *sock = static_cast(ptr->data); bNodeSocketValueFloat *dval = static_cast(sock->default_value); int subtype = sock->typeinfo->subtype; if (dval->max < dval->min) { dval->max = dval->min; } *min = (subtype == PROP_UNSIGNED ? 0.0f : -FLT_MAX); *max = FLT_MAX; *softmin = dval->min; *softmax = dval->max; } void rna_NodeSocketStandard_int_range( PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) { bNodeSocket *sock = static_cast(ptr->data); bNodeSocketValueInt *dval = static_cast(sock->default_value); int subtype = sock->typeinfo->subtype; if (dval->max < dval->min) { dval->max = dval->min; } *min = (subtype == PROP_UNSIGNED ? 0 : INT_MIN); *max = INT_MAX; *softmin = dval->min; *softmax = dval->max; } void rna_NodeSocketStandard_vector_range( PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax) { bNodeSocket *sock = static_cast(ptr->data); bNodeSocketValueVector *dval = static_cast(sock->default_value); if (dval->max < dval->min) { dval->max = dval->min; } *min = -FLT_MAX; *max = FLT_MAX; *softmin = dval->min; *softmax = dval->max; } float rna_NodeSocketStandard_float_default(PointerRNA *ptr, PropertyRNA * /*prop*/) { bNodeSocket *sock = static_cast(ptr->data); if (!sock->runtime->declaration) { return 0.0f; } auto *decl = static_cast(sock->runtime->declaration); return decl->default_value; } int rna_NodeSocketStandard_int_default(PointerRNA *ptr, PropertyRNA * /*prop*/) { bNodeSocket *sock = static_cast(ptr->data); if (!sock->runtime->declaration) { return 0; } auto *decl = static_cast(sock->runtime->declaration); return decl->default_value; } bool rna_NodeSocketStandard_boolean_default(PointerRNA *ptr, PropertyRNA * /*prop*/) { bNodeSocket *sock = static_cast(ptr->data); if (!sock->runtime->declaration) { return false; } auto *decl = static_cast(sock->runtime->declaration); return decl->default_value; } void rna_NodeSocketStandard_vector_default(PointerRNA *ptr, PropertyRNA * /*prop*/, float *r_values) { bNodeSocket *sock = static_cast(ptr->data); if (!sock->runtime->declaration) { std::fill_n(r_values, 3, 0.0f); return; } auto *decl = static_cast(sock->runtime->declaration); std::copy_n(&decl->default_value.x, 3, r_values); } void rna_NodeSocketStandard_color_default(PointerRNA *ptr, PropertyRNA * /*prop*/, float *r_values) { bNodeSocket *sock = static_cast(ptr->data); if (!sock->runtime->declaration) { std::fill_n(r_values, 4, 0.0f); return; } auto *decl = static_cast(sock->runtime->declaration); std::copy_n(&decl->default_value.r, 4, r_values); } /* using a context update function here, to avoid searching the node if possible */ static void rna_NodeSocketStandard_value_update(bContext *C, PointerRNA *ptr) { /* default update */ rna_NodeSocket_update(CTX_data_main(C), CTX_data_scene(C), ptr); } static void rna_NodeSocketStandard_value_and_relation_update(bContext *C, PointerRNA *ptr) { rna_NodeSocketStandard_value_update(C, ptr); Main *bmain = CTX_data_main(C); DEG_relations_tag_update(bmain); } const EnumPropertyItem *RNA_node_enum_definition_itemf( const blender::bke::RuntimeNodeEnumItems &enum_items, bool *r_free) { EnumPropertyItem tmp = {0}; EnumPropertyItem *result = nullptr; int totitem = 0; for (const blender::bke::RuntimeNodeEnumItem &item : enum_items.items) { tmp.value = item.identifier; /* Item name is unique and used as the RNA identifier as well. * The integer value is persistent and unique and should be used * when storing the enum value. */ tmp.identifier = item.name.c_str(); /* TODO support icons in enum definition. */ tmp.icon = ICON_NONE; tmp.name = item.name.c_str(); tmp.description = item.description.c_str(); RNA_enum_item_add(&result, &totitem, &tmp); } if (totitem == 0) { *r_free = false; return rna_enum_dummy_NULL_items; } RNA_enum_item_end(&result, &totitem); *r_free = true; return result; } const EnumPropertyItem *RNA_node_socket_menu_itemf(bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool *r_free) { const bNodeSocket *socket = static_cast(ptr->data); if (!socket) { *r_free = false; return rna_enum_dummy_NULL_items; } const bNodeSocketValueMenu *data = static_cast(socket->default_value); if (!data->enum_items) { *r_free = false; return rna_enum_dummy_NULL_items; } return RNA_node_enum_definition_itemf(*data->enum_items, r_free); } std::optional rna_NodeSocketString_filepath_filter(const bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/) { bNodeSocket *socket = static_cast(ptr->data); BLI_assert(socket->type == SOCK_STRING); if (const auto *decl = dynamic_cast( socket->runtime->declaration)) { return decl->path_filter; } return std::nullopt; } #else static void rna_def_node_socket(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; PropertyRNA *parm; FunctionRNA *func; static const EnumPropertyItem rna_enum_node_socket_display_shape_items[] = { {SOCK_DISPLAY_SHAPE_CIRCLE, "CIRCLE", 0, "Circle", ""}, {SOCK_DISPLAY_SHAPE_SQUARE, "SQUARE", 0, "Square", ""}, {SOCK_DISPLAY_SHAPE_DIAMOND, "DIAMOND", 0, "Diamond", ""}, {SOCK_DISPLAY_SHAPE_CIRCLE_DOT, "CIRCLE_DOT", 0, "Circle with inner dot", ""}, {SOCK_DISPLAY_SHAPE_SQUARE_DOT, "SQUARE_DOT", 0, "Square with inner dot", ""}, {SOCK_DISPLAY_SHAPE_DIAMOND_DOT, "DIAMOND_DOT", 0, "Diamond with inner dot", ""}, {0, nullptr, 0, nullptr, nullptr}}; static const float default_draw_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; srna = RNA_def_struct(brna, "NodeSocket", nullptr); RNA_def_struct_ui_text(srna, "Node Socket", "Input or output socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_refine_func(srna, "rna_NodeSocket_refine"); RNA_def_struct_ui_icon(srna, ICON_NONE); RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); RNA_def_struct_register_funcs( srna, "rna_NodeSocket_register", "rna_NodeSocket_unregister", nullptr); RNA_def_struct_idprops_func(srna, "rna_NodeSocket_idprops"); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Socket name"); RNA_def_struct_name_property(srna, prop); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update"); prop = RNA_def_property(srna, "label", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, nullptr, "label"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Label", "Custom dynamic defined socket label"); prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, nullptr, "identifier"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Identifier", "Unique identifier for mapping sockets"); prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, nullptr, "description"); RNA_def_property_ui_text(prop, "Tooltip", "Socket tooltip"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update"); prop = RNA_def_property(srna, "is_output", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_NodeSocket_is_output_get", nullptr); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Is Output", "True if the socket is an output, otherwise input"); prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", SOCK_HIDDEN); RNA_def_property_boolean_funcs(prop, nullptr, "rna_NodeSocket_hide_set"); RNA_def_property_ui_text(prop, "Hide", "Hide the socket"); RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, nullptr); prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, nullptr, "flag", SOCK_UNAVAIL); RNA_def_property_ui_text(prop, "Enabled", "Enable the socket"); RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeSocket_enabled_update"); prop = RNA_def_property(srna, "link_limit", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, nullptr, "limit"); RNA_def_property_int_funcs( prop, "rna_NodeSocket_link_limit_get", "rna_NodeSocket_link_limit_set", nullptr); RNA_def_property_range(prop, 1, 0xFFF); RNA_def_property_ui_text(prop, "Link Limit", "Max number of links allowed for this socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, nullptr); prop = RNA_def_property(srna, "is_linked", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_NodeSocket_is_linked_get", nullptr); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Linked", "True if the socket is connected"); prop = RNA_def_property(srna, "is_unavailable", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", SOCK_UNAVAIL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Unavailable", "True if the socket is unavailable"); prop = RNA_def_property(srna, "is_multi_input", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", SOCK_MULTI_INPUT); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( prop, "Multi Input", "True if the socket can accept multiple ordered input links"); prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE); RNA_def_property_boolean_negative_sdna(prop, nullptr, "flag", SOCK_COLLAPSED); RNA_def_property_ui_text(prop, "Expanded", "Socket links are expanded in the user interface"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, nullptr); prop = RNA_def_property(srna, "hide_value", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", SOCK_HIDE_VALUE); RNA_def_property_ui_text(prop, "Hide Value", "Hide the socket input value"); RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, nullptr); prop = RNA_def_property(srna, "pin_gizmo", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", SOCK_GIZMO_PIN); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text( prop, "Pin Gizmo", "Keep gizmo visible even when the node is not selected"); RNA_def_property_update(prop, NC_NODE | ND_NODE_GIZMO, nullptr); prop = RNA_def_property(srna, "node", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_funcs(prop, "rna_NodeSocket_node_get", nullptr, nullptr, nullptr); RNA_def_property_struct_type(prop, "Node"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP); RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); RNA_def_property_ui_text(prop, "Node", "Node owning this socket"); /* NOTE: The type property is used by standard sockets. * Ideally should be defined only for the registered subclass, * but to use the existing DNA is added in the base type here. * Future socket types can ignore or override this if needed. */ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "type"); RNA_def_property_enum_items(prop, rna_enum_node_socket_type_items); RNA_def_property_enum_default(prop, SOCK_FLOAT); RNA_def_property_enum_funcs(prop, nullptr, "rna_NodeSocket_type_set", nullptr); RNA_def_property_ui_text(prop, "Type", "Data type"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update"); prop = RNA_def_property(srna, "display_shape", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "display_shape"); RNA_def_property_enum_items(prop, rna_enum_node_socket_display_shape_items); RNA_def_property_enum_default(prop, SOCK_DISPLAY_SHAPE_CIRCLE); RNA_def_property_ui_text(prop, "Shape", "Socket shape"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update"); /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_NodeSocket_bl_idname_get", "rna_NodeSocket_bl_idname_length", "rna_NodeSocket_bl_idname_set"); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "ID Name", ""); prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_NodeSocket_bl_label_get", "rna_NodeSocket_bl_label_length", "rna_NodeSocket_bl_label_set"); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); RNA_def_property_ui_text(prop, "Type Label", "Label to display for the socket type in the UI"); prop = RNA_def_property(srna, "bl_subtype_label", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_NodeSocket_bl_subtype_label_get", "rna_NodeSocket_bl_subtype_label_length", "rna_NodeSocket_bl_subtype_label_set"); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); RNA_def_property_ui_text( prop, "Subtype Label", "Label to display for the socket subtype in the UI"); /* draw socket */ func = RNA_def_function(srna, "draw", nullptr); RNA_def_function_ui_description(func, "Draw socket"); RNA_def_function_flag(func, FUNC_REGISTER); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_property(func, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_property(func, "node", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(parm, "Node"); RNA_def_property_ui_text(parm, "Node", "Node the socket belongs to"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_property(func, "text", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(parm, "Text", "Text label to draw alongside properties"); // RNA_def_property_string_default(parm, ""); RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED); func = RNA_def_function(srna, "draw_color", nullptr); RNA_def_function_ui_description(func, "Color of the socket icon"); RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_property(func, "node", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(parm, "Node"); RNA_def_property_ui_text(parm, "Node", "Node the socket belongs to"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_float_array( func, "color", 4, default_draw_color, 0.0f, 1.0f, "Color", "", 0.0f, 1.0f); RNA_def_function_output(func, parm); func = RNA_def_function(srna, "draw_color_simple", nullptr); RNA_def_function_ui_description( func, "Color of the socket icon. Used to draw sockets in places where the socket does not belong " "to a node, like the node interface panel. Also used to draw node sockets if draw_color is " "not defined."); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL); parm = RNA_def_float_array( func, "color", 4, default_draw_color, 0.0f, 1.0f, "Color", "", 0.0f, 1.0f); RNA_def_function_output(func, parm); } static void rna_def_node_socket_standard(BlenderRNA *brna) { /* XXX Workaround: Registered functions are not exposed in python by bpy, * it expects them to be registered from python and use the native implementation. * However, the standard socket types below are not registering these functions from python, * so in order to call them in py scripts we need to overload and * replace them with plain C callbacks. * These types provide a usable basis for socket types defined in C. */ StructRNA *srna; PropertyRNA *parm; FunctionRNA *func; static const float default_draw_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; srna = RNA_def_struct(brna, "NodeSocketStandard", "NodeSocket"); RNA_def_struct_sdna(srna, "bNodeSocket"); /* draw socket */ func = RNA_def_function(srna, "draw", "rna_NodeSocketStandard_draw"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Draw socket"); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_property(func, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_property(func, "node", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(parm, "Node"); RNA_def_property_ui_text(parm, "Node", "Node the socket belongs to"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_property(func, "text", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(parm, "Text", "Text label to draw alongside properties"); // RNA_def_property_string_default(parm, ""); RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED); func = RNA_def_function(srna, "draw_color", "rna_NodeSocketStandard_draw_color"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Color of the socket icon"); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_property(func, "node", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(parm, "Node"); RNA_def_property_ui_text(parm, "Node", "Node the socket belongs to"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); parm = RNA_def_float_array( func, "color", 4, default_draw_color, 0.0f, 1.0f, "Color", "", 0.0f, 1.0f); RNA_def_function_output(func, parm); func = RNA_def_function(srna, "draw_color_simple", "rna_NodeSocketStandard_draw_color_simple"); RNA_def_function_ui_description(func, "Color of the socket icon"); RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE | FUNC_REGISTER_OPTIONAL); parm = RNA_def_float_array( func, "color", 4, default_draw_color, 0.0f, 1.0f, "Color", "", 0.0f, 1.0f); RNA_def_function_output(func, parm); } /* Common functions for all builtin socket interface types. */ static void rna_def_node_tree_interface_socket_builtin(StructRNA *srna) { FunctionRNA *func; PropertyRNA *parm; /* Override for functions, invoking the typeinfo callback directly * instead of expecting an existing RNA registered function implementation. */ func = RNA_def_function(srna, "draw", "rna_NodeTreeInterfaceSocket_draw_builtin"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Draw interface socket settings"); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_property(func, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(parm, "UILayout"); RNA_def_property_ui_text(parm, "Layout", "Layout in the UI"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); func = RNA_def_function(srna, "init_socket", "rna_NodeTreeInterfaceSocket_init_socket_builtin"); RNA_def_function_ui_description(func, "Initialize a node socket instance"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the socket to initialize"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Socket to initialize"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_string( func, "data_path", nullptr, 0, "Data Path", "Path to specialized socket data"); RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED); func = RNA_def_function(srna, "from_socket", "rna_NodeTreeInterfaceSocket_from_socket_builtin"); RNA_def_function_ui_description(func, "Setup template parameters from an existing socket"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the original socket"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Original socket"); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); } static void rna_def_node_socket_float(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Float Node Socket", "Floating-point number socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_FLOAT); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueFloat", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype); RNA_def_property_float_sdna(prop, nullptr, "value"); RNA_def_property_float_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_float_range"); RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_float_default"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_float(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; float value_default; /* choose sensible common default based on subtype */ switch (subtype) { case PROP_FACTOR: value_default = 1.0f; break; case PROP_PERCENTAGE: value_default = 100.0f; break; default: value_default = 0.0f; break; } srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text( srna, "Float Node Socket Interface", "Floating-point number socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueFloat", "socket_data"); prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_dummy_DEFAULT_items); RNA_def_property_enum_sdna(prop, nullptr, "subtype"); RNA_def_property_enum_funcs( prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocketFloat_subtype_itemf"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Subtype", "Subtype of the default value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype); RNA_def_property_float_sdna(prop, nullptr, "value"); RNA_def_property_float_default(prop, value_default); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_funcs( prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocketFloat_default_value_range"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "min_value", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, nullptr, "min"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "max_value", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, nullptr, "max"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; int value_default; /* choose sensible common default based on subtype */ switch (subtype) { case PROP_FACTOR: value_default = 1; break; case PROP_PERCENTAGE: value_default = 100; break; default: value_default = 0; break; } srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Integer Node Socket", "Integer number socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_INT); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueInt", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_INT, subtype); RNA_def_property_int_sdna(prop, nullptr, "value"); RNA_def_property_int_default(prop, value_default); RNA_def_property_int_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_int_range"); RNA_def_property_int_default_func(prop, "rna_NodeSocketStandard_int_default"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_int(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Integer Node Socket Interface", "Integer number socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueInt", "socket_data"); prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_dummy_DEFAULT_items); RNA_def_property_enum_sdna(prop, nullptr, "subtype"); RNA_def_property_enum_funcs( prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocketInt_subtype_itemf"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Subtype", "Subtype of the default value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "default_value", PROP_INT, subtype); RNA_def_property_int_sdna(prop, nullptr, "value"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_funcs( prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocketInt_default_value_range"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "min_value", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, nullptr, "min"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "max_value", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, nullptr, "max"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_bool(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Boolean Node Socket", "Boolean value socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_BOOLEAN); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueBoolean", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "value", 1); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_boolean_default_func(prop, "rna_NodeSocketStandard_boolean_default"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_bool(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Boolean Node Socket Interface", "Boolean value socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueBoolean", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "value", 1); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_rotation(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Rotation Node Socket", "Rotation value socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_ROTATION); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueRotation", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, nullptr, "value_euler"); // RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_rotation(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text( srna, "Rotation Node Socket Interface", "Rotation value socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueRotation", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, nullptr, "value_euler"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_matrix(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Matrix Node Socket", "Matrix value socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_MATRIX); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_matrix(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Matrix Node Socket Interface", "Matrix value socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Vector Node Socket", "3D vector socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_VECTOR); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueVector", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype); RNA_def_property_float_sdna(prop, nullptr, "value"); RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_vector_default"); RNA_def_property_float_funcs(prop, nullptr, nullptr, "rna_NodeSocketStandard_vector_range"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_vector(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Vector Node Socket Interface", "3D vector socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueVector", "socket_data"); prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_dummy_DEFAULT_items); RNA_def_property_enum_sdna(prop, nullptr, "subtype"); RNA_def_property_enum_funcs( prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocketVector_subtype_itemf"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Subtype", "Subtype of the default value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype); RNA_def_property_float_sdna(prop, nullptr, "value"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_funcs( prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocketVector_default_value_range"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "min_value", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, nullptr, "min"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "max_value", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, nullptr, "max"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_color(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Color Node Socket", "RGBA color socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_RGBA); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueRGBA", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, nullptr, "value"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_float_default_func(prop, "rna_NodeSocketStandard_color_default"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_color(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Color Node Socket Interface", "RGBA color socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueRGBA", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, nullptr, "value"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_string(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "String Node Socket", "String socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_STRING); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_STRING, subtype); RNA_def_property_string_sdna(prop, nullptr, "value"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); if (subtype == PROP_FILEPATH) { RNA_def_property_string_filepath_filter_func(prop, "rna_NodeSocketString_filepath_filter"); } RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_string(BlenderRNA *brna, const char *identifier, PropertySubType subtype) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "String Node Socket Interface", "String socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "socket_data"); prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_dummy_DEFAULT_items); RNA_def_property_enum_sdna(prop, nullptr, "subtype"); RNA_def_property_enum_funcs( prop, nullptr, nullptr, "rna_NodeTreeInterfaceSocketString_subtype_itemf"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Subtype", "Subtype of the default value"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); prop = RNA_def_property(srna, "default_value", PROP_STRING, subtype); RNA_def_property_string_sdna(prop, nullptr, "value"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); // TODO: Do I need to call RNA_def_property_string_funcs() ? RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_menu(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Menu Node Socket", "Menu socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_MENU); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueMenu", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "value"); RNA_def_property_enum_items(prop, rna_enum_dummy_NULL_items); RNA_def_property_enum_funcs(prop, nullptr, nullptr, "RNA_node_socket_menu_itemf"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_struct_sdna_from(srna, "bNodeSocket", nullptr); } static void rna_def_node_socket_interface_menu(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Menu Node Socket Interface", "Menu socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueMenu", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "value"); RNA_def_property_enum_items(prop, rna_enum_dummy_NULL_items); RNA_def_property_enum_funcs(prop, nullptr, nullptr, "RNA_node_tree_interface_socket_menu_itemf"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_struct_sdna_from(srna, "bNodeTreeInterfaceSocket", nullptr); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_shader(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Shader Node Socket", "Shader socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_SHADER); RNA_def_struct_sdna(srna, "bNodeSocket"); } static void rna_def_node_socket_interface_shader(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Shader Node Socket Interface", "Shader socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_object(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Object Node Socket", "Object socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_OBJECT); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueObject", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update( prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_interface_object(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Object Node Socket Interface", "Object socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueObject", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_image(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Image Node Socket", "Image socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_IMAGE); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueImage", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Image"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update( prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_interface_image(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Image Node Socket Interface", "Image socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueImage", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Image"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_geometry(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Geometry Node Socket", "Geometry socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_GEOMETRY); RNA_def_struct_sdna(srna, "bNodeSocket"); } static void rna_def_node_socket_interface_geometry(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Geometry Node Socket Interface", "Geometry socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_bundle(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Bundle Node Socket", "Bundle socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_BUNDLE); RNA_def_struct_sdna(srna, "bNodeSocket"); } static void rna_def_node_socket_interface_bundle(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Bundle Node Socket Interface", "Bundle socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_closure(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Closure Node Socket", "Closure socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_CLOSURE); RNA_def_struct_sdna(srna, "bNodeSocket"); } static void rna_def_node_socket_interface_closure(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Closure Node Socket Interface", "Closure socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_collection(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Collection Node Socket", "Collection socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_COLLECTION); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueCollection", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Collection"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update( prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_interface_collection(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Collection Node Socket Interface", "Collection socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueCollection", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Collection"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_texture(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Texture Node Socket", "Texture socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_TEXTURE); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueTexture", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Texture"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update( prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_interface_texture(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Texture Node Socket Interface", "Texture socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueTexture", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Texture"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_material(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Material Node Socket", "Material socket of a node"); RNA_def_struct_ui_icon(srna, ICON_NODE_SOCKET_MATERIAL); RNA_def_struct_sdna(srna, "bNodeSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueMaterial", "default_value"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Material"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update( prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); } static void rna_def_node_socket_interface_material(BlenderRNA *brna, const char *identifier) { StructRNA *srna; PropertyRNA *prop; srna = RNA_def_struct(brna, identifier, "NodeTreeInterfaceSocket"); RNA_def_struct_ui_text(srna, "Material Node Socket Interface", "Material socket of a node"); RNA_def_struct_sdna(srna, "bNodeTreeInterfaceSocket"); RNA_def_struct_sdna_from(srna, "bNodeSocketValueMaterial", "socket_data"); prop = RNA_def_property(srna, "default_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "value"); RNA_def_property_struct_type(prop, "Material"); RNA_def_property_pointer_funcs( prop, nullptr, nullptr, nullptr, "rna_NodeTreeInterfaceSocketMaterial_default_value_poll"); RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeTreeInterfaceSocket_value_update"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); rna_def_node_tree_interface_socket_builtin(srna); } static void rna_def_node_socket_virtual(BlenderRNA *brna, const char *identifier) { StructRNA *srna; srna = RNA_def_struct(brna, identifier, "NodeSocketStandard"); RNA_def_struct_ui_text(srna, "Virtual Node Socket", "Virtual socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); } /* Info for generating static subtypes. */ struct bNodeSocketStaticTypeInfo { const char *socket_identifier; const char *interface_identifier; eNodeSocketDatatype type; PropertySubType subtype; const char *label; }; /* NOTE: Socket and interface subtypes could be defined from a single central list, * but makesrna cannot have a dependency on BKE, so this list would have to live in RNA itself, * with BKE etc. accessing the RNA API to get the subtypes info. */ static const bNodeSocketStaticTypeInfo node_socket_subtypes[] = { {"NodeSocketFloat", "NodeTreeInterfaceSocketFloat", SOCK_FLOAT, PROP_NONE}, {"NodeSocketFloatUnsigned", "NodeTreeInterfaceSocketFloatUnsigned", SOCK_FLOAT, PROP_UNSIGNED}, {"NodeSocketFloatPercentage", "NodeTreeInterfaceSocketFloatPercentage", SOCK_FLOAT, PROP_PERCENTAGE}, {"NodeSocketFloatFactor", "NodeTreeInterfaceSocketFloatFactor", SOCK_FLOAT, PROP_FACTOR}, {"NodeSocketFloatAngle", "NodeTreeInterfaceSocketFloatAngle", SOCK_FLOAT, PROP_ANGLE}, {"NodeSocketFloatTime", "NodeTreeInterfaceSocketFloatTime", SOCK_FLOAT, PROP_TIME}, {"NodeSocketFloatTimeAbsolute", "NodeTreeInterfaceSocketFloatTimeAbsolute", SOCK_FLOAT, PROP_TIME_ABSOLUTE}, {"NodeSocketFloatDistance", "NodeTreeInterfaceSocketFloatDistance", SOCK_FLOAT, PROP_DISTANCE}, {"NodeSocketFloatWavelength", "NodeTreeInterfaceSocketFloatWavelength", SOCK_FLOAT, PROP_WAVELENGTH}, {"NodeSocketFloatColorTemperature", "NodeTreeInterfaceSocketFloatColorTemperature", SOCK_FLOAT, PROP_COLOR_TEMPERATURE}, {"NodeSocketFloatFrequency", "NodeTreeInterfaceSocketFloatFrequency", SOCK_FLOAT, PROP_FREQUENCY}, {"NodeSocketInt", "NodeTreeInterfaceSocketInt", SOCK_INT, PROP_NONE}, {"NodeSocketIntUnsigned", "NodeTreeInterfaceSocketIntUnsigned", SOCK_INT, PROP_UNSIGNED}, {"NodeSocketIntPercentage", "NodeTreeInterfaceSocketIntPercentage", SOCK_INT, PROP_PERCENTAGE}, {"NodeSocketIntFactor", "NodeTreeInterfaceSocketIntFactor", SOCK_INT, PROP_FACTOR}, {"NodeSocketBool", "NodeTreeInterfaceSocketBool", SOCK_BOOLEAN, PROP_NONE}, {"NodeSocketRotation", "NodeTreeInterfaceSocketRotation", SOCK_ROTATION, PROP_NONE}, {"NodeSocketMatrix", "NodeTreeInterfaceSocketMatrix", SOCK_MATRIX, PROP_NONE}, {"NodeSocketVector", "NodeTreeInterfaceSocketVector", SOCK_VECTOR, PROP_NONE}, {"NodeSocketVectorTranslation", "NodeTreeInterfaceSocketVectorTranslation", SOCK_VECTOR, PROP_TRANSLATION}, {"NodeSocketVectorDirection", "NodeTreeInterfaceSocketVectorDirection", SOCK_VECTOR, PROP_DIRECTION}, {"NodeSocketVectorVelocity", "NodeTreeInterfaceSocketVectorVelocity", SOCK_VECTOR, PROP_VELOCITY}, {"NodeSocketVectorAcceleration", "NodeTreeInterfaceSocketVectorAcceleration", SOCK_VECTOR, PROP_ACCELERATION}, {"NodeSocketVectorEuler", "NodeTreeInterfaceSocketVectorEuler", SOCK_VECTOR, PROP_EULER}, {"NodeSocketVectorXYZ", "NodeTreeInterfaceSocketVectorXYZ", SOCK_VECTOR, PROP_XYZ}, {"NodeSocketColor", "NodeTreeInterfaceSocketColor", SOCK_RGBA, PROP_NONE}, {"NodeSocketString", "NodeTreeInterfaceSocketString", SOCK_STRING, PROP_NONE}, {"NodeSocketStringFilePath", "NodeTreeInterfaceSocketStringFilePath", SOCK_STRING, PROP_FILEPATH}, {"NodeSocketShader", "NodeTreeInterfaceSocketShader", SOCK_SHADER, PROP_NONE}, {"NodeSocketObject", "NodeTreeInterfaceSocketObject", SOCK_OBJECT, PROP_NONE}, {"NodeSocketImage", "NodeTreeInterfaceSocketImage", SOCK_IMAGE, PROP_NONE}, {"NodeSocketGeometry", "NodeTreeInterfaceSocketGeometry", SOCK_GEOMETRY, PROP_NONE}, {"NodeSocketCollection", "NodeTreeInterfaceSocketCollection", SOCK_COLLECTION, PROP_NONE}, {"NodeSocketTexture", "NodeTreeInterfaceSocketTexture", SOCK_TEXTURE, PROP_NONE}, {"NodeSocketMaterial", "NodeTreeInterfaceSocketMaterial", SOCK_MATERIAL, PROP_NONE}, {"NodeSocketMenu", "NodeTreeInterfaceSocketMenu", SOCK_MENU, PROP_NONE}, {"NodeSocketBundle", "NodeTreeInterfaceSocketBundle", SOCK_BUNDLE, PROP_NONE}, {"NodeSocketClosure", "NodeTreeInterfaceSocketClosure", SOCK_CLOSURE, PROP_NONE}, }; static void rna_def_node_socket_subtypes(BlenderRNA *brna) { for (const bNodeSocketStaticTypeInfo &info : node_socket_subtypes) { const char *identifier = info.socket_identifier; switch (info.type) { case SOCK_FLOAT: rna_def_node_socket_float(brna, identifier, info.subtype); break; case SOCK_INT: rna_def_node_socket_int(brna, identifier, info.subtype); break; case SOCK_BOOLEAN: rna_def_node_socket_bool(brna, identifier); break; case SOCK_ROTATION: rna_def_node_socket_rotation(brna, identifier); break; case SOCK_MATRIX: rna_def_node_socket_matrix(brna, identifier); break; case SOCK_VECTOR: rna_def_node_socket_vector(brna, identifier, info.subtype); break; case SOCK_RGBA: rna_def_node_socket_color(brna, identifier); break; case SOCK_STRING: rna_def_node_socket_string(brna, identifier, info.subtype); break; case SOCK_SHADER: rna_def_node_socket_shader(brna, identifier); break; case SOCK_OBJECT: rna_def_node_socket_object(brna, identifier); break; case SOCK_IMAGE: rna_def_node_socket_image(brna, identifier); break; case SOCK_GEOMETRY: rna_def_node_socket_geometry(brna, identifier); break; case SOCK_COLLECTION: rna_def_node_socket_collection(brna, identifier); break; case SOCK_TEXTURE: rna_def_node_socket_texture(brna, identifier); break; case SOCK_MATERIAL: rna_def_node_socket_material(brna, identifier); break; case SOCK_MENU: rna_def_node_socket_menu(brna, identifier); break; case SOCK_BUNDLE: rna_def_node_socket_bundle(brna, identifier); break; case SOCK_CLOSURE: rna_def_node_socket_closure(brna, identifier); break; case SOCK_CUSTOM: break; } } rna_def_node_socket_virtual(brna, "NodeSocketVirtual"); } void rna_def_node_socket_interface_subtypes(BlenderRNA *brna) { /* NOTE: interface items are defined outside this file. * The subtypes must be defined after the base type, so this function * is called from the interface rna file to ensure correct order. */ for (const bNodeSocketStaticTypeInfo &info : node_socket_subtypes) { const char *identifier = info.interface_identifier; switch (info.type) { case SOCK_FLOAT: rna_def_node_socket_interface_float(brna, identifier, info.subtype); break; case SOCK_INT: rna_def_node_socket_interface_int(brna, identifier, info.subtype); break; case SOCK_BOOLEAN: rna_def_node_socket_interface_bool(brna, identifier); break; case SOCK_ROTATION: rna_def_node_socket_interface_rotation(brna, identifier); break; case SOCK_MATRIX: rna_def_node_socket_interface_matrix(brna, identifier); break; case SOCK_VECTOR: rna_def_node_socket_interface_vector(brna, identifier, info.subtype); break; case SOCK_RGBA: rna_def_node_socket_interface_color(brna, identifier); break; case SOCK_STRING: rna_def_node_socket_interface_string(brna, identifier, info.subtype); break; case SOCK_MENU: rna_def_node_socket_interface_menu(brna, identifier); break; case SOCK_SHADER: rna_def_node_socket_interface_shader(brna, identifier); break; case SOCK_OBJECT: rna_def_node_socket_interface_object(brna, identifier); break; case SOCK_IMAGE: rna_def_node_socket_interface_image(brna, identifier); break; case SOCK_GEOMETRY: rna_def_node_socket_interface_geometry(brna, identifier); break; case SOCK_COLLECTION: rna_def_node_socket_interface_collection(brna, identifier); break; case SOCK_TEXTURE: rna_def_node_socket_interface_texture(brna, identifier); break; case SOCK_MATERIAL: rna_def_node_socket_interface_material(brna, identifier); break; case SOCK_BUNDLE: rna_def_node_socket_interface_bundle(brna, identifier); break; case SOCK_CLOSURE: rna_def_node_socket_interface_closure(brna, identifier); break; case SOCK_CUSTOM: break; } } } void RNA_def_node_socket_subtypes(BlenderRNA *brna) { rna_def_node_socket(brna); rna_def_node_socket_standard(brna); rna_def_node_socket_subtypes(brna); } #endif