Blender V2.61 - r43446
|
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 }