Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/makesrna/intern/rna_nodetree.c')
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c4154
1 files changed, 3038 insertions, 1116 deletions
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index e7c030d5cdf..99b4f5a794d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -61,11 +62,22 @@
#include "MEM_guardedalloc.h"
-EnumPropertyItem nodetree_type_items[] = {
- {NTREE_SHADER, "SHADER", ICON_MATERIAL, "Shader", "Shader nodes"},
- {NTREE_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture nodes"},
- {NTREE_COMPOSIT, "COMPOSITING", ICON_RENDERLAYERS, "Compositing", "Compositing nodes"},
- {0, NULL, 0, NULL, NULL}
+EnumPropertyItem node_socket_in_out_items[] = {
+ { SOCK_IN, "IN", 0, "Input", "" },
+ { SOCK_OUT, "OUT", 0, "Output", "" },
+ { 0, NULL, 0, NULL, NULL }
+};
+
+EnumPropertyItem node_socket_type_items[] = {
+ {SOCK_CUSTOM, "CUSTOM", 0, "Custom", ""},
+ {SOCK_FLOAT, "VALUE", 0, "Value", ""},
+ {SOCK_INT, "INT", 0, "Int", ""},
+ {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
+ {SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
+ {SOCK_STRING, "STRING", 0, "String", ""},
+ {SOCK_RGBA, "RGBA", 0, "RGBA", ""},
+ {SOCK_SHADER, "SHADER", 0, "Shader", ""},
+ {0, NULL, 0, NULL, NULL}
};
EnumPropertyItem node_quality_items[] = {
@@ -85,17 +97,15 @@ EnumPropertyItem node_chunksize_items[] = {
{0, NULL, 0, NULL, NULL}
};
-EnumPropertyItem node_socket_type_items[] = {
- {SOCK_FLOAT, "VALUE", 0, "Value", ""},
- {SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
- {SOCK_RGBA, "RGBA", 0, "RGBA", ""},
- {SOCK_SHADER, "SHADER", 0, "Shader", ""},
- {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
- {SOCK_MESH, "MESH", 0, "Mesh", ""},
- {SOCK_INT, "INT", 0, "Int", ""},
- {SOCK_STRING, "STRING", 0, "String", ""},
- {0, NULL, 0, NULL, NULL}
-};
+#define DEF_ICON_BLANK_SKIP
+#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""},
+#define DEF_VICO(name)
+EnumPropertyItem node_icon_items[] = {
+#include "UI_icons.h"
+ {0, NULL, 0, NULL, NULL}};
+#undef DEF_ICON_BLANK_SKIP
+#undef DEF_ICON
+#undef DEF_VICO
EnumPropertyItem node_math_items[] = {
{ 0, "ADD", 0, "Add", ""},
@@ -174,52 +184,20 @@ EnumPropertyItem prop_wave_items[] = {
};
#endif
-/* Add any new socket value subtype here.
- * When adding a new subtype here, make sure you also add it
- * to the subtype definitions in DNA_node_types.h.
- * This macro is used by the RNA and the internal converter functions
- * to define all socket subtypes. The SUBTYPE macro must be defined
- * before using this macro, and undefined afterwards.
- */
-#define NODE_DEFINE_SUBTYPES_INT \
- SUBTYPE(INT, Int, NONE, None) \
- SUBTYPE(INT, Int, UNSIGNED, Unsigned)
-
-#define NODE_DEFINE_SUBTYPES_FLOAT \
- SUBTYPE(FLOAT, Float, NONE, None) \
- SUBTYPE(FLOAT, Float, UNSIGNED, Unsigned) \
- SUBTYPE(FLOAT, Float, PERCENTAGE, Percentage) \
- SUBTYPE(FLOAT, Float, FACTOR, Factor) \
- SUBTYPE(FLOAT, Float, ANGLE, Angle) \
- SUBTYPE(FLOAT, Float, TIME, Time) \
- SUBTYPE(FLOAT, Float, DISTANCE, Distance)
-
-#define NODE_DEFINE_SUBTYPES_STRING \
- SUBTYPE(STRING, String, NONE, None) \
- SUBTYPE(STRING, String, FILEPATH, Filepath)
-
-#define NODE_DEFINE_SUBTYPES_VECTOR \
- SUBTYPE(VECTOR, Vector, NONE, None) \
- SUBTYPE(VECTOR, Vector, TRANSLATION, Translation) \
- SUBTYPE(VECTOR, Vector, DIRECTION, Direction) \
- SUBTYPE(VECTOR, Vector, VELOCITY, Velocity) \
- SUBTYPE(VECTOR, Vector, ACCELERATION, Acceleration) \
- SUBTYPE(VECTOR, Vector, EULER, Euler) \
- SUBTYPE(VECTOR, Vector, XYZ, XYZ)
-
-#define NODE_DEFINE_SUBTYPES \
- NODE_DEFINE_SUBTYPES_INT \
- NODE_DEFINE_SUBTYPES_FLOAT \
- NODE_DEFINE_SUBTYPES_STRING \
- NODE_DEFINE_SUBTYPES_VECTOR \
-
#ifdef RNA_RUNTIME
#include "BLI_linklist.h"
+#include "BLI_string.h"
+
+#include "BKE_context.h"
+#include "BKE_idprop.h"
#include "BKE_global.h"
#include "ED_node.h"
+#include "ED_render.h"
+
+#include "NOD_socket.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -227,66 +205,1334 @@ EnumPropertyItem prop_wave_items[] = {
#include "DNA_scene_types.h"
#include "WM_api.h"
-static StructRNA *rna_Node_refine(struct PointerRNA *ptr)
+
+int rna_node_tree_type_to_enum(bNodeTreeType *typeinfo)
{
- bNode *node = (bNode *)ptr->data;
+ int i=0, result=-1;
+ NODE_TREE_TYPES_BEGIN(nt)
+ if (nt == typeinfo) {
+ result = i;
+ break;
+ }
+ ++i;
+ NODE_TREE_TYPES_END
+ return result;
+}
+
+int rna_node_tree_idname_to_enum(const char *idname)
+{
+ int i=0, result=-1;
+ NODE_TREE_TYPES_BEGIN(nt)
+ if (strcmp(nt->idname, idname)==0) {
+ result = i;
+ break;
+ }
+ ++i;
+ NODE_TREE_TYPES_END
+ return result;
+}
- switch (node->type) {
+bNodeTreeType *rna_node_tree_type_from_enum(int value)
+{
+ int i=0;
+ bNodeTreeType *result=NULL;
+ NODE_TREE_TYPES_BEGIN(nt)
+ if (i == value) {
+ result = nt;
+ break;
+ }
+ ++i;
+ NODE_TREE_TYPES_END
+ return result;
+}
+
+EnumPropertyItem *rna_node_tree_type_itemf(void *data, int (*poll)(void *data, bNodeTreeType *), int *free)
+{
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ EnumPropertyItem *item = NULL;
+ int totitem=0, i=0;
+
+ NODE_TREE_TYPES_BEGIN(nt)
+ if (poll && !poll(data, nt)) {
+ ++i;
+ continue;
+ }
- #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
- case ID: return &RNA_##Category##StructName;
-
- #include "rna_nodetree_types.h"
+ tmp.value = i;
+ tmp.identifier = nt->idname;
+ tmp.icon = nt->ui_icon;
+ tmp.name = nt->ui_name;
+ tmp.description = nt->ui_description;
- case NODE_GROUP:
- return &RNA_NodeGroup;
- case NODE_FRAME:
- return &RNA_NodeFrame;
- case NODE_REROUTE:
- return &RNA_NodeReroute;
- default:
- return &RNA_Node;
+ RNA_enum_item_add(&item, &totitem, &tmp);
+
+ ++i;
+ NODE_TREE_TYPES_END
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+
+int rna_node_type_to_enum(bNodeType *typeinfo)
+{
+ int i=0, result=-1;
+ NODE_TYPES_BEGIN(ntype)
+ if (ntype==typeinfo) {
+ result = i;
+ break;
+ }
+ ++i;
+ NODE_TYPES_END
+ return result;
+}
+
+int rna_node_idname_to_enum(const char *idname)
+{
+ int i=0, result=-1;
+ NODE_TYPES_BEGIN(ntype)
+ if (strcmp(ntype->idname, idname)==0) {
+ result = i;
+ break;
+ }
+ ++i;
+ NODE_TYPES_END
+ return result;
+}
+
+bNodeType *rna_node_type_from_enum(int value)
+{
+ int i=0;
+ bNodeType *result=NULL;
+ NODE_TYPES_BEGIN(ntype)
+ if (i==value) {
+ result = ntype;
+ break;
+ }
+ ++i;
+ NODE_TYPES_END
+ return result;
+}
+
+EnumPropertyItem *rna_node_type_itemf(void *data, int (*poll)(void *data, bNodeType *), int *free)
+{
+ EnumPropertyItem *item = NULL;
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ int totitem=0, i=0;
+
+ NODE_TYPES_BEGIN(ntype)
+ if (poll && !poll(data, ntype)) {
+ ++i;
+ continue;
+ }
+
+ tmp.value = i;
+ tmp.identifier = ntype->idname;
+ tmp.icon = ntype->ui_icon;
+ tmp.name = ntype->ui_name;
+ tmp.description = ntype->ui_description;
+
+ RNA_enum_item_add(&item, &totitem, &tmp);
+
+ ++i;
+ NODE_TYPES_END
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+
+int rna_node_socket_type_to_enum(bNodeSocketType *typeinfo)
+{
+ int i=0, result=-1;
+ NODE_SOCKET_TYPES_BEGIN(stype)
+ if (stype==typeinfo) {
+ result = i;
+ break;
+ }
+ ++i;
+ NODE_SOCKET_TYPES_END
+ return result;
+}
+
+int rna_node_socket_idname_to_enum(const char *idname)
+{
+ int i=0, result=-1;
+ NODE_SOCKET_TYPES_BEGIN(stype)
+ if (strcmp(stype->idname, idname)==0) {
+ result = i;
+ break;
+ }
+ ++i;
+ NODE_SOCKET_TYPES_END
+ return result;
+}
+
+bNodeSocketType *rna_node_socket_type_from_enum(int value)
+{
+ int i=0;
+ bNodeSocketType *result=NULL;
+ NODE_SOCKET_TYPES_BEGIN(stype)
+ if (i==value) {
+ result = stype;
+ break;
+ }
+ ++i;
+ NODE_SOCKET_TYPES_END
+ return result;
+}
+
+EnumPropertyItem *rna_node_socket_type_itemf(void *data, int (*poll)(void *data, bNodeSocketType *), int *free)
+{
+ EnumPropertyItem *item = NULL;
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ int totitem=0, i=0;
+ StructRNA *srna;
+
+ NODE_SOCKET_TYPES_BEGIN(stype)
+ if (poll && !poll(data, stype)) {
+ ++i;
+ continue;
+ }
+
+ srna = stype->ext_socket.srna;
+ tmp.value = i;
+ tmp.identifier = stype->idname;
+ tmp.icon = RNA_struct_ui_icon(srna);
+ tmp.name = RNA_struct_ui_name(srna);
+ tmp.description = RNA_struct_ui_description(srna);
+
+ RNA_enum_item_add(&item, &totitem, &tmp);
+
+ ++i;
+ NODE_SOCKET_TYPES_END
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
+}
+
+static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+{
+ EnumPropertyItem *item = NULL;
+ EnumPropertyItem tmp;
+ int totitem=0;
+
+ /* hack, don't want to add include path to RNA just for this, since in the future RNA types
+ * for nodes should be defined locally at runtime anyway ...
+ */
+
+ tmp.value = NODE_CUSTOM;
+ tmp.identifier = "CUSTOM";
+ tmp.name = "Custom";
+ tmp.description = "Custom Node";
+ tmp.icon = ICON_NONE;
+ RNA_enum_item_add(&item, &totitem, &tmp);
+
+ tmp.value = NODE_UNDEFINED;
+ tmp.identifier = "UNDEFINED";
+ tmp.name = "UNDEFINED";
+ tmp.description = "";
+ tmp.icon = ICON_NONE;
+ RNA_enum_item_add(&item, &totitem, &tmp);
+
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (strcmp(#Category, "Node")==0) { \
+ tmp.value = ID; \
+ tmp.identifier = EnumName; \
+ tmp.name = UIName; \
+ tmp.description = UIDesc; \
+ tmp.icon = ICON_NONE; \
+ RNA_enum_item_add(&item, &totitem, &tmp); \
+ }
+ #include "../../nodes/NOD_static_types.h"
+ #undef DefNode
+
+ if (RNA_struct_is_a(ptr->type, &RNA_ShaderNode)) {
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (strcmp(#Category, "ShaderNode")==0) { \
+ tmp.value = ID; \
+ tmp.identifier = EnumName; \
+ tmp.name = UIName; \
+ tmp.description = UIDesc; \
+ tmp.icon = ICON_NONE; \
+ RNA_enum_item_add(&item, &totitem, &tmp); \
+ }
+ #include "../../nodes/NOD_static_types.h"
+ #undef DefNode
+ }
+
+ if (RNA_struct_is_a(ptr->type, &RNA_CompositorNode)) {
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (strcmp(#Category, "CompositorNode")==0) { \
+ tmp.value = ID; \
+ tmp.identifier = EnumName; \
+ tmp.name = UIName; \
+ tmp.description = UIDesc; \
+ tmp.icon = ICON_NONE; \
+ RNA_enum_item_add(&item, &totitem, &tmp); \
+ }
+ #include "../../nodes/NOD_static_types.h"
+ #undef DefNode
+ }
+
+ if (RNA_struct_is_a(ptr->type, &RNA_TextureNode)) {
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ if (strcmp(#Category, "TextureNode")==0) { \
+ tmp.value = ID; \
+ tmp.identifier = EnumName; \
+ tmp.name = UIName; \
+ tmp.description = UIDesc; \
+ tmp.icon = ICON_NONE; \
+ RNA_enum_item_add(&item, &totitem, &tmp); \
+ }
+ #include "../../nodes/NOD_static_types.h"
+ #undef DefNode
}
+
+ RNA_enum_item_end(&item, &totitem);
+ *free = 1;
+
+ return item;
}
+/* ******** Node Tree ******** */
+
static StructRNA *rna_NodeTree_refine(struct PointerRNA *ptr)
{
+ bNodeTree *ntree= (bNodeTree*)ptr->data;
+
+ if (ntree->typeinfo && ntree->typeinfo->ext.srna)
+ return ntree->typeinfo->ext.srna;
+ else
+ return &RNA_NodeTree;
+}
+
+static int rna_NodeTree_poll(const bContext *C, bNodeTreeType *ntreetype)
+{
+ extern FunctionRNA rna_NodeTree_poll_func;
+
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+ int visible;
+
+ RNA_pointer_create(NULL, ntreetype->ext.srna, NULL, &ptr); /* dummy */
+ func = &rna_NodeTree_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ ntreetype->ext.call((bContext *)C, &ptr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "visible", &ret);
+ visible = *(int*)ret;
+
+ RNA_parameter_list_free(&list);
+
+ return visible;
+}
+
+static void rna_NodeTree_draw_add_menu(const bContext *C, struct uiLayout *layout, bNodeTree *ntree)
+{
+ extern FunctionRNA rna_NodeTree_draw_add_menu_func;
+
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!ntreeIsValid(ntree))
+ return;
+
+ RNA_id_pointer_create(&ntree->id, &ptr);
+ func = &rna_NodeTree_draw_add_menu_func; /* RNA_struct_find_function(&ptr, "draw_add_menu"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ RNA_parameter_set_lookup(&list, "layout", &layout);
+ ntree->typeinfo->ext.call((bContext *)C, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_NodeTree_get_from_context(const bContext *C, bNodeTreeType *ntreetype,
+ bNodeTree **r_ntree, ID **r_id, ID **r_from)
+{
+ extern FunctionRNA rna_NodeTree_get_from_context_func;
+
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret1, *ret2, *ret3;
+
+ RNA_pointer_create(NULL, ntreetype->ext.srna, NULL, &ptr); /* dummy */
+ func = &rna_NodeTree_get_from_context_func; /* RNA_struct_find_function(&ptr, "get_from_context"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ ntreetype->ext.call((bContext *)C, &ptr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "result_1", &ret1);
+ RNA_parameter_get_lookup(&list, "result_2", &ret2);
+ RNA_parameter_get_lookup(&list, "result_3", &ret3);
+ *r_ntree = *(bNodeTree **)ret1;
+ *r_id = *(ID **)ret2;
+ *r_from = *(ID **)ret3;
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_NodeTree_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+ bNodeTreeType *nt= RNA_struct_blender_type_get(type);
+
+ if(!nt)
+ return;
+
+ RNA_struct_free_extension(type, &nt->ext);
+
+ ntreeTypeFreeLink(nt);
+
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+}
+
+static StructRNA *rna_NodeTree_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeTreeType *nt, dummynt;
+ bNodeTree dummyntree;
+ PointerRNA dummyptr;
+ int have_function[3];
+
+ /* setup dummy tree & tree type to store static properties in */
+ memset(&dummynt, 0, sizeof(bNodeTreeType));
+ memset(&dummyntree, 0, sizeof(bNodeTree));
+ dummyntree.typeinfo= &dummynt;
+ RNA_pointer_create(NULL, &RNA_NodeTree, &dummyntree, &dummyptr);
+
+ /* validate the python class */
+ if(validate(&dummyptr, data, have_function) != 0)
+ return NULL;
+
+ if(strlen(identifier) >= sizeof(dummynt.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "registering node tree class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummynt.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this tree type before, and remove it */
+ nt= ntreeTypeFind(dummynt.idname);
+ if(nt)
+ rna_NodeTree_unregister(bmain, nt->ext.srna);
+
+ /* create a new node tree type */
+ nt= MEM_callocN(sizeof(bNodeTreeType), "node tree type");
+ memcpy(nt, &dummynt, sizeof(dummynt));
+
+ nt->type = NTREE_CUSTOM;
+
+ nt->ext.srna= RNA_def_struct_ptr(&BLENDER_RNA, nt->idname, &RNA_NodeTree);
+ nt->ext.data= data;
+ nt->ext.call= call;
+ nt->ext.free= free;
+ RNA_struct_blender_type_set(nt->ext.srna, nt);
+
+ RNA_def_struct_ui_text(nt->ext.srna, nt->ui_name, nt->ui_description);
+ RNA_def_struct_ui_icon(nt->ext.srna, nt->ui_icon);
+
+ nt->poll = (have_function[0]) ? rna_NodeTree_poll : NULL;
+ nt->draw_add_menu = (have_function[1]) ? rna_NodeTree_draw_add_menu : NULL;
+ nt->get_from_context = (have_function[2]) ? rna_NodeTree_get_from_context : NULL;
+
+ ntreeTypeAdd(nt);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return nt->ext.srna;
+}
+
+static void rna_NodeTree_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+
+ /* when using border, make it so no old data from outside of
+ * border is hanging around
+ * ideally shouldn't be in RNA callback, but how to teach
+ * compo to only clear frame when border usage is actually
+ * toggling
+ */
+ if (ntree->flag & NTREE_VIEWER_BORDER) {
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ if (ibuf->rect)
+ memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y);
+
+ if (ibuf->rect_float)
+ memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float));
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
+
+ WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
+
+ ED_node_tag_update_nodetree(bmain, ntree);
+}
+
+static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *reports, const char *type)
+{
+ bNodeType *ntype;
+ bNode *node;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return NULL;
+ }
+
+ ntype = nodeTypeFind(type);
+ if (!ntype) {
+ BKE_reportf(reports, RPT_ERROR, "Node type %s undefined", type);
+ return NULL;
+ }
+
+ if (ntype->poll && !ntype->poll(ntype, ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Cannot add node of type %s to node tree '%s'", type, ntree->id.name+2);
+ return NULL;
+ }
+
+ node = nodeAddNode(C, ntree, type);
+ BLI_assert(node && node->typeinfo);
+
+ /* XXX ugly stuff, should be done with specialized operators (after actual node creation)! */
+ if (ntree->type==NTREE_COMPOSIT) {
+ if(ELEM4(node->type, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE, CMP_NODE_R_LAYERS)) {
+ /* annoying, find the node tree we are in, scene can be NULL */
+ Scene *scene;
+ for(scene= CTX_data_main(C)->scene.first; scene; scene= scene->id.next) {
+ if(scene->nodetree == ntree) {
+ break;
+ }
+ }
+ node->id= (ID *)scene;
+ id_us_plus(node->id);
+ }
+
+ ntreeCompositForceHidden(ntree, CTX_data_scene(C));
+ }
+ else if (ntree->type==NTREE_TEXTURE) {
+ ntreeTexCheckCyclics(ntree);
+ }
+
+ ntreeUpdateTree(ntree);
+ nodeUpdate(ntree, node);
+ WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
+
+ return node;
+}
+
+static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *node_ptr)
+{
+ bNode *node = node_ptr->data;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return;
+ }
+
+ if (BLI_findindex(&ntree->nodes, node) == -1) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in node tree", node->name);
+ return;
+ }
+
+ id_us_min(node->id);
+ nodeFreeNode(ntree, node);
+ RNA_POINTER_INVALIDATE(node_ptr);
+
+ ntreeUpdateTree(ntree); /* update group node socket links */
+ WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
+}
+
+static void rna_NodeTree_node_clear(bNodeTree *ntree, ReportList *reports)
+{
+ bNode *node = ntree->nodes.first;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return;
+ }
+
+ while (node) {
+ bNode *next_node = node->next;
+
+ if (node->id)
+ id_us_min(node->id);
+
+ nodeFreeNode(ntree, node);
+
+ node = next_node;
+ }
+
+ ntreeUpdateTree(ntree);
+
+ WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
+}
+
+static PointerRNA rna_NodeTree_active_node_get(PointerRNA *ptr)
+{
bNodeTree *ntree = (bNodeTree *)ptr->data;
+ bNode *node = nodeGetActive(ntree);
+ return rna_pointer_inherit_refine(ptr, &RNA_Node, node);
+}
- switch (ntree->type) {
- case NTREE_SHADER:
- return &RNA_ShaderNodeTree;
- case NTREE_COMPOSIT:
- return &RNA_CompositorNodeTree;
- case NTREE_TEXTURE:
- return &RNA_TextureNodeTree;
- default:
- return &RNA_NodeTree;
+static void rna_NodeTree_active_node_set(PointerRNA *ptr, const PointerRNA value)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->data;
+ bNode *node = (bNode *)value.data;
+
+ /* activating node might require valid typeinfo */
+ if (!ntreeIsValid(ntree))
+ return;
+
+ if (node && BLI_findindex(&ntree->nodes, node) != -1)
+ nodeSetActive(ntree, node);
+ else
+ nodeClearActive(ntree);
+}
+
+static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports,
+ bNodeSocket *fromsock, bNodeSocket *tosock,
+ int verify_limits)
+{
+ bNodeLink *ret;
+ bNode *fromnode = NULL, *tonode = NULL;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return NULL;
+ }
+
+ nodeFindNode(ntree, fromsock, &fromnode, NULL);
+ nodeFindNode(ntree, tosock, &tonode, NULL);
+
+ if (&fromsock->in_out == &tosock->in_out) {
+ BKE_report(reports, RPT_ERROR, "Same input/output direction of sockets");
+ return NULL;
+ }
+
+ if (verify_limits) {
+ /* remove other socket links if limit is exceeded */
+ if (nodeCountSocketLinks(ntree, fromsock) > fromsock->limit)
+ nodeRemSocketLinks(ntree, fromsock);
+ if (nodeCountSocketLinks(ntree, tosock) > tosock->limit)
+ nodeRemSocketLinks(ntree, tosock);
+ }
+
+ ret = nodeAddLink(ntree, fromnode, fromsock, tonode, tosock);
+
+ if (ret) {
+ if (tonode)
+ nodeUpdate(ntree, tonode);
+
+ ntreeUpdateTree(ntree);
+
+ WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
+ return ret;
}
-static char *rna_Node_path(PointerRNA *ptr)
+static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *link_ptr)
+{
+ bNodeLink *link = link_ptr->data;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return;
+ }
+
+ if (BLI_findindex(&ntree->links, link) == -1) {
+ BKE_report(reports, RPT_ERROR, "Unable to locate link in node tree");
+ return;
+ }
+
+ nodeRemLink(ntree, link);
+ RNA_POINTER_INVALIDATE(link_ptr);
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
+}
+
+static void rna_NodeTree_link_clear(bNodeTree *ntree, ReportList *reports)
+{
+ bNodeLink *link = ntree->links.first;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return;
+ }
+
+ while (link) {
+ bNodeLink *next_link = link->next;
+
+ nodeRemLink(ntree, link);
+
+ link = next_link;
+ }
+ ntreeUpdateTree(ntree);
+
+ WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
+}
+
+static int rna_NodeTree_active_input_get(PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree*)ptr->data;
+ bNodeSocket *gsock;
+ int index;
+
+ for (gsock = ntree->inputs.first, index = 0; gsock; gsock = gsock->next, ++index)
+ if (gsock->flag & SELECT)
+ return index;
+ return -1;
+}
+
+static void rna_NodeTree_active_input_set(PointerRNA *ptr, int value)
+{
+ bNodeTree *ntree = (bNodeTree*)ptr->data;
+ bNodeSocket *gsock;
+ int index;
+
+ for (gsock = ntree->inputs.first, index = 0; gsock; gsock = gsock->next, ++index) {
+ if (index == value)
+ gsock->flag |= SELECT;
+ else
+ gsock->flag &= ~SELECT;
+ }
+ for (gsock = ntree->outputs.first; gsock; gsock = gsock->next) {
+ gsock->flag &= ~SELECT;
+ }
+}
+
+static int rna_NodeTree_active_output_get(PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree*)ptr->data;
+ bNodeSocket *gsock;
+ int index;
+
+ for (gsock = ntree->outputs.first, index = 0; gsock; gsock = gsock->next, ++index)
+ if (gsock->flag & SELECT)
+ return index;
+ return -1;
+}
+
+static void rna_NodeTree_active_output_set(PointerRNA *ptr, int value)
+{
+ bNodeTree *ntree = (bNodeTree*)ptr->data;
+ bNodeSocket *gsock;
+ int index;
+
+ for (gsock = ntree->inputs.first; gsock; gsock = gsock->next) {
+ gsock->flag &= ~SELECT;
+ }
+ for (gsock = ntree->outputs.first, index = 0; gsock; gsock = gsock->next, ++index) {
+ if (index == value)
+ gsock->flag |= SELECT;
+ else
+ gsock->flag &= ~SELECT;
+ }
+}
+
+static int rna_NodeTree_inputs_lookupstring(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->data;
+ bNodeSocket *sock = ntreeFindSocketInterface(ntree, SOCK_IN, key);
+ RNA_pointer_create(ptr->id.data, &RNA_NodeSocketInterface, sock, r_ptr);
+ return (sock != NULL);
+}
+
+static int rna_NodeTree_outputs_lookupstring(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->data;
+ bNodeSocket *sock = ntreeFindSocketInterface(ntree, SOCK_OUT, key);
+ RNA_pointer_create(ptr->id.data, &RNA_NodeSocketInterface, sock, r_ptr);
+ return (sock != NULL);
+}
+
+static bNodeSocket *rna_NodeTree_inputs_new(bNodeTree *ntree, ReportList *reports, const char *type, const char *name)
+{
+ bNodeSocket *sock;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return NULL;
+ }
+
+ sock = ntreeAddSocketInterface(ntree, SOCK_IN, type, name);
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+
+ return sock;
+}
+
+static bNodeSocket *rna_NodeTree_outputs_new(bNodeTree *ntree, ReportList *reports, const char *type, const char *name)
+{
+ bNodeSocket *sock;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return NULL;
+ }
+
+ sock = ntreeAddSocketInterface(ntree, SOCK_OUT, type, name);
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+
+ return sock;
+}
+
+static void rna_NodeTree_socket_remove(bNodeTree *ntree, ReportList *reports, bNodeSocket *sock)
+{
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return;
+ }
+
+ if (BLI_findindex(&ntree->inputs, sock) == -1 && BLI_findindex(&ntree->outputs, sock) == -1) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to locate socket '%s' in node", sock->identifier);
+ }
+ else {
+ ntreeRemoveSocketInterface(ntree, sock);
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+ }
+}
+
+static void rna_NodeTree_inputs_clear(bNodeTree *ntree, ReportList *reports)
+{
+ bNodeSocket *sock, *nextsock;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return;
+ }
+
+ for (sock = ntree->inputs.first; sock; sock = nextsock) {
+ nextsock = sock->next;
+ ntreeRemoveSocketInterface(ntree, sock);
+ }
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+}
+
+static void rna_NodeTree_outputs_clear(bNodeTree *ntree, ReportList *reports)
+{
+ bNodeSocket *sock, *nextsock;
+
+ if (!ntreeIsValid(ntree)) {
+ BKE_reportf(reports, RPT_ERROR, "Node tree %s invalid", ntree->id.name+2);
+ return;
+ }
+
+ for (sock = ntree->outputs.first; sock; sock = nextsock) {
+ nextsock = sock->next;
+ ntreeRemoveSocketInterface(ntree, sock);
+ }
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+}
+
+static void rna_NodeTree_interface_update(bNodeTree *ntree, bContext *C)
+{
+ if (!ntreeIsValid(ntree))
+ return;
+
+ ntree->update |= NTREE_UPDATE_GROUP;
+ ntreeUpdateTree(ntree);
+
+ ED_node_tag_update_nodetree(CTX_data_main(C), ntree);
+}
+
+static void rna_NodeTree_bl_idname_get(PointerRNA *ptr, char *value)
+{
+ bNodeTree *ntree = ptr->data;
+ if (ntree->typeinfo)
+ strcpy(value, ntree->typeinfo->idname);
+ else
+ strcpy(value, "UNDEFINED");
+}
+static int rna_NodeTree_bl_idname_length(PointerRNA *ptr)
+{
+ bNodeTree *ntree = ptr->data;
+ if (ntree->typeinfo)
+ return strlen(ntree->typeinfo->idname);
+ else
+ return strlen("UNDEFINED");
+}
+
+static void rna_NodeTree_bl_label_get(PointerRNA *ptr, char *value)
+{
+ bNodeTree *ntree = ptr->data;
+ if (ntree->typeinfo)
+ strcpy(value, ntree->typeinfo->ui_name);
+ else
+ strcpy(value, "UNDEFINED");
+}
+static int rna_NodeTree_bl_label_length(PointerRNA *ptr)
+{
+ bNodeTree *ntree = ptr->data;
+ if (ntree->typeinfo)
+ return strlen(ntree->typeinfo->ui_name);
+ else
+ return strlen("UNDEFINED");
+}
+
+static void rna_NodeTree_bl_description_get(PointerRNA *ptr, char *value)
+{
+ bNodeTree *ntree = ptr->data;
+ if (ntree->typeinfo)
+ strcpy(value, ntree->typeinfo->ui_description);
+ else
+ strcpy(value, "UNDEFINED");
+}
+static int rna_NodeTree_bl_description_length(PointerRNA *ptr)
+{
+ bNodeTree *ntree = ptr->data;
+ if (ntree->typeinfo)
+ return strlen(ntree->typeinfo->ui_description);
+ else
+ return strlen("UNDEFINED");
+}
+
+static int rna_NodeTree_bl_icon_get(PointerRNA *ptr)
+{
+ bNodeTree *ntree = ptr->data;
+ if (ntree->typeinfo)
+ return ntree->typeinfo->ui_icon;
+ else
+ return ICON_NONE;
+}
+
+
+/* ******** NodeLink ******** */
+
+static int rna_NodeLink_is_hidden_get(PointerRNA *ptr)
+{
+ bNodeLink *link = ptr->data;
+ return nodeLinkIsHidden(link);
+}
+
+
+/* ******** Node ******** */
+
+static StructRNA *rna_Node_refine(struct PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
+
+ if (node->typeinfo && node->typeinfo->ext.srna)
+ return node->typeinfo->ext.srna;
+ else
+ return ptr->type;
+}
+
+static char *rna_Node_path(PointerRNA *ptr)
+{
+ bNode *node = (bNode*)ptr->data;
return BLI_sprintfN("nodes[\"%s\"]", node->name);
}
-static const char *rna_Node_get_node_type(StructRNA *type)
+static int rna_Node_poll(bNodeType *ntype, bNodeTree *ntree)
{
- bNodeType *nodetype = RNA_struct_blender_type_get(type);
- if (nodetype) {
- /* XXX hack: with customnodes branch, nodes will use an identifier string instead of integer ID.
- * Then this can be returned directly instead of doing this ugly include thingy ...
- */
- #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
- if (ID == nodetype->type) { \
- return EnumName; \
- }
-
- #include "rna_nodetree_types.h"
+ extern FunctionRNA rna_Node_poll_func;
+
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+ int visible;
+
+ RNA_pointer_create(NULL, ntype->ext.srna, NULL, &ptr); /* dummy */
+ func = &rna_Node_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "node_tree", &ntree);
+ ntype->ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "visible", &ret);
+ visible = *(int*)ret;
+
+ RNA_parameter_list_free(&list);
+
+ return visible;
+}
+
+static int rna_Node_poll_instance(bNode *node, bNodeTree *ntree)
+{
+ extern FunctionRNA rna_Node_poll_instance_func;
+
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+ int visible;
+
+ if (!node->typeinfo)
+ return FALSE;
+
+ RNA_pointer_create(NULL, node->typeinfo->ext.srna, node, &ptr); /* dummy */
+ func = &rna_Node_poll_instance_func; /* RNA_struct_find_function(&ptr, "poll_instance"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "node_tree", &ntree);
+ node->typeinfo->ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "visible", &ret);
+ visible = *(int*)ret;
+
+ RNA_parameter_list_free(&list);
+
+ return visible;
+}
+
+static int rna_Node_poll_instance_default(bNode *node, bNodeTree *ntree)
+{
+ if (!node->typeinfo)
+ return FALSE;
+
+ /* use the basic poll function */
+ return rna_Node_poll(node->typeinfo, ntree);
+}
+
+static void rna_Node_update_reg(bNodeTree *ntree, bNode *node)
+{
+ extern FunctionRNA rna_Node_update_func;
+
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!node->typeinfo)
+ return;
+
+ RNA_pointer_create((ID *)ntree, node->typeinfo->ext.srna, node, &ptr);
+ func = &rna_Node_update_func; /* RNA_struct_find_function(&ptr, "update"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ node->typeinfo->ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_Node_init(const bContext *C, PointerRNA *ptr)
+{
+ extern FunctionRNA rna_Node_init_func;
+
+ bNode *node = (bNode *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!node->typeinfo)
+ return;
+
+ func = &rna_Node_init_func; /* RNA_struct_find_function(&ptr, "init"); */
+
+ RNA_parameter_list_create(&list, ptr, func);
+ node->typeinfo->ext.call((bContext *)C, ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_Node_copy(PointerRNA *ptr, struct bNode *copynode)
+{
+ extern FunctionRNA rna_Node_copy_func;
+
+ bNode *node = (bNode *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!node->typeinfo)
+ return;
+
+ func = &rna_Node_copy_func; /* RNA_struct_find_function(&ptr, "copy"); */
+
+ RNA_parameter_list_create(&list, ptr, func);
+ RNA_parameter_set_lookup(&list, "node", &copynode);
+ node->typeinfo->ext.call(NULL, ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_Node_free(PointerRNA *ptr)
+{
+ extern FunctionRNA rna_Node_free_func;
+
+ bNode *node = (bNode *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!node->typeinfo)
+ return;
+
+ func = &rna_Node_free_func; /* RNA_struct_find_function(&ptr, "free"); */
+
+ RNA_parameter_list_create(&list, ptr, func);
+ node->typeinfo->ext.call(NULL, ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_Node_draw_buttons(struct uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ extern FunctionRNA rna_Node_draw_buttons_func;
+
+ bNode *node = (bNode *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!node->typeinfo)
+ return;
+
+ func = &rna_Node_draw_buttons_func; /* RNA_struct_find_function(&ptr, "draw_buttons"); */
+
+ RNA_parameter_list_create(&list, ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ RNA_parameter_set_lookup(&list, "layout", &layout);
+ node->typeinfo->ext.call(C, ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_Node_draw_buttons_ext(struct uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ extern FunctionRNA rna_Node_draw_buttons_ext_func;
+
+ bNode *node = (bNode *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!node->typeinfo)
+ return;
+
+ func = &rna_Node_draw_buttons_ext_func; /* RNA_struct_find_function(&ptr, "draw_buttons_ext"); */
+
+ RNA_parameter_list_create(&list, ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ RNA_parameter_set_lookup(&list, "layout", &layout);
+ node->typeinfo->ext.call(C, ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
+static int rna_Node_is_registered_node_type(StructRNA *type)
+{
+ return (RNA_struct_blender_type_get(type) != NULL);
+}
+
+static void rna_Node_is_registered_node_type_runtime(bContext *UNUSED(C), ReportList *UNUSED(reports), PointerRNA *ptr, ParameterList *parms)
+{
+ int result = (RNA_struct_blender_type_get(ptr->type) != NULL);
+ RNA_parameter_set_lookup(parms, "result", &result);
+}
+
+static void rna_Node_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+ bNodeType *nt= RNA_struct_blender_type_get(type);
+
+ if(!nt)
+ return;
+
+ RNA_struct_free_extension(type, &nt->ext);
+
+ /* this also frees the allocated nt pointer, no MEM_free call needed! */
+ nodeUnregisterType(nt);
+
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+}
+
+/* Generic internal registration function.
+ * Can be used to implement callbacks for registerable RNA node subtypes.
+ */
+static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, StructRNA *basetype,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeType *nt, dummynt;
+ bNode dummynode;
+ PointerRNA dummyptr;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+ int have_function[8];
+
+ /* setup dummy node & node type to store static properties in */
+ memset(&dummynt, 0, sizeof(bNodeType));
+ /* this does some additional initialization of default values */
+ node_type_base_custom(&dummynt, identifier, "", 0, 0);
+
+ memset(&dummynode, 0, sizeof(bNode));
+ dummynode.typeinfo= &dummynt;
+ RNA_pointer_create(NULL, basetype, &dummynode, &dummyptr);
+
+ /* validate the python class */
+ if(validate(&dummyptr, data, have_function) != 0)
+ return NULL;
+
+ if(strlen(identifier) >= sizeof(dummynt.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "registering node class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummynt.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this node type before, and remove it */
+ nt= nodeTypeFind(dummynt.idname);
+ if(nt)
+ rna_Node_unregister(bmain, nt->ext.srna);
+
+ /* create a new node type */
+ nt= MEM_callocN(sizeof(bNodeType), "node type");
+ memcpy(nt, &dummynt, sizeof(dummynt));
+ /* make sure the node type struct is freed on unregister */
+ nt->needs_free = 1;
+
+ nt->ext.srna= RNA_def_struct_ptr(&BLENDER_RNA, nt->idname, basetype);
+ nt->ext.data= data;
+ nt->ext.call= call;
+ nt->ext.free= free;
+ RNA_struct_blender_type_set(nt->ext.srna, nt);
+
+ RNA_def_struct_ui_text(nt->ext.srna, nt->ui_name, nt->ui_description);
+ RNA_def_struct_ui_icon(nt->ext.srna, nt->ui_icon);
+
+ func = RNA_def_function_runtime(nt->ext.srna, "is_registered_node_type", rna_Node_is_registered_node_type_runtime);
+ RNA_def_function_ui_description(func, "True if a registered node type");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
+ parm = RNA_def_boolean(func, "result", FALSE, "Result", "");
+ RNA_def_function_return(func, parm);
+
+ /* XXX bad level call! needed to initialize the basic draw functions ... */
+ ED_init_custom_node_type(nt);
+
+ nt->poll = (have_function[0]) ? rna_Node_poll : NULL;
+ nt->poll_instance = (have_function[1]) ? rna_Node_poll_instance : rna_Node_poll_instance_default;
+ nt->updatefunc = (have_function[2]) ? rna_Node_update_reg : NULL;
+ nt->initfunc_api = (have_function[3]) ? rna_Node_init : NULL;
+ nt->copyfunc_api = (have_function[4]) ? rna_Node_copy : NULL;
+ nt->freefunc_api = (have_function[5]) ? rna_Node_free : NULL;
+ nt->uifunc = (have_function[6]) ? rna_Node_draw_buttons : NULL;
+ nt->uifuncbut = (have_function[7]) ? rna_Node_draw_buttons_ext : NULL;
+ /* node buttons are only drawn if the options flag is set */
+ if (nt->uifunc || nt->uifuncbut)
+ nt->flag |= NODE_OPTIONS;
+
+ return nt;
+}
+
+static StructRNA *rna_Node_register(Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_Node, data, identifier, validate, call, free);
+ if (!nt)
+ return NULL;
+
+ nodeRegisterType(nt);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return nt->ext.srna;
+}
+
+static StructRNA *rna_NodeGroup_register(Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_NodeGroup, data, identifier, validate, call, free);
+ if (!nt)
+ return NULL;
+
+ nodeRegisterType(nt);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return nt->ext.srna;
+}
+
+static StructRNA *rna_ShaderNode_register(Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_ShaderNode, data, identifier, validate, call, free);
+ if (!nt)
+ return NULL;
+
+ nodeRegisterType(nt);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return nt->ext.srna;
+}
+
+static StructRNA *rna_CompositorNode_register(Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_CompositorNode, data, identifier, validate, call, free);
+ if (!nt)
+ return NULL;
+
+ nodeRegisterType(nt);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return nt->ext.srna;
+}
+
+static StructRNA *rna_TextureNode_register(Main *bmain, ReportList *reports,
+ void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeType *nt = rna_Node_register_base(bmain, reports, &RNA_TextureNode, data, identifier, validate, call, free);
+ if (!nt)
+ return NULL;
+
+ nodeRegisterType(nt);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return nt->ext.srna;
+}
+
+static IDProperty *rna_Node_idprops(PointerRNA *ptr, bool create)
+{
+ bNode *node = ptr->data;
+
+ if (create && !node->prop) {
+ IDPropertyTemplate val = {0};
+ node->prop = IDP_New(IDP_GROUP, &val, "RNA_Node ID properties");
}
- return "";
+
+ return node->prop;
}
static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value)
@@ -330,47 +1576,388 @@ static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value)
return TRUE;
}
-static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
+static void rna_Node_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
- bNodeSocket *sock = (bNodeSocket *)ptr->data;
+ bNodeTree *ntree = (bNodeTree*)ptr->id.data;
+ ED_node_tag_update_nodetree(bmain, ntree);
+}
+
+static void rna_Node_socket_value_update(ID *id, bNode *UNUSED(node), bContext *C)
+{
+ ED_node_tag_update_nodetree(CTX_data_main(C), (bNodeTree *)id);
+}
+
+static void rna_Node_select_set(PointerRNA *ptr, int value)
+{
+ bNode *node= (bNode*)ptr->data;
+ nodeSetSelected(node, value);
+}
+
+static void rna_Node_name_set(PointerRNA *ptr, const char *value)
+{
+ bNodeTree *ntree = (bNodeTree*)ptr->id.data;
+ bNode *node = (bNode*)ptr->data;
+ char oldname[sizeof(node->name)];
- if (sock->default_value) {
- /* This returns the refined socket type with the full definition
- * of the default input value with type and subtype.
- */
-
- #define SUBTYPE(socktype, stypename, id, idname) \
- { \
- bNodeSocketValue##stypename *value = (bNodeSocketValue##stypename *)sock->default_value; \
- if (value->subtype == PROP_##id) \
- return &RNA_NodeSocket##stypename##idname; \
- }
+ /* make a copy of the old name first */
+ BLI_strncpy(oldname, node->name, sizeof(node->name));
+ /* set new name */
+ BLI_strncpy_utf8(node->name, value, sizeof(node->name));
+
+ nodeUniqueName(ntree, node);
+
+ /* fix all the animation data which may link to this */
+ BKE_all_animdata_fix_paths_rename(NULL, "nodes", oldname, node->name);
+}
+
+static int rna_Node_inputs_lookupstring(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ bNodeSocket *sock = nodeFindSocket(node, SOCK_IN, key);
+ RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, sock, r_ptr);
+ return (sock != NULL);
+}
+
+static int rna_Node_outputs_lookupstring(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ bNodeSocket *sock = nodeFindSocket(node, SOCK_OUT, key);
+ RNA_pointer_create(ptr->id.data, &RNA_NodeSocket, sock, r_ptr);
+ return (sock != NULL);
+}
+
+static bNodeSocket *rna_Node_inputs_new(ID *id, bNode *node, ReportList *reports, const char *type, const char *name, const char *identifier)
+{
+ bNodeTree *ntree = (bNodeTree *)id;
+ bNodeSocket *sock;
+
+ if (!node->typeinfo) {
+ BKE_reportf(reports, RPT_ERROR, "Node type %s of node %s undefined", node->idname, node->name);
+ return NULL;
+ }
+
+ sock = nodeAddSocket(ntree, node, SOCK_IN, type, identifier, name);
+
+ if (sock == NULL) {
+ BKE_report(reports, RPT_ERROR, "Unable to create socket");
+ }
+ else {
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+ }
+
+ return sock;
+}
+
+static bNodeSocket *rna_Node_outputs_new(ID *id, bNode *node, ReportList *reports, const char *type, const char *name, const char *identifier)
+{
+ bNodeTree *ntree = (bNodeTree *)id;
+ bNodeSocket *sock;
+
+ if (!node->typeinfo) {
+ BKE_reportf(reports, RPT_ERROR, "Node type %s of node %s undefined", node->idname, node->name);
+ return NULL;
+ }
+
+ sock = nodeAddSocket(ntree, node, SOCK_OUT, type, identifier, name);
+
+ if (sock == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to create socket");
+ }
+ else {
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+ }
+
+ return sock;
+}
+
+static void rna_Node_socket_remove(ID *id, bNode *node, ReportList *reports, bNodeSocket *sock)
+{
+ bNodeTree *ntree = (bNodeTree *)id;
+
+ if (!node->typeinfo) {
+ BKE_reportf(reports, RPT_ERROR, "Node type %s of node %s undefined", node->idname, node->name);
+ return;
+ }
+
+ if (BLI_findindex(&node->inputs, sock) == -1 && BLI_findindex(&node->outputs, sock) == -1) {
+ BKE_reportf(reports, RPT_ERROR, "Unable to locate socket '%s' in node", sock->identifier);
+ }
+ else {
+ nodeRemoveSocket(ntree, node, sock);
- switch (sock->type) {
- case SOCK_FLOAT:
- NODE_DEFINE_SUBTYPES_FLOAT
- break;
- case SOCK_INT:
- NODE_DEFINE_SUBTYPES_INT
- break;
- case SOCK_BOOLEAN:
- return &RNA_NodeSocketBoolean;
- case SOCK_VECTOR:
- NODE_DEFINE_SUBTYPES_VECTOR
- break;
- case SOCK_STRING:
- NODE_DEFINE_SUBTYPES_STRING
- break;
- case SOCK_RGBA:
- return &RNA_NodeSocketRGBA;
- case SOCK_SHADER:
- return &RNA_NodeSocketShader;
- }
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+ }
+}
+
+static void rna_Node_inputs_clear(ID *id, bNode *node, ReportList *reports)
+{
+ bNodeTree *ntree = (bNodeTree *)id;
+ bNodeSocket *sock, *nextsock;
+
+ if (!node->typeinfo) {
+ BKE_reportf(reports, RPT_ERROR, "Node type %s of node %s undefined", node->idname, node->name);
+ return;
+ }
+
+ for (sock = node->inputs.first; sock; sock = nextsock) {
+ nextsock = sock->next;
+ nodeRemoveSocket(ntree, node, sock);
+ }
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+}
+
+static void rna_Node_outputs_clear(ID *id, bNode *node, ReportList *reports)
+{
+ bNodeTree *ntree = (bNodeTree *)id;
+ bNodeSocket *sock, *nextsock;
+
+ if (!node->typeinfo) {
+ BKE_reportf(reports, RPT_ERROR, "Node type %s of node %s undefined", node->idname, node->name);
+ return;
+ }
+
+ for (sock = node->outputs.first; sock; sock = nextsock) {
+ nextsock = sock->next;
+ nodeRemoveSocket(ntree, node, sock);
+ }
+
+ ntreeUpdateTree(ntree);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree);
+}
+
+static void rna_Node_width_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+{
+ bNode *node = ptr->data;
+ if (node->typeinfo) {
+ *min = *softmin = node->typeinfo->minwidth;
+ *max = *softmax = node->typeinfo->maxwidth;
+ }
+ else {
+ *min = *softmin = 0.0f;
+ *max = *softmax = 0.0f;
+ }
+}
+
+static void rna_Node_height_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+{
+ bNode *node = ptr->data;
+ if (node->typeinfo) {
+ *min = *softmin = node->typeinfo->minheight;
+ *max = *softmax = node->typeinfo->maxheight;
+ }
+ else {
+ *min = *softmin = 0.0f;
+ *max = *softmax = 0.0f;
+ }
+}
+
+static void rna_Node_bl_idname_get(PointerRNA *ptr, char *value)
+{
+ bNode *node= ptr->data;
+ if (node->typeinfo)
+ strcpy(value, node->typeinfo->idname);
+ else
+ strcpy(value, "UNDEFINED");
+}
+static int rna_Node_bl_idname_length(PointerRNA *ptr)
+{
+ bNode *node = ptr->data;
+ if (node->typeinfo)
+ return strlen(node->typeinfo->idname);
+ else
+ return strlen("UNDEFINED");
+}
+
+static void rna_Node_bl_label_get(PointerRNA *ptr, char *value)
+{
+ bNode *node= ptr->data;
+ if (node->typeinfo)
+ strcpy(value, node->typeinfo->ui_name);
+ else
+ strcpy(value, "UNDEFINED");
+}
+static int rna_Node_bl_label_length(PointerRNA *ptr)
+{
+ bNode *node = ptr->data;
+ if (node->typeinfo)
+ return strlen(node->typeinfo->ui_name);
+ else
+ return strlen("UNDEFINED");
+}
+
+static void rna_Node_bl_description_get(PointerRNA *ptr, char *value)
+{
+ bNode *node= ptr->data;
+ if (node->typeinfo)
+ strcpy(value, node->typeinfo->ui_description);
+ else
+ strcpy(value, "");
+}
+static int rna_Node_bl_description_length(PointerRNA *ptr)
+{
+ bNode *node = ptr->data;
+ if (node->typeinfo)
+ return strlen(node->typeinfo->ui_description);
+ else
+ return strlen("");
+}
+
+static int rna_Node_bl_icon_get(PointerRNA *ptr)
+{
+ bNode *node = ptr->data;
+ if (node->typeinfo)
+ return node->typeinfo->ui_icon;
+ else
+ return ICON_NONE;
+}
+
+static int rna_Node_bl_static_type_get(PointerRNA *ptr)
+{
+ bNode *node = ptr->data;
+ if (node->typeinfo)
+ return node->typeinfo->type;
+ else
+ return NODE_UNDEFINED;
+}
+
+
+/* ******** Node Socket ******** */
+
+static void rna_NodeSocket_draw(bContext *C, struct uiLayout *layout, PointerRNA *ptr, PointerRNA *node_ptr)
+{
+ extern FunctionRNA rna_NodeSocket_draw_func;
+
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!sock->typeinfo)
+ return;
+
+ 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);
+ 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)
+{
+ extern FunctionRNA rna_NodeSocket_draw_color_func;
+
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+
+ if (!sock->typeinfo)
+ return;
+
+ 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, (float *)ret);
+
+ RNA_parameter_list_free(&list);
+}
+
+static void rna_NodeSocket_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+ bNodeSocketType *st= RNA_struct_blender_type_get(type);
+ if(!st)
+ return;
+
+ RNA_struct_free_extension(type, &st->ext_socket);
+
+ nodeUnregisterSocketType(st);
+
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+}
+
+static StructRNA *rna_NodeSocket_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeSocketType *st, dummyst;
+ bNodeSocket dummysock;
+ PointerRNA dummyptr;
+ int have_function[2];
+
+ /* setup dummy socket & socket type to store static properties in */
+ memset(&dummyst, 0, sizeof(bNodeSocketType));
+
+ memset(&dummysock, 0, sizeof(bNodeSocket));
+ dummysock.typeinfo= &dummyst;
+ RNA_pointer_create(NULL, &RNA_NodeSocket, &dummysock, &dummyptr);
+
+ /* validate the python class */
+ if(validate(&dummyptr, data, have_function) != 0)
+ return NULL;
+
+ if(strlen(identifier) >= sizeof(dummyst.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "registering node socket class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummyst.idname));
+ return NULL;
+ }
+
+ /* check if we have registered this socket type before */
+ st= nodeSocketTypeFind(dummyst.idname);
+ if (!st) {
+ /* create a new node socket type */
+ st= MEM_callocN(sizeof(bNodeSocketType), "node socket type");
+ memcpy(st, &dummyst, sizeof(dummyst));
- #undef SUBTYPE
+ nodeRegisterSocketType(st);
+ }
+
+ /* 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, &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);
- return &RNA_NodeSocket;
+ /* 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 : NULL;
+ st->draw_color = (have_function[1]) ? rna_NodeSocket_draw_color : NULL;
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return st->ext_socket.srna;
+}
+
+static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr)
+{
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
+
+ if (sock->typeinfo && sock->typeinfo->ext_socket.srna)
+ return sock->typeinfo->ext_socket.srna;
+ else
+ return &RNA_NodeSocket;
}
static char *rna_NodeSocket_path(PointerRNA *ptr)
@@ -380,29 +1967,65 @@ static char *rna_NodeSocket_path(PointerRNA *ptr)
bNode *node;
int socketindex;
- /* group sockets */
- socketindex = BLI_findindex(&ntree->inputs, sock);
- if (socketindex != -1)
- return BLI_sprintfN("inputs[%d]", socketindex);
-
- socketindex = BLI_findindex(&ntree->outputs, sock);
- if (socketindex != -1)
- return BLI_sprintfN("outputs[%d]", socketindex);
-
- /* node sockets */
- if (!nodeFindNode(ntree, sock, &node, NULL, NULL)) return NULL;
+ if (!nodeFindNode(ntree, sock, &node, &socketindex))
+ return NULL;
- socketindex = BLI_findindex(&node->inputs, sock);
- if (socketindex != -1)
+ if (sock->in_out == SOCK_IN)
return BLI_sprintfN("nodes[\"%s\"].inputs[%d]", node->name, socketindex);
-
- socketindex = BLI_findindex(&node->outputs, sock);
- if (socketindex != -1)
+ else
return BLI_sprintfN("nodes[\"%s\"].outputs[%d]", node->name, socketindex);
return NULL;
}
+static IDProperty *rna_NodeSocket_idprops(PointerRNA *ptr, bool create)
+{
+ bNodeSocket *sock = ptr->data;
+
+ if (create && !sock->prop) {
+ IDPropertyTemplate val = {0};
+ sock->prop = IDP_New(IDP_GROUP, &val, "RNA_NodeSocket ID properties");
+ }
+
+ return sock->prop;
+}
+
+static void rna_NodeSocket_bl_idname_get(PointerRNA *ptr, char *value)
+{
+ bNodeSocket *sock = ptr->data;
+ if (sock->typeinfo)
+ strcpy(value, sock->typeinfo->idname);
+ else
+ strcpy(value, "UNDEFINED");
+}
+static int rna_NodeSocket_bl_idname_length(PointerRNA *ptr)
+{
+ bNodeSocket *sock = ptr->data;
+ if (sock->typeinfo)
+ return strlen(sock->typeinfo->idname);
+ else
+ return strlen("UNDEFINED");
+}
+
+static PointerRNA rna_NodeSocket_node_get(PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree*)ptr->id.data;
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
+ bNode *node;
+ PointerRNA r_ptr;
+
+ nodeFindNode(ntree, sock, &node, NULL);
+
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &r_ptr);
+ return r_ptr;
+}
+
+static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree*)ptr->id.data;
+ ED_node_tag_update_nodetree(bmain, ntree);
+}
+
static void rna_NodeSocket_hide_set(PointerRNA *ptr, int value)
{
bNodeSocket *sock = (bNodeSocket *)ptr->data;
@@ -417,151 +2040,334 @@ static void rna_NodeSocket_hide_set(PointerRNA *ptr, int value)
sock->flag &= ~SOCK_HIDDEN;
}
-/* Button Set Funcs for Matte Nodes */
-static void rna_Matte_t1_set(PointerRNA *ptr, float value)
+
+static void rna_NodeSocketInterface_draw(bContext *C, struct uiLayout *layout, PointerRNA *ptr)
{
- bNode *node = (bNode *)ptr->data;
- NodeChroma *chroma = node->storage;
-
- chroma->t1 = value;
-
- if (value < chroma->t2)
- chroma->t2 = value;
+ extern FunctionRNA rna_NodeSocketInterface_draw_func;
+
+ bNodeSocket *stemp = (bNodeSocket *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!stemp->typeinfo)
+ return;
+
+ func = &rna_NodeSocketInterface_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);
+ stemp->typeinfo->ext_interface.call(C, ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
}
-static void rna_Matte_t2_set(PointerRNA *ptr, float value)
+static void rna_NodeSocketInterface_draw_color(bContext *C, PointerRNA *ptr, float *r_color)
{
- bNode *node = (bNode *)ptr->data;
- NodeChroma *chroma = node->storage;
-
- if (value > chroma->t1)
- value = chroma->t1;
-
- chroma->t2 = value;
+ extern FunctionRNA rna_NodeSocketInterface_draw_color_func;
+
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+
+ if (!sock->typeinfo)
+ return;
+
+ func = &rna_NodeSocketInterface_draw_color_func; /* RNA_struct_find_function(&ptr, "draw_color"); */
+
+ RNA_parameter_list_create(&list, ptr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ sock->typeinfo->ext_interface.call(C, ptr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "color", &ret);
+ copy_v4_v4(r_color, (float *)ret);
+
+ RNA_parameter_list_free(&list);
}
-static void rna_distance_matte_t1_set(PointerRNA *ptr, float value)
+static void rna_NodeSocketInterface_register_properties(bNodeTree *ntree, bNodeSocket *stemp, StructRNA *data_srna)
{
- bNode *node = (bNode *)ptr->data;
- NodeChroma *chroma = node->storage;
+ extern FunctionRNA rna_NodeSocketInterface_register_properties_func;
- chroma->t1 = value;
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!stemp->typeinfo)
+ return;
+
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, stemp, &ptr);
+ func = &rna_NodeSocketInterface_register_properties_func; /* RNA_struct_find_function(&ptr, "register_properties"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "data_rna_type", &data_srna);
+ stemp->typeinfo->ext_interface.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
}
-static void rna_distance_matte_t2_set(PointerRNA *ptr, float value)
+static void rna_NodeSocketInterface_init_socket(bNodeTree *ntree, bNodeSocket *stemp, bNode *node, bNodeSocket *sock, const char *data_path)
{
- bNode *node = (bNode *)ptr->data;
- NodeChroma *chroma = node->storage;
+ extern FunctionRNA rna_NodeSocketInterface_init_socket_func;
- chroma->t2 = value;
+ PointerRNA ptr, node_ptr, sock_ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!stemp->typeinfo)
+ return;
+
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, stemp, &ptr);
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr);
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sock_ptr);
+ func = &rna_NodeSocketInterface_init_socket_func; /* RNA_struct_find_function(&ptr, "init_socket"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "node", &node_ptr);
+ RNA_parameter_set_lookup(&list, "socket", &sock_ptr);
+ RNA_parameter_set_lookup(&list, "data_path", &data_path);
+ stemp->typeinfo->ext_interface.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
}
-static void rna_difference_matte_t1_set(PointerRNA *ptr, float value)
+static void rna_NodeSocketInterface_from_socket(bNodeTree *ntree, bNodeSocket *stemp, bNode *node, bNodeSocket *sock)
{
- bNode *node = (bNode *)ptr->data;
- NodeChroma *chroma = node->storage;
+ extern FunctionRNA rna_NodeSocketInterface_from_socket_func;
- chroma->t1 = value;
+ PointerRNA ptr, node_ptr, sock_ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ if (!stemp->typeinfo)
+ return;
+
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, stemp, &ptr);
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr);
+ RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sock_ptr);
+ func = &rna_NodeSocketInterface_from_socket_func; /* RNA_struct_find_function(&ptr, "from_socket"); */
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "node", &node_ptr);
+ RNA_parameter_set_lookup(&list, "socket", &sock_ptr);
+ stemp->typeinfo->ext_interface.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
}
-static void rna_difference_matte_t2_set(PointerRNA *ptr, float value)
+static void rna_NodeSocketInterface_unregister(Main *UNUSED(bmain), StructRNA *type)
{
- bNode *node = (bNode *)ptr->data;
- NodeChroma *chroma = node->storage;
+ bNodeSocketType *st= RNA_struct_blender_type_get(type);
+ if(!st)
+ return;
+
+ RNA_struct_free_extension(type, &st->ext_interface);
+
+ RNA_struct_free(&BLENDER_RNA, type);
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+}
- chroma->t2 = value;
+static StructRNA *rna_NodeSocketInterface_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+ bNodeSocketType *st, dummyst;
+ bNodeSocket dummysock;
+ PointerRNA dummyptr;
+ int have_function[5];
+
+ /* setup dummy socket & socket type to store static properties in */
+ memset(&dummyst, 0, sizeof(bNodeSocketType));
+
+ memset(&dummysock, 0, sizeof(bNodeSocket));
+ dummysock.typeinfo= &dummyst;
+ RNA_pointer_create(NULL, &RNA_NodeSocketInterface, &dummysock, &dummyptr);
+
+ /* validate the python class */
+ if (validate(&dummyptr, data, have_function) != 0)
+ return NULL;
+
+ /* check if we have registered this socket type before */
+ st= nodeSocketTypeFind(dummyst.idname);
+ if (st) {
+ /* basic socket type registered by a socket class before. */
+ }
+ else {
+ /* create a new node socket type */
+ st= MEM_callocN(sizeof(bNodeSocketType), "node socket type");
+ memcpy(st, &dummyst, sizeof(dummyst));
+
+ nodeRegisterSocketType(st);
+ }
+
+ /* if RNA type is already registered, unregister first */
+ if (st->ext_interface.srna) {
+ StructRNA *srna = st->ext_interface.srna;
+ RNA_struct_free_extension(srna, &st->ext_interface);
+ RNA_struct_free(&BLENDER_RNA, srna);
+ }
+ st->ext_interface.srna= RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_NodeSocketInterface);
+ st->ext_interface.data= data;
+ st->ext_interface.call= call;
+ st->ext_interface.free= free;
+ RNA_struct_blender_type_set(st->ext_interface.srna, st);
+
+ st->interface_draw = (have_function[0]) ? rna_NodeSocketInterface_draw : NULL;
+ st->interface_draw_color = (have_function[1]) ? rna_NodeSocketInterface_draw_color : NULL;
+ st->interface_register_properties = (have_function[2]) ? rna_NodeSocketInterface_register_properties : NULL;
+ st->interface_init_socket = (have_function[3]) ? rna_NodeSocketInterface_init_socket : NULL;
+ st->interface_from_socket = (have_function[4]) ? rna_NodeSocketInterface_from_socket : NULL;
+
+ /* update while blender is running */
+ WM_main_add_notifier(NC_NODE|NA_EDITED, NULL);
+
+ return st->ext_interface.srna;
}
+static StructRNA *rna_NodeSocketInterface_refine(PointerRNA *ptr)
+{
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
+
+ if (sock->typeinfo && sock->typeinfo->ext_interface.srna)
+ return sock->typeinfo->ext_interface.srna;
+ else
+ return &RNA_NodeSocketInterface;
+}
-static void rna_Node_scene_set(PointerRNA *ptr, PointerRNA value)
+static char *rna_NodeSocketInterface_path(PointerRNA *ptr)
{
- bNode *node = (bNode *)ptr->data;
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNodeSocket *sock = (bNodeSocket *)ptr->data;
+ int socketindex;
+
+ socketindex = BLI_findindex(&ntree->inputs, sock);
+ if (socketindex != -1)
+ return BLI_sprintfN("inputs[%d]", socketindex);
+
+ socketindex = BLI_findindex(&ntree->outputs, sock);
+ if (socketindex != -1)
+ return BLI_sprintfN("outputs[%d]", socketindex);
+
+ return NULL;
+}
- if (node->id) {
- id_us_min(node->id);
- node->id = NULL;
+static IDProperty *rna_NodeSocketInterface_idprops(PointerRNA *ptr, bool create)
+{
+ bNodeSocket *sock = ptr->data;
+
+ if (create && !sock->prop) {
+ IDPropertyTemplate val = {0};
+ sock->prop = IDP_New(IDP_GROUP, &val, "RNA_NodeSocketInterface ID properties");
}
+
+ return sock->prop;
+}
- node->id = value.data;
-
- id_us_plus(node->id);
+static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ bNodeTree *ntree = ptr->id.data;
+ bNodeSocket *stemp = ptr->data;
+
+ if (!stemp->typeinfo)
+ return;
+
+ ntree->update |= NTREE_UPDATE_GROUP;
+ ntreeUpdateTree(ntree);
+
+ ED_node_tag_update_nodetree(bmain, ntree);
}
+/* ******** Standard Node Socket Base Types ******** */
-static void node_update(Main *bmain, Scene *UNUSED(scene), bNodeTree *ntree, bNode *node)
+static void rna_NodeSocketStandard_draw(ID *id, bNodeSocket *sock, struct bContext *C, struct uiLayout *layout, PointerRNA *nodeptr)
{
- ED_node_generic_update(bmain, ntree, node);
+ PointerRNA ptr;
+ RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr);
+ sock->typeinfo->draw(C, layout, &ptr, nodeptr);
}
-static void rna_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_NodeSocketStandard_draw_color(ID *id, bNodeSocket *sock, struct bContext *C, PointerRNA *nodeptr, float *r_color)
{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- bNode *node = (bNode *)ptr->data;
-
- node_update(bmain, scene, ntree, node);
+ PointerRNA ptr;
+ RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr);
+ sock->typeinfo->draw_color(C, &ptr, nodeptr, r_color);
}
-static void rna_Node_tex_image_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_NodeSocketInterfaceStandard_draw(ID *id, bNodeSocket *sock, struct bContext *C, struct uiLayout *layout)
{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- bNode *node = (bNode *)ptr->data;
+ PointerRNA ptr;
+ RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr);
+ sock->typeinfo->interface_draw(C, layout, &ptr);
+}
- node_update(bmain, scene, ntree, node);
- WM_main_add_notifier(NC_IMAGE, NULL);
+static void rna_NodeSocketInterfaceStandard_draw_color(ID *id, bNodeSocket *sock, struct bContext *C, float *r_color)
+{
+ PointerRNA ptr;
+ RNA_pointer_create(id, &RNA_NodeSocket, sock, &ptr);
+ sock->typeinfo->interface_draw_color(C, &ptr, r_color);
}
-static void rna_Node_material_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+/* using a context update function here, to avoid searching the node if possible */
+static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA *ptr)
{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- bNode *node = (bNode *)ptr->data;
+ bNode *node;
+
+ /* default update */
+ rna_NodeSocket_update(CTX_data_main(C), CTX_data_scene(C), ptr);
+
+ /* try to use node from context, faster */
+ node = CTX_data_pointer_get(C, "node").data;
+ if (!node) {
+ bNodeTree *ntree = ptr->id.data;
+ bNodeSocket *sock = ptr->data;
+
+ /* fall back to searching node in the tree */
+ nodeFindNode(ntree, sock, &node, NULL);
+ }
+
+ if (node)
+ nodeSynchronizeID(node, true);
+}
- if (node->id)
- nodeSetActive(ntree, node);
- node_update(bmain, scene, ntree, node);
+/* ******** Node Types ******** */
+
+static void rna_CompositorNode_tag_need_exec(bNode *node)
+{
+ node->need_exec = TRUE;
}
-static void rna_NodeTree_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- /* when using border, make it so no old data from outside of
- * border is hanging around
- * ideally shouldn't be in RNA callback, but how to teach
- * compo to only clear frame when border usage is actually
- * toggling
- */
- if (ntree->flag & NTREE_VIEWER_BORDER) {
- Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
- void *lock;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
-
- if (ibuf) {
- if (ibuf->rect)
- memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y);
-
- if (ibuf->rect_float)
- memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float));
+ ED_node_tag_update_nodetree(bmain, ntree);
+ WM_main_add_notifier(NC_IMAGE, NULL);
+}
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
- }
+static void rna_Node_material_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
- BKE_image_release_ibuf(ima, ibuf, lock);
- }
+ if (node->id)
+ nodeSetActive(ntree, node);
- WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
- WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
+ ED_node_tag_update_nodetree(bmain, ntree);
}
-static void rna_NodeGroup_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
bNode *node = (bNode *)ptr->data;
- ntreeUpdateTree((bNodeTree *)node->id);
+ if (node->id)
+ ntreeUpdateTree((bNodeTree *)node->id);
- node_update(bmain, scene, ntree, node);
+ ED_node_tag_update_nodetree(bmain, ntree);
}
static int rna_NodeGroup_node_tree_poll(PointerRNA *ptr, const PointerRNA value)
@@ -573,91 +2379,99 @@ static int rna_NodeGroup_node_tree_poll(PointerRNA *ptr, const PointerRNA value)
return (ngroup->type == ntree->type);
}
-static void rna_Node_name_set(PointerRNA *ptr, const char *value)
+
+static StructRNA *rna_NodeGroup_interface_typef(PointerRNA *ptr)
{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- bNode *node = (bNode *)ptr->data;
- char oldname[sizeof(node->name)];
-
- /* make a copy of the old name first */
- BLI_strncpy(oldname, node->name, sizeof(node->name));
- /* set new name */
- BLI_strncpy_utf8(node->name, value, sizeof(node->name));
-
- nodeUniqueName(ntree, node);
-
- /* fix all the animation data which may link to this */
- BKE_all_animdata_fix_paths_rename(NULL, "nodes", oldname, node->name);
+ bNode *node = ptr->data;
+ bNodeTree *ngroup = (bNodeTree *)node->id;
+
+ if (ngroup) {
+ StructRNA *srna = ntreeInterfaceTypeGet(ngroup, TRUE);
+ if (srna)
+ return srna;
+ }
+ return &RNA_PropertyGroup;
}
-static void rna_Node_width_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static StructRNA *rna_NodeGroupInputOutput_interface_typef(PointerRNA *ptr)
{
- bNode *node = ptr->data;
- *min = *softmin = node->typeinfo->minwidth;
- *max = *softmax = node->typeinfo->maxwidth;
+ bNodeTree *ntree = ptr->id.data;
+
+ if (ntree) {
+ StructRNA *srna = ntreeInterfaceTypeGet(ntree, TRUE);
+ if (srna)
+ return srna;
+ }
+ return &RNA_PropertyGroup;
}
-static void rna_Node_height_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_distance_matte_t1_set(PointerRNA *ptr, float value)
{
- bNode *node = ptr->data;
- *min = *softmin = node->typeinfo->minheight;
- *max = *softmax = node->typeinfo->maxheight;
+ bNode *node = (bNode *)ptr->data;
+ NodeChroma *chroma = node->storage;
+
+ chroma->t1 = value;
}
-static void rna_NodeSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_distance_matte_t2_set(PointerRNA *ptr, float value)
{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- bNodeSocket *sock = (bNodeSocket *)ptr->data;
- bNode *node;
-
- if (nodeFindNode(ntree, sock, &node, NULL, NULL))
- node_update(bmain, scene, ntree, node);
+ bNode *node = (bNode *)ptr->data;
+ NodeChroma *chroma = node->storage;
+
+ chroma->t2 = value;
}
-static void rna_NodeGroupSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_difference_matte_t1_set(PointerRNA *ptr, float value)
{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
- bNodeSocket *sock = (bNodeSocket *)ptr->data;
- bNode *node;
-
- ntreeUpdateTree(ntree);
-
- if (nodeFindNode(ntree, sock, &node, NULL, NULL))
- node_update(bmain, scene, ntree, node);
+ bNode *node = (bNode *)ptr->data;
+ NodeChroma *chroma = node->storage;
+
+ chroma->t1 = value;
}
-#if 0 /* UNUSED */
-static void rna_NodeLink_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_difference_matte_t2_set(PointerRNA *ptr, float value)
{
- bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
+ NodeChroma *chroma = node->storage;
- ntree->update |= NTREE_UPDATE_LINKS;
- ntreeUpdateTree(ntree);
+ chroma->t2 = value;
}
-#endif
-static void rna_NodeSocketInt_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+/* Button Set Funcs for Matte Nodes */
+static void rna_Matte_t1_set(PointerRNA *ptr, float value)
{
- bNodeSocket *sock = (bNodeSocket *)ptr->data;
- bNodeSocketValueInt *val = (bNodeSocketValueInt *)sock->default_value;
- *softmin = val->min;
- *softmax = val->max;
+ bNode *node = (bNode *)ptr->data;
+ NodeChroma *chroma = node->storage;
+
+ chroma->t1 = value;
+
+ if (value < chroma->t2)
+ chroma->t2 = value;
}
-static void rna_NodeSocketFloat_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_Matte_t2_set(PointerRNA *ptr, float value)
{
- bNodeSocket *sock = (bNodeSocket *)ptr->data;
- bNodeSocketValueFloat *val = (bNodeSocketValueFloat *)sock->default_value;
- *softmin = val->min;
- *softmax = val->max;
+ bNode *node = (bNode *)ptr->data;
+ NodeChroma *chroma = node->storage;
+
+ if (value > chroma->t1)
+ value = chroma->t1;
+
+ chroma->t2 = value;
}
-static void rna_NodeSocketVector_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
+static void rna_Node_scene_set(PointerRNA *ptr, PointerRNA value)
{
- bNodeSocket *sock = (bNodeSocket *)ptr->data;
- bNodeSocketValueVector *val = (bNodeSocketValueVector *)sock->default_value;
- *softmin = val->min;
- *softmax = val->max;
+ bNode *node = (bNode *)ptr->data;
+
+ if (node->id) {
+ id_us_min(node->id);
+ node->id = NULL;
+ }
+
+ node->id = value.data;
+
+ id_us_plus(node->id);
}
static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -741,35 +2555,35 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA
switch (node->custom1) {
case CMP_NODE_CHANNEL_MATTE_CS_RGB:
- tmp.identifier = "R"; tmp.name = "R"; tmp.value = 1;
+ tmp.identifier = "R"; tmp.name= "R"; tmp.value= 1;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "G"; tmp.name = "G"; tmp.value = 2;
+ tmp.identifier = "G"; tmp.name= "G"; tmp.value= 2;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "B"; tmp.name = "B"; tmp.value = 3;
+ tmp.identifier = "B"; tmp.name= "B"; tmp.value= 3;
RNA_enum_item_add(&item, &totitem, &tmp);
break;
case CMP_NODE_CHANNEL_MATTE_CS_HSV:
- tmp.identifier = "H"; tmp.name = "H"; tmp.value = 1;
+ tmp.identifier = "H"; tmp.name= "H"; tmp.value= 1;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "S"; tmp.name = "S"; tmp.value = 2;
+ tmp.identifier = "S"; tmp.name= "S"; tmp.value= 2;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "V"; tmp.name = "V"; tmp.value = 3;
+ tmp.identifier = "V"; tmp.name= "V"; tmp.value= 3;
RNA_enum_item_add(&item, &totitem, &tmp);
break;
case CMP_NODE_CHANNEL_MATTE_CS_YUV:
- tmp.identifier = "Y"; tmp.name = "Y"; tmp.value = 1;
+ tmp.identifier = "Y"; tmp.name= "Y"; tmp.value= 1;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "G"; tmp.name = "U"; tmp.value = 2;
+ tmp.identifier = "G"; tmp.name= "U"; tmp.value= 2;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "V"; tmp.name = "V"; tmp.value = 3;
+ tmp.identifier = "V"; tmp.name= "V"; tmp.value= 3;
RNA_enum_item_add(&item, &totitem, &tmp);
break;
case CMP_NODE_CHANNEL_MATTE_CS_YCC:
- tmp.identifier = "Y"; tmp.name = "Y"; tmp.value = 1;
+ tmp.identifier = "Y"; tmp.name= "Y"; tmp.value= 1;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "CB"; tmp.name = "Cr"; tmp.value = 2;
+ tmp.identifier = "CB"; tmp.name= "Cr"; tmp.value= 2;
RNA_enum_item_add(&item, &totitem, &tmp);
- tmp.identifier = "CR"; tmp.name = "Cb"; tmp.value = 3;
+ tmp.identifier = "CR"; tmp.name= "Cb"; tmp.value= 3;
RNA_enum_item_add(&item, &totitem, &tmp);
break;
default:
@@ -782,274 +2596,13 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA
return item;
}
-static PointerRNA rna_NodeTree_active_node_get(PointerRNA *ptr)
-{
- bNodeTree *ntree = (bNodeTree *)ptr->data;
- bNode *node = nodeGetActive(ntree);
- return rna_pointer_inherit_refine(ptr, &RNA_Node, node);
-}
-
-static void rna_NodeTree_active_node_set(PointerRNA *ptr, PointerRNA value)
-{
- bNodeTree *ntree = (bNodeTree *)ptr->data;
- bNode *node = (bNode *)value.data;
- if (node && BLI_findindex(&ntree->nodes, node) != -1)
- nodeSetActive(ntree, node);
- else
- nodeClearActive(ntree);
-}
-
-static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *reports,
- int type, bNodeTree *group)
-{
- bNode *node;
- bNodeTemplate ntemp;
-
- if (type == NODE_GROUP && group == NULL) {
- BKE_report(reports, RPT_ERROR, "Node type 'GROUP' missing group argument");
- return NULL;
- }
-
- ntemp.type = type;
- ntemp.ngroup = group;
- ntemp.scene = CTX_data_scene(C);
- ntemp.main = CTX_data_main(C);
- node = nodeAddNode(ntree, &ntemp);
-
- if (node == NULL) {
- BKE_report(reports, RPT_ERROR, "Unable to create node");
- }
- else {
- ntreeUpdateTree(ntree); /* update group node socket links*/
- nodeUpdate(ntree, node);
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-
- if (group)
- id_us_plus(&group->id);
- }
-
- return node;
-}
-
-static bNode *rna_NodeTree_node_composite_new(bNodeTree *ntree, bContext *C, ReportList *reports,
- int type, bNodeTree *group)
-{
- /* raises error on failure */
- bNode *node = rna_NodeTree_node_new(ntree, C, reports, type, group);
-
- if (node) {
- if (ELEM4(node->type, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE, CMP_NODE_R_LAYERS)) {
- /* annoying, find the node tree we are in, scene can be NULL */
- Scene *scene;
- for (scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next) {
- if (scene->nodetree == ntree) {
- break;
- }
- }
- node->id = (ID *)scene;
- id_us_plus(node->id);
- }
-
- ntreeCompositForceHidden(ntree, CTX_data_scene(C));
- ntreeUpdateTree(ntree);
- }
-
- return node;
-}
-
-static bNode *rna_NodeTree_node_texture_new(bNodeTree *ntree, bContext *C, ReportList *reports,
- int type, bNodeTree *group)
-{
- /* raises error on failure */
- bNode *node = rna_NodeTree_node_new(ntree, C, reports, type, group);
-
- if (node) {
- ntreeTexCheckCyclics(ntree);
- }
-
- return node;
-}
-
-static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *node_ptr)
-{
- bNode *node = node_ptr->data;
- if (BLI_findindex(&ntree->nodes, node) == -1) {
- BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in node tree", node->name);
- return;
- }
-
- id_us_min(node->id);
- nodeFreeNode(ntree, node);
- RNA_POINTER_INVALIDATE(node_ptr);
-
- ntreeUpdateTree(ntree); /* update group node socket links */
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-}
-
-static void rna_NodeTree_node_clear(bNodeTree *ntree)
-{
- bNode *node = ntree->nodes.first;
-
- while (node) {
- bNode *next_node = node->next;
-
- if (node->id)
- id_us_min(node->id);
-
- nodeFreeNode(ntree, node);
-
- node = next_node;
- }
-
- ntreeUpdateTree(ntree); /* update group node socket links*/
-
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-}
-
-static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports,
- bNodeSocket *fromsock, bNodeSocket *tosock)
-{
- bNodeLink *ret;
- bNode *fromnode = NULL, *tonode = NULL;
- int from_in_out, to_in_out;
-
- nodeFindNode(ntree, fromsock, &fromnode, NULL, &from_in_out);
- nodeFindNode(ntree, tosock, &tonode, NULL, &to_in_out);
-
- if (&from_in_out == &to_in_out) {
- BKE_report(reports, RPT_ERROR, "Same input/output direction of sockets");
- return NULL;
- }
-
- /* unlink node input socket */
- if (to_in_out == SOCK_IN)
- nodeRemSocketLinks(ntree, tosock);
- else
- nodeRemSocketLinks(ntree, fromsock);
-
- ret = nodeAddLink(ntree, fromnode, fromsock, tonode, tosock);
-
- if (ret) {
- if (tonode)
- nodeUpdate(ntree, tonode);
-
- ntreeUpdateTree(ntree);
-
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
- }
-
- return ret;
-}
-
-static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *link_ptr)
-{
- bNodeLink *link = link_ptr->data;
- if (BLI_findindex(&ntree->links, link) == -1) {
- BKE_report(reports, RPT_ERROR, "Unable to locate link in node tree");
- return;
- }
-
- nodeRemLink(ntree, link);
- RNA_POINTER_INVALIDATE(link_ptr);
-
- ntreeUpdateTree(ntree);
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-}
-
-static void rna_NodeTree_link_clear(bNodeTree *ntree)
-{
- bNodeLink *link = ntree->links.first;
-
- while (link) {
- bNodeLink *next_link = link->next;
-
- nodeRemLink(ntree, link);
-
- link = next_link;
- }
- ntreeUpdateTree(ntree);
-
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
-}
-
-static bNodeSocket *rna_NodeTree_input_new(bNodeTree *ntree, ReportList *UNUSED(reports), const char *name, int type)
-{
- /* XXX should check if tree is a group here! no good way to do this currently. */
- bNodeSocket *gsock = node_group_add_socket(ntree, name, type, SOCK_IN);
-
- ntree->update |= NTREE_UPDATE_GROUP_IN;
- ntreeUpdateTree(ntree);
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
- return gsock;
-}
-
-static bNodeSocket *rna_NodeTree_output_new(bNodeTree *ntree, ReportList *UNUSED(reports), const char *name, int type)
-{
- /* XXX should check if tree is a group here! no good way to do this currently. */
- bNodeSocket *gsock = node_group_add_socket(ntree, name, type, SOCK_OUT);
-
- ntree->update |= NTREE_UPDATE_GROUP_OUT;
- ntreeUpdateTree(ntree);
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
- return gsock;
-}
-
-static bNodeSocket *rna_NodeTree_input_expose(bNodeTree *ntree, ReportList *reports, bNodeSocket *sock, int add_link)
-{
- bNode *node;
- bNodeSocket *gsock;
- int index, in_out;
-
- if (!nodeFindNode(ntree, sock, &node, &index, &in_out))
- BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree");
- else if (in_out != SOCK_IN)
- BKE_report(reports, RPT_ERROR, "Socket is not an input");
- else {
- /* XXX should check if tree is a group here! no good way to do this currently. */
- gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_IN);
- if (add_link)
- nodeAddLink(ntree, NULL, gsock, node, sock);
-
- ntree->update |= NTREE_UPDATE_GROUP_IN;
- ntreeUpdateTree(ntree);
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
- return gsock;
- }
- return NULL;
-}
-
-static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *reports, bNodeSocket *sock, int add_link)
-{
- bNode *node;
- bNodeSocket *gsock;
- int index, in_out;
-
- if (!nodeFindNode(ntree, sock, &node, &index, &in_out))
- BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree");
- else if (in_out != SOCK_OUT)
- BKE_report(reports, RPT_ERROR, "Socket is not an output");
- else {
- /* XXX should check if tree is a group here! no good way to do this currently. */
- gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_OUT);
- if (add_link)
- nodeAddLink(ntree, node, sock, NULL, gsock);
-
- ntree->update |= NTREE_UPDATE_GROUP_OUT;
- ntreeUpdateTree(ntree);
- WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
- return gsock;
- }
- return NULL;
-}
-
-static void rna_Image_Node_update_id(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Image_Node_update_id(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
bNode *node = (bNode *)ptr->data;
node->update |= NODE_UPDATE_ID;
- node_update(bmain, scene, ntree, node);
- node->update &= ~NODE_UPDATE_ID;
+ nodeUpdate(ntree, node); /* to update image node sockets */
}
static void rna_Mapping_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -1073,6 +2626,8 @@ static PointerRNA rna_NodeOutputFile_slot_file_get(CollectionPropertyIterator *i
return ptr;
}
+/* ******** Node Socket Types ******** */
+
static PointerRNA rna_NodeOutputFile_slot_layer_get(CollectionPropertyIterator *iter)
{
PointerRNA ptr;
@@ -1126,53 +2681,6 @@ static void rna_NodeOutputFileSlotLayer_name_set(PointerRNA *ptr, const char *va
}
}
-static bNodeSocket *rna_ShaderNodeScript_find_socket(bNode *node, const char *name, int is_output)
-{
- bNodeSocket *sock;
-
- if (is_output) {
- for (sock = node->outputs.first; sock; sock = sock->next) {
- if (strcmp(sock->name, name) == 0) {
- return sock;
- }
- }
- }
- else {
- for (sock = node->inputs.first; sock; sock = sock->next) {
- if (strcmp(sock->name, name) == 0) {
- return sock;
- }
- }
- }
-
- return NULL;
-}
-
-static void rna_ShaderNodeScript_remove_socket(ID *id, bNode *node, bNodeSocket *sock)
-{
- bNodeTree *ntree = (bNodeTree *)id;
-
- nodeRemoveSocket(ntree, node, sock);
-
- ED_node_generic_update(G.main, ntree, node);
-}
-
-static bNodeSocket *rna_ShaderNodeScript_add_socket(ID *id, bNode *node, const char *name, int type, int is_output)
-{
- bNodeTree *ntree = (bNodeTree *)id;
- bNodeSocket *sock;
-
- /* replace existing socket with the same name, to keep it unique */
- sock = rna_ShaderNodeScript_find_socket(node, name, is_output);
- if (sock)
- nodeRemoveSocket(ntree, node, sock);
- sock = nodeAddSocket(ntree, node, (is_output ? SOCK_OUT : SOCK_IN), name, type);
-
- ED_node_generic_update(G.main, ntree, node);
-
- return sock;
-}
-
static void rna_ShaderNodeScript_mode_set(PointerRNA *ptr, int value)
{
bNode *node = (bNode *)ptr->data;
@@ -1236,19 +2744,6 @@ static void rna_ShaderNodeScript_bytecode_set(PointerRNA *ptr, const char *value
nss->bytecode = NULL;
}
-static IDProperty *rna_ShaderNodeScript_idprops(PointerRNA *ptr, bool create)
-{
- bNode *node = (bNode *)ptr->data;
- NodeShaderScript *nss = node->storage;
-
- if (create && !nss->prop) {
- IDPropertyTemplate val = {0};
- nss->prop = IDP_New(IDP_GROUP, &val, "RNA_ShaderNodeScript ID properties");
- }
-
- return nss->prop;
-}
-
static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -1262,7 +2757,7 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p
RE_engine_free(engine);
}
- node_update(bmain, scene, ntree, node);
+ ED_node_tag_update_nodetree(bmain, ntree);
}
#else
@@ -1311,139 +2806,36 @@ static EnumPropertyItem node_script_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
-#define MaxNodes 50000
-
-enum
-{
- Category_GroupNode,
- Category_LayoutNode,
- Category_ShaderNode,
- Category_CompositorNode,
- Category_TextureNode,
-};
-
-typedef struct NodeInfo {
- int defined;
- int category;
- const char *enum_name;
- const char *struct_name;
- const char *base_name;
- int icon;
- const char *ui_name;
- const char *ui_desc;
-} NodeInfo;
-
-static NodeInfo nodes[MaxNodes];
-
-static void reg_node(int ID, int category, const char *enum_name, const char *struct_name,
- const char *base_name, const char *ui_name, const char *ui_desc)
-{
- NodeInfo *ni = nodes + ID;
-
- ni->defined = 1;
- ni->category = category;
- ni->enum_name = enum_name;
- ni->struct_name = struct_name;
- ni->base_name = base_name;
- ni->ui_name = ui_name;
- ni->ui_desc = ui_desc;
-}
-
-static void init(void)
-{
- memset(nodes, 0, sizeof(nodes));
-
- #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
- reg_node(ID, Category_##Category, EnumName, STRINGIFY_ARG(Category##StructName), #Category, UIName, UIDesc);
-
- #include "rna_nodetree_types.h"
-
- reg_node(NODE_GROUP, Category_GroupNode, "GROUP", "NodeGroup", "SpecialNode", "Group", "");
- reg_node(NODE_FRAME, Category_LayoutNode, "FRAME", "NodeFrame", "SpecialNode", "Frame", "");
- reg_node(NODE_REROUTE, Category_LayoutNode, "REROUTE", "NodeReroute", "SpecialNode", "Reroute", "");
-}
+/* -- Common nodes ---------------------------------------------------------- */
-static StructRNA *def_node(BlenderRNA *brna, int node_id)
+static void def_group_input(StructRNA *srna)
{
- StructRNA *srna;
- FunctionRNA *func;
- PropertyRNA *parm;
- NodeInfo *node = nodes + node_id;
-
- srna = RNA_def_struct(brna, node->struct_name, node->base_name);
- RNA_def_struct_ui_text(srna, node->ui_name, node->ui_desc);
- RNA_def_struct_sdna(srna, "bNode");
-
- func = RNA_def_function(srna, "get_node_type", "rna_Node_get_node_type");
- RNA_def_function_ui_description(func, "Get the identifier of the node type");
- RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
- parm = RNA_def_string(func, "result", "", 0, "Result", "");
- RNA_def_function_return(func, parm);
+ PropertyRNA *prop;
- return srna;
+ prop = RNA_def_property(srna, "interface", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_NodeGroupInputOutput_interface_typef", NULL);
+ RNA_def_property_struct_type(prop, "PropertyGroup");
+ RNA_def_property_flag(prop, PROP_IDPROPERTY);
+ RNA_def_property_ui_text(prop, "Interface", "Interface socket data");
}
-static void alloc_node_type_items(EnumPropertyItem *items, int category)
+static void def_group_output(StructRNA *srna)
{
- int i;
- int count = 4;
- EnumPropertyItem *item = items;
-
- for (i = 0; i < MaxNodes; i++)
- if (nodes[i].defined && nodes[i].category == category)
- count++;
-
- /*item = items = MEM_callocN(count * sizeof(EnumPropertyItem), "alloc_node_type_items");*/
-
- for (i = 0; i < MaxNodes; i++) {
- NodeInfo *node = nodes + i;
- if (node->defined && node->category == category) {
- item->value = i;
- item->identifier = node->enum_name;
- item->icon = node->icon;
- item->name = node->ui_name;
- item->description = node->ui_desc;
-
- item++;
- }
- }
-
- item->value = NODE_GROUP;
- item->identifier = "GROUP";
- item->icon = 0;
- item->name = "Group";
- item->description = "";
-
- item++;
-
- item->value = NODE_REROUTE;
- item->identifier = "REROUTE";
- item->icon = 0;
- item->name = "Reroute";
- item->description = "";
-
- item++;
-
- item->value = NODE_FRAME;
- item->identifier = "FRAME";
- item->icon = 0;
- item->name = "Frame";
- item->description = "";
-
- item++;
-
- /* NOTE!, increase 'count' when adding items here */
+ PropertyRNA *prop;
- memset(item, 0, sizeof(EnumPropertyItem));
+ prop = RNA_def_property(srna, "interface", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_NodeGroupInputOutput_interface_typef", NULL);
+ RNA_def_property_struct_type(prop, "PropertyGroup");
+ RNA_def_property_flag(prop, PROP_IDPROPERTY);
+ RNA_def_property_ui_text(prop, "Interface", "Interface socket data");
}
-
-/* -- Common nodes ---------------------------------------------------------- */
-
static void def_group(StructRNA *srna)
{
PropertyRNA *prop;
+ RNA_def_struct_register_funcs(srna, "rna_NodeGroup_register", "rna_Node_unregister", NULL);
+
prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_struct_type(prop, "NodeTree");
@@ -1451,6 +2843,18 @@ static void def_group(StructRNA *srna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Node Tree", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeGroup_update");
+
+ prop = RNA_def_property(srna, "interface", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_NodeGroup_interface_typef", NULL);
+ RNA_def_property_struct_type(prop, "PropertyGroup");
+ RNA_def_property_flag(prop, PROP_IDPROPERTY);
+ RNA_def_property_ui_text(prop, "Interface", "Interface socket data");
+
+ /* registration */
+ prop = RNA_def_property(srna, "bl_group_tree_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->group_tree_idname");
+ RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
+ RNA_def_property_ui_text(prop, "Group Tree Type", "");
}
static void def_frame(StructRNA *srna)
@@ -2062,8 +3466,7 @@ static void def_sh_tangent(StructRNA *srna)
static void def_sh_script(StructRNA *srna)
{
- FunctionRNA *func;
- PropertyRNA *prop, *parm;
+ PropertyRNA *prop;
prop = RNA_def_property(srna, "script", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
@@ -2073,7 +3476,6 @@ static void def_sh_script(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeScript_update");
RNA_def_struct_sdna_from(srna, "NodeShaderScript", "storage");
- RNA_def_struct_idprops_func(srna, "rna_ShaderNodeScript_idprops");
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
RNA_def_property_ui_text(prop, "File Path", "Shader script path");
@@ -2104,7 +3506,8 @@ static void def_sh_script(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "bNode", NULL);
/* API functions */
-
+
+#if 0 /* XXX TODO use general node api for this */
func = RNA_def_function(srna, "find_socket", "rna_ShaderNodeScript_find_socket");
RNA_def_function_ui_description(func, "Find a socket by name");
parm = RNA_def_string(func, "name", "", 0, "Socket name", "");
@@ -2129,6 +3532,7 @@ static void def_sh_script(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
parm = RNA_def_pointer(func, "sock", "NodeSocket", "Socket", "");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+#endif
}
/* -- Compositor Nodes ------------------------------------------------------ */
@@ -4382,390 +5786,571 @@ static void def_tex_bricks(StructRNA *srna)
/* -------------------------------------------------------------------------- */
-static EnumPropertyItem shader_node_type_items[MaxNodes];
static void rna_def_shader_node(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
- alloc_node_type_items(shader_node_type_items, Category_ShaderNode);
-
srna = RNA_def_struct(brna, "ShaderNode", "Node");
RNA_def_struct_ui_text(srna, "Shader Node", "Material shader node");
RNA_def_struct_sdna(srna, "bNode");
-
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_enum_items(prop, shader_node_type_items);
- RNA_def_property_ui_text(prop, "Type", "");
+ RNA_def_struct_register_funcs(srna, "rna_ShaderNode_register", "rna_Node_unregister", NULL);
}
-static EnumPropertyItem compositor_node_type_items[MaxNodes];
static void rna_def_compositor_node(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
-
- alloc_node_type_items(compositor_node_type_items, Category_CompositorNode);
+ FunctionRNA *func;
srna = RNA_def_struct(brna, "CompositorNode", "Node");
RNA_def_struct_ui_text(srna, "Compositor Node", "");
RNA_def_struct_sdna(srna, "bNode");
-
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_enum_items(prop, compositor_node_type_items);
- RNA_def_property_ui_text(prop, "Type", "");
+ RNA_def_struct_register_funcs(srna, "rna_CompositorNode_register", "rna_Node_unregister", NULL);
+
+ /* compositor node need_exec flag */
+ func = RNA_def_function(srna, "tag_need_exec", "rna_CompositorNode_tag_need_exec");
+ RNA_def_function_ui_description(func, "Tag the node for compositor update");
}
-static EnumPropertyItem texture_node_type_items[MaxNodes];
static void rna_def_texture_node(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
-
- alloc_node_type_items(texture_node_type_items, Category_TextureNode);
srna = RNA_def_struct(brna, "TextureNode", "Node");
RNA_def_struct_ui_text(srna, "Texture Node", "");
RNA_def_struct_sdna(srna, "bNode");
-
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_enum_items(prop, texture_node_type_items);
- RNA_def_property_ui_text(prop, "Type", "");
+ RNA_def_struct_register_funcs(srna, "rna_TextureNode_register", "rna_Node_unregister", NULL);
}
-static void rna_def_special_node(BlenderRNA *brna)
+/* -------------------------------------------------------------------------- */
+
+static void rna_def_node_socket(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ PropertyRNA *parm;
+ FunctionRNA *func;
+
+ static float default_draw_color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+
+ srna = RNA_def_struct(brna, "NodeSocket", NULL);
+ 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_PLUG);
+ RNA_def_struct_path_func(srna, "rna_NodeSocket_path");
+ RNA_def_struct_register_funcs(srna, "rna_NodeSocket_register", "rna_NodeSocket_unregister", NULL);
+ RNA_def_struct_idprops_func(srna, "rna_NodeSocket_idprops");
- static EnumPropertyItem specific_node_type_items[] = {
- {NODE_GROUP, "GROUP", ICON_NODE, "Group", ""},
- {NODE_FRAME, "FRAME", ICON_NODE, "Frame", ""},
- {NODE_REROUTE, "REROUTE", ICON_NODE, "Reroute", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
- srna = RNA_def_struct(brna, "SpecialNode", "Node");
- RNA_def_struct_ui_text(srna, "Special Node", "");
- RNA_def_struct_sdna(srna, "bNode");
+ 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, "type", PROP_ENUM, PROP_NONE);
+ prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "identifier");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_enum_items(prop, specific_node_type_items);
- RNA_def_property_ui_text(prop, "Type", "");
-}
+ RNA_def_property_ui_text(prop, "Identifier", "Unique identifier for mapping sockets");
-/* -------------------------------------------------------------------------- */
+ prop = RNA_def_property(srna, "in_out", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "in_out");
+ RNA_def_property_enum_items(prop, node_socket_in_out_items);
+ RNA_def_property_enum_default(prop, SOCK_IN);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Input or Output", "Input or Output type");
-static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
-{
- StructRNA *srna;
- PropertyRNA *parm;
- FunctionRNA *func;
+ prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_HIDDEN);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_NodeSocket_hide_set");
+ RNA_def_property_ui_text(prop, "Hide", "Hide the socket");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
- RNA_def_property_srna(cprop, "NodeLinks");
- srna = RNA_def_struct(brna, "NodeLinks", NULL);
- RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_text(srna, "Node Links", "Collection of Node Links");
+ prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SOCK_UNAVAIL);
+ RNA_def_property_ui_text(prop, "Enabled", "Enable the socket");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
- func = RNA_def_function(srna, "new", "rna_NodeTree_link_new");
- RNA_def_function_ui_description(func, "Add a node link to this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm = RNA_def_pointer(func, "input", "NodeSocket", "", "The input socket");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_pointer(func, "output", "NodeSocket", "", "The output socket");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- /* return */
- parm = RNA_def_pointer(func, "link", "NodeLink", "", "New node link");
- RNA_def_function_return(func, parm);
+ prop = RNA_def_property(srna, "is_linked", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_IN_USE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Linked", "True if the socket is connected");
- func = RNA_def_function(srna, "remove", "rna_NodeTree_link_remove");
- RNA_def_function_ui_description(func, "remove a node link from the node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm = RNA_def_pointer(func, "link", "NodeLink", "", "The node link to remove");
- RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
- RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+ prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "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, NULL);
- func = RNA_def_function(srna, "clear", "rna_NodeTree_link_clear");
- RNA_def_function_ui_description(func, "remove all node links from the node tree");
-}
+ prop = RNA_def_property(srna, "node", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_funcs(prop, "rna_NodeSocket_node_get", NULL, NULL, NULL);
+ RNA_def_property_struct_type(prop, "Node");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Node", "Node owning this socket");
-/* shared between all note tree types*/
-static void rna_def_nodetree_active_api(StructRNA *srna, PropertyRNA *UNUSED(cprop))
-{
- PropertyRNA *prop;
+ /* NB: 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, NULL, "type");
+ RNA_def_property_enum_items(prop, node_socket_type_items);
+ RNA_def_property_enum_default(prop, SOCK_FLOAT);
+ RNA_def_property_ui_text(prop, "Type", "Data type");
+ 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_sdna(prop, NULL, "typeinfo->idname");
+ RNA_def_property_string_funcs(prop, "rna_NodeSocket_bl_idname_get", "rna_NodeSocket_bl_idname_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
+ RNA_def_property_ui_text(prop, "ID Name", "");
+
+ /* draw socket */
+ func = RNA_def_function(srna, "draw", NULL);
+ RNA_def_function_ui_description(func, "Draw socket");
+ RNA_def_function_flag(func, FUNC_REGISTER);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
- prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "Node");
- RNA_def_property_pointer_funcs(prop, "rna_NodeTree_active_node_get", "rna_NodeTree_active_node_set", NULL, NULL);
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
- RNA_def_property_ui_text(prop, "Active Node", "Active node in this tree");
- RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
+ func = RNA_def_function(srna, "draw_color", NULL);
+ RNA_def_function_ui_description(func, "Color of the socket icon");
+ RNA_def_function_flag(func, FUNC_REGISTER);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_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);
}
-static void rna_def_composite_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
+static void rna_def_node_socket_interface(BlenderRNA *brna)
{
StructRNA *srna;
+ PropertyRNA *prop;
PropertyRNA *parm;
FunctionRNA *func;
+
+ static float default_draw_color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+
+ srna = RNA_def_struct(brna, "NodeSocketInterface", NULL);
+ RNA_def_struct_ui_text(srna, "Node Socket Template", "Parameters to define node sockets");
+ /* XXX Using bNodeSocket DNA for templates is a compatibility hack.
+ * This allows to keep the inputs/outputs lists in bNodeTree working for earlier versions
+ * and at the same time use them for socket templates in groups.
+ */
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+ RNA_def_struct_refine_func(srna, "rna_NodeSocketInterface_refine");
+ RNA_def_struct_path_func(srna, "rna_NodeSocketInterface_path");
+ RNA_def_struct_idprops_func(srna, "rna_NodeSocketInterface_idprops");
+ RNA_def_struct_register_funcs(srna, "rna_NodeSocketInterface_register", "rna_NodeSocketInterface_unregister", NULL);
- RNA_def_property_srna(cprop, "CompositorNodes");
- srna = RNA_def_struct(brna, "CompositorNodes", NULL);
- RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_text(srna, "Compositor Nodes", "Collection of Compositor Nodes");
+ 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_NodeSocketInterface_update");
- func = RNA_def_function(srna, "new", "rna_NodeTree_node_composite_new");
- RNA_def_function_ui_description(func, "Add a node to this node tree");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
- parm = RNA_def_enum(func, "type", compositor_node_type_items, 0, "Type", "Type of node to add");
+ prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "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, "in_out", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "in_out");
+ RNA_def_property_enum_items(prop, node_socket_in_out_items);
+ RNA_def_property_enum_default(prop, SOCK_IN);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Input or Output", "Input or Output type");
+
+ /* registration */
+ prop = RNA_def_property(srna, "bl_socket_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname");
+ RNA_def_property_string_funcs(prop, "rna_NodeSocket_bl_idname_get", "rna_NodeSocket_bl_idname_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP);
+ RNA_def_property_ui_text(prop, "ID Name", "");
+
+ func = RNA_def_function(srna, "draw", NULL);
+ RNA_def_function_ui_description(func, "Draw template settings");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+
+ func = RNA_def_function(srna, "draw_color", NULL);
+ RNA_def_function_ui_description(func, "Color of the socket icon");
+ RNA_def_function_flag(func, FUNC_REGISTER);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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, "register_properties", NULL);
+ RNA_def_function_ui_description(func, "Define RNA properties of a socket");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "data_rna_type", "Struct", "Data RNA Type", "RNA type for special socket properties");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_pointer(func, "group", "NodeTree", "", "The group tree");
- /* return value */
- parm = RNA_def_pointer(func, "node", "Node", "", "New node");
- RNA_def_function_return(func, parm);
- func = RNA_def_function(srna, "remove", "rna_NodeTree_node_remove");
- RNA_def_function_ui_description(func, "Remove a node from this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm = RNA_def_pointer(func, "node", "Node", "", "The node to remove");
+ func = RNA_def_function(srna, "init_socket", NULL);
+ RNA_def_function_ui_description(func, "Initialize a node socket instance");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the socket to initialize");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
- RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+ parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Socket to initialize");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ parm = RNA_def_string(func, "data_path", "", 0, "Data Path", "Path to specialized socket data");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
- func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
- RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
+ func = RNA_def_function(srna, "from_socket", NULL);
+ RNA_def_function_ui_description(func, "Setup template parameters from an existing socket");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "node", "Node", "Node", "Node of the original socket");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ parm = RNA_def_pointer(func, "socket", "NodeSocket", "Socket", "Original socket");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+}
- rna_def_nodetree_active_api(srna, cprop);
+static void rna_def_node_socket_float(BlenderRNA *brna, const char *idname, const char *interface_idname, PropertySubType subtype)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, idname, "NodeSocketStandard");
+ RNA_def_struct_ui_text(srna, "Float Node Socket", "Floating point number socket of a node");
+ 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, NULL, "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);
+
+ /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
+ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
+
+ /* socket interface */
+ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
+ RNA_def_struct_ui_text(srna, "Float Node Socket Interface", "Floating point number socket of a node");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
}
-static void rna_def_shader_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
+static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, const char *interface_idname, PropertySubType subtype)
{
StructRNA *srna;
- PropertyRNA *parm;
- FunctionRNA *func;
+ PropertyRNA *prop;
+
+ 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_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, NULL, "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);
+
+ /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
+ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
+
+ /* socket interface */
+ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
+ RNA_def_struct_ui_text(srna, "Integer Node Socket Interface", "Integer number socket of a node");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+}
- RNA_def_property_srna(cprop, "ShaderNodes");
- srna = RNA_def_struct(brna, "ShaderNodes", NULL);
- RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_text(srna, "Shader Nodes", "Collection of Shader Nodes");
+static void rna_def_node_socket_bool(BlenderRNA *brna, const char *identifier, const char *interface_idname)
+{
+ 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_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, NULL, "value", 1);
+ 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);
+
+ /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
+ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
+
+ /* socket interface */
+ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
+ RNA_def_struct_ui_text(srna, "Boolean Node Socket Interface", "Boolean value socket of a node");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+}
- func = RNA_def_function(srna, "new", "rna_NodeTree_node_new");
- RNA_def_function_ui_description(func, "Add a node to this node tree");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
- parm = RNA_def_enum(func, "type", shader_node_type_items, 0, "Type", "Type of node to add");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_pointer(func, "group", "NodeTree", "", "The group tree");
- /* return value */
- parm = RNA_def_pointer(func, "node", "Node", "", "New node");
- RNA_def_function_return(func, parm);
+static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier, const char *interface_idname, 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_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, NULL, "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);
+
+ /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
+ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
+
+ /* socket interface */
+ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
+ RNA_def_struct_ui_text(srna, "Vector Node Socket Interface", "3D vector socket of a node");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+}
- func = RNA_def_function(srna, "remove", "rna_NodeTree_node_remove");
- RNA_def_function_ui_description(func, "Remove a node from this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm = RNA_def_pointer(func, "node", "Node", "", "The node to remove");
- RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
- RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+static void rna_def_node_socket_color(BlenderRNA *brna, const char *identifier, const char *interface_idname)
+{
+ 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_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, NULL, "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);
+
+ /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
+ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
+
+ /* socket interface */
+ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
+ RNA_def_struct_ui_text(srna, "Color Node Socket Interface", "RGBA color socket of a node");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+}
- func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
- RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
+static void rna_def_node_socket_string(BlenderRNA *brna, const char *identifier, const char *interface_idname)
+{
+ 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_sdna(srna, "bNodeSocket");
+
+ RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "default_value");
+
+ prop = RNA_def_property(srna, "default_value", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "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);
+
+ /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
+ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
+
+ /* socket interface */
+ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
+ RNA_def_struct_ui_text(srna, "String Node Socket Interface", "String socket of a node");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+}
+
+static void rna_def_node_socket_shader(BlenderRNA *brna, const char *identifier, const char *interface_idname)
+{
+ 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_sdna(srna, "bNodeSocket");
+
+ /* socket interface */
+ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
+ RNA_def_struct_ui_text(srna, "Shader Node Socket Interface", "Shader socket of a node");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+}
- rna_def_nodetree_active_api(srna, cprop);
+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");
}
-static void rna_def_texture_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
+static void rna_def_node_socket_standard_types(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 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
- RNA_def_property_srna(cprop, "TextureNodes");
- srna = RNA_def_struct(brna, "TextureNodes", NULL);
- RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_text(srna, "Texture Nodes", "Collection of Texture Nodes");
-
- func = RNA_def_function(srna, "new", "rna_NodeTree_node_texture_new");
- RNA_def_function_ui_description(func, "Add a node to this node tree");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
- parm = RNA_def_enum(func, "type", texture_node_type_items, 0, "Type", "Type of node to add");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_pointer(func, "group", "NodeTree", "", "The group tree");
- /* return value */
- parm = RNA_def_pointer(func, "node", "Node", "", "New node");
- RNA_def_function_return(func, parm);
-
- func = RNA_def_function(srna, "remove", "rna_NodeTree_node_remove");
- RNA_def_function_ui_description(func, "Remove a node from this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm = RNA_def_pointer(func, "node", "Node", "", "The node to remove");
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
- RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+ 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);
+
+
+ srna = RNA_def_struct(brna, "NodeSocketInterfaceStandard", "NodeSocketInterface");
+ RNA_def_struct_sdna(srna, "bNodeSocket");
+
+ func = RNA_def_function(srna, "draw", "rna_NodeSocketInterfaceStandard_draw");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Draw template settings");
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
- func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
- RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
+ func = RNA_def_function(srna, "draw_color", "rna_NodeSocketInterfaceStandard_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_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ 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);
- rna_def_nodetree_active_api(srna, cprop);
-}
-static void rna_def_node_socket(BlenderRNA *brna)
-{
- StructRNA *srna;
- PropertyRNA *prop;
+ /* XXX These types should eventually be registered at runtime.
+ * Then use the nodeStaticSocketType and nodeStaticSocketInterfaceType functions
+ * to get the idname strings from int type and subtype (see node_socket.c, register_standard_node_socket_types).
+ */
+
+ rna_def_node_socket_float(brna, "NodeSocketFloat", "NodeSocketInterfaceFloat", PROP_NONE);
+ rna_def_node_socket_float(brna, "NodeSocketFloatUnsigned", "NodeSocketInterfaceFloatUnsigned", PROP_UNSIGNED);
+ rna_def_node_socket_float(brna, "NodeSocketFloatPercentage", "NodeSocketInterfaceFloatPercentage", PROP_PERCENTAGE);
+ rna_def_node_socket_float(brna, "NodeSocketFloatFactor", "NodeSocketInterfaceFloatFactor", PROP_FACTOR);
+ rna_def_node_socket_float(brna, "NodeSocketFloatAngle", "NodeSocketInterfaceFloatAngle", PROP_ANGLE);
+ rna_def_node_socket_float(brna, "NodeSocketFloatTime", "NodeSocketInterfaceFloatTime", PROP_TIME);
- srna = RNA_def_struct(brna, "NodeSocket", NULL);
- 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_PLUG);
- RNA_def_struct_path_func(srna, "rna_NodeSocket_path");
+ rna_def_node_socket_int(brna, "NodeSocketInt", "NodeSocketInterfaceInt", PROP_NONE);
+ rna_def_node_socket_int(brna, "NodeSocketIntUnsigned", "NodeSocketInterfaceIntUnsigned", PROP_UNSIGNED);
+ rna_def_node_socket_int(brna, "NodeSocketIntPercentage", "NodeSocketInterfaceIntPercentage", PROP_PERCENTAGE);
+ rna_def_node_socket_int(brna, "NodeSocketIntFactor", "NodeSocketInterfaceIntFactor", PROP_FACTOR);
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "type");
- RNA_def_property_enum_items(prop, node_socket_type_items);
- RNA_def_property_enum_default(prop, 0);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Type", "Node Socket type");
+ rna_def_node_socket_bool(brna, "NodeSocketBool", "NodeSocketInterfaceBool");
- prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- /* XXX must be editable for group sockets. if necessary use a special rna definition for these */
-/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
- 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_NodeGroupSocket_update");
+ rna_def_node_socket_vector(brna, "NodeSocketVector", "NodeSocketInterfaceVector", PROP_NONE);
+ rna_def_node_socket_vector(brna, "NodeSocketVectorTranslation", "NodeSocketInterfaceVectorTranslation", PROP_TRANSLATION);
+ rna_def_node_socket_vector(brna, "NodeSocketVectorDirection", "NodeSocketInterfaceVectorDirection", PROP_DIRECTION);
+ rna_def_node_socket_vector(brna, "NodeSocketVectorVelocity", "NodeSocketInterfaceVectorVelocity", PROP_VELOCITY);
+ rna_def_node_socket_vector(brna, "NodeSocketVectorAcceleration", "NodeSocketInterfaceVectorAcceleration", PROP_ACCELERATION);
+ rna_def_node_socket_vector(brna, "NodeSocketVectorEuler", "NodeSocketInterfaceVectorEuler", PROP_EULER);
+ rna_def_node_socket_vector(brna, "NodeSocketVectorXYZ", "NodeSocketInterfaceVectorXYZ", PROP_XYZ);
- prop = RNA_def_property(srna, "group_socket", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "groupsock");
- RNA_def_property_struct_type(prop, "NodeSocket");
- RNA_def_property_ui_text(prop, "Group Socket",
- "For group nodes, the group input or output socket this corresponds to");
+ rna_def_node_socket_color(brna, "NodeSocketColor", "NodeSocketInterfaceColor");
- prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_HIDDEN);
- RNA_def_property_boolean_funcs(prop, NULL, "rna_NodeSocket_hide_set");
- RNA_def_property_ui_text(prop, "Hide", "Hide the socket");
- RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
+ rna_def_node_socket_string(brna, "NodeSocketString", "NodeSocketInterfaceString");
- prop = RNA_def_property(srna, "is_linked", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_IN_USE);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Linked", "True if the socket is connected");
+ rna_def_node_socket_shader(brna, "NodeSocketShader", "NodeSocketInterfaceShader");
- prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "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, NULL);
+ rna_def_node_socket_virtual(brna, "NodeSocketVirtual");
}
-static void rna_def_node_socket_subtype(BlenderRNA *brna, int type, int subtype, const char *name, const char *ui_name)
+static void rna_def_node_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int in_out)
{
StructRNA *srna;
- PropertyRNA *prop = NULL;
- PropertySubType propsubtype = PROP_NONE;
-
- #define SUBTYPE(socktype, stypename, id, idname) { PROP_##id, #socktype "_" #id, 0, #idname, ""},
- static EnumPropertyItem subtype_items[] = {
- NODE_DEFINE_SUBTYPES
- {0, NULL, 0, NULL, NULL}
- };
- #undef SUBTYPE
+ PropertyRNA *parm;
+ FunctionRNA *func;
+ const char *structtype = (in_out == SOCK_IN ? "NodeInputs" : "NodeOutputs");
+ const char *uiname = (in_out == SOCK_IN ? "Node Inputs" : "Node Outputs");
+ const char *newfunc = (in_out == SOCK_IN ? "rna_Node_inputs_new" : "rna_Node_outputs_new");
+ const char *clearfunc = (in_out == SOCK_IN ? "rna_Node_inputs_clear" : "rna_Node_outputs_clear");
- #define SUBTYPE(socktype, stypename, id, idname) if (subtype == (PROP_##id)) propsubtype = PROP_##id;
- NODE_DEFINE_SUBTYPES
- #undef SUBTYPE
-
- srna = RNA_def_struct(brna, name, "NodeSocket");
- RNA_def_struct_ui_text(srna, ui_name, "Input or output socket of a node");
- RNA_def_struct_sdna(srna, "bNodeSocket");
- RNA_def_struct_ui_icon(srna, ICON_PLUG);
- RNA_def_struct_path_func(srna, "rna_NodeSocket_path");
-
- switch (type) {
- case SOCK_INT:
- RNA_def_struct_sdna_from(srna, "bNodeSocketValueInt", "default_value");
-
- prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "subtype");
- RNA_def_property_enum_items(prop, subtype_items);
- RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
-
- prop = RNA_def_property(srna, "default_value", PROP_INT, propsubtype);
- RNA_def_property_int_sdna(prop, NULL, "value");
- RNA_def_property_int_funcs(prop, NULL, NULL, "rna_NodeSocketInt_range");
- RNA_def_property_ui_text(prop, "Default Value", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
- break;
- case SOCK_FLOAT:
- RNA_def_struct_sdna_from(srna, "bNodeSocketValueFloat", "default_value");
-
- prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "subtype");
- RNA_def_property_enum_items(prop, subtype_items);
- RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
-
- prop = RNA_def_property(srna, "default_value", PROP_FLOAT, propsubtype);
- RNA_def_property_float_sdna(prop, NULL, "value");
- RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketFloat_range");
- RNA_def_property_ui_text(prop, "Default Value", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
- break;
- case SOCK_BOOLEAN:
- 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, NULL, "value", 1);
- RNA_def_property_ui_text(prop, "Default Value", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
- break;
- case SOCK_VECTOR:
- RNA_def_struct_sdna_from(srna, "bNodeSocketValueVector", "default_value");
-
- prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "subtype");
- RNA_def_property_enum_items(prop, subtype_items);
- RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
-
- prop = RNA_def_property(srna, "default_value", PROP_FLOAT, propsubtype);
- RNA_def_property_float_sdna(prop, NULL, "value");
- RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketVector_range");
- RNA_def_property_ui_text(prop, "Default Value", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
- break;
- case SOCK_RGBA:
- RNA_def_struct_sdna_from(srna, "bNodeSocketValueRGBA", "default_value");
+ RNA_def_property_srna(cprop, structtype);
+ srna= RNA_def_struct(brna, structtype, NULL);
+ RNA_def_struct_sdna(srna, "bNode");
+ RNA_def_struct_ui_text(srna, uiname, "Collection of Node Sockets");
- prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_float_sdna(prop, NULL, "value");
- RNA_def_property_ui_text(prop, "Default Value", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
- break;
- case SOCK_STRING:
- RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "default_value");
-
- prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "subtype");
- RNA_def_property_enum_items(prop, subtype_items);
- RNA_def_property_ui_text(prop, "Subtype", "Subtype defining the socket value details");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
-
- prop = RNA_def_property(srna, "default_value", PROP_STRING, PROP_FILEPATH);
- RNA_def_property_string_sdna(prop, NULL, "value");
- RNA_def_property_ui_text(prop, "Default Value", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
- break;
- }
-
- /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */
- RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
+ func= RNA_def_function(srna, "new", newfunc);
+ RNA_def_function_ui_description(func, "Add a socket to this node");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
+ parm= RNA_def_string(func, "type", "", MAX_NAME, "Type", "Data type");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_string(func, "name", "", MAX_NAME, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_string(func, "identifier", "", MAX_NAME, "Identifier", "Unique socket identifier");
+ /* return value */
+ parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "New socket");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "rna_Node_socket_remove");
+ RNA_def_function_ui_description(func, "Remove a socket from this node");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
+ parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "The socket to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "clear", clearfunc);
+ RNA_def_function_ui_description(func, "Remove all sockets from this node");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
}
static void rna_def_node(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ static EnumPropertyItem dummy_static_type_items[] = {
+ {NODE_CUSTOM, "CUSTOM", 0, "Custom", "Custom Node"},
+ {0, NULL, 0, NULL, NULL}};
srna = RNA_def_struct(brna, "Node", NULL);
RNA_def_struct_ui_text(srna, "Node", "Node in a node tree");
@@ -4773,6 +6358,16 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_NODE);
RNA_def_struct_refine_func(srna, "rna_Node_refine");
RNA_def_struct_path_func(srna, "rna_Node_path");
+ RNA_def_struct_register_funcs(srna, "rna_Node_register", "rna_Node_unregister", NULL);
+ RNA_def_struct_idprops_func(srna, "rna_Node_idprops");
+
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, dummy_static_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_node_static_type_itemf");
+ RNA_def_property_enum_default(prop, NODE_CUSTOM);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Type", "Node type (deprecated, use bl_static_type or bl_idname for the actual identifier string)");
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "locx");
@@ -4812,13 +6407,24 @@ static void rna_def_node(BlenderRNA *brna)
prop = RNA_def_property(srna, "inputs", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "inputs", NULL);
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL,
+ "rna_Node_inputs_lookupstring", NULL);
RNA_def_property_struct_type(prop, "NodeSocket");
RNA_def_property_ui_text(prop, "Inputs", "");
+ rna_def_node_sockets_api(brna, prop, SOCK_IN);
prop = RNA_def_property(srna, "outputs", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "outputs", NULL);
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL,
+ "rna_Node_outputs_lookupstring", NULL);
RNA_def_property_struct_type(prop, "NodeSocket");
RNA_def_property_ui_text(prop, "Outputs", "");
+ rna_def_node_sockets_api(brna, prop, SOCK_OUT);
+
+ prop = RNA_def_property(srna, "internal_links", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "internal_links", NULL);
+ RNA_def_property_struct_type(prop, "NodeLink");
+ RNA_def_property_ui_text(prop, "Internal Links", "Internal input-to-output connections for muting");
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "parent");
@@ -4840,8 +6446,9 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL);
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SELECT);
- RNA_def_property_ui_text(prop, "Select", "");
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_Node_select_set");
+ RNA_def_property_ui_text(prop, "Select", "Node selection state");
RNA_def_property_update(prop, NC_NODE | NA_SELECTED, NULL);
prop = RNA_def_property(srna, "show_options", PROP_BOOLEAN, PROP_NONE);
@@ -4868,6 +6475,115 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_ACTIVE_TEXTURE);
RNA_def_property_ui_text(prop, "Show Texture", "Draw node in viewport textured draw mode");
RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ /* generic property update function */
+ func = RNA_def_function(srna, "socket_value_update", "rna_Node_socket_value_update");
+ RNA_def_function_ui_description(func, "Update after property changes");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+
+ func = RNA_def_function(srna, "is_registered_node_type", "rna_Node_is_registered_node_type");
+ RNA_def_function_ui_description(func, "True if a registered node type");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
+ parm = RNA_def_boolean(func, "result", FALSE, "Result", "");
+ RNA_def_function_return(func, parm);
+
+ /* registration */
+ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname");
+ RNA_def_property_string_funcs(prop, "rna_Node_bl_idname_get", "rna_Node_bl_idname_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
+ RNA_def_property_ui_text(prop, "ID Name", "");
+
+ prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->ui_name");
+ RNA_def_property_string_funcs(prop, "rna_Node_bl_label_get", "rna_Node_bl_label_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER);
+ RNA_def_property_ui_text(prop, "Label", "The node label");
+
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATION);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->ui_description");
+ RNA_def_property_string_funcs(prop, "rna_Node_bl_description_get", "rna_Node_bl_description_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop = RNA_def_property(srna, "bl_icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "typeinfo->ui_icon");
+ RNA_def_property_enum_funcs(prop, "rna_Node_bl_icon_get", NULL, NULL);
+ RNA_def_property_enum_items(prop, node_icon_items);
+ RNA_def_property_enum_default(prop, ICON_NODE);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(prop, "Icon", "The node icon");
+
+ prop = RNA_def_property(srna, "bl_static_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "typeinfo->type");
+ RNA_def_property_enum_funcs(prop, "rna_Node_bl_static_type_get", NULL, NULL);
+ RNA_def_property_enum_items(prop, dummy_static_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_node_static_type_itemf");
+ RNA_def_property_enum_default(prop, NODE_CUSTOM);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(prop, "Static Type", "Node type (deprecated, use with care)");
+
+ /* poll */
+ func = RNA_def_function(srna, "poll", NULL);
+ RNA_def_function_ui_description(func, "If non-null output is returned, the node type can be added to the tree");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER);
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+ parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func = RNA_def_function(srna, "poll_instance", NULL);
+ RNA_def_function_ui_description(func, "If non-null output is returned, the node can be added to the tree");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+ parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ /* update */
+ func = RNA_def_function(srna, "update", NULL);
+ RNA_def_function_ui_description(func, "Update on editor changes");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+
+ /* init */
+ func = RNA_def_function(srna, "init", NULL);
+ RNA_def_function_ui_description(func, "Initialize a new instance of this node");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+
+ /* copy */
+ func = RNA_def_function(srna, "copy", NULL);
+ RNA_def_function_ui_description(func, "Initialize a new instance of this node from an existing node");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "node", "Node", "Node", "Existing node to copy");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+
+ /* free */
+ func = RNA_def_function(srna, "free", NULL);
+ RNA_def_function_ui_description(func, "Clean up node on removal");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+
+ /* draw buttons */
+ func = RNA_def_function(srna, "draw_buttons", NULL);
+ RNA_def_function_ui_description(func, "Draw node buttons");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+
+ /* draw buttons extended */
+ func = RNA_def_function(srna, "draw_buttons_ext", NULL);
+ RNA_def_function_ui_description(func, "Draw node buttons in the sidebar");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+ 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_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
}
static void rna_def_node_link(BlenderRNA *brna)
@@ -4880,63 +6596,165 @@ static void rna_def_node_link(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "bNodeLink");
RNA_def_struct_ui_icon(srna, ICON_NODE);
+ prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_LINK_VALID);
+ RNA_def_struct_ui_text(srna, "Valid", "Link is valid");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, NULL);
+
prop = RNA_def_property(srna, "from_node", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "fromnode");
RNA_def_property_struct_type(prop, "Node");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "From node", "");
prop = RNA_def_property(srna, "to_node", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tonode");
RNA_def_property_struct_type(prop, "Node");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "To node", "");
prop = RNA_def_property(srna, "from_socket", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "fromsock");
RNA_def_property_struct_type(prop, "NodeSocket");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "From socket", "");
prop = RNA_def_property(srna, "to_socket", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tosock");
RNA_def_property_struct_type(prop, "NodeSocket");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "To socket", "");
+
+ prop = RNA_def_property(srna, "is_hidden", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_NodeLink_is_hidden_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Is Hidden", "Link is hidden due to invisible sockets");
}
-static void rna_def_group_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int in_out)
+static void rna_def_nodetree_nodes_api(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ PropertyRNA *parm, *prop;
+ FunctionRNA *func;
+
+ RNA_def_property_srna(cprop, "Nodes");
+ srna= RNA_def_struct(brna, "Nodes", NULL);
+ RNA_def_struct_sdna(srna, "bNodeTree");
+ RNA_def_struct_ui_text(srna, "Nodes", "Collection of Nodes");
+
+ func= RNA_def_function(srna, "new", "rna_NodeTree_node_new");
+ RNA_def_function_ui_description(func, "Add a node to this node tree");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ parm= RNA_def_string(func, "type", "", MAX_NAME, "Type", "Type of node to add");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ /* return value */
+ parm= RNA_def_pointer(func, "node", "Node", "", "New node");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "rna_NodeTree_node_remove");
+ RNA_def_function_ui_description(func, "Remove a node from this node tree");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_pointer(func, "node", "Node", "", "The node to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+
+ func= RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
+ RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+
+ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Node");
+ RNA_def_property_pointer_funcs(prop, "rna_NodeTree_active_node_get", "rna_NodeTree_active_node_set", NULL, NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
+ RNA_def_property_ui_text(prop, "Active Node", "Active node in this tree");
+ RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
+}
+
+static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *parm;
FunctionRNA *func;
- RNA_def_property_srna(cprop, (in_out == SOCK_IN ? "GroupInputs" : "GroupOutputs"));
- srna = RNA_def_struct(brna, (in_out == SOCK_IN ? "GroupInputs" : "GroupOutputs"), NULL);
+ RNA_def_property_srna(cprop, "NodeLinks");
+ srna = RNA_def_struct(brna, "NodeLinks", NULL);
RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_text(srna, "Group Sockets", "Collection of group sockets");
+ RNA_def_struct_ui_text(srna, "Node Links", "Collection of Node Links");
- func = RNA_def_function(srna, "new", (in_out == SOCK_IN ? "rna_NodeTree_input_new" : "rna_NodeTree_output_new"));
- RNA_def_function_ui_description(func, "Add a socket to the group tree");
+ func = RNA_def_function(srna, "new", "rna_NodeTree_link_new");
+ RNA_def_function_ui_description(func, "Add a node link to this node tree");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
- RNA_def_string(func, "name", "Socket", MAX_NAME, "Name", "Name of the socket");
- RNA_def_enum(func, "type", node_socket_type_items, SOCK_FLOAT, "Type", "Type of socket");
- /* return value */
- parm = RNA_def_pointer(func, "socket", "NodeSocket", "", "New socket");
+ parm = RNA_def_pointer(func, "input", "NodeSocket", "", "The input socket");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_pointer(func, "output", "NodeSocket", "", "The output socket");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "verify_limits", TRUE, "Verify Limits", "Remove existing links if connection limit is exceeded");
+ /* return */
+ parm = RNA_def_pointer(func, "link", "NodeLink", "", "New node link");
RNA_def_function_return(func, parm);
- func = RNA_def_function(srna, "expose",
- (in_out == SOCK_IN ? "rna_NodeTree_input_expose" : "rna_NodeTree_output_expose"));
- RNA_def_function_ui_description(func, "Expose an internal socket in the group tree");
+ func = RNA_def_function(srna, "remove", "rna_NodeTree_link_remove");
+ RNA_def_function_ui_description(func, "remove a node link from the node tree");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "link", "NodeLink", "", "The node link to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+
+ func = RNA_def_function(srna, "clear", "rna_NodeTree_link_clear");
+ RNA_def_function_ui_description(func, "remove all node links from the node tree");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+}
+
+static void rna_def_node_tree_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int in_out)
+{
+ StructRNA *srna;
+ PropertyRNA *parm;
+ FunctionRNA *func;
+ const char *structtype = (in_out == SOCK_IN ? "NodeTreeInputs" : "NodeTreeOutputs");
+ const char *uiname = (in_out == SOCK_IN ? "Node Tree Inputs" : "Node Tree Outputs");
+ const char *newfunc = (in_out == SOCK_IN ? "rna_NodeTree_inputs_new" : "rna_NodeTree_outputs_new");
+ const char *clearfunc = (in_out == SOCK_IN ? "rna_NodeTree_inputs_clear" : "rna_NodeTree_outputs_clear");
+
+ RNA_def_property_srna(cprop, structtype);
+ srna= RNA_def_struct(brna, structtype, NULL);
+ RNA_def_struct_sdna(srna, "bNodeTree");
+ RNA_def_struct_ui_text(srna, uiname, "Collection of Node Tree Sockets");
+
+ func= RNA_def_function(srna, "new", newfunc);
+ RNA_def_function_ui_description(func, "Add a socket to this node tree");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
- RNA_def_pointer(func, "sock", "NodeSocket", "Socket", "Internal node socket to expose");
+ parm= RNA_def_string(func, "type", "", MAX_NAME, "Type", "Data type");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_string(func, "name", "", MAX_NAME, "Name", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "add_link", TRUE, "Add Link", "If TRUE, adds a link to the internal socket");
/* return value */
- parm = RNA_def_pointer(func, "socket", "NodeSocket", "", "New socket");
+ parm= RNA_def_pointer(func, "socket", "NodeSocketInterface", "", "New socket");
RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "rna_NodeTree_socket_remove");
+ RNA_def_function_ui_description(func, "Remove a socket from this node tree");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_pointer(func, "socket", "NodeSocketInterface", "", "The socket to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "clear", clearfunc);
+ RNA_def_function_ui_description(func, "Remove all sockets from this node tree");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
}
static void rna_def_nodetree(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ static EnumPropertyItem static_type_items[] = {
+ {NTREE_SHADER, "SHADER", ICON_MATERIAL, "Shader", "Shader nodes"},
+ {NTREE_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture nodes"},
+ {NTREE_COMPOSIT, "COMPOSITING", ICON_RENDERLAYERS, "Compositing", "Compositing nodes"},
+ {0, NULL, 0, NULL, NULL}
+ };
srna = RNA_def_struct(brna, "NodeTree", "ID");
RNA_def_struct_ui_text(srna, "Node Tree",
@@ -4944,10 +6762,18 @@ static void rna_def_nodetree(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "bNodeTree");
RNA_def_struct_ui_icon(srna, ICON_NODETREE);
RNA_def_struct_refine_func(srna, "rna_NodeTree_refine");
+ RNA_def_struct_register_funcs(srna, "rna_NodeTree_register", "rna_NodeTree_unregister", NULL);
/* AnimData */
rna_def_animdata_common(srna);
-
+
+ /* Nodes Collection */
+ prop = RNA_def_property(srna, "nodes", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "nodes", NULL);
+ RNA_def_property_struct_type(prop, "Node");
+ RNA_def_property_ui_text(prop, "Nodes", "");
+ rna_def_nodetree_nodes_api(brna, prop);
+
/* NodeLinks Collection */
prop = RNA_def_property(srna, "links", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "links", NULL);
@@ -4965,21 +6791,100 @@ static void rna_def_nodetree(BlenderRNA *brna)
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_enum_items(prop, nodetree_type_items);
- RNA_def_property_ui_text(prop, "Type", "Node Tree type");
+ RNA_def_property_enum_items(prop, static_type_items);
+ RNA_def_property_ui_text(prop, "Type", "Node Tree type (deprecated, bl_idname is the actual node tree type identifier)");
- /* group sockets */
prop = RNA_def_property(srna, "inputs", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "inputs", NULL);
- RNA_def_property_struct_type(prop, "NodeSocket");
- RNA_def_property_ui_text(prop, "Inputs", "");
- rna_def_group_sockets_api(brna, prop, SOCK_IN);
-
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL,
+ "rna_NodeTree_inputs_lookupstring", NULL);
+ RNA_def_property_struct_type(prop, "NodeSocketInterface");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Inputs", "Node tree inputs");
+ rna_def_node_tree_sockets_api(brna, prop, SOCK_IN);
+
+ prop = RNA_def_property(srna, "active_input", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop, "rna_NodeTree_active_input_get", "rna_NodeTree_active_input_set", NULL);
+ RNA_def_property_ui_text(prop, "Active Input", "Index of the active input");
+ RNA_def_property_update(prop, NC_NODE, NULL);
+
prop = RNA_def_property(srna, "outputs", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "outputs", NULL);
- RNA_def_property_struct_type(prop, "NodeSocket");
- RNA_def_property_ui_text(prop, "Outputs", "");
- rna_def_group_sockets_api(brna, prop, SOCK_OUT);
+ RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL,
+ "rna_NodeTree_outputs_lookupstring", NULL);
+ RNA_def_property_struct_type(prop, "NodeSocketInterface");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Outputs", "Node tree outputs");
+ rna_def_node_tree_sockets_api(brna, prop, SOCK_OUT);
+
+ prop = RNA_def_property(srna, "active_output", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop, "rna_NodeTree_active_output_get", "rna_NodeTree_active_output_set", NULL);
+ RNA_def_property_ui_text(prop, "Active Output", "Index of the active output");
+ RNA_def_property_update(prop, NC_NODE, NULL);
+
+ /* exposed as a function for runtime interface type properties */
+ func = RNA_def_function(srna, "interface_update", "rna_NodeTree_interface_update");
+ RNA_def_function_ui_description(func, "Updated node group interface");
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+
+ /* registration */
+ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname");
+ RNA_def_property_string_funcs(prop, "rna_NodeTree_bl_idname_get", "rna_NodeTree_bl_idname_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
+ RNA_def_property_ui_text(prop, "ID Name", "");
+
+ prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->ui_name");
+ RNA_def_property_string_funcs(prop, "rna_NodeTree_bl_label_get", "rna_NodeTree_bl_label_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER);
+ RNA_def_property_ui_text(prop, "Label", "The node tree label");
+
+ prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATION);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->ui_description");
+ RNA_def_property_string_funcs(prop, "rna_NodeTree_bl_description_get", "rna_NodeTree_bl_description_length", NULL);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop = RNA_def_property(srna, "bl_icon", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "typeinfo->ui_icon");
+ RNA_def_property_enum_funcs(prop, "rna_NodeTree_bl_icon_get", NULL, NULL);
+ RNA_def_property_enum_items(prop, node_icon_items);
+ RNA_def_property_enum_default(prop, ICON_NODETREE);
+ RNA_def_property_flag(prop, PROP_REGISTER);
+ RNA_def_property_ui_text(prop, "Icon", "The node tree icon");
+
+ /* poll */
+ func = RNA_def_function(srna, "poll", NULL);
+ RNA_def_function_ui_description(func, "Check visibility in the editor");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ RNA_def_function_return(func, RNA_def_boolean(func, "visible", FALSE, "", ""));
+
+ /* draw add menu */
+ func = RNA_def_function(srna, "draw_add_menu", NULL);
+ RNA_def_function_ui_description(func, "Draw the menu for adding nodes");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+ parm = RNA_def_property(func, "layout", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(parm, "UILayout");
+ RNA_def_property_ui_text(parm, "Layout", "Menu layout in the UI");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+
+ /* get a node tree from context */
+ func = RNA_def_function(srna, "get_from_context", NULL);
+ RNA_def_function_ui_description(func, "Get a node tree from the context");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+ parm = RNA_def_pointer(func, "result_1", "NodeTree", "Node Tree", "Active node tree from context");
+ RNA_def_function_output(func, parm);
+ parm = RNA_def_pointer(func, "result_2", "ID", "Owner ID", "ID data block that owns the node tree");
+ RNA_def_function_output(func, parm);
+ parm = RNA_def_pointer(func, "result_3", "ID", "From ID", "Original ID data block selected from the context");
+ RNA_def_function_output(func, parm);
}
static void rna_def_composite_nodetree(BlenderRNA *brna)
@@ -4990,15 +6895,7 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
srna = RNA_def_struct(brna, "CompositorNodeTree", "NodeTree");
RNA_def_struct_ui_text(srna, "Compositor Node Tree", "Node tree consisting of linked nodes used for compositing");
RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_icon(srna, ICON_NODETREE);
-
- /* Nodes Collection */
- prop = RNA_def_property(srna, "nodes", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "nodes", NULL);
- RNA_def_property_struct_type(prop, "Node");
- RNA_def_property_ui_text(prop, "Nodes", "");
-
- rna_def_composite_nodetree_api(brna, prop);
+ RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
prop = RNA_def_property(srna, "render_quality", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "render_quality");
@@ -5029,6 +6926,11 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Two Pass", "Use two pass execution during editing: first calculate fast nodes, "
"second pass calculate all nodes");
+ prop = RNA_def_property(srna, "is_local_tree", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_default(prop, FALSE);
+ RNA_def_property_flag(prop, PROP_IDPROPERTY);
+ RNA_def_property_ui_text(prop, "Local Scene Tree", "Local scene node tree, eligible for special node types");
+
prop = RNA_def_property(srna, "use_viewer_border", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_VIEWER_BORDER);
RNA_def_property_ui_text(prop, "Viewer Border", "Use boundaries for viewer nodes and composite backdrop");
@@ -5044,15 +6946,12 @@ static void rna_def_shader_nodetree(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Shader Node Tree",
"Node tree consisting of linked nodes used for materials (and other shading datablocks)");
RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_icon(srna, ICON_NODETREE);
+ RNA_def_struct_ui_icon(srna, ICON_MATERIAL);
- /* Nodes Collection */
- prop = RNA_def_property(srna, "nodes", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "nodes", NULL);
- RNA_def_property_struct_type(prop, "Node");
- RNA_def_property_ui_text(prop, "Nodes", "");
-
- rna_def_shader_nodetree_api(brna, prop);
+ prop = RNA_def_property(srna, "is_local_tree", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_default(prop, FALSE);
+ RNA_def_property_flag(prop, PROP_IDPROPERTY);
+ RNA_def_property_ui_text(prop, "Local Material Tree", "Local material node tree, eligible for special node types");
}
static void rna_def_texture_nodetree(BlenderRNA *brna)
@@ -5063,64 +6962,87 @@ static void rna_def_texture_nodetree(BlenderRNA *brna)
srna = RNA_def_struct(brna, "TextureNodeTree", "NodeTree");
RNA_def_struct_ui_text(srna, "Texture Node Tree", "Node tree consisting of linked nodes used for textures");
RNA_def_struct_sdna(srna, "bNodeTree");
- RNA_def_struct_ui_icon(srna, ICON_NODETREE);
-
- /* Nodes Collection */
- prop = RNA_def_property(srna, "nodes", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "nodes", NULL);
- RNA_def_property_struct_type(prop, "Node");
- RNA_def_property_ui_text(prop, "Nodes", "");
+ RNA_def_struct_ui_icon(srna, ICON_TEXTURE);
- rna_def_texture_nodetree_api(brna, prop);
+ prop = RNA_def_property(srna, "is_local_tree", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_default(prop, FALSE);
+ RNA_def_property_flag(prop, PROP_IDPROPERTY);
+ RNA_def_property_ui_text(prop, "Local Texture Tree", "Local texture node tree, eligible for special node types");
}
-static void define_specific_node(BlenderRNA *brna, int id, void (*def_func)(StructRNA *))
+static void define_specific_node(BlenderRNA *brna, const char *struct_name, const char *base_name,
+ const char *ui_name, const char *ui_desc, void (*def_func)(StructRNA *))
{
- StructRNA *srna = def_node(brna, id);
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+ srna = RNA_def_struct(brna, struct_name, base_name);
+ RNA_def_struct_ui_text(srna, ui_name, ui_desc);
+ RNA_def_struct_sdna(srna, "bNode");
+
+ func = RNA_def_function(srna, "is_registered_node_type", "rna_Node_is_registered_node_type");
+ RNA_def_function_ui_description(func, "True if a registered node type");
+ RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_SELF_TYPE);
+ parm = RNA_def_boolean(func, "result", FALSE, "Result", "");
+ RNA_def_function_return(func, parm);
+
if (def_func)
def_func(srna);
}
+static void rna_def_node_instance_hash(BlenderRNA *brna)
+{
+ StructRNA *srna;
+
+ srna = RNA_def_struct(brna, "NodeInstanceHash", NULL);
+ RNA_def_struct_ui_text(srna, "Node Instance Hash", "Hash table containing node instance data");
+
+ /* XXX This type is a stub for now, only used to store instance hash in the context.
+ * Eventually could use a StructRNA pointer to define a specific data type
+ * and expose lookup functions.
+ */
+}
+
void RNA_def_nodetree(BlenderRNA *brna)
{
- init();
- rna_def_nodetree(brna);
-
rna_def_node_socket(brna);
-
- /* Generate RNA definitions for all socket subtypes */
- #define SUBTYPE(socktype, stypename, id, idname) \
- rna_def_node_socket_subtype(brna, SOCK_##socktype, PROP_##id, "NodeSocket"#stypename#idname, \
- #idname" "#stypename" Node Socket");
- NODE_DEFINE_SUBTYPES
- #undef SUBTYPE
- rna_def_node_socket_subtype(brna, SOCK_BOOLEAN, 0, "NodeSocketBoolean", "Boolean Node Socket");
- rna_def_node_socket_subtype(brna, SOCK_RGBA, 0, "NodeSocketRGBA", "RGBA Node Socket");
- rna_def_node_socket_subtype(brna, SOCK_SHADER, 0, "NodeSocketShader", "Shader Closure Node Socket");
+ rna_def_node_socket_interface(brna);
rna_def_node(brna);
rna_def_node_link(brna);
rna_def_shader_node(brna);
rna_def_compositor_node(brna);
rna_def_texture_node(brna);
- rna_def_special_node(brna);
+
+ rna_def_nodetree(brna);
+
+ rna_def_node_socket_standard_types(brna);
rna_def_composite_nodetree(brna);
rna_def_shader_nodetree(brna);
rna_def_texture_nodetree(brna);
+
#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
- define_specific_node(brna, ID, DefFunc);
-
- #include "rna_nodetree_types.h"
+ define_specific_node(brna, #Category #StructName, #Category, UIName, UIDesc, DefFunc);
- define_specific_node(brna, NODE_GROUP, def_group);
- define_specific_node(brna, NODE_FRAME, def_frame);
- define_specific_node(brna, NODE_REROUTE, 0);
+ /* hack, don't want to add include path to RNA just for this, since in the future RNA types
+ * for nodes should be defined locally at runtime anyway ...
+ */
+ #include "../../nodes/NOD_static_types.h"
+
+ /* Node group types need to be defined for shader, compositor, texture nodes individually.
+ * Cannot use the static types header for this, since they share the same int id.
+ */
+ define_specific_node(brna, "ShaderNodeGroup", "ShaderNode", "Group", "", def_group);
+ define_specific_node(brna, "CompositorNodeGroup", "CompositorNode", "Group", "", def_group);
+ define_specific_node(brna, "TextureNodeGroup", "TextureNode", "Group", "", def_group);
/* special socket types */
rna_def_cmp_output_file_slot_file(brna);
rna_def_cmp_output_file_slot_layer(brna);
+
+ rna_def_node_instance_hash(brna);
}
/* clean up macro definition */