[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33419] trunk/blender/source/blender/ makesrna: patch [#23212] Python api for Nodes

Campbell Barton ideasman42 at gmail.com
Thu Dec 2 02:18:59 CET 2010


Revision: 33419
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33419
Author:   campbellbarton
Date:     2010-12-02 02:18:59 +0100 (Thu, 02 Dec 2010)

Log Message:
-----------
patch [#23212] Python api for Nodes
from Dan Eicher (dna)

This allows automated node tree creation and editing.

developer note, made some changes to the patch.
- removed incorrect use of container_of(), GCC only also, search for the scene instead.
- commented socket min/max access, these are internal use only as far as I can tell.
- commented group/ungroup functions, these use the selection context and are not really data level functions.
- use remove() rather then delete()

Modified Paths:
--------------
    trunk/blender/source/blender/makesrna/RNA_access.h
    trunk/blender/source/blender/makesrna/intern/rna_nodetree.c

Modified: trunk/blender/source/blender/makesrna/RNA_access.h
===================================================================
--- trunk/blender/source/blender/makesrna/RNA_access.h	2010-12-01 23:40:21 UTC (rev 33418)
+++ trunk/blender/source/blender/makesrna/RNA_access.h	2010-12-02 01:18:59 UTC (rev 33419)
@@ -157,6 +157,7 @@
 extern StructRNA RNA_CompositorNodeTime;
 extern StructRNA RNA_CompositorNodeTonemap;
 extern StructRNA RNA_CompositorNodeTranslate;
+extern StructRNA RNA_CompositorNodeTree;
 extern StructRNA RNA_CompositorNodeValToRGB;
 extern StructRNA RNA_CompositorNodeValue;
 extern StructRNA RNA_CompositorNodeVecBlur;
@@ -417,6 +418,7 @@
 extern StructRNA RNA_ShaderNodeSeparateRGB;
 extern StructRNA RNA_ShaderNodeSqueeze;
 extern StructRNA RNA_ShaderNodeTexture;
+extern StructRNA RNA_ShaderNodeTree;
 extern StructRNA RNA_ShaderNodeValToRGB;
 extern StructRNA RNA_ShaderNodeValue;
 extern StructRNA RNA_ShaderNodeVectorCurve;
@@ -496,6 +498,7 @@
 extern StructRNA RNA_TextureNodeScale;
 extern StructRNA RNA_TextureNodeTexture;
 extern StructRNA RNA_TextureNodeTranslate;
+extern StructRNA RNA_TextureNodeTree;
 extern StructRNA RNA_TextureNodeValToNor;
 extern StructRNA RNA_TextureNodeValToRGB;
 extern StructRNA RNA_TextureNodeViewer;

Modified: trunk/blender/source/blender/makesrna/intern/rna_nodetree.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_nodetree.c	2010-12-01 23:40:21 UTC (rev 33418)
+++ trunk/blender/source/blender/makesrna/intern/rna_nodetree.c	2010-12-02 01:18:59 UTC (rev 33419)
@@ -48,10 +48,15 @@
 
 #ifdef RNA_RUNTIME
 
+#include "BLI_linklist.h"
+
 #include "ED_node.h"
 
 #include "RE_pipeline.h"
 
+#include "DNA_scene_types.h"
+#include "WM_api.h"
+
 static StructRNA *rna_Node_refine(struct PointerRNA *ptr)
 {
 	bNode *node = (bNode*)ptr->data;
@@ -89,6 +94,22 @@
 	}
 }		
 
+static StructRNA *rna_NodeTree_refine(struct PointerRNA *ptr)
+{
+	bNodeTree *ntree= (bNodeTree*)ptr->data;
+
+	switch(ntree->type) {
+		case NTREE_SHADER:
+			return &RNA_ShaderNodeTree;
+		case NTREE_COMPOSIT:
+			return &RNA_CompositorNodeTree;
+		case NTREE_TEXTURE:
+			return &RNA_TextureNodeTree;
+		default:
+			return &RNA_UnknownType;
+	}
+}
+
 static char *rna_Node_path(PointerRNA *ptr)
 {
 	bNode *node= (bNode*)ptr->data;
@@ -157,6 +178,22 @@
 	image->efra= value;
 }
 
+static void rna_Node_scene_set(PointerRNA *ptr, PointerRNA value)
+{
+	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 node_update(Main *bmain, Scene *scene, bNodeTree *ntree, bNode *node)
 {
 	ED_node_generic_update(bmain, ntree, node);
@@ -390,7 +427,118 @@
 	return item;
 }
 
+static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *reports, int type, bNodeTree *group)
+{
+	bNode *node= nodeAddNodeType(ntree, type, group, NULL);
 
+	if (node == NULL) {
+		 BKE_reportf(reports, RPT_ERROR, "Unable to create node");
+	}
+	else {
+		nodeVerifyGroup(ntree); /* update group node socket links*/
+		NodeTagChanged(ntree, node);
+		WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree);
+	}
+
+	return node;
+}
+
+static bNode *rna_NodeTree_node_composite_new(bNodeTree *ntree, bContext *C, ReportList *reports, int type, bNodeTree *group)
+{
+	/* raises error on failier */
+	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));
+		ntreeSolveOrder(ntree);
+	}
+
+	return node;
+}
+
+static bNode *rna_NodeTree_node_texture_new(bNodeTree *ntree, bContext *C, ReportList *reports, int type, bNodeTree *group)
+{
+	/* raises error on failier */
+	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, bContext *C, ReportList *reports, bNode *node)
+{
+	if (BLI_findindex(&ntree->nodes, node) == -1) {
+		BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in nodetree", node->name);
+	}
+	else {
+		if (node->id)
+			id_us_min(node->id);
+
+		nodeFreeNode(ntree, node);
+		nodeVerifyGroup(ntree); /* update group node socket links*/
+
+		WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree);
+	}
+}
+
+static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, bContext *C, ReportList *reports, bNodeSocket *in, bNodeSocket *out)
+{
+	bNodeLink *ret;
+	bNode *fromnode, *tonode;
+
+	if (!nodeFindNode(ntree, in, &fromnode, NULL)) {
+		BKE_reportf(reports, RPT_ERROR, "Unable to locate input socket's node in nodetree");
+		return NULL;
+	}
+
+	if (!nodeFindNode(ntree, out, &tonode, NULL)) {
+		BKE_reportf(reports, RPT_ERROR, "Unable to locate output socket's node in nodetree");
+		return NULL;
+	}
+
+	/* unlink node input socket */
+	nodeRemSocketLinks(ntree, out);
+
+	ret= nodeAddLink(ntree, fromnode, in, tonode, out);
+
+	NodeTagChanged(ntree, tonode);
+
+	ntreeSolveOrder(ntree);
+
+	WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree);
+
+	return ret;
+}
+
+static void rna_NodeTree_link_remove(bNodeTree *ntree, bContext *C, ReportList *reports, bNodeLink *link)
+{
+	if (BLI_findindex(&ntree->links, link) == -1) {
+		BKE_reportf(reports, RPT_ERROR, "Unable to locate link in nodetree");
+	}
+	else {
+		nodeRemLink(ntree, link);
+		ntreeSolveOrder(ntree);
+		nodeVerifyGroup(ntree); /* update group node socket links*/
+
+		WM_event_add_notifier(C, NC_NODE|NA_EDITED, ntree);
+	}
+}
+
 #else
 
 static EnumPropertyItem prop_image_layer_items[] = {
@@ -1095,8 +1243,9 @@
 	
 	prop = RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
 	RNA_def_property_pointer_sdna(prop, NULL, "id");
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL);
 	RNA_def_property_struct_type(prop, "Scene");
-	RNA_def_property_flag(prop, PROP_EDITABLE);
+	RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
 	RNA_def_property_ui_text(prop, "Scene", "");
 	RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
 	
@@ -2167,10 +2316,130 @@
 
 /* -------------------------------------------------------------------------- */
 
+static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
+{
+	StructRNA *srna;
+	PropertyRNA *parm;
+	FunctionRNA *func;
+
+	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");
+
+	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_CONTEXT|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);
+
+	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_CONTEXT|FUNC_USE_REPORTS);
+	parm= RNA_def_pointer(func, "link", "NodeLink", "", "The node link to remove.");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
+static void rna_def_composite_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
+{
+	StructRNA *srna;
+	PropertyRNA *parm;
+	FunctionRNA *func;
+
+	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");
+
+	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");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	parm= 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_CONTEXT|FUNC_USE_REPORTS);
+	parm= RNA_def_pointer(func, "node", "Node", "", "The node to remove.");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
+static void rna_def_shader_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
+{
+	StructRNA *srna;
+	PropertyRNA *parm;
+	FunctionRNA *func;
+
+	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");
+
+	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);
+	parm= 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_CONTEXT|FUNC_USE_REPORTS);
+	parm= RNA_def_pointer(func, "node", "Node", "", "The node to remove.");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
+static void rna_def_texture_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop)
+{

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list