Blender V2.61 - r43446

node_socket.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2007 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): Lukas Toennne
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "DNA_node_types.h"
00034 
00035 #include "DNA_mesh_types.h"
00036 #include "DNA_meshdata_types.h"
00037 #include "DNA_object_types.h"
00038 #include "DNA_scene_types.h"
00039 
00040 #include "BLI_listbase.h"
00041 #include "BLI_math.h"
00042 #include "BLI_utildefines.h"
00043 
00044 #include "BKE_DerivedMesh.h"
00045 #include "BKE_node.h"
00046 
00047 #include "RNA_access.h"
00048 #include "RNA_types.h"
00049 
00050 #include "MEM_guardedalloc.h"
00051 
00052 #include "NOD_socket.h"
00053 
00054 /****************** FLOAT ******************/
00055 
00056 static bNodeSocketType node_socket_type_float = {
00057     /* type */              SOCK_FLOAT,
00058     /* ui_name */           "Float",
00059     /* ui_description */    "Floating Point",
00060     /* ui_icon */           0,
00061     /* ui_color */          {160,160,160,255},
00062 
00063     /* value_structname */  "bNodeSocketValueFloat",
00064     /* value_structsize */  sizeof(bNodeSocketValueFloat),
00065 
00066     /* buttonfunc */        NULL,
00067 };
00068 
00069 /****************** VECTOR ******************/
00070 
00071 static bNodeSocketType node_socket_type_vector = {
00072     /* type */              SOCK_VECTOR,
00073     /* ui_name */           "Vector",
00074     /* ui_description */    "3-dimensional floating point vector",
00075     /* ui_icon */           0,
00076     /* ui_color */          {100,100,200,255},
00077 
00078     /* value_structname */  "bNodeSocketValueVector",
00079     /* value_structsize */  sizeof(bNodeSocketValueVector),
00080 
00081     /* buttonfunc */        NULL,
00082 };
00083 
00084 /****************** RGBA ******************/
00085 
00086 static bNodeSocketType node_socket_type_rgba = {
00087     /* type */              SOCK_RGBA,
00088     /* ui_name */           "RGBA",
00089     /* ui_description */    "RGBA color",
00090     /* ui_icon */           0,
00091     /* ui_color */          {200,200,40,255},
00092 
00093     /* value_structname */  "bNodeSocketValueRGBA",
00094     /* value_structsize */  sizeof(bNodeSocketValueRGBA),
00095 
00096     /* buttonfunc */        NULL,
00097 };
00098 
00099 /****************** INT ******************/
00100 
00101 static bNodeSocketType node_socket_type_int = {
00102     /* type */              SOCK_INT,
00103     /* ui_name */           "Int",
00104     /* ui_description */    "Integer",
00105     /* ui_icon */           0,
00106     /* ui_color */          {17,133,37,255},
00107 
00108     /* value_structname */  "bNodeSocketValueInt",
00109     /* value_structsize */  sizeof(bNodeSocketValueInt),
00110 
00111     /* buttonfunc */        NULL,
00112 };
00113 
00114 /****************** BOOLEAN ******************/
00115 
00116 static bNodeSocketType node_socket_type_boolean = {
00117     /* type */              SOCK_BOOLEAN,
00118     /* ui_name */           "Boolean",
00119     /* ui_description */    "Boolean",
00120     /* ui_icon */           0,
00121     /* ui_color */          {158,139,63,255},
00122 
00123     /* value_structname */  "bNodeSocketValueBoolean",
00124     /* value_structsize */  sizeof(bNodeSocketValueBoolean),
00125 
00126     /* buttonfunc */        NULL,
00127 };
00128 
00129 /****************** SHADER ******************/
00130 
00131 static bNodeSocketType node_socket_type_shader = {
00132     /* type */              SOCK_SHADER,
00133     /* ui_name */           "Shader",
00134     /* ui_description */    "Shader",
00135     /* ui_icon */           0,
00136     /* ui_color */          {100,200,100,255},
00137 
00138     /* value_structname */  NULL,
00139     /* value_structsize */  0,
00140 
00141     /* buttonfunc */        NULL,
00142 };
00143 
00144 /****************** MESH ******************/
00145 
00146 static bNodeSocketType node_socket_type_mesh = {
00147     /* type */              SOCK_MESH,
00148     /* ui_name */           "Mesh",
00149     /* ui_description */    "Mesh geometry data",
00150     /* ui_icon */           0,
00151     /* ui_color */          {255,133,7,255},
00152 
00153     /* value_structname */  NULL,
00154     /* value_structsize */  0,
00155 
00156     /* buttonfunc */        NULL,
00157 };
00158 
00159 
00160 void node_socket_type_init(bNodeSocketType *types[])
00161 {
00162     #define INIT_TYPE(name)     types[node_socket_type_##name.type] = &node_socket_type_##name;
00163     
00164     INIT_TYPE(float);
00165     INIT_TYPE(vector);
00166     INIT_TYPE(rgba);
00167     INIT_TYPE(int);
00168     INIT_TYPE(boolean);
00169     INIT_TYPE(shader);
00170     INIT_TYPE(mesh);
00171     
00172     #undef INIT_TYPE
00173 }
00174 
00175 struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
00176                                     int value, int min, int max)
00177 {
00178     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_INT);
00179     bNodeSocketValueInt *dval= (bNodeSocketValueInt*)sock->default_value;
00180     dval->subtype = subtype;
00181     dval->value = value;
00182     dval->min = min;
00183     dval->max = max;
00184     return sock;
00185 }
00186 struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name)
00187 {
00188     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_INT);
00189     return sock;
00190 }
00191 
00192 struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
00193                                       float value, float min, float max)
00194 {
00195     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_FLOAT);
00196     bNodeSocketValueFloat *dval= (bNodeSocketValueFloat*)sock->default_value;
00197     dval->subtype = subtype;
00198     dval->value = value;
00199     dval->min = min;
00200     dval->max = max;
00201     return sock;
00202 }
00203 struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name)
00204 {
00205     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_FLOAT);
00206     return sock;
00207 }
00208 
00209 struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value)
00210 {
00211     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_BOOLEAN);
00212     bNodeSocketValueBoolean *dval= (bNodeSocketValueBoolean*)sock->default_value;
00213     dval->value = value;
00214     return sock;
00215 }
00216 struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name)
00217 {
00218     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_BOOLEAN);
00219     return sock;
00220 }
00221 
00222 struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype,
00223                                        float x, float y, float z, float min, float max)
00224 {
00225     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_VECTOR);
00226     bNodeSocketValueVector *dval= (bNodeSocketValueVector*)sock->default_value;
00227     dval->subtype = subtype;
00228     dval->value[0] = x;
00229     dval->value[1] = y;
00230     dval->value[2] = z;
00231     dval->min = min;
00232     dval->max = max;
00233     return sock;
00234 }
00235 struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name)
00236 {
00237     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_VECTOR);
00238     return sock;
00239 }
00240 
00241 struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name,
00242                                      float r, float g, float b, float a)
00243 {
00244     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_RGBA);
00245     bNodeSocketValueRGBA *dval= (bNodeSocketValueRGBA*)sock->default_value;
00246     dval->value[0] = r;
00247     dval->value[1] = g;
00248     dval->value[2] = b;
00249     dval->value[3] = a;
00250     return sock;
00251 }
00252 struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name)
00253 {
00254     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_RGBA);
00255     return sock;
00256 }
00257 
00258 struct bNodeSocket *nodeAddInputShader(struct bNodeTree *ntree, struct bNode *node, const char *name)
00259 {
00260     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_SHADER);
00261     return sock;
00262 }
00263 struct bNodeSocket *nodeAddOutputShader(struct bNodeTree *ntree, struct bNode *node, const char *name)
00264 {
00265     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_SHADER);
00266     return sock;
00267 }
00268 
00269 struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name)
00270 {
00271     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_MESH);
00272     return sock;
00273 }
00274 struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name)
00275 {
00276     bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_MESH);
00277     return sock;
00278 }
00279 
00280 struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
00281 {
00282     bNodeSocket *sock;
00283     switch (stemp->type) {
00284     case SOCK_INT:
00285         sock = nodeAddInputInt(ntree, node, stemp->name, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max);
00286         break;
00287     case SOCK_FLOAT:
00288         sock = nodeAddInputFloat(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->min, stemp->max);
00289         break;
00290     case SOCK_BOOLEAN:
00291         sock = nodeAddInputBoolean(ntree, node, stemp->name, (char)stemp->val1);
00292         break;
00293     case SOCK_VECTOR:
00294         sock = nodeAddInputVector(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max);
00295         break;
00296     case SOCK_RGBA:
00297         sock = nodeAddInputRGBA(ntree, node, stemp->name, stemp->val1, stemp->val2, stemp->val3, stemp->val4);
00298         break;
00299     case SOCK_SHADER:
00300         sock = nodeAddInputShader(ntree, node, stemp->name);
00301         break;
00302     case SOCK_MESH:
00303         sock = nodeAddInputMesh(ntree, node, stemp->name);
00304         break;
00305     default:
00306         sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type);
00307     }
00308     sock->flag |= stemp->flag;
00309     return sock;
00310 }
00311 
00312 struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp)
00313 {
00314     bNodeSocket *sock;
00315     switch (stemp->type) {
00316     case SOCK_INT:
00317         sock = nodeAddOutputInt(ntree, node, stemp->name);
00318         break;
00319     case SOCK_FLOAT:
00320         sock = nodeAddOutputFloat(ntree, node, stemp->name);
00321         break;
00322     case SOCK_BOOLEAN:
00323         sock = nodeAddOutputBoolean(ntree, node, stemp->name);
00324         break;
00325     case SOCK_VECTOR:
00326         sock = nodeAddOutputVector(ntree, node, stemp->name);
00327         break;
00328     case SOCK_RGBA:
00329         sock = nodeAddOutputRGBA(ntree, node, stemp->name);
00330         break;
00331     case SOCK_SHADER:
00332         sock = nodeAddOutputShader(ntree, node, stemp->name);
00333         break;
00334     case SOCK_MESH:
00335         sock = nodeAddOutputMesh(ntree, node, stemp->name);
00336         break;
00337     default:
00338         sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type);
00339     }
00340     return sock;
00341 }
00342 
00343 static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp)
00344 {
00345     bNodeSocket *sock;
00346     
00347     for(sock= socklist->first; sock; sock= sock->next) {
00348         if(!(sock->flag & SOCK_DYNAMIC) && strncmp(sock->name, stemp->name, NODE_MAXSTR)==0)
00349             break;
00350     }
00351     if(sock) {
00352         sock->type= stemp->type;        /* in future, read this from tydefs! */
00353         if(stemp->limit==0) sock->limit= 0xFFF;
00354         else sock->limit= stemp->limit;
00355         sock->flag |= stemp->flag;
00356         
00357         /* Copy the property range and subtype parameters in case the template changed.
00358          * NOT copying the actual value here, only button behavior changes!
00359          */
00360         switch (sock->type) {
00361         case SOCK_FLOAT:
00362             {
00363                 bNodeSocketValueFloat *dval= sock->default_value;
00364                 dval->min = stemp->min;
00365                 dval->max = stemp->max;
00366                 dval->subtype = stemp->subtype;
00367             }
00368             break;
00369         case SOCK_INT:
00370             {
00371                 bNodeSocketValueInt *dval= sock->default_value;
00372                 dval->min = stemp->min;
00373                 dval->max = stemp->max;
00374                 dval->subtype = stemp->subtype;
00375             }
00376             break;
00377         case SOCK_VECTOR:
00378             {
00379                 bNodeSocketValueVector *dval= sock->default_value;
00380                 dval->min = stemp->min;
00381                 dval->max = stemp->max;
00382                 dval->subtype = stemp->subtype;
00383             }
00384             break;
00385         }
00386         
00387         BLI_remlink(socklist, sock);
00388         
00389         return sock;
00390     }
00391     else {
00392         /* no socket for this template found, make a new one */
00393         if (in_out==SOCK_IN)
00394             sock = node_add_input_from_template(ntree, node, stemp);
00395         else
00396             sock = node_add_output_from_template(ntree, node, stemp);
00397         /* remove the new socket from the node socket list first,
00398          * will be added back after verification.
00399          */
00400         BLI_remlink(socklist, sock);
00401     }
00402     
00403     return sock;
00404 }
00405 
00406 static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp_first)
00407 {
00408     bNodeSocket *sock, *nextsock;
00409     bNodeSocketTemplate *stemp;
00410     
00411     /* no inputs anymore? */
00412     if(stemp_first==NULL) {
00413         for (sock = (bNodeSocket*)socklist->first; sock; sock=nextsock) {
00414             nextsock = sock->next;
00415             if (!(sock->flag & SOCK_DYNAMIC))
00416                 nodeRemoveSocket(ntree, node, sock);
00417         }
00418     }
00419     else {
00420         /* step by step compare */
00421         stemp= stemp_first;
00422         while(stemp->type != -1) {
00423             stemp->sock= verify_socket_template(ntree, node, in_out, socklist, stemp);
00424             stemp++;
00425         }
00426         /* leftovers are removed */
00427         for (sock = (bNodeSocket*)socklist->first; sock; sock=nextsock) {
00428             nextsock = sock->next;
00429             if (!(sock->flag & SOCK_DYNAMIC))
00430                 nodeRemoveSocket(ntree, node, sock);
00431         }
00432         
00433         /* and we put back the verified sockets */
00434         stemp= stemp_first;
00435         if (socklist->first) {
00436             /* some dynamic sockets left, store the list start
00437              * so we can add static sockets infront of it.
00438              */
00439             sock = socklist->first;
00440             while(stemp->type != -1) {
00441                 /* put static sockets infront of dynamic */
00442                 BLI_insertlinkbefore(socklist, sock, stemp->sock);
00443                 stemp++;
00444             }
00445         }
00446         else {
00447             while(stemp->type != -1) {
00448                 BLI_addtail(socklist, stemp->sock);
00449                 stemp++;
00450             }
00451         }
00452     }
00453 }
00454 
00455 void node_verify_socket_templates(bNodeTree *ntree, bNode *node)
00456 {
00457     bNodeType *ntype= node->typeinfo;
00458     /* XXX Small trick: don't try to match socket lists when there are no templates.
00459      * This also prevents group node sockets from being removed, without the need to explicitly
00460      * check the node type here.
00461      */
00462     if(ntype && ((ntype->inputs && ntype->inputs[0].type>=0) || (ntype->outputs && ntype->outputs[0].type>=0))) {
00463         verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs);
00464         verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs);
00465     }
00466 }