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:
authorLukas Toenne <lukas.toenne@googlemail.com>2013-03-18 20:34:57 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2013-03-18 20:34:57 +0400
commit4638e5f99a9ba59ad0b8a1fd52b12e876480b9e8 (patch)
tree2444f12b4612440f44cf02835cdf5951b6564e92 /source/blender/makesrna
parent7bfef29f2f2a1b262d28abdc6e30fcd9c1f1caad (diff)
Merge of the PyNodes branch (aka "custom nodes") into trunk.
PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
Diffstat (limited to 'source/blender/makesrna')
-rw-r--r--source/blender/makesrna/RNA_access.h12
-rw-r--r--source/blender/makesrna/RNA_define.h2
-rw-r--r--source/blender/makesrna/RNA_enum_types.h23
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt2
-rw-r--r--source/blender/makesrna/intern/rna_access.c61
-rw-r--r--source/blender/makesrna/intern/rna_color.c2
-rw-r--r--source/blender/makesrna/intern/rna_define.c72
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c8
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c40
-rw-r--r--source/blender/makesrna/intern/rna_material.c10
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c4154
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h215
-rw-r--r--source/blender/makesrna/intern/rna_scene.c9
-rw-r--r--source/blender/makesrna/intern/rna_space.c168
-rw-r--r--source/blender/makesrna/intern/rna_texture.c20
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c16
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c6
-rw-r--r--source/blender/makesrna/intern/rna_world.c8
18 files changed, 3435 insertions, 1393 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index cde104710df..efa6f37648a 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -363,14 +363,13 @@ extern StructRNA RNA_NearSensor;
extern StructRNA RNA_NlaStrip;
extern StructRNA RNA_NlaTrack;
extern StructRNA RNA_Node;
-extern StructRNA RNA_NodeForLoop;
-extern StructRNA RNA_NodeGroup;
extern StructRNA RNA_NodeOutputFileSlotFile;
extern StructRNA RNA_NodeOutputFileSlotLayer;
+extern StructRNA RNA_NodeInstanceHash;
extern StructRNA RNA_NodeLink;
extern StructRNA RNA_NodeSocket;
+extern StructRNA RNA_NodeSocketInterface;
extern StructRNA RNA_NodeTree;
-extern StructRNA RNA_NodeWhileLoop;
extern StructRNA RNA_NoiseTexture;
extern StructRNA RNA_NorController;
extern StructRNA RNA_Object;
@@ -655,7 +654,9 @@ StructRNA *RNA_struct_find(const char *identifier);
const char *RNA_struct_identifier(StructRNA *type);
const char *RNA_struct_ui_name(StructRNA *type);
+const char *RNA_struct_ui_name_raw(StructRNA *type);
const char *RNA_struct_ui_description(StructRNA *type);
+const char *RNA_struct_ui_description_raw(StructRNA *type);
const char *RNA_struct_translation_context(StructRNA *type);
int RNA_struct_ui_icon(StructRNA *type);
@@ -721,7 +722,9 @@ int RNA_property_array_item_index(PropertyRNA *prop, char name);
int RNA_property_string_maxlength(PropertyRNA *prop);
const char *RNA_property_ui_name(PropertyRNA *prop);
+const char *RNA_property_ui_name_raw(PropertyRNA *prop);
const char *RNA_property_ui_description(PropertyRNA *prop);
+const char *RNA_property_ui_description_raw(PropertyRNA *prop);
const char *RNA_property_translation_context(PropertyRNA *prop);
int RNA_property_ui_icon(PropertyRNA *prop);
@@ -976,9 +979,11 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name);
/* check if the idproperty exists, for operators */
bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost);
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop);
+void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop);
bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost);
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier);
bool RNA_property_is_idprop(PropertyRNA *prop);
+void RNA_struct_property_unset(PointerRNA *ptr, const char *identifier);
/* python compatible string representation of this property, (must be freed!) */
char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index);
@@ -995,6 +1000,7 @@ char *RNA_function_as_string_keywords(struct bContext *C, FunctionRNA *func, Poi
const char *RNA_function_identifier(FunctionRNA *func);
const char *RNA_function_ui_description(FunctionRNA *func);
+const char *RNA_function_ui_description_raw(FunctionRNA *func);
int RNA_function_flag(FunctionRNA *func);
int RNA_function_defined(FunctionRNA *func);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 5ab37c6d97b..924fc505fda 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -223,6 +223,8 @@ const char *RNA_property_typename(PropertyType type);
#define IS_DNATYPE_FLOAT_COMPAT(_str) (strcmp(_str, "float") == 0 || strcmp(_str, "double") == 0)
#define IS_DNATYPE_INT_COMPAT(_str) (strcmp(_str, "int") == 0 || strcmp(_str, "short") == 0 || strcmp(_str, "char") == 0)
+void RNA_identifier_sanitize(char *identifier, int property);
+
/* max size for dynamic defined type descriptors,
* this value is arbitrary */
#define RNA_DYN_DESCR_MAX 240
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index eabf0391c01..2719ae889d4 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -29,6 +29,10 @@
#include "RNA_types.h"
+struct bNodeTreeType;
+struct bNodeType;
+struct bNodeSocketType;
+
/* Types */
extern EnumPropertyItem id_type_items[];
@@ -128,8 +132,23 @@ extern EnumPropertyItem gameproperty_type_items[];
extern EnumPropertyItem viewport_shade_items[];
-extern EnumPropertyItem nodetree_type_items[];
-extern EnumPropertyItem node_socket_type_items[];
+int rna_node_tree_type_to_enum(struct bNodeTreeType *typeinfo);
+int rna_node_tree_idname_to_enum(const char *idname);
+struct bNodeTreeType *rna_node_tree_type_from_enum(int value);
+EnumPropertyItem *rna_node_tree_type_itemf(void *data, int (*poll)(void *data, struct bNodeTreeType *), int *free);
+
+int rna_node_type_to_enum(struct bNodeType *typeinfo);
+int rna_node_idname_to_enum(const char *idname);
+struct bNodeType *rna_node_type_from_enum(int value);
+EnumPropertyItem *rna_node_type_itemf(void *data, int (*poll)(void *data, struct bNodeType*), int *free);
+
+int rna_node_socket_type_to_enum(struct bNodeSocketType *typeinfo);
+int rna_node_socket_idname_to_enum(const char *idname);
+struct bNodeSocketType *rna_node_socket_type_from_enum(int value);
+EnumPropertyItem *rna_node_socket_type_itemf(void *data, int (*poll)(void *data, struct bNodeSocketType*), int *free);
+
+extern EnumPropertyItem node_socket_in_out_items[];
+extern EnumPropertyItem node_icon_items[];
extern EnumPropertyItem node_math_items[];
extern EnumPropertyItem node_vec_math_items[];
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 7621ebb70b3..a0ee5e05390 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -259,6 +259,7 @@ blender_include_dirs(
../../imbuf
../../ikplugin
../../makesdna
+ ../../nodes/
../../windowmanager
../../editors/include
../../render/extern/include
@@ -296,7 +297,6 @@ set(SRC
${SRC_RNA_INC}
rna_internal.h
rna_internal_types.h
- rna_nodetree_types.h
rna_mesh_utils.h
)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index f3efbd0d53e..92ce8122597 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -282,6 +282,20 @@ static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
return NULL;
}
+static void rna_idproperty_free(PointerRNA *ptr, const char *name)
+{
+ IDProperty *group = RNA_struct_idprops(ptr, 0);
+
+ if (group) {
+ IDProperty *idprop = IDP_GetPropertyFromGroup(group, name);
+ if (idprop) {
+ IDP_RemFromGroup(group, idprop);
+ IDP_FreeProperty(idprop);
+ MEM_freeN(idprop);
+ }
+ }
+}
+
static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
{
if (prop->magic == RNA_MAGIC) {
@@ -477,7 +491,7 @@ static const char *rna_ensure_property_description(PropertyRNA *prop)
description = ((IDProperty *)prop)->name; /* XXX - not correct */
}
- return TIP_(description);
+ return description;
}
static const char *rna_ensure_property_name(PropertyRNA *prop)
@@ -489,7 +503,7 @@ static const char *rna_ensure_property_name(PropertyRNA *prop)
else
name = ((IDProperty *)prop)->name;
- return CTX_IFACE_(prop->translation_context, name);
+ return name;
}
/* Structs */
@@ -515,6 +529,11 @@ const char *RNA_struct_ui_name(StructRNA *type)
return CTX_IFACE_(type->translation_context, type->name);
}
+const char *RNA_struct_ui_name_raw(StructRNA *type)
+{
+ return type->name;
+}
+
int RNA_struct_ui_icon(StructRNA *type)
{
if (type)
@@ -528,6 +547,11 @@ const char *RNA_struct_ui_description(StructRNA *type)
return TIP_(type->description);
}
+const char *RNA_struct_ui_description_raw(StructRNA *type)
+{
+ return type->description;
+}
+
const char *RNA_struct_translation_context(StructRNA *type)
{
return type->translation_context ? type->translation_context : BLF_I18NCONTEXT_DEFAULT;
@@ -778,7 +802,7 @@ const char *RNA_property_identifier(PropertyRNA *prop)
const char *RNA_property_description(PropertyRNA *prop)
{
- return rna_ensure_property_description(prop);
+ return TIP_(rna_ensure_property_description(prop));
}
PropertyType RNA_property_type(PropertyRNA *prop)
@@ -1401,11 +1425,21 @@ int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, Property
const char *RNA_property_ui_name(PropertyRNA *prop)
{
+ return CTX_IFACE_(prop->translation_context, rna_ensure_property_name(prop));
+}
+
+const char *RNA_property_ui_name_raw(PropertyRNA *prop)
+{
return rna_ensure_property_name(prop);
}
const char *RNA_property_ui_description(PropertyRNA *prop)
{
+ return TIP_(rna_ensure_property_description(prop));
+}
+
+const char *RNA_property_ui_description_raw(PropertyRNA *prop)
+{
return rna_ensure_property_description(prop);
}
@@ -4797,6 +4831,13 @@ bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
}
}
+void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop)
+{
+ if (prop->flag & PROP_IDPROPERTY) {
+ rna_idproperty_free(ptr, prop->identifier);
+ }
+}
+
bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
@@ -4825,6 +4866,15 @@ bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
}
}
+void RNA_struct_property_unset(PointerRNA *ptr, const char *identifier)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
+
+ if (prop) {
+ RNA_property_unset(ptr, prop);
+ }
+}
+
bool RNA_property_is_idprop(PropertyRNA *prop)
{
return (prop->magic != RNA_MAGIC);
@@ -5190,6 +5240,11 @@ const char *RNA_function_identifier(FunctionRNA *func)
const char *RNA_function_ui_description(FunctionRNA *func)
{
+ return TIP_(func->description);
+}
+
+const char *RNA_function_ui_description_raw(FunctionRNA *func)
+{
return func->description;
}
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 74d212fae57..49e1122bf18 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -298,7 +298,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
for (node = ntree->nodes.first; node; node = node->next) {
if (ELEM3(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
- ED_node_generic_update(bmain, ntree, node);
+ ED_node_tag_update_nodetree(bmain, ntree);
}
}
}
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index c92777af8fd..61e67ad3298 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -458,6 +458,78 @@ static int rna_validate_identifier(const char *identifier, char *error, int prop
return 1;
}
+void RNA_identifier_sanitize(char *identifier, int property)
+{
+ int a = 0;
+
+ /* list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
+ static const char *kwlist[] = {
+ /* "False", "None", "True", */
+ "and", "as", "assert", "break",
+ "class", "continue", "def", "del", "elif", "else", "except",
+ "finally", "for", "from", "global", "if", "import", "in",
+ "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
+ "return", "try", "while", "with", "yield", NULL
+ };
+
+
+ if (!isalpha(identifier[0])) {
+ /* first character failed isalpha() check */
+ identifier[0] = '_';
+ }
+
+ for (a = 0; identifier[a]; a++) {
+ if (DefRNA.preprocess && property) {
+ if (isalpha(identifier[a]) && isupper(identifier[a])) {
+ /* property names must contain lower case characters only */
+ identifier[a] = tolower(identifier[a]);
+ }
+ }
+
+ if (identifier[a] == '_') {
+ continue;
+ }
+
+ if (identifier[a] == ' ') {
+ /* spaces are not okay in identifier names */
+ identifier[a] = '_';
+ }
+
+ if (isalnum(identifier[a]) == 0) {
+ /* one of the characters failed an isalnum() check and is not an underscore */
+ identifier[a] = '_';
+ }
+ }
+
+ for (a = 0; kwlist[a]; a++) {
+ if (strcmp(identifier, kwlist[a]) == 0) {
+ /* this keyword is reserved by python.
+ * just replace the last character by '_' to keep it readable.
+ */
+ identifier[strlen(identifier)-1] = '_';
+ break;
+ }
+ }
+
+ if (property) {
+ static const char *kwlist_prop[] = {
+ /* not keywords but reserved all the same because py uses */
+ "keys", "values", "items", "get",
+ NULL
+ };
+
+ for (a = 0; kwlist_prop[a]; a++) {
+ if (strcmp(identifier, kwlist_prop[a]) == 0) {
+ /* this keyword is reserved by python.
+ * just replace the last character by '_' to keep it readable.
+ */
+ identifier[strlen(identifier)-1] = '_';
+ break;
+ }
+ }
+ }
+}
+
/* Blender Data Definition */
BlenderRNA *RNA_create(void)
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index 912f4d914cb..7fee67cd569 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -42,6 +42,7 @@
#include "MEM_guardedalloc.h"
+#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_texture.h"
@@ -169,14 +170,14 @@ static void rna_Lamp_spot_size_set(PointerRNA *ptr, float value)
la->spotsize = RAD2DEGF(value);
}
-static void rna_Lamp_use_nodes_update(Main *blain, Scene *scene, PointerRNA *ptr)
+static void rna_Lamp_use_nodes_update(bContext *C, PointerRNA *ptr)
{
Lamp *la = (Lamp *)ptr->data;
if (la->use_nodes && la->nodetree == NULL)
- ED_node_shader_default(scene, &la->id);
+ ED_node_shader_default(C, &la->id);
- rna_Lamp_update(blain, scene, ptr);
+ rna_Lamp_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
#else
@@ -414,6 +415,7 @@ static void rna_def_lamp(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the lamp");
RNA_def_property_update(prop, 0, "rna_Lamp_use_nodes_update");
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 4d5d4d4a7cd..a79fa1aaed4 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -235,23 +235,32 @@ static void rna_Main_materials_remove(Main *bmain, ReportList *reports, PointerR
}
}
-static bNodeTree *rna_Main_nodetree_new(Main *bmain, const char *name, int type)
+static EnumPropertyItem *rna_Main_nodetree_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
- bNodeTree *tree = ntreeAddTree(bmain, name, type, NODE_GROUP);
-
- id_us_min(&tree->id);
- return tree;
+ return rna_node_tree_type_itemf(NULL, NULL, free);
+}
+static struct bNodeTree *rna_Main_nodetree_new(Main *bmain, const char *name, int type)
+{
+ bNodeTreeType *typeinfo = rna_node_tree_type_from_enum(type);
+ if (typeinfo) {
+ bNodeTree *ntree = ntreeAddTree(bmain, name, typeinfo->idname);
+
+ id_us_min(&ntree->id);
+ return ntree;
+ }
+ else
+ return NULL;
}
-static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, PointerRNA *tree_ptr)
+static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, PointerRNA *ntree_ptr)
{
- bNodeTree *tree = tree_ptr->data;
- if (ID_REAL_USERS(tree) <= 0) {
- BKE_libblock_free(&bmain->nodetree, tree);
- RNA_POINTER_INVALIDATE(tree_ptr);
+ bNodeTree *ntree = ntree_ptr->data;
+ if (ID_REAL_USERS(ntree) <= 0) {
+ BKE_libblock_free(&bmain->nodetree, ntree);
+ RNA_POINTER_INVALIDATE(ntree_ptr);
}
else {
BKE_reportf(reports, RPT_ERROR, "Node tree '%s' must have zero users to be removed, found %d",
- tree->id.name + 2, ID_REAL_USERS(tree));
+ ntree->id.name + 2, ID_REAL_USERS(ntree));
}
}
@@ -1069,10 +1078,8 @@ void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop)
PropertyRNA *parm;
PropertyRNA *prop;
- static EnumPropertyItem node_nodetree_items[] = {
- {0, "SHADER", 0, "Shader", ""},
- {1, "COMPOSITE", 0, "Composite", ""},
- {2, "TEXTURE", 0, "Texture", ""},
+ static EnumPropertyItem dummy_items[] = {
+ {0, "DUMMY", 0, "", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1085,7 +1092,8 @@ void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Add a new node tree to the main database");
parm = RNA_def_string(func, "name", "NodeGroup", 0, "", "New name for the datablock");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_enum(func, "type", node_nodetree_items, 0, "Type", "The type of node_group to add");
+ parm = RNA_def_enum(func, "type", dummy_items, 0, "Type", "The type of node_group to add");
+ RNA_def_property_enum_funcs(parm, NULL, NULL, "rna_Main_nodetree_type_itemf");
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
parm = RNA_def_pointer(func, "tree", "NodeTree", "", "New node tree datablock");
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index d1c81200e6a..57ae217cff6 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -82,6 +82,7 @@ EnumPropertyItem ramp_blend_items[] = {
#include "DNA_node_types.h"
#include "DNA_object_types.h"
+#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -111,7 +112,7 @@ static void rna_Material_update_previews(Main *bmain, Scene *scene, PointerRNA *
Material *ma = ptr->id.data;
if (ma->nodetree)
- ntreeClearPreview(ma->nodetree);
+ BKE_node_preview_clear_tree(ma->nodetree);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, ma);
}
@@ -287,14 +288,14 @@ static void rna_Material_use_specular_ramp_set(PointerRNA *ptr, int value)
ma->ramp_spec = add_colorband(0);
}
-static void rna_Material_use_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Material_use_nodes_update(bContext *C, PointerRNA *ptr)
{
Material *ma = (Material *)ptr->data;
if (ma->use_nodes && ma->nodetree == NULL)
- ED_node_shader_default(scene, &ma->id);
+ ED_node_shader_default(C, &ma->id);
- rna_Material_update(bmain, scene, ptr);
+ rna_Material_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
static EnumPropertyItem *rna_Material_texture_coordinates_itemf(bContext *UNUSED(C), PointerRNA *ptr,
@@ -2024,6 +2025,7 @@ void RNA_def_material(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the material");
RNA_def_property_update(prop, 0, "rna_Material_use_nodes_update");
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 */
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
deleted file mode 100644
index b7ec9235483..00000000000
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Robin Allen
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/makesrna/intern/rna_nodetree_types.h
- * \ingroup RNA
- */
-
-/* intentionally no include guard */
-
-/* Empty definitions for undefined macros to avoid warnings */
-#ifndef DefNode
-#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc)
-#endif
-
-/* WARNING! If you edit those strings, please do the same in relevant nodes files (under blender/nodes/...)! */
-
-/* Tree type Node ID RNA def function Enum name Struct name UI Name UI Description */
-DefNode( ShaderNode, SH_NODE_OUTPUT, 0, "OUTPUT", Output, "Output", "" )
-DefNode( ShaderNode, SH_NODE_MATERIAL, def_sh_material, "MATERIAL", Material, "Material", "" )
-DefNode( ShaderNode, SH_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
-DefNode( ShaderNode, SH_NODE_VALUE, 0, "VALUE", Value, "Value", "" )
-DefNode( ShaderNode, SH_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "MixRGB", "" )
-DefNode( ShaderNode, SH_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
-DefNode( ShaderNode, SH_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
-DefNode( ShaderNode, SH_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
-DefNode( ShaderNode, SH_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
-DefNode( ShaderNode, SH_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" )
-DefNode( ShaderNode, SH_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" )
-DefNode( ShaderNode, SH_NODE_GEOMETRY, def_sh_geometry, "GEOMETRY", Geometry, "Geometry", "" )
-DefNode( ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPING", Mapping, "Mapping", "" )
-DefNode( ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curves", "" )
-DefNode( ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curves", "" )
-DefNode( ShaderNode, SH_NODE_CAMERA, 0, "CAMERA", CameraData, "Camera Data", "" )
-DefNode( ShaderNode, SH_NODE_MATH, def_math, "MATH", Math, "Math", "" )
-DefNode( ShaderNode, SH_NODE_VECT_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" )
-DefNode( ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze Value", "" )
-DefNode( ShaderNode, SH_NODE_MATERIAL_EXT, def_sh_material, "MATERIAL_EXT", ExtendedMaterial, "Extended Material", "" )
-DefNode( ShaderNode, SH_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
-DefNode( ShaderNode, SH_NODE_SEPRGB, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" )
-DefNode( ShaderNode, SH_NODE_COMBRGB, 0, "COMBRGB", CombineRGB, "Combine RGB", "" )
-DefNode( ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
-
-DefNode( ShaderNode, SH_NODE_OUTPUT_MATERIAL, 0, "OUTPUT_MATERIAL", OutputMaterial, "Material Output", "" )
-DefNode( ShaderNode, SH_NODE_OUTPUT_LAMP, 0, "OUTPUT_LAMP", OutputLamp, "Lamp Output", "" )
-DefNode( ShaderNode, SH_NODE_OUTPUT_WORLD, 0, "OUTPUT_WORLD", OutputWorld, "World Output", "" )
-DefNode( ShaderNode, SH_NODE_FRESNEL, 0, "FRESNEL", Fresnel, "Fresnel", "" )
-DefNode( ShaderNode, SH_NODE_LAYER_WEIGHT, 0, "LAYER_WEIGHT", LayerWeight, "LayerWeight", "" )
-DefNode( ShaderNode, SH_NODE_MIX_SHADER, 0, "MIX_SHADER", MixShader, "Mix Shader", "" )
-DefNode( ShaderNode, SH_NODE_ADD_SHADER, 0, "ADD_SHADER", AddShader, "Add Shader", "" )
-DefNode( ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATTRIBUTE", Attribute, "Attribute", "" )
-DefNode( ShaderNode, SH_NODE_AMBIENT_OCCLUSION, 0, "AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "" )
-DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "" )
-DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, 0, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy BSDF", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glossy, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_REFRACTION, def_glossy, "BSDF_REFRACTION", BsdfRefraction, "Refraction BSDF", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_TRANSLUCENT, 0, "BSDF_TRANSLUCENT", BsdfTranslucent, "Translucent BSDF", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_TRANSPARENT, 0, "BSDF_TRANSPARENT", BsdfTransparent, "Transparent BSDF", "" )
-DefNode( ShaderNode, SH_NODE_BSDF_VELVET, 0, "BSDF_VELVET", BsdfVelvet, "Velvet BSDF", "" )
-DefNode( ShaderNode, SH_NODE_VOLUME_TRANSPARENT, 0, "VOLUME_TRANSPARENT", VolumeTransparent,"Transparent Volume","" )
-DefNode( ShaderNode, SH_NODE_VOLUME_ISOTROPIC, 0, "VOLUME_ISOTROPIC", VolumeIsotropic, "Isotropic Volume", "" )
-DefNode( ShaderNode, SH_NODE_EMISSION, 0, "EMISSION", Emission, "Emission", "" )
-DefNode( ShaderNode, SH_NODE_NEW_GEOMETRY, 0, "NEW_GEOMETRY", NewGeometry, "Geometry", "" )
-DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LIGHT_PATH", LightPath, "Light Path", "" )
-DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" )
-DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" )
-DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" )
-DefNode( ShaderNode, SH_NODE_HAIR_INFO, 0, "HAIR_INFO", HairInfo, "Hair Info", "" )
-DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", Bump, "Bump", "" )
-DefNode( ShaderNode, SH_NODE_NORMAL_MAP, def_sh_normal_map, "NORMAL_MAP", NormalMap, "Normal Map", "" )
-DefNode( ShaderNode, SH_NODE_TANGENT, def_sh_tangent, "TANGENT", Tangent, "Tangent", "" )
-DefNode( ShaderNode, SH_NODE_SCRIPT, def_sh_script, "SCRIPT", Script, "Script", "" )
-DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" )
-DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_GRADIENT, def_sh_tex_gradient, "TEX_GRADIENT", TexGradient, "Gradient Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_NOISE, def_sh_tex_noise, "TEX_NOISE", TexNoise, "Noise Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_MAGIC, def_sh_tex_magic, "TEX_MAGIC", TexMagic, "Magic Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_WAVE, def_sh_tex_wave, "TEX_WAVE", TexWave, "Wave Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TEX_MUSGRAVE", TexMusgrave, "Musgrave Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TEX_VORONOI", TexVoronoi, "Voronoi Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" )
-DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" )
-
-DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
-DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
-DefNode( CompositorNode, CMP_NODE_VALUE, 0, "VALUE", Value, "Value", "" )
-DefNode( CompositorNode, CMP_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix", "" )
-DefNode( CompositorNode, CMP_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
-DefNode( CompositorNode, CMP_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
-DefNode( CompositorNode, CMP_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
-DefNode( CompositorNode, CMP_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", CurveVec, "Vector Curves", "" )
-DefNode( CompositorNode, CMP_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curves", "" )
-DefNode( CompositorNode, CMP_NODE_ALPHAOVER, def_cmp_alpha_over, "ALPHAOVER", AlphaOver, "Alpha Over", "" )
-DefNode( CompositorNode, CMP_NODE_BLUR, def_cmp_blur, "BLUR", Blur, "Blur", "" )
-DefNode( CompositorNode, CMP_NODE_FILTER, def_cmp_filter, "FILTER", Filter, "Filter", "" )
-DefNode( CompositorNode, CMP_NODE_MAP_VALUE, def_cmp_map_value, "MAP_VALUE", MapValue, "Map Value", "" )
-DefNode( CompositorNode, CMP_NODE_MAP_RANGE, def_cmp_map_range, "MAP_RANGE", MapRange, "Map Range", "" )
-DefNode( CompositorNode, CMP_NODE_TIME, def_time, "TIME", Time, "Time", "" )
-DefNode( CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBLUR", VecBlur, "Vector Blur", "" )
-DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
-DefNode( CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
-DefNode( CompositorNode, CMP_NODE_SETALPHA, 0, "SETALPHA", SetAlpha, "Set Alpha", "" )
-DefNode( CompositorNode, CMP_NODE_HUE_SAT, def_cmp_hue_saturation, "HUE_SAT", HueSat, "Hue Saturation Value","" )
-DefNode( CompositorNode, CMP_NODE_IMAGE, def_cmp_image, "IMAGE", Image, "Image", "" )
-DefNode( CompositorNode, CMP_NODE_R_LAYERS, def_cmp_render_layers, "R_LAYERS", RLayers, "Render Layers", "" )
-DefNode( CompositorNode, CMP_NODE_COMPOSITE, def_cmp_composite, "COMPOSITE", Composite, "Composite", "" )
-DefNode( CompositorNode, CMP_NODE_OUTPUT_FILE, def_cmp_output_file, "OUTPUT_FILE", OutputFile, "File Output", "" )
-DefNode( CompositorNode, CMP_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
-DefNode( CompositorNode, CMP_NODE_TRANSLATE, def_cmp_translate, "TRANSLATE", Translate, "Translate", "" )
-DefNode( CompositorNode, CMP_NODE_ZCOMBINE, def_cmp_zcombine, "ZCOMBINE", Zcombine, "Z Combine", "" )
-DefNode( CompositorNode, CMP_NODE_COMBRGBA, 0, "COMBRGBA", CombRGBA, "Combine RGBA", "" )
-DefNode( CompositorNode, CMP_NODE_DILATEERODE, def_cmp_dilate_erode, "DILATEERODE", DilateErode, "Dilate/Erode", "" )
-DefNode( CompositorNode, CMP_NODE_INPAINT, def_cmp_inpaint, "INPAINT", Inpaint, "Inpaint", "" )
-DefNode( CompositorNode, CMP_NODE_DESPECKLE, def_cmp_despeckle, "DESPECKLE", Despeckle, "Despeckle", "" )
-DefNode( CompositorNode, CMP_NODE_ROTATE, def_cmp_rotate, "ROTATE", Rotate, "Rotate", "" )
-DefNode( CompositorNode, CMP_NODE_SCALE, def_cmp_scale, "SCALE", Scale, "Scale", "" )
-DefNode( CompositorNode, CMP_NODE_SEPYCCA, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCbCrA", "" )
-DefNode( CompositorNode, CMP_NODE_COMBYCCA, def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCbCrA", "" )
-DefNode( CompositorNode, CMP_NODE_SEPYUVA, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
-DefNode( CompositorNode, CMP_NODE_COMBYUVA, 0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
-DefNode( CompositorNode, CMP_NODE_DIFF_MATTE, def_cmp_diff_matte, "DIFF_MATTE", DiffMatte, "Difference Key", "" )
-DefNode( CompositorNode, CMP_NODE_COLOR_SPILL, def_cmp_color_spill, "COLOR_SPILL", ColorSpill, "Color Spill", "" )
-DefNode( CompositorNode, CMP_NODE_CHROMA_MATTE, def_cmp_chroma_matte, "CHROMA_MATTE", ChromaMatte, "Chroma Key", "" )
-DefNode( CompositorNode, CMP_NODE_CHANNEL_MATTE, def_cmp_channel_matte, "CHANNEL_MATTE", ChannelMatte, "Channel Key", "" )
-DefNode( CompositorNode, CMP_NODE_FLIP, def_cmp_flip, "FLIP", Flip, "Flip", "" )
-DefNode( CompositorNode, CMP_NODE_SPLITVIEWER, def_cmp_splitviewer, "SPLITVIEWER", SplitViewer, "Split Viewer", "" )
-DefNode( CompositorNode, CMP_NODE_MAP_UV, def_cmp_map_uv, "MAP_UV", MapUV, "Map UV", "" )
-DefNode( CompositorNode, CMP_NODE_ID_MASK, def_cmp_id_mask, "ID_MASK", IDMask, "ID Mask", "" )
-DefNode( CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
-DefNode( CompositorNode, CMP_NODE_DEFOCUS, def_cmp_defocus, "DEFOCUS", Defocus, "Defocus", "" )
-DefNode( CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" )
-DefNode( CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
-DefNode( CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
-DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
-DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
-DefNode( CompositorNode, CMP_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" )
-DefNode( CompositorNode, CMP_NODE_INVERT, def_cmp_invert, "INVERT", Invert, "Invert", "" )
-DefNode( CompositorNode, CMP_NODE_NORMALIZE, 0, "NORMALIZE", Normalize, "Normalize", "" )
-DefNode( CompositorNode, CMP_NODE_CROP, def_cmp_crop, "CROP", Crop, "Crop", "" )
-DefNode( CompositorNode, CMP_NODE_DBLUR, def_cmp_dblur, "DBLUR", DBlur, "Directional Blur", "" )
-DefNode( CompositorNode, CMP_NODE_BILATERALBLUR, def_cmp_bilateral_blur, "BILATERALBLUR", Bilateralblur, "Bilateral Blur", "" )
-DefNode( CompositorNode, CMP_NODE_PREMULKEY, def_cmp_premul_key, "PREMULKEY", PremulKey, "Alpha Convert", "" )
-DefNode( CompositorNode, CMP_NODE_GLARE, def_cmp_glare, "GLARE", Glare, "Glare", "" )
-DefNode( CompositorNode, CMP_NODE_TONEMAP, def_cmp_tonemap, "TONEMAP", Tonemap, "Tonemap", "" )
-DefNode( CompositorNode, CMP_NODE_LENSDIST, def_cmp_lensdist, "LENSDIST", Lensdist, "Lens Distortion", "" )
-DefNode( CompositorNode, CMP_NODE_VIEW_LEVELS, def_cmp_levels, "LEVELS", Levels, "Levels", "" )
-DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR_MATTE", ColorMatte, "Color Key", "" )
-DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Key", "" )
-DefNode( CompositorNode, CMP_NODE_COLORBALANCE, def_cmp_colorbalance, "COLORBALANCE", ColorBalance, "Color Balance", "" )
-DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECORRECT", HueCorrect, "Hue Correct", "" )
-DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "Movie Clip", "" )
-DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" )
-DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabilize 2D", "" )
-DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" )
-DefNode( CompositorNode, CMP_NODE_MASK_BOX, def_cmp_boxmask, "BOXMASK", BoxMask, "Box Mask", "" )
-DefNode( CompositorNode, CMP_NODE_MASK_ELLIPSE, def_cmp_ellipsemask, "ELLIPSEMASK", EllipseMask, "Ellipse Mask", "" )
-DefNode( CompositorNode, CMP_NODE_BOKEHIMAGE, def_cmp_bokehimage, "BOKEHIMAGE", BokehImage, "Bokeh Image", "" )
-DefNode( CompositorNode, CMP_NODE_BOKEHBLUR, def_cmp_bokehblur, "BOKEHBLUR", BokehBlur, "Bokeh Blur", "" )
-DefNode( CompositorNode, CMP_NODE_SWITCH, def_cmp_switch, "SWITCH", Switch, "Switch", "" )
-DefNode( CompositorNode, CMP_NODE_COLORCORRECTION,def_cmp_colorcorrection,"COLORCORRECTION",ColorCorrection, "Color Correction", "" )
-DefNode( CompositorNode, CMP_NODE_MASK, def_cmp_mask, "MASK", Mask, "Mask", "" )
-DefNode( CompositorNode, CMP_NODE_KEYINGSCREEN, def_cmp_keyingscreen, "KEYINGSCREEN", KeyingScreen, "Keying Screen", "" )
-DefNode( CompositorNode, CMP_NODE_KEYING, def_cmp_keying, "KEYING", Keying, "Keying", "" )
-DefNode( CompositorNode, CMP_NODE_TRACKPOS, def_cmp_trackpos, "TRACKPOS", TrackPos, "Track Position", "" )
-DefNode( CompositorNode, CMP_NODE_PIXELATE, 0, "PIXELATE", Pixelate, "Pixelate", "" )
-
-DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
-DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
-DefNode( TextureNode, TEX_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
-DefNode( TextureNode, TEX_NODE_BRICKS, def_tex_bricks, "BRICKS", Bricks, "Bricks", "" )
-DefNode( TextureNode, TEX_NODE_MATH, def_math, "MATH", Math, "Math", "" )
-DefNode( TextureNode, TEX_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix RGB", "" )
-DefNode( TextureNode, TEX_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
-DefNode( TextureNode, TEX_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "ColorRamp", "" )
-DefNode( TextureNode, TEX_NODE_IMAGE, def_tex_image, "IMAGE", Image, "Image", "" )
-DefNode( TextureNode, TEX_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curves", "" )
-DefNode( TextureNode, TEX_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
-DefNode( TextureNode, TEX_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
-DefNode( TextureNode, TEX_NODE_CURVE_TIME, def_time, "CURVE_TIME", CurveTime, "Curve Time", "" )
-DefNode( TextureNode, TEX_NODE_ROTATE, 0, "ROTATE", Rotate, "Rotate", "" )
-DefNode( TextureNode, TEX_NODE_VIEWER, 0, "VIEWER", Viewer, "Viewer", "" )
-DefNode( TextureNode, TEX_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
-DefNode( TextureNode, TEX_NODE_COORD, 0, "COORD", Coordinates, "Coordinates", "" )
-DefNode( TextureNode, TEX_NODE_DISTANCE, 0, "DISTANCE", Distance, "Distance", "" )
-DefNode( TextureNode, TEX_NODE_COMPOSE, 0, "COMPOSE", Compose, "Combine RGBA", "" )
-DefNode( TextureNode, TEX_NODE_DECOMPOSE, 0, "DECOMPOSE", Decompose, "Separate RGBA", "" )
-DefNode( TextureNode, TEX_NODE_VALTONOR, 0, "VALTONOR", ValToNor, "Value to Normal", "" )
-DefNode( TextureNode, TEX_NODE_SCALE, 0, "SCALE", Scale, "Scale", "" )
-
-
-/* undefine macros */
-#undef DefNode
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d556cc0dcdc..e03e7d222c6 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1173,13 +1173,12 @@ static void rna_SceneRenderLayer_pass_update(Main *bmain, Scene *activescene, Po
rna_Scene_glsl_update(bmain, activescene, ptr);
}
-static void rna_Scene_use_nodes_set(PointerRNA *ptr, int value)
+static void rna_Scene_use_nodes_update(bContext *C, PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->data;
- scene->use_nodes = value;
if (scene->use_nodes && scene->nodetree == NULL)
- ED_node_composit_default(scene);
+ ED_node_composit_default(C, scene);
}
static void rna_Physics_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
@@ -4533,9 +4532,9 @@ void RNA_def_scene(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
- RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_use_nodes_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Enable the compositing node tree");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_use_nodes_update");
/* Sequencer */
prop = RNA_def_property(srna, "sequence_editor", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index d88e8ed782a..f365352ca30 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -25,6 +25,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include "MEM_guardedalloc.h"
@@ -32,6 +33,7 @@
#include "BKE_key.h"
#include "BKE_movieclip.h"
+#include "BKE_node.h"
#include "DNA_action_types.h"
#include "DNA_key_types.h"
@@ -1014,20 +1016,91 @@ static void rna_BackgroundImage_clear(View3D *v3d)
/* Space Node Editor */
-static int rna_SpaceNodeEditor_node_tree_poll(PointerRNA *ptr, PointerRNA value)
+static void rna_SpaceNodeEditor_node_tree_set(PointerRNA *ptr, const PointerRNA value)
+{
+ SpaceNode *snode = (SpaceNode *)ptr->data;
+ ED_node_tree_start(snode, (bNodeTree *)value.data, NULL, NULL);
+}
+
+static int rna_SpaceNodeEditor_node_tree_poll(PointerRNA *ptr, const PointerRNA value)
{
SpaceNode *snode = (SpaceNode *)ptr->data;
bNodeTree *ntree = (bNodeTree *)value.data;
- /* exclude group trees, only trees of the active type */
- return (ntree->nodetype == 0 && ntree->type == snode->treetype);
+ /* node tree type must match the selected type in node editor */
+ return (strcmp(snode->tree_idname, ntree->idname) == 0);
}
-static void rna_SpaceNodeEditor_node_tree_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+static void rna_SpaceNodeEditor_node_tree_update(const bContext *C, PointerRNA *UNUSED(ptr))
{
- SpaceNode *snode = (SpaceNode *)ptr->data;
+ ED_node_tree_update(C);
+}
+
+static int rna_SpaceNodeEditor_tree_type_get(PointerRNA *ptr)
+{
+ SpaceNode *snode= (SpaceNode*)ptr->data;
+ return rna_node_tree_idname_to_enum(snode->tree_idname);
+}
+static void rna_SpaceNodeEditor_tree_type_set(PointerRNA *ptr, int value)
+{
+ SpaceNode *snode= (SpaceNode*)ptr->data;
+ ED_node_set_tree_type(snode, rna_node_tree_type_from_enum(value));
+}
+static int rna_SpaceNodeEditor_tree_type_poll(void *Cv, bNodeTreeType *type)
+{
+ bContext *C = (bContext *)Cv;
+ if (type->poll)
+ return type->poll(C, type);
+ else
+ return TRUE;
+}
+static EnumPropertyItem *rna_SpaceNodeEditor_tree_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
+{
+ return rna_node_tree_type_itemf(C, rna_SpaceNodeEditor_tree_type_poll, free);
+}
+
+static void rna_SpaceNodeEditor_path_get(PointerRNA *ptr, char *value)
+{
+ SpaceNode *snode = ptr->data;
+ ED_node_tree_path_get(snode, value);
+}
+
+static int rna_SpaceNodeEditor_path_length(PointerRNA *ptr)
+{
+ SpaceNode *snode = ptr->data;
+ return ED_node_tree_path_length(snode);
+}
+
+void rna_SpaceNodeEditor_path_clear(SpaceNode *snode, bContext *C)
+{
+ ED_node_tree_start(snode, NULL, NULL, NULL);
+ ED_node_tree_update(C);
+}
+
+void rna_SpaceNodeEditor_path_start(SpaceNode *snode, bContext *C, PointerRNA *node_tree)
+{
+ ED_node_tree_start(snode, (bNodeTree *)node_tree->data, NULL, NULL);
+ ED_node_tree_update(C);
+}
+
+void rna_SpaceNodeEditor_path_push(SpaceNode *snode, bContext *C, ReportList *reports, PointerRNA *node)
+{
+ PointerRNA tree_ptr;
+
+ tree_ptr = RNA_pointer_get(node, "node_tree");
+ if (!tree_ptr.data) {
+ BKE_reportf(reports, RPT_WARNING, "Missing node group tree in node %s", ((bNode *)node->data)->name);
+ return;
+ }
- ED_node_tree_update(snode, scene);
+ ED_node_tree_push(snode, (bNodeTree *)tree_ptr.data, (bNode *)node->data);
+ ED_node_tree_update(C);
+}
+
+void rna_SpaceNodeEditor_path_pop(SpaceNode *snode, bContext *C)
+{
+ ED_node_tree_pop(snode);
+ ED_node_tree_update(C);
}
static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C, PointerRNA *UNUSED(ptr),
@@ -3077,6 +3150,58 @@ static void rna_def_space_userpref(BlenderRNA *brna)
}
+static void rna_def_node_tree_path(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "NodeTreePath", NULL);
+ RNA_def_struct_sdna(srna, "bNodeTreePath");
+ RNA_def_struct_ui_text(srna, "Node Tree Path", "Element of the node space tree path");
+
+ prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Node Tree", "Base node tree from context");
+}
+
+static void rna_def_space_node_path_api(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ PropertyRNA *prop, *parm;
+ FunctionRNA *func;
+
+ RNA_def_property_srna(cprop, "SpaceNodeEditorPath");
+ srna = RNA_def_struct(brna, "SpaceNodeEditorPath", NULL);
+ RNA_def_struct_sdna(srna, "SpaceNode");
+ RNA_def_struct_ui_text(srna, "Space Node Editor Path", "History of node trees in the editor");
+
+ prop = RNA_def_property(srna, "to_string", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_SpaceNodeEditor_path_get", "rna_SpaceNodeEditor_path_length", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_struct_ui_text(srna, "Path", "Get the node tree path as a string");
+
+ func = RNA_def_function(srna, "clear", "rna_SpaceNodeEditor_path_clear");
+ RNA_def_function_ui_description(func, "Reset the node tree path");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+
+ func = RNA_def_function(srna, "start", "rna_SpaceNodeEditor_path_start");
+ RNA_def_function_ui_description(func, "Set the root node tree");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ parm = RNA_def_pointer(func, "node_tree", "NodeTree", "Node Tree", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
+
+ func = RNA_def_function(srna, "push", "rna_SpaceNodeEditor_path_push");
+ RNA_def_function_ui_description(func, "Append a node group tree to the path");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "node", "NodeGroup", "Node", "Group node");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
+
+ func = RNA_def_function(srna, "pop", "rna_SpaceNodeEditor_path_pop");
+ RNA_def_function_ui_description(func, "Remove the last node tree from the path");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+}
+
static void rna_def_space_node(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3106,13 +3231,17 @@ static void rna_def_space_node(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem dummy_items[] = {
+ {0, "DUMMY", 0, "", ""},
+ {0, NULL, 0, NULL, NULL}};
+
srna = RNA_def_struct(brna, "SpaceNodeEditor", "Space");
RNA_def_struct_sdna(srna, "SpaceNode");
RNA_def_struct_ui_text(srna, "Space Node Editor", "Node editor space data");
prop = RNA_def_property(srna, "tree_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "treetype");
- RNA_def_property_enum_items(prop, nodetree_type_items);
+ RNA_def_property_enum_items(prop, dummy_items);
+ RNA_def_property_enum_funcs(prop, "rna_SpaceNodeEditor_tree_type_get", "rna_SpaceNodeEditor_tree_type_set", "rna_SpaceNodeEditor_tree_type_itemf");
RNA_def_property_ui_text(prop, "Tree Type", "Node tree type to display and edit");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, NULL);
@@ -3137,17 +3266,29 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "ID From", "Datablock from which the edited datablock is linked");
+ prop= RNA_def_property(srna, "path", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "treepath", NULL);
+ RNA_def_property_struct_type(prop, "NodeTreePath");
+ RNA_def_property_ui_text(prop, "Node Tree Path", "Path from the data block to the currently edited node tree");
+ rna_def_space_node_path_api(brna, prop);
+
prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceNodeEditor_node_tree_set", NULL, "rna_SpaceNodeEditor_node_tree_poll");
RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
- RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_SpaceNodeEditor_node_tree_poll");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Node Tree", "Node tree being displayed");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
+ RNA_def_property_ui_text(prop, "Node Tree", "Base node tree from context");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, "rna_SpaceNodeEditor_node_tree_update");
- prop = RNA_def_property(srna, "edit_tree", PROP_POINTER, PROP_NONE);
+ prop= RNA_def_property(srna, "edit_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "edittree");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Edit Tree", "Edited node tree");
+ RNA_def_property_ui_text(prop, "Edit Tree", "Node tree being displayed and edited");
+
+ prop= RNA_def_property(srna, "pin", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_PIN);
+ RNA_def_property_ui_text(prop, "Pinned", "Use the pinned node tree");
+ RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1);
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL);
prop = RNA_def_property(srna, "show_backdrop", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_BACKDRAW);
@@ -3544,6 +3685,7 @@ void RNA_def_space(BlenderRNA *brna)
rna_def_console_line(brna);
rna_def_space_info(brna);
rna_def_space_userpref(brna);
+ rna_def_node_tree_path(brna);
rna_def_space_node(brna);
rna_def_space_logic(brna);
rna_def_space_clip(brna);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index d86e5fd0d9c..009823555f0 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -107,6 +107,7 @@ EnumPropertyItem blend_type_items[] = {
#include "RNA_access.h"
+#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_image.h"
#include "BKE_texture.h"
@@ -167,7 +168,7 @@ static void rna_Texture_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *pt
}
else if (GS(id->name) == ID_NT) {
bNodeTree *ntree = ptr->id.data;
- ED_node_generic_update(bmain, ntree, NULL);
+ ED_node_tag_update_nodetree(bmain, ntree);
}
}
@@ -384,15 +385,18 @@ static void rna_Texture_use_color_ramp_set(PointerRNA *ptr, int value)
tex->coba = add_colorband(0);
}
-static void rna_Texture_use_nodes_set(PointerRNA *ptr, int v)
+static void rna_Texture_use_nodes_update(bContext *C, PointerRNA *ptr)
{
Tex *tex = (Tex *)ptr->data;
- tex->use_nodes = v;
- tex->type = 0;
+ if (tex->use_nodes) {
+ tex->type = 0;
+
+ if (tex->nodetree == NULL)
+ ED_node_texture_default(C, tex);
+ }
- if (v && tex->nodetree == NULL)
- ED_node_texture_default(tex);
+ rna_Texture_nodes_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
static void rna_ImageTexture_mipmap_set(PointerRNA *ptr, int value)
@@ -2021,9 +2025,9 @@ static void rna_def_texture(BlenderRNA *brna)
/* nodetree */
prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
- RNA_def_property_boolean_funcs(prop, NULL, "rna_Texture_use_nodes_set");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Make this a node-based texture");
- RNA_def_property_update(prop, 0, "rna_Texture_nodes_update");
+ RNA_def_property_update(prop, 0, "rna_Texture_use_nodes_update");
prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 0204fa5367b..41d1411d35c 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -419,6 +419,8 @@ void RNA_api_ui_layout(StructRNA *srna)
{0, NULL, 0, NULL, NULL}
};
+ static float node_socket_color_default[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+
/* simple layout specifiers */
func = RNA_def_function(srna, "row", "uiLayoutRow");
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
@@ -829,6 +831,14 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_pointer(func, "item", "KeyMapItem", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
+ func = RNA_def_function(srna, "template_component_menu", "uiTemplateComponentMenu");
+ RNA_def_function_ui_description(func, "Item. Display expanded property in a popup menu");
+ parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR);
+ parm = RNA_def_string(func, "property", "", 0, "", "Identifier of property in data");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_string(func, "name", "", 0, "", "");
+
func = RNA_def_function(srna, "introspect", "uiLayoutIntrospect");
parm = RNA_def_string(func, "string", "", 1024 * 1024, "Descr", "DESCR");
RNA_def_function_return(func, parm);
@@ -843,6 +853,12 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
/* RNA_def_boolean(func, "show_global_settings", 0, "", "Show widgets to control global color management settings"); */
+
+ /* node socket icon */
+ func = RNA_def_function(srna, "template_node_socket", "uiTemplateNodeSocket");
+ RNA_def_function_ui_description(func, "Node Socket Icon");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+ RNA_def_float_array(func, "color", 4, node_socket_color_default, 0.0f, 1.0f, "Color", "", 0.0f, 1.0f);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 3824ee28956..12fac82fb75 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1884,6 +1884,12 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Group Node", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ prop= RNA_def_property(srna, "group_socket_node", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "console_output");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Group Socket Node", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
prop = RNA_def_property(srna, "frame_node", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "movie");
RNA_def_property_array(prop, 4);
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 02a04d36c23..b689a82c231 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -42,6 +42,7 @@
#include "MEM_guardedalloc.h"
+#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_texture.h"
@@ -121,14 +122,14 @@ static void rna_World_stars_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
WM_main_add_notifier(NC_WORLD | ND_WORLD_STARS, wo);
}
-static void rna_World_use_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_World_use_nodes_update(bContext *C, PointerRNA *ptr)
{
World *wrld = (World *)ptr->data;
if (wrld->use_nodes && wrld->nodetree == NULL)
- ED_node_shader_default(scene, &wrld->id);
+ ED_node_shader_default(C, &wrld->id);
- rna_World_update(bmain, scene, ptr);
+ rna_World_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
#else
@@ -581,6 +582,7 @@ void RNA_def_world(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the world");
RNA_def_property_update(prop, 0, "rna_World_use_nodes_update");