diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_nodetree.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 193 |
1 files changed, 154 insertions, 39 deletions
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 98739874db8..a526f360355 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -47,6 +47,13 @@ #include "MEM_guardedalloc.h" + +EnumPropertyItem node_socket_type_items[] = { + {SOCK_VALUE, "VALUE", 0, "Value", ""}, + {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, + {SOCK_RGBA, "RGBA", 0, "RGBA", ""}, + {0, NULL, 0, NULL, NULL}}; + EnumPropertyItem node_blend_type_items[] = { { 0, "MIX", 0, "Mix", ""}, { 1, "ADD", 0, "Add", ""}, @@ -185,12 +192,22 @@ static char *rna_NodeSocket_path(PointerRNA *ptr) bNode *node; int socketindex; - if (!nodeFindNode(ntree, sock, &node, NULL)) return NULL; - + /* 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; + socketindex = BLI_findindex(&node->inputs, sock); if (socketindex != -1) return BLI_sprintfN("nodes[\"%s\"].inputs[%d]", node->name, socketindex); - + socketindex = BLI_findindex(&node->outputs, sock); if (socketindex != -1) return BLI_sprintfN("nodes[\"%s\"].outputs[%d]", node->name, socketindex); @@ -273,7 +290,7 @@ static void rna_NodeGroup_update(Main *bmain, Scene *scene, PointerRNA *ptr) bNodeTree *ntree= (bNodeTree*)ptr->id.data; bNode *node= (bNode*)ptr->data; - nodeVerifyGroup((bNodeTree *)node->id); + nodeGroupVerify((bNodeTree *)node->id); node_update(bmain, scene, ntree, node); } @@ -350,7 +367,19 @@ static void rna_NodeSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr) bNodeSocket *sock= (bNodeSocket*)ptr->data; bNode *node; - if (nodeFindNode(ntree, sock, &node, NULL)) + if (nodeFindNode(ntree, sock, &node, NULL, NULL)) + node_update(bmain, scene, ntree, node); +} + +static void rna_NodeGroupSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + bNodeTree *ntree= (bNodeTree*)ptr->id.data; + bNodeSocket *sock= (bNodeSocket*)ptr->data; + bNode *node; + + nodeGroupVerify(ntree); + + if (nodeFindNode(ntree, sock, &node, NULL, NULL)) node_update(bmain, scene, ntree, node); } @@ -500,7 +529,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r BKE_reportf(reports, RPT_ERROR, "Unable to create node"); } else { - nodeVerifyGroup(ntree); /* update group node socket links*/ + nodeGroupVerify(ntree); /* update group node socket links*/ NodeTagChanged(ntree, node); WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); @@ -558,7 +587,7 @@ static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, bNod id_us_min(node->id); nodeFreeNode(ntree, node); - nodeVerifyGroup(ntree); /* update group node socket links*/ + nodeGroupVerify(ntree); /* update group node socket links*/ WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); } @@ -569,12 +598,12 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, b bNodeLink *ret; bNode *fromnode, *tonode; - if (!nodeFindNode(ntree, in, &fromnode, NULL)) { + if (!nodeFindNode(ntree, in, &fromnode, NULL, NULL)) { BKE_reportf(reports, RPT_ERROR, "Unable to locate input socket's node in nodetree"); return NULL; } - if (!nodeFindNode(ntree, out, &tonode, NULL)) { + if (!nodeFindNode(ntree, out, &tonode, NULL, NULL)) { BKE_reportf(reports, RPT_ERROR, "Unable to locate output socket's node in nodetree"); return NULL; } @@ -587,7 +616,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, b if(ret) { NodeTagChanged(ntree, tonode); - nodeVerifyGroup(ntree); /* update group node socket links*/ + nodeGroupVerify(ntree); /* update group node socket links*/ ntreeSolveOrder(ntree); @@ -604,12 +633,78 @@ static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNod else { nodeRemLink(ntree, link); ntreeSolveOrder(ntree); - nodeVerifyGroup(ntree); /* update group node socket links*/ + nodeGroupVerify(ntree); /* update group node socket links*/ 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= nodeGroupAddSocket(ntree, name, type, SOCK_IN); + + nodeGroupVerify(ntree); /* update group node socket links*/ + 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= nodeGroupAddSocket(ntree, name, type, SOCK_OUT); + + nodeGroupVerify(ntree); /* update group node socket links*/ + 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_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + else if (in_out!=SOCK_IN) + BKE_reportf(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 = nodeGroupAddSocket(ntree, sock->name, sock->type, SOCK_IN); + if (add_link) + nodeAddLink(ntree, NULL, gsock, node, sock); + + nodeGroupVerify(ntree); /* update group node socket links*/ + 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_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + else if (in_out!=SOCK_OUT) + BKE_reportf(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 = nodeGroupAddSocket(ntree, sock->name, sock->type, SOCK_OUT); + if (add_link) + nodeAddLink(ntree, node, sock, NULL, gsock); + + nodeGroupVerify(ntree); /* update group node socket links*/ + WM_main_add_notifier(NC_NODE|NA_EDITED, ntree); + return gsock; + } + return NULL; +} + #else static EnumPropertyItem prop_image_layer_items[] = { @@ -2473,12 +2568,6 @@ static void rna_def_node_socket(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem node_socket_type_items[] = { - {SOCK_VALUE, "VALUE", 0, "Value", ""}, - {SOCK_VECTOR, "VECTOR", 0, "Vector", ""}, - {SOCK_RGBA, "RGBA", 0, "RGBA", ""}, - {0, NULL, 0, NULL, NULL}}; - 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_refine_func(srna, "rna_NodeSocketType_refine"); @@ -2487,9 +2576,11 @@ static void rna_def_node_socket(BlenderRNA *brna) RNA_def_struct_path_func(srna, "rna_NodeSocket_path"); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); + /* 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"); /* can add back if there is any use in reading them */ #if 0 @@ -2636,12 +2727,41 @@ static void rna_def_node_link(BlenderRNA *brna) RNA_def_property_ui_text(prop, "To socket", ""); } +static void rna_def_group_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int in_out) +{ + 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_struct_sdna(srna, "bNodeTree"); + RNA_def_struct_ui_text(srna, "Group Sockets", "Collection of group sockets"); + + 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."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_string(func, "name", "Socket", 32, "Name", "Name of the socket"); + RNA_def_enum(func, "type", node_socket_type_items, SOCK_VALUE, "Type", "Type of socket"); + /* return value */ + parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "New socket."); + 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."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_pointer(func, "sock", "NodeSocket", "Socket", "Internal node socket to expose"); + 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."); + RNA_def_function_return(func, parm); +} + static void rna_def_nodetree(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - /* FunctionRNA *func; */ - /* PropertyRNA *parm; */ static EnumPropertyItem nodetree_type_items[] = { {NTREE_SHADER, "SHADER", 0, "Shader", ""}, @@ -2671,29 +2791,24 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock"); - - /* these are too much like operators, better to have data level access - * ngroup = bpy.data.node_groups.new() - * ngroup.nodes.new(....) etc. */ -#if 0 - func= RNA_def_function(srna, "group_add", "nodeMakeGroupFromSelected"); - RNA_def_function_ui_description(func, "Make a group from the active nodes."); - /* return */ - parm= RNA_def_pointer(func, "group", "Node", "", "New group."); - RNA_def_function_return(func, parm); - - func= RNA_def_function(srna, "ungroup", "nodeGroupUnGroup"); - RNA_def_function_ui_description(func, "Ungroup node group"); - parm= RNA_def_pointer(func, "group", "Node", "", "The group to ungroup."); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_int(func, "bool", 0, 0, 1, "Bool", "", 0, 1); - RNA_def_function_return(func, parm); -#endif 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"); + + /* 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); + + 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); } static void rna_def_composite_nodetree(BlenderRNA *brna) |