| 
									
										
										
										
											2011-10-23 17:52:20 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  |  * ***** 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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2007 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: all of this file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Lukas Toennne | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/nodes/intern/node_socket.c
 | 
					
						
							|  |  |  |  *  \ingroup nodes | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | #include <limits.h>
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_node_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							|  |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_listbase.h"
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_DerivedMesh.h"
 | 
					
						
							|  |  |  | #include "BKE_node.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | #include "RNA_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "NOD_socket.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /****************** FLOAT ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocketType node_socket_type_float = { | 
					
						
							|  |  |  | 	/* type */				SOCK_FLOAT, | 
					
						
							|  |  |  | 	/* ui_name */			"Float", | 
					
						
							|  |  |  | 	/* ui_description */	"Floating Point", | 
					
						
							|  |  |  | 	/* ui_icon */			0, | 
					
						
							|  |  |  | 	/* ui_color */			{160,160,160,255}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* value_structname */	"bNodeSocketValueFloat", | 
					
						
							|  |  |  | 	/* value_structsize */	sizeof(bNodeSocketValueFloat), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* buttonfunc */		NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /****************** VECTOR ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocketType node_socket_type_vector = { | 
					
						
							|  |  |  | 	/* type */				SOCK_VECTOR, | 
					
						
							|  |  |  | 	/* ui_name */			"Vector", | 
					
						
							|  |  |  | 	/* ui_description */	"3-dimensional floating point vector", | 
					
						
							|  |  |  | 	/* ui_icon */			0, | 
					
						
							|  |  |  | 	/* ui_color */			{100,100,200,255}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* value_structname */	"bNodeSocketValueVector", | 
					
						
							|  |  |  | 	/* value_structsize */	sizeof(bNodeSocketValueVector), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* buttonfunc */		NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /****************** RGBA ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocketType node_socket_type_rgba = { | 
					
						
							|  |  |  | 	/* type */				SOCK_RGBA, | 
					
						
							|  |  |  | 	/* ui_name */			"RGBA", | 
					
						
							|  |  |  | 	/* ui_description */	"RGBA color", | 
					
						
							|  |  |  | 	/* ui_icon */			0, | 
					
						
							|  |  |  | 	/* ui_color */			{200,200,40,255}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* value_structname */	"bNodeSocketValueRGBA", | 
					
						
							|  |  |  | 	/* value_structsize */	sizeof(bNodeSocketValueRGBA), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* buttonfunc */		NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /****************** INT ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocketType node_socket_type_int = { | 
					
						
							|  |  |  | 	/* type */				SOCK_INT, | 
					
						
							|  |  |  | 	/* ui_name */			"Int", | 
					
						
							|  |  |  | 	/* ui_description */	"Integer", | 
					
						
							|  |  |  | 	/* ui_icon */			0, | 
					
						
							|  |  |  | 	/* ui_color */			{17,133,37,255}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* value_structname */	"bNodeSocketValueInt", | 
					
						
							|  |  |  | 	/* value_structsize */	sizeof(bNodeSocketValueInt), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* buttonfunc */		NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /****************** BOOLEAN ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocketType node_socket_type_boolean = { | 
					
						
							|  |  |  | 	/* type */				SOCK_BOOLEAN, | 
					
						
							|  |  |  | 	/* ui_name */			"Boolean", | 
					
						
							|  |  |  | 	/* ui_description */	"Boolean", | 
					
						
							|  |  |  | 	/* ui_icon */			0, | 
					
						
							|  |  |  | 	/* ui_color */			{158,139,63,255}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* value_structname */	"bNodeSocketValueBoolean", | 
					
						
							|  |  |  | 	/* value_structsize */	sizeof(bNodeSocketValueBoolean), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* buttonfunc */		NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | /****************** SHADER ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocketType node_socket_type_shader = { | 
					
						
							|  |  |  | 	/* type */				SOCK_SHADER, | 
					
						
							|  |  |  | 	/* ui_name */			"Shader", | 
					
						
							|  |  |  | 	/* ui_description */	"Shader", | 
					
						
							|  |  |  | 	/* ui_icon */			0, | 
					
						
							|  |  |  | 	/* ui_color */			{100,200,100,255}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* value_structname */	NULL, | 
					
						
							|  |  |  | 	/* value_structsize */	0, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* buttonfunc */		NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | /****************** MESH ******************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocketType node_socket_type_mesh = { | 
					
						
							|  |  |  | 	/* type */				SOCK_MESH, | 
					
						
							|  |  |  | 	/* ui_name */			"Mesh", | 
					
						
							|  |  |  | 	/* ui_description */	"Mesh geometry data", | 
					
						
							|  |  |  | 	/* ui_icon */			0, | 
					
						
							|  |  |  | 	/* ui_color */			{255,133,7,255}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* value_structname */	NULL, | 
					
						
							|  |  |  | 	/* value_structsize */	0, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* buttonfunc */		NULL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void node_socket_type_init(bNodeSocketType *types[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	#define INIT_TYPE(name)		types[node_socket_type_##name.type] = &node_socket_type_##name;
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	INIT_TYPE(float); | 
					
						
							|  |  |  | 	INIT_TYPE(vector); | 
					
						
							|  |  |  | 	INIT_TYPE(rgba); | 
					
						
							|  |  |  | 	INIT_TYPE(int); | 
					
						
							|  |  |  | 	INIT_TYPE(boolean); | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | 	INIT_TYPE(shader); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	INIT_TYPE(mesh); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	#undef INIT_TYPE
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | void *node_socket_make_default_value(int type) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	/* XXX currently just allocates from stype->structsize.
 | 
					
						
							|  |  |  | 	 * it might become necessary to do more complex allocations for later types. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	bNodeSocketType *stype = ntreeGetSocketType(type); | 
					
						
							|  |  |  | 	if (stype->value_structsize > 0) { | 
					
						
							|  |  |  | 		void *default_value = MEM_callocN(stype->value_structsize, "default socket value"); | 
					
						
							|  |  |  | 		return default_value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | void node_socket_free_default_value(int UNUSED(type), void *default_value) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	/* XXX can just free the pointee for all current socket types. */ | 
					
						
							| 
									
										
										
										
											2012-01-21 16:36:06 +00:00
										 |  |  | 	if (default_value) | 
					
						
							|  |  |  | 		MEM_freeN(default_value); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | void node_socket_init_default_value(int type, void *default_value) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case SOCK_FLOAT: | 
					
						
							|  |  |  | 		node_socket_set_default_value_float(default_value, PROP_NONE, 0.0f, -FLT_MAX, FLT_MAX); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_INT: | 
					
						
							|  |  |  | 		node_socket_set_default_value_int(default_value, PROP_NONE, 0, INT_MIN, INT_MAX); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_BOOLEAN: | 
					
						
							|  |  |  | 		node_socket_set_default_value_boolean(default_value, FALSE); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_VECTOR: | 
					
						
							|  |  |  | 		node_socket_set_default_value_vector(default_value, PROP_NONE, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_RGBA: | 
					
						
							|  |  |  | 		node_socket_set_default_value_rgba(default_value, 0.0f, 0.0f, 0.0f, 1.0f); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_SHADER: | 
					
						
							|  |  |  | 		node_socket_set_default_value_shader(default_value); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_MESH: | 
					
						
							|  |  |  | 		node_socket_set_default_value_mesh(default_value); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | void node_socket_set_default_value_int(void *default_value, PropertySubType subtype, int value, int min, int max) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	bNodeSocketValueInt *val = default_value; | 
					
						
							|  |  |  | 	val->subtype = subtype; | 
					
						
							|  |  |  | 	val->value = value; | 
					
						
							|  |  |  | 	val->min = min; | 
					
						
							|  |  |  | 	val->max = max; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void node_socket_set_default_value_float(void *default_value, PropertySubType subtype, float value, float min, float max) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	bNodeSocketValueFloat *val = default_value; | 
					
						
							|  |  |  | 	val->subtype = subtype; | 
					
						
							|  |  |  | 	val->value = value; | 
					
						
							|  |  |  | 	val->min = min; | 
					
						
							|  |  |  | 	val->max = max; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | void node_socket_set_default_value_boolean(void *default_value, char value) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	bNodeSocketValueBoolean *val = default_value; | 
					
						
							|  |  |  | 	val->value = value; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | void node_socket_set_default_value_vector(void *default_value, PropertySubType subtype, float x, float y, float z, float min, float max) | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	bNodeSocketValueVector *val = default_value; | 
					
						
							|  |  |  | 	val->subtype = subtype; | 
					
						
							|  |  |  | 	val->value[0] = x; | 
					
						
							|  |  |  | 	val->value[1] = y; | 
					
						
							|  |  |  | 	val->value[2] = z; | 
					
						
							|  |  |  | 	val->min = min; | 
					
						
							|  |  |  | 	val->max = max; | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a) | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	bNodeSocketValueRGBA *val = default_value; | 
					
						
							|  |  |  | 	val->value[0] = r; | 
					
						
							|  |  |  | 	val->value[1] = g; | 
					
						
							|  |  |  | 	val->value[2] = b; | 
					
						
							|  |  |  | 	val->value[3] = a; | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | void node_socket_set_default_value_shader(void *UNUSED(default_value)) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void node_socket_set_default_value_mesh(void *UNUSED(default_value)) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void node_socket_copy_default_value(int type, void *to_default_value, void *from_default_value) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	/* XXX only one of these pointers is valid! just putting them here for convenience */ | 
					
						
							|  |  |  | 	bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	case SOCK_FLOAT: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		*tofloat = *fromfloat; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_INT: | 
					
						
							|  |  |  | 		*toint = *fromint; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_BOOLEAN: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		*tobool = *frombool; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_VECTOR: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		*tovector = *fromvector; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_RGBA: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		*torgba = *fromrgba; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* XXX This is a makeshift function to have useful initial group socket values.
 | 
					
						
							|  |  |  |  * In the end this should be implemented by a flexible socket data conversion system, | 
					
						
							|  |  |  |  * which is yet to be implemented. The idea is that beside default standard conversions, | 
					
						
							|  |  |  |  * such as int-to-float, it should be possible to quickly select a conversion method or | 
					
						
							|  |  |  |  * a chain of conversions for each input, whenever there is more than one option. | 
					
						
							|  |  |  |  * E.g. a vector-to-float conversion could use either of the x/y/z components or | 
					
						
							|  |  |  |  * the vector length. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * In the interface this could be implemented by a pseudo-script textbox on linked inputs, | 
					
						
							|  |  |  |  * with quick selection from a predefined list of conversion options. Some Examples: | 
					
						
							|  |  |  |  * - vector component 'z' (vector->float):						"z" | 
					
						
							|  |  |  |  * - greyscale color (float->color):							"grey" | 
					
						
							|  |  |  |  * - color luminance (color->float):							"lum" | 
					
						
							|  |  |  |  * - matrix column 2 length (matrix->vector->float):			"col[1].len" | 
					
						
							|  |  |  |  * - mesh vertex coordinate 'y' (mesh->vertex->vector->float):	"vertex.co.y" | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The actual conversion is then done by a series of conversion functions, | 
					
						
							|  |  |  |  * which are defined in the socket type structs. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void node_socket_convert_default_value(int to_type, void *to_default_value, int from_type, void *from_default_value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* XXX only one of these pointers is valid! just putting them here for convenience */ | 
					
						
							|  |  |  | 	bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value; | 
					
						
							|  |  |  | 	bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (from_type) { | 
					
						
							|  |  |  | 	case SOCK_FLOAT: | 
					
						
							|  |  |  | 		switch (to_type) { | 
					
						
							|  |  |  | 		case SOCK_FLOAT: | 
					
						
							|  |  |  | 			tofloat->value = fromfloat->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_INT: | 
					
						
							|  |  |  | 			toint->value = (int)fromfloat->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_BOOLEAN: | 
					
						
							|  |  |  | 			tobool->value = (fromfloat->value > 0.0f); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_VECTOR: | 
					
						
							|  |  |  | 			tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_RGBA: | 
					
						
							|  |  |  | 			torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-01-20 16:13:26 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	case SOCK_INT: | 
					
						
							|  |  |  | 		switch (to_type) { | 
					
						
							|  |  |  | 		case SOCK_FLOAT: | 
					
						
							|  |  |  | 			tofloat->value = (float)fromint->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_INT: | 
					
						
							|  |  |  | 			toint->value = fromint->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_BOOLEAN: | 
					
						
							|  |  |  | 			tobool->value = (fromint->value > 0); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_VECTOR: | 
					
						
							|  |  |  | 			tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_RGBA: | 
					
						
							|  |  |  | 			torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_BOOLEAN: | 
					
						
							|  |  |  | 		switch (to_type) { | 
					
						
							|  |  |  | 		case SOCK_FLOAT: | 
					
						
							|  |  |  | 			tofloat->value = (float)frombool->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_INT: | 
					
						
							|  |  |  | 			toint->value = (int)frombool->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_BOOLEAN: | 
					
						
							|  |  |  | 			tobool->value = frombool->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_VECTOR: | 
					
						
							|  |  |  | 			tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_RGBA: | 
					
						
							|  |  |  | 			torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_VECTOR: | 
					
						
							|  |  |  | 		switch (to_type) { | 
					
						
							|  |  |  | 		case SOCK_FLOAT: | 
					
						
							|  |  |  | 			tofloat->value = fromvector->value[0]; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_INT: | 
					
						
							|  |  |  | 			toint->value = (int)fromvector->value[0]; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_BOOLEAN: | 
					
						
							|  |  |  | 			tobool->value = (fromvector->value[0] > 0.0f); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_VECTOR: | 
					
						
							|  |  |  | 			copy_v3_v3(tovector->value, fromvector->value); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_RGBA: | 
					
						
							|  |  |  | 			copy_v3_v3(torgba->value, fromvector->value); | 
					
						
							|  |  |  | 			torgba->value[3] = 1.0f; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_RGBA: | 
					
						
							|  |  |  | 		switch (to_type) { | 
					
						
							|  |  |  | 		case SOCK_FLOAT: | 
					
						
							|  |  |  | 			tofloat->value = fromrgba->value[0]; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_INT: | 
					
						
							|  |  |  | 			toint->value = (int)fromrgba->value[0]; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_BOOLEAN: | 
					
						
							|  |  |  | 			tobool->value = (fromrgba->value[0] > 0.0f); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_VECTOR: | 
					
						
							|  |  |  | 			copy_v3_v3(tovector->value, fromrgba->value); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_RGBA: | 
					
						
							|  |  |  | 			copy_v4_v4(torgba->value, fromrgba->value); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type); | 
					
						
							|  |  |  | 	sock->flag |= stemp->flag; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	switch (stemp->type) { | 
					
						
							|  |  |  | 	case SOCK_INT: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		node_socket_set_default_value_int(sock->default_value, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_FLOAT: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		node_socket_set_default_value_float(sock->default_value, stemp->subtype, stemp->val1, stemp->min, stemp->max); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_BOOLEAN: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		node_socket_set_default_value_boolean(sock->default_value, (char)stemp->val1); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_VECTOR: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		node_socket_set_default_value_vector(sock->default_value, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case SOCK_RGBA: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		node_socket_set_default_value_rgba(sock->default_value, stemp->val1, stemp->val2, stemp->val3, stemp->val4); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | 	case SOCK_SHADER: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		node_socket_set_default_value_shader(sock->default_value); | 
					
						
							| 
									
										
										
										
											2011-10-14 12:20:58 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	case SOCK_MESH: | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 		node_socket_set_default_value_mesh(sock->default_value); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-01-20 13:27:54 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return sock; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	return sock; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeSocket *sock; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for(sock= socklist->first; sock; sock= sock->next) { | 
					
						
							|  |  |  | 		if(!(sock->flag & SOCK_DYNAMIC) && strncmp(sock->name, stemp->name, NODE_MAXSTR)==0) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(sock) { | 
					
						
							|  |  |  | 		sock->type= stemp->type;		/* in future, read this from tydefs! */ | 
					
						
							|  |  |  | 		if(stemp->limit==0) sock->limit= 0xFFF; | 
					
						
							|  |  |  | 		else sock->limit= stemp->limit; | 
					
						
							| 
									
										
										
										
											2011-11-07 17:30:52 +00:00
										 |  |  | 		sock->flag |= stemp->flag; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		/* Copy the property range and subtype parameters in case the template changed.
 | 
					
						
							|  |  |  | 		 * NOT copying the actual value here, only button behavior changes! | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		switch (sock->type) { | 
					
						
							|  |  |  | 		case SOCK_FLOAT: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				bNodeSocketValueFloat *dval= sock->default_value; | 
					
						
							|  |  |  | 				dval->min = stemp->min; | 
					
						
							|  |  |  | 				dval->max = stemp->max; | 
					
						
							|  |  |  | 				dval->subtype = stemp->subtype; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_INT: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				bNodeSocketValueInt *dval= sock->default_value; | 
					
						
							|  |  |  | 				dval->min = stemp->min; | 
					
						
							|  |  |  | 				dval->max = stemp->max; | 
					
						
							|  |  |  | 				dval->subtype = stemp->subtype; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SOCK_VECTOR: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				bNodeSocketValueVector *dval= sock->default_value; | 
					
						
							|  |  |  | 				dval->min = stemp->min; | 
					
						
							|  |  |  | 				dval->max = stemp->max; | 
					
						
							|  |  |  | 				dval->subtype = stemp->subtype; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		BLI_remlink(socklist, sock); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		return sock; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* no socket for this template found, make a new one */ | 
					
						
							|  |  |  | 		if (in_out==SOCK_IN) | 
					
						
							|  |  |  | 			sock = node_add_input_from_template(ntree, node, stemp); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			sock = node_add_output_from_template(ntree, node, stemp); | 
					
						
							|  |  |  | 		/* remove the new socket from the node socket list first,
 | 
					
						
							|  |  |  | 		 * will be added back after verification. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		BLI_remlink(socklist, sock); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return sock; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp_first) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-20 10:36:02 +00:00
										 |  |  | 	bNodeSocket *sock, *nextsock; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	bNodeSocketTemplate *stemp; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* no inputs anymore? */ | 
					
						
							|  |  |  | 	if(stemp_first==NULL) { | 
					
						
							| 
									
										
										
										
											2011-10-20 10:36:02 +00:00
										 |  |  | 		for (sock = (bNodeSocket*)socklist->first; sock; sock=nextsock) { | 
					
						
							|  |  |  | 			nextsock = sock->next; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			if (!(sock->flag & SOCK_DYNAMIC)) | 
					
						
							| 
									
										
										
										
											2011-10-20 10:36:02 +00:00
										 |  |  | 				nodeRemoveSocket(ntree, node, sock); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* step by step compare */ | 
					
						
							|  |  |  | 		stemp= stemp_first; | 
					
						
							|  |  |  | 		while(stemp->type != -1) { | 
					
						
							|  |  |  | 			stemp->sock= verify_socket_template(ntree, node, in_out, socklist, stemp); | 
					
						
							|  |  |  | 			stemp++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/* leftovers are removed */ | 
					
						
							| 
									
										
										
										
											2011-10-20 10:36:02 +00:00
										 |  |  | 		for (sock = (bNodeSocket*)socklist->first; sock; sock=nextsock) { | 
					
						
							|  |  |  | 			nextsock = sock->next; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			if (!(sock->flag & SOCK_DYNAMIC)) | 
					
						
							| 
									
										
										
										
											2011-10-20 10:36:02 +00:00
										 |  |  | 				nodeRemoveSocket(ntree, node, sock); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* and we put back the verified sockets */ | 
					
						
							|  |  |  | 		stemp= stemp_first; | 
					
						
							|  |  |  | 		if (socklist->first) { | 
					
						
							|  |  |  | 			/* some dynamic sockets left, store the list start
 | 
					
						
							|  |  |  | 			 * so we can add static sockets infront of it. | 
					
						
							|  |  |  | 			 */ | 
					
						
							|  |  |  | 			sock = socklist->first; | 
					
						
							|  |  |  | 			while(stemp->type != -1) { | 
					
						
							|  |  |  | 				/* put static sockets infront of dynamic */ | 
					
						
							|  |  |  | 				BLI_insertlinkbefore(socklist, sock, stemp->sock); | 
					
						
							|  |  |  | 				stemp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			while(stemp->type != -1) { | 
					
						
							|  |  |  | 				BLI_addtail(socklist, stemp->sock); | 
					
						
							|  |  |  | 				stemp++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void node_verify_socket_templates(bNodeTree *ntree, bNode *node) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeType *ntype= node->typeinfo; | 
					
						
							| 
									
										
										
										
											2011-09-06 08:28:06 +00:00
										 |  |  | 	/* XXX Small trick: don't try to match socket lists when there are no templates.
 | 
					
						
							|  |  |  | 	 * This also prevents group node sockets from being removed, without the need to explicitly | 
					
						
							|  |  |  | 	 * check the node type here. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if(ntype && ((ntype->inputs && ntype->inputs[0].type>=0) || (ntype->outputs && ntype->outputs[0].type>=0))) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs); | 
					
						
							|  |  |  | 		verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |