aabaf5b86dee669f6abd5ae09394aacb0028f58c
[blender.git] / source / blender / nodes / intern / node_socket.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2007 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Lukas Toennne
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file blender/nodes/intern/node_socket.c
31  *  \ingroup nodes
32  */
33
34
35 #include "DNA_node_types.h"
36
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41
42 #include "BLI_listbase.h"
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45
46 #include "BKE_DerivedMesh.h"
47 #include "BKE_node.h"
48
49 #include "RNA_access.h"
50 #include "RNA_types.h"
51
52 #include "MEM_guardedalloc.h"
53
54 #include "NOD_socket.h"
55
56 /****************** FLOAT ******************/
57
58 static bNodeSocketType node_socket_type_float = {
59         /* type */                              SOCK_FLOAT,
60         /* ui_name */                   "Float",
61         /* ui_description */    "Floating Point",
62         /* ui_icon */                   0,
63         /* ui_color */                  {160,160,160,255},
64
65         /* value_structname */  "bNodeSocketValueFloat",
66         /* value_structsize */  sizeof(bNodeSocketValueFloat),
67
68         /* buttonfunc */                NULL,
69 };
70
71 /****************** VECTOR ******************/
72
73 static bNodeSocketType node_socket_type_vector = {
74         /* type */                              SOCK_VECTOR,
75         /* ui_name */                   "Vector",
76         /* ui_description */    "3-dimensional floating point vector",
77         /* ui_icon */                   0,
78         /* ui_color */                  {100,100,200,255},
79
80         /* value_structname */  "bNodeSocketValueVector",
81         /* value_structsize */  sizeof(bNodeSocketValueVector),
82
83         /* buttonfunc */                NULL,
84 };
85
86 /****************** RGBA ******************/
87
88 static bNodeSocketType node_socket_type_rgba = {
89         /* type */                              SOCK_RGBA,
90         /* ui_name */                   "RGBA",
91         /* ui_description */    "RGBA color",
92         /* ui_icon */                   0,
93         /* ui_color */                  {200,200,40,255},
94
95         /* value_structname */  "bNodeSocketValueRGBA",
96         /* value_structsize */  sizeof(bNodeSocketValueRGBA),
97
98         /* buttonfunc */                NULL,
99 };
100
101 /****************** INT ******************/
102
103 static bNodeSocketType node_socket_type_int = {
104         /* type */                              SOCK_INT,
105         /* ui_name */                   "Int",
106         /* ui_description */    "Integer",
107         /* ui_icon */                   0,
108         /* ui_color */                  {17,133,37,255},
109
110         /* value_structname */  "bNodeSocketValueInt",
111         /* value_structsize */  sizeof(bNodeSocketValueInt),
112
113         /* buttonfunc */                NULL,
114 };
115
116 /****************** BOOLEAN ******************/
117
118 static bNodeSocketType node_socket_type_boolean = {
119         /* type */                              SOCK_BOOLEAN,
120         /* ui_name */                   "Boolean",
121         /* ui_description */    "Boolean",
122         /* ui_icon */                   0,
123         /* ui_color */                  {158,139,63,255},
124
125         /* value_structname */  "bNodeSocketValueBoolean",
126         /* value_structsize */  sizeof(bNodeSocketValueBoolean),
127
128         /* buttonfunc */                NULL,
129 };
130
131 /****************** MESH ******************/
132
133 static bNodeSocketType node_socket_type_mesh = {
134         /* type */                              SOCK_MESH,
135         /* ui_name */                   "Mesh",
136         /* ui_description */    "Mesh geometry data",
137         /* ui_icon */                   0,
138         /* ui_color */                  {255,133,7,255},
139
140         /* value_structname */  NULL,
141         /* value_structsize */  0,
142
143         /* buttonfunc */                NULL,
144 };
145
146
147 void node_socket_type_init(bNodeSocketType *types[])
148 {
149         #define INIT_TYPE(name)         types[node_socket_type_##name.type] = &node_socket_type_##name;
150         
151         INIT_TYPE(float);
152         INIT_TYPE(vector);
153         INIT_TYPE(rgba);
154         INIT_TYPE(int);
155         INIT_TYPE(boolean);
156         INIT_TYPE(mesh);
157         
158         #undef INIT_TYPE
159 }
160
161 struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
162                                                                         int value, int min, int max)
163 {
164         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_INT);
165         bNodeSocketValueInt *dval= (bNodeSocketValueInt*)sock->default_value;
166         dval->subtype = subtype;
167         dval->value = value;
168         dval->min = min;
169         dval->max = max;
170         return sock;
171 }
172 struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name)
173 {
174         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_INT);
175         return sock;
176 }
177
178 struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
179                                                                           float value, float min, float max)
180 {
181         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_FLOAT);
182         bNodeSocketValueFloat *dval= (bNodeSocketValueFloat*)sock->default_value;
183         dval->subtype = subtype;
184         dval->value = value;
185         dval->min = min;
186         dval->max = max;
187         return sock;
188 }
189 struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name)
190 {
191         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_FLOAT);
192         return sock;
193 }
194
195 struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value)
196 {
197         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_BOOLEAN);
198         bNodeSocketValueBoolean *dval= (bNodeSocketValueBoolean*)sock->default_value;
199         dval->value = value;
200         return sock;
201 }
202 struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name)
203 {
204         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_BOOLEAN);
205         return sock;
206 }
207
208 struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
209                                                                            float x, float y, float z, float min, float max)
210 {
211         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_VECTOR);
212         bNodeSocketValueVector *dval= (bNodeSocketValueVector*)sock->default_value;
213         dval->subtype = subtype;
214         dval->value[0] = x;
215         dval->value[1] = y;
216         dval->value[2] = z;
217         dval->min = min;
218         dval->max = max;
219         return sock;
220 }
221 struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name)
222 {
223         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_VECTOR);
224         return sock;
225 }
226
227 struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name,
228                                                                          float r, float g, float b, float a)
229 {
230         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_RGBA);
231         bNodeSocketValueRGBA *dval= (bNodeSocketValueRGBA*)sock->default_value;
232         dval->value[0] = r;
233         dval->value[1] = g;
234         dval->value[2] = b;
235         dval->value[3] = a;
236         return sock;
237 }
238 struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name)
239 {
240         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_RGBA);
241         return sock;
242 }
243
244 struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name)
245 {
246         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_MESH);
247         return sock;
248 }
249 struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name)
250 {
251         bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_MESH);
252         return sock;
253 }
254
255 struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
256 {
257         bNodeSocket *sock;
258         switch (stemp->type) {
259         case SOCK_INT:
260                 sock = nodeAddInputInt(ntree, node, stemp->name, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max);
261                 break;
262         case SOCK_FLOAT:
263                 sock = nodeAddInputFloat(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->min, stemp->max);
264                 break;
265         case SOCK_BOOLEAN:
266                 sock = nodeAddInputBoolean(ntree, node, stemp->name, (char)stemp->val1);
267                 break;
268         case SOCK_VECTOR:
269                 sock = nodeAddInputVector(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max);
270                 break;
271         case SOCK_RGBA:
272                 sock = nodeAddInputRGBA(ntree, node, stemp->name, stemp->val1, stemp->val2, stemp->val3, stemp->val4);
273                 break;
274         case SOCK_MESH:
275                 sock = nodeAddInputMesh(ntree, node, stemp->name);
276                 break;
277         default:
278                 sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type);
279         }
280         return sock;
281 }
282
283 struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
284 {
285         bNodeSocket *sock;
286         switch (stemp->type) {
287         case SOCK_INT:
288                 sock = nodeAddOutputInt(ntree, node, stemp->name);
289                 break;
290         case SOCK_FLOAT:
291                 sock = nodeAddOutputFloat(ntree, node, stemp->name);
292                 break;
293         case SOCK_BOOLEAN:
294                 sock = nodeAddOutputBoolean(ntree, node, stemp->name);
295                 break;
296         case SOCK_VECTOR:
297                 sock = nodeAddOutputVector(ntree, node, stemp->name);
298                 break;
299         case SOCK_RGBA:
300                 sock = nodeAddOutputRGBA(ntree, node, stemp->name);
301                 break;
302         case SOCK_MESH:
303                 sock = nodeAddOutputMesh(ntree, node, stemp->name);
304                 break;
305         default:
306                 sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type);
307         }
308         return sock;
309 }
310
311 static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp)
312 {
313         bNodeSocket *sock;
314         
315         for(sock= socklist->first; sock; sock= sock->next) {
316                 if(!(sock->flag & SOCK_DYNAMIC) && strncmp(sock->name, stemp->name, NODE_MAXSTR)==0)
317                         break;
318         }
319         if(sock) {
320                 sock->type= stemp->type;                /* in future, read this from tydefs! */
321                 if(stemp->limit==0) sock->limit= 0xFFF;
322                 else sock->limit= stemp->limit;
323                 
324                 /* Copy the property range and subtype parameters in case the template changed.
325                  * NOT copying the actual value here, only button behavior changes!
326                  */
327                 switch (sock->type) {
328                 case SOCK_FLOAT:
329                         {
330                                 bNodeSocketValueFloat *dval= sock->default_value;
331                                 dval->min = stemp->min;
332                                 dval->max = stemp->max;
333                                 dval->subtype = stemp->subtype;
334                         }
335                         break;
336                 case SOCK_INT:
337                         {
338                                 bNodeSocketValueInt *dval= sock->default_value;
339                                 dval->min = stemp->min;
340                                 dval->max = stemp->max;
341                                 dval->subtype = stemp->subtype;
342                         }
343                         break;
344                 case SOCK_VECTOR:
345                         {
346                                 bNodeSocketValueVector *dval= sock->default_value;
347                                 dval->min = stemp->min;
348                                 dval->max = stemp->max;
349                                 dval->subtype = stemp->subtype;
350                         }
351                         break;
352                 }
353                 
354                 BLI_remlink(socklist, sock);
355                 
356                 return sock;
357         }
358         else {
359                 /* no socket for this template found, make a new one */
360                 if (in_out==SOCK_IN)
361                         sock = node_add_input_from_template(ntree, node, stemp);
362                 else
363                         sock = node_add_output_from_template(ntree, node, stemp);
364                 /* remove the new socket from the node socket list first,
365                  * will be added back after verification.
366                  */
367                 BLI_remlink(socklist, sock);
368         }
369         
370         return sock;
371 }
372
373 static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp_first)
374 {
375         bNodeSocket *sock;
376         bNodeSocketTemplate *stemp;
377         
378         /* no inputs anymore? */
379         if(stemp_first==NULL) {
380                 while(socklist->first) {
381                         sock = (bNodeSocket*)socklist->first;
382                         if (!(sock->flag & SOCK_DYNAMIC))
383                                 nodeRemoveSocket(ntree, node, socklist->first);
384                 }
385         }
386         else {
387                 /* step by step compare */
388                 stemp= stemp_first;
389                 while(stemp->type != -1) {
390                         stemp->sock= verify_socket_template(ntree, node, in_out, socklist, stemp);
391                         stemp++;
392                 }
393                 /* leftovers are removed */
394                 while(socklist->first) {
395                         sock = (bNodeSocket*)socklist->first;
396                         if (!(sock->flag & SOCK_DYNAMIC))
397                                 nodeRemoveSocket(ntree, node, socklist->first);
398                 }
399                 
400                 /* and we put back the verified sockets */
401                 stemp= stemp_first;
402                 if (socklist->first) {
403                         /* some dynamic sockets left, store the list start
404                          * so we can add static sockets infront of it.
405                          */
406                         sock = socklist->first;
407                         while(stemp->type != -1) {
408                                 /* put static sockets infront of dynamic */
409                                 BLI_insertlinkbefore(socklist, sock, stemp->sock);
410                                 stemp++;
411                         }
412                 }
413                 else {
414                         while(stemp->type != -1) {
415                                 BLI_addtail(socklist, stemp->sock);
416                                 stemp++;
417                         }
418                 }
419         }
420 }
421
422 void node_verify_socket_templates(bNodeTree *ntree, bNode *node)
423 {
424         bNodeType *ntype= node->typeinfo;
425         /* XXX Small trick: don't try to match socket lists when there are no templates.
426          * This also prevents group node sockets from being removed, without the need to explicitly
427          * check the node type here.
428          */
429         if(ntype && ((ntype->inputs && ntype->inputs[0].type>=0) || (ntype->outputs && ntype->outputs[0].type>=0))) {
430                 verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs);
431                 verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs);
432         }
433 }