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 Toenne. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <string.h> 00034 00035 #include "DNA_action_types.h" 00036 #include "DNA_anim_types.h" 00037 #include "DNA_node_types.h" 00038 00039 #include "BLI_listbase.h" 00040 #include "BLI_string.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "BKE_action.h" 00044 #include "BKE_animsys.h" 00045 #include "BKE_global.h" 00046 #include "BKE_library.h" 00047 #include "BKE_main.h" 00048 #include "BLI_math.h" 00049 #include "BKE_node.h" 00050 #include "BKE_utildefines.h" 00051 00052 #include "RNA_access.h" 00053 #include "RNA_types.h" 00054 00055 #include "MEM_guardedalloc.h" 00056 00057 #include "node_common.h" 00058 #include "node_exec.h" 00059 #include "NOD_socket.h" 00060 00061 /**** Group ****/ 00062 00063 bNodeSocket *node_group_find_input(bNode *gnode, bNodeSocket *gsock) 00064 { 00065 bNodeSocket *sock; 00066 for (sock=gnode->inputs.first; sock; sock=sock->next) 00067 if (sock->groupsock == gsock) 00068 return sock; 00069 return NULL; 00070 } 00071 00072 bNodeSocket *node_group_find_output(bNode *gnode, bNodeSocket *gsock) 00073 { 00074 bNodeSocket *sock; 00075 for (sock=gnode->outputs.first; sock; sock=sock->next) 00076 if (sock->groupsock == gsock) 00077 return sock; 00078 return NULL; 00079 } 00080 00081 bNodeSocket *node_group_add_extern_socket(bNodeTree *UNUSED(ntree), ListBase *lb, int in_out, bNodeSocket *gsock) 00082 { 00083 bNodeSocket *sock; 00084 00085 if (gsock->flag & SOCK_INTERNAL) 00086 return NULL; 00087 00088 sock= MEM_callocN(sizeof(bNodeSocket), "sock"); 00089 00090 /* make a copy of the group socket */ 00091 *sock = *gsock; 00092 sock->link = NULL; 00093 sock->next = sock->prev = NULL; 00094 sock->new_sock = NULL; 00095 00096 /* group sockets are dynamically added */ 00097 sock->flag |= SOCK_DYNAMIC; 00098 00099 sock->own_index = gsock->own_index; 00100 sock->groupsock = gsock; 00101 sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); 00102 00103 if (gsock->default_value) 00104 sock->default_value = MEM_dupallocN(gsock->default_value); 00105 00106 if(lb) 00107 BLI_addtail(lb, sock); 00108 00109 return sock; 00110 } 00111 00112 bNode *node_group_make_from_selected(bNodeTree *ntree) 00113 { 00114 bNodeLink *link, *linkn; 00115 bNode *node, *gnode, *nextn; 00116 bNodeTree *ngroup; 00117 bNodeSocket *gsock; 00118 ListBase anim_basepaths = {NULL, NULL}; 00119 float min[2], max[2]; 00120 int totnode=0; 00121 bNodeTemplate ntemp; 00122 00123 INIT_MINMAX2(min, max); 00124 00125 /* is there something to group? also do some clearing */ 00126 for(node= ntree->nodes.first; node; node= node->next) { 00127 if(node->flag & NODE_SELECT) { 00128 /* no groups in groups */ 00129 if(node->type==NODE_GROUP) 00130 return NULL; 00131 DO_MINMAX2( (&node->locx), min, max); 00132 totnode++; 00133 } 00134 node->done= 0; 00135 } 00136 if(totnode==0) return NULL; 00137 00138 /* check if all connections are OK, no unselected node has both 00139 inputs and outputs to a selection */ 00140 for(link= ntree->links.first; link; link= link->next) { 00141 if(link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT) 00142 link->tonode->done |= 1; 00143 if(link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT) 00144 link->fromnode->done |= 2; 00145 } 00146 00147 for(node= ntree->nodes.first; node; node= node->next) { 00148 if((node->flag & NODE_SELECT)==0) 00149 if(node->done==3) 00150 break; 00151 } 00152 if(node) 00153 return NULL; 00154 00155 /* OK! new nodetree */ 00156 ngroup= ntreeAddTree("NodeGroup", ntree->type, NODE_GROUP); 00157 00158 /* move nodes over */ 00159 for(node= ntree->nodes.first; node; node= nextn) { 00160 nextn= node->next; 00161 if(node->flag & NODE_SELECT) { 00162 /* keep track of this node's RNA "base" path (the part of the pat identifying the node) 00163 * if the old nodetree has animation data which potentially covers this node 00164 */ 00165 if (ntree->adt) { 00166 PointerRNA ptr; 00167 char *path; 00168 00169 RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); 00170 path = RNA_path_from_ID_to_struct(&ptr); 00171 00172 if (path) 00173 BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); 00174 } 00175 00176 /* change node-collection membership */ 00177 BLI_remlink(&ntree->nodes, node); 00178 BLI_addtail(&ngroup->nodes, node); 00179 00180 node->locx-= 0.5f*(min[0]+max[0]); 00181 node->locy-= 0.5f*(min[1]+max[1]); 00182 } 00183 } 00184 00185 /* move animation data over */ 00186 if (ntree->adt) { 00187 LinkData *ld, *ldn=NULL; 00188 00189 BKE_animdata_separate_by_basepath(&ntree->id, &ngroup->id, &anim_basepaths); 00190 00191 /* paths + their wrappers need to be freed */ 00192 for (ld = anim_basepaths.first; ld; ld = ldn) { 00193 ldn = ld->next; 00194 00195 MEM_freeN(ld->data); 00196 BLI_freelinkN(&anim_basepaths, ld); 00197 } 00198 } 00199 00200 /* node groups don't use internal cached data */ 00201 ntreeFreeCache(ngroup); 00202 00203 /* make group node */ 00204 ntemp.type = NODE_GROUP; 00205 ntemp.ngroup = ngroup; 00206 gnode= nodeAddNode(ntree, &ntemp); 00207 gnode->locx= 0.5f*(min[0]+max[0]); 00208 gnode->locy= 0.5f*(min[1]+max[1]); 00209 00210 /* relink external sockets */ 00211 for(link= ntree->links.first; link; link= linkn) { 00212 linkn= link->next; 00213 00214 if(link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) { 00215 BLI_remlink(&ntree->links, link); 00216 BLI_addtail(&ngroup->links, link); 00217 } 00218 else if(link->tonode && (link->tonode->flag & NODE_SELECT)) { 00219 gsock = node_group_expose_socket(ngroup, link->tosock, SOCK_IN); 00220 link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); 00221 link->tosock = node_group_add_extern_socket(ntree, &gnode->inputs, SOCK_IN, gsock); 00222 link->tonode = gnode; 00223 } 00224 else if(link->fromnode && (link->fromnode->flag & NODE_SELECT)) { 00225 /* search for existing group node socket */ 00226 for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) 00227 if (gsock->link && gsock->link->fromsock==link->fromsock) 00228 break; 00229 if (!gsock) { 00230 gsock = node_group_expose_socket(ngroup, link->fromsock, SOCK_OUT); 00231 gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); 00232 link->fromsock = node_group_add_extern_socket(ntree, &gnode->outputs, SOCK_OUT, gsock); 00233 } 00234 else 00235 link->fromsock = node_group_find_output(gnode, gsock); 00236 link->fromnode = gnode; 00237 } 00238 } 00239 00240 /* update of the group tree */ 00241 ngroup->update |= NTREE_UPDATE; 00242 ntreeUpdateTree(ngroup); 00243 /* update of the tree containing the group instance node */ 00244 ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; 00245 ntreeUpdateTree(ntree); 00246 00247 return gnode; 00248 } 00249 00250 /* XXX This is a makeshift function to have useful initial group socket values. 00251 * In the end this should be implemented by a flexible socket data conversion system, 00252 * which is yet to be implemented. The idea is that beside default standard conversions, 00253 * such as int-to-float, it should be possible to quickly select a conversion method or 00254 * a chain of conversions for each input, whenever there is more than one option. 00255 * E.g. a vector-to-float conversion could use either of the x/y/z components or 00256 * the vector length. 00257 * 00258 * In the interface this could be implemented by a pseudo-script textbox on linked inputs, 00259 * with quick selection from a predefined list of conversion options. Some Examples: 00260 * - vector component 'z' (vector->float): "z" 00261 * - greyscale color (float->color): "grey" 00262 * - color luminance (color->float): "lum" 00263 * - matrix column 2 length (matrix->vector->float): "col[1].len" 00264 * - mesh vertex coordinate 'y' (mesh->vertex->vector->float): "vertex.co.y" 00265 * 00266 * The actual conversion is then done by a series of conversion functions, 00267 * which are defined in the socket type structs. 00268 */ 00269 static void convert_socket_value(bNodeSocket *from, bNodeSocket *to) 00270 { 00271 /* XXX only one of these pointers is valid! just putting them here for convenience */ 00272 bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value; 00273 bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value; 00274 bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value; 00275 bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value; 00276 bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value; 00277 00278 bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value; 00279 bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value; 00280 bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value; 00281 bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value; 00282 bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value; 00283 00284 switch (from->type) { 00285 case SOCK_FLOAT: 00286 switch (to->type) { 00287 case SOCK_FLOAT: 00288 tofloat->value = fromfloat->value; 00289 break; 00290 case SOCK_INT: 00291 toint->value = (int)fromfloat->value; 00292 break; 00293 case SOCK_BOOLEAN: 00294 tobool->value = (fromfloat->value > 0.0f); 00295 break; 00296 case SOCK_VECTOR: 00297 tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value; 00298 break; 00299 case SOCK_RGBA: 00300 torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value; 00301 break; 00302 } 00303 break; 00304 case SOCK_INT: 00305 switch (to->type) { 00306 case SOCK_FLOAT: 00307 tofloat->value = (float)fromint->value; 00308 break; 00309 case SOCK_INT: 00310 toint->value = fromint->value; 00311 break; 00312 case SOCK_BOOLEAN: 00313 tobool->value = (fromint->value > 0); 00314 break; 00315 case SOCK_VECTOR: 00316 tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value; 00317 break; 00318 case SOCK_RGBA: 00319 torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value; 00320 break; 00321 } 00322 break; 00323 case SOCK_BOOLEAN: 00324 switch (to->type) { 00325 case SOCK_FLOAT: 00326 tofloat->value = (float)frombool->value; 00327 break; 00328 case SOCK_INT: 00329 toint->value = (int)frombool->value; 00330 break; 00331 case SOCK_BOOLEAN: 00332 tobool->value = frombool->value; 00333 break; 00334 case SOCK_VECTOR: 00335 tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value; 00336 break; 00337 case SOCK_RGBA: 00338 torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value; 00339 break; 00340 } 00341 break; 00342 case SOCK_VECTOR: 00343 switch (to->type) { 00344 case SOCK_FLOAT: 00345 tofloat->value = fromvector->value[0]; 00346 break; 00347 case SOCK_INT: 00348 toint->value = (int)fromvector->value[0]; 00349 break; 00350 case SOCK_BOOLEAN: 00351 tobool->value = (fromvector->value[0] > 0.0f); 00352 break; 00353 case SOCK_VECTOR: 00354 copy_v3_v3(tovector->value, fromvector->value); 00355 break; 00356 case SOCK_RGBA: 00357 copy_v3_v3(torgba->value, fromvector->value); 00358 torgba->value[3] = 1.0f; 00359 break; 00360 } 00361 break; 00362 case SOCK_RGBA: 00363 switch (to->type) { 00364 case SOCK_FLOAT: 00365 tofloat->value = fromrgba->value[0]; 00366 break; 00367 case SOCK_INT: 00368 toint->value = (int)fromrgba->value[0]; 00369 break; 00370 case SOCK_BOOLEAN: 00371 tobool->value = (fromrgba->value[0] > 0.0f); 00372 break; 00373 case SOCK_VECTOR: 00374 copy_v3_v3(tovector->value, fromrgba->value); 00375 break; 00376 case SOCK_RGBA: 00377 copy_v4_v4(torgba->value, fromrgba->value); 00378 break; 00379 } 00380 break; 00381 } 00382 } 00383 00384 static void copy_socket_value(bNodeSocket *from, bNodeSocket *to) 00385 { 00386 /* XXX only one of these pointers is valid! just putting them here for convenience */ 00387 bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value; 00388 bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value; 00389 bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value; 00390 bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value; 00391 bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value; 00392 00393 bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value; 00394 bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value; 00395 bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value; 00396 bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value; 00397 bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value; 00398 00399 if (from->type != to->type) 00400 return; 00401 00402 switch (from->type) { 00403 case SOCK_FLOAT: 00404 *tofloat = *fromfloat; 00405 break; 00406 case SOCK_INT: 00407 *toint = *fromint; 00408 break; 00409 case SOCK_BOOLEAN: 00410 *tobool = *frombool; 00411 break; 00412 case SOCK_VECTOR: 00413 *tovector = *fromvector; 00414 break; 00415 case SOCK_RGBA: 00416 *torgba = *fromrgba; 00417 break; 00418 } 00419 } 00420 00421 /* returns 1 if its OK */ 00422 int node_group_ungroup(bNodeTree *ntree, bNode *gnode) 00423 { 00424 bNodeLink *link, *linkn; 00425 bNode *node, *nextn; 00426 bNodeTree *ngroup, *wgroup; 00427 ListBase anim_basepaths = {NULL, NULL}; 00428 00429 ngroup= (bNodeTree *)gnode->id; 00430 if(ngroup==NULL) return 0; 00431 00432 /* clear new pointers, set in copytree */ 00433 for(node= ntree->nodes.first; node; node= node->next) 00434 node->new_node= NULL; 00435 00436 /* wgroup is a temporary copy of the NodeTree we're merging in 00437 * - all of wgroup's nodes are transferred across to their new home 00438 * - ngroup (i.e. the source NodeTree) is left unscathed 00439 */ 00440 wgroup= ntreeCopyTree(ngroup); 00441 00442 /* add the nodes into the ntree */ 00443 for(node= wgroup->nodes.first; node; node= nextn) { 00444 nextn= node->next; 00445 00446 /* keep track of this node's RNA "base" path (the part of the pat identifying the node) 00447 * if the old nodetree has animation data which potentially covers this node 00448 */ 00449 if (wgroup->adt) { 00450 PointerRNA ptr; 00451 char *path; 00452 00453 RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr); 00454 path = RNA_path_from_ID_to_struct(&ptr); 00455 00456 if (path) 00457 BLI_addtail(&anim_basepaths, BLI_genericNodeN(path)); 00458 } 00459 00460 /* migrate node */ 00461 BLI_remlink(&wgroup->nodes, node); 00462 BLI_addtail(&ntree->nodes, node); 00463 00464 node->locx+= gnode->locx; 00465 node->locy+= gnode->locy; 00466 00467 node->flag |= NODE_SELECT; 00468 } 00469 00470 /* restore external links to and from the gnode */ 00471 for(link= ntree->links.first; link; link= link->next) { 00472 if (link->fromnode==gnode) { 00473 if (link->fromsock->groupsock) { 00474 bNodeSocket *gsock= link->fromsock->groupsock; 00475 if (gsock->link) { 00476 if (gsock->link->fromnode) { 00477 /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ 00478 link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); 00479 link->fromsock = gsock->link->fromsock->new_sock; 00480 } 00481 else { 00482 /* group output directly maps to group input */ 00483 bNodeSocket *insock= node_group_find_input(gnode, gsock->link->fromsock); 00484 if (insock->link) { 00485 link->fromnode = insock->link->fromnode; 00486 link->fromsock = insock->link->fromsock; 00487 } 00488 } 00489 } 00490 else { 00491 /* copy the default input value from the group socket default to the external socket */ 00492 convert_socket_value(gsock, link->tosock); 00493 } 00494 } 00495 } 00496 } 00497 /* remove internal output links, these are not used anymore */ 00498 for(link=wgroup->links.first; link; link= linkn) { 00499 linkn = link->next; 00500 if (!link->tonode) 00501 nodeRemLink(wgroup, link); 00502 } 00503 /* restore links from internal nodes */ 00504 for(link= wgroup->links.first; link; link= link->next) { 00505 /* indicates link to group input */ 00506 if (!link->fromnode) { 00507 /* NB: can't use find_group_node_input here, 00508 * because gnode sockets still point to the old tree! 00509 */ 00510 bNodeSocket *insock; 00511 for (insock= gnode->inputs.first; insock; insock= insock->next) 00512 if (insock->groupsock->new_sock == link->fromsock) 00513 break; 00514 if (insock->link) { 00515 link->fromnode = insock->link->fromnode; 00516 link->fromsock = insock->link->fromsock; 00517 } 00518 else { 00519 /* copy the default input value from the group node socket default to the internal socket */ 00520 convert_socket_value(insock, link->tosock); 00521 nodeRemLink(wgroup, link); 00522 } 00523 } 00524 } 00525 00526 /* add internal links to the ntree */ 00527 for(link= wgroup->links.first; link; link= linkn) { 00528 linkn= link->next; 00529 BLI_remlink(&wgroup->links, link); 00530 BLI_addtail(&ntree->links, link); 00531 } 00532 00533 /* and copy across the animation, 00534 * note that the animation data's action can be NULL here */ 00535 if (wgroup->adt) { 00536 LinkData *ld, *ldn=NULL; 00537 bAction *waction; 00538 00539 /* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */ 00540 waction = wgroup->adt->action = copy_action(wgroup->adt->action); 00541 00542 /* now perform the moving */ 00543 BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths); 00544 00545 /* paths + their wrappers need to be freed */ 00546 for (ld = anim_basepaths.first; ld; ld = ldn) { 00547 ldn = ld->next; 00548 00549 MEM_freeN(ld->data); 00550 BLI_freelinkN(&anim_basepaths, ld); 00551 } 00552 00553 /* free temp action too */ 00554 if (waction) { 00555 free_libblock(&G.main->action, waction); 00556 } 00557 } 00558 00559 /* delete the group instance. this also removes old input links! */ 00560 nodeFreeNode(ntree, gnode); 00561 00562 /* free the group tree (takes care of user count) */ 00563 free_libblock(&G.main->nodetree, wgroup); 00564 00565 ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS; 00566 ntreeUpdateTree(ntree); 00567 00568 return 1; 00569 } 00570 00571 bNodeSocket *node_group_add_socket(bNodeTree *ngroup, const char *name, int type, int in_out) 00572 { 00573 bNodeSocketType *stype = ntreeGetSocketType(type); 00574 bNodeSocket *gsock = MEM_callocN(sizeof(bNodeSocket), "bNodeSocket"); 00575 00576 BLI_strncpy(gsock->name, name, sizeof(gsock->name)); 00577 gsock->type = type; 00578 /* group sockets are dynamically added */ 00579 gsock->flag |= SOCK_DYNAMIC; 00580 00581 gsock->next = gsock->prev = NULL; 00582 gsock->new_sock = NULL; 00583 gsock->link = NULL; 00584 /* assign new unique index */ 00585 gsock->own_index = ngroup->cur_index++; 00586 gsock->limit = (in_out==SOCK_IN ? 0xFFF : 1); 00587 00588 if (stype->value_structsize > 0) 00589 gsock->default_value = MEM_callocN(stype->value_structsize, "default socket value"); 00590 00591 BLI_addtail(in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs, gsock); 00592 00593 ngroup->update |= (in_out==SOCK_IN ? NTREE_UPDATE_GROUP_IN : NTREE_UPDATE_GROUP_OUT); 00594 00595 return gsock; 00596 } 00597 00598 bNodeSocket *node_group_expose_socket(bNodeTree *ngroup, bNodeSocket *sock, int in_out) 00599 { 00600 bNodeSocket *gsock= node_group_add_socket(ngroup, sock->name, sock->type, in_out); 00601 00602 /* initialize the default value. */ 00603 copy_socket_value(sock, gsock); 00604 00605 return gsock; 00606 } 00607 00608 void node_group_expose_all_sockets(bNodeTree *ngroup) 00609 { 00610 bNode *node; 00611 bNodeSocket *sock, *gsock; 00612 00613 for (node=ngroup->nodes.first; node; node=node->next) { 00614 for (sock=node->inputs.first; sock; sock=sock->next) { 00615 if (!sock->link && !nodeSocketIsHidden(sock)) { 00616 gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN); 00617 00618 /* initialize the default value. */ 00619 copy_socket_value(sock, gsock); 00620 00621 sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); 00622 } 00623 } 00624 for (sock=node->outputs.first; sock; sock=sock->next) { 00625 if (nodeCountSocketLinks(ngroup, sock)==0 && !nodeSocketIsHidden(sock)) { 00626 gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT); 00627 00628 /* initialize the default value. */ 00629 copy_socket_value(sock, gsock); 00630 00631 gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); 00632 } 00633 } 00634 } 00635 } 00636 00637 void node_group_remove_socket(bNodeTree *ngroup, bNodeSocket *gsock, int in_out) 00638 { 00639 nodeRemSocketLinks(ngroup, gsock); 00640 00641 switch (in_out) { 00642 case SOCK_IN: 00643 BLI_remlink(&ngroup->inputs, gsock); 00644 ngroup->update |= NTREE_UPDATE_GROUP_IN; 00645 break; 00646 case SOCK_OUT: 00647 BLI_remlink(&ngroup->outputs, gsock); 00648 ngroup->update |= NTREE_UPDATE_GROUP_OUT; 00649 break; 00650 } 00651 00652 if (gsock->default_value) 00653 MEM_freeN(gsock->default_value); 00654 00655 MEM_freeN(gsock); 00656 } 00657 00658 /* groups display their internal tree name as label */ 00659 const char *node_group_label(bNode *node) 00660 { 00661 return (node->id)? node->id->name+2: "Missing Datablock"; 00662 } 00663 00664 int node_group_valid(bNodeTree *ntree, bNodeTemplate *ntemp) 00665 { 00666 bNodeTemplate childtemp; 00667 bNode *node; 00668 00669 /* regular groups cannot be recursive */ 00670 if (ntree == ntemp->ngroup) 00671 return 0; 00672 00673 /* make sure all children are valid */ 00674 for (node=ntemp->ngroup->nodes.first; node; node=node->next) { 00675 childtemp = nodeMakeTemplate(node); 00676 if (!nodeValid(ntree, &childtemp)) 00677 return 0; 00678 } 00679 00680 return 1; 00681 } 00682 00683 bNodeTemplate node_group_template(bNode *node) 00684 { 00685 bNodeTemplate ntemp; 00686 ntemp.type = NODE_GROUP; 00687 ntemp.ngroup = (bNodeTree*)node->id; 00688 return ntemp; 00689 } 00690 00691 void node_group_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) 00692 { 00693 node->id = (ID*)ntemp->ngroup; 00694 00695 /* NB: group socket input/output roles are inverted internally! 00696 * Group "inputs" work as outputs in links and vice versa. 00697 */ 00698 if (ntemp->ngroup) { 00699 bNodeSocket *gsock; 00700 for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next) 00701 node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock); 00702 for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next) 00703 node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock); 00704 } 00705 } 00706 00707 static bNodeSocket *group_verify_socket(bNodeTree *ntree, ListBase *lb, int in_out, bNodeSocket *gsock) 00708 { 00709 bNodeSocket *sock; 00710 00711 /* group sockets tagged as internal are not exposed ever */ 00712 if (gsock->flag & SOCK_INTERNAL) 00713 return NULL; 00714 00715 for(sock= lb->first; sock; sock= sock->next) { 00716 if(sock->own_index==gsock->own_index) 00717 break; 00718 } 00719 if(sock) { 00720 sock->groupsock = gsock; 00721 00722 BLI_strncpy(sock->name, gsock->name, sizeof(sock->name)); 00723 sock->type= gsock->type; 00724 00725 /* XXX hack: group socket input/output roles are inverted internally, 00726 * need to change the limit value when making actual node sockets from them. 00727 */ 00728 sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); 00729 00730 BLI_remlink(lb, sock); 00731 00732 return sock; 00733 } 00734 else { 00735 return node_group_add_extern_socket(ntree, NULL, in_out, gsock); 00736 } 00737 } 00738 00739 static void group_verify_socket_list(bNodeTree *ntree, bNode *node, ListBase *lb, int in_out, ListBase *glb) 00740 { 00741 bNodeSocket *sock, *nextsock, *gsock; 00742 00743 /* step by step compare */ 00744 for (gsock= glb->first; gsock; gsock=gsock->next) { 00745 /* abusing new_sock pointer for verification here! only used inside this function */ 00746 gsock->new_sock= group_verify_socket(ntree, lb, in_out, gsock); 00747 } 00748 /* leftovers are removed */ 00749 for (sock=lb->first; sock; sock=nextsock) { 00750 nextsock=sock->next; 00751 if (sock->flag & SOCK_DYNAMIC) 00752 nodeRemoveSocket(ntree, node, sock); 00753 } 00754 /* and we put back the verified sockets */ 00755 for (gsock= glb->first; gsock; gsock=gsock->next) { 00756 if (gsock->new_sock) { 00757 BLI_addtail(lb, gsock->new_sock); 00758 gsock->new_sock = NULL; 00759 } 00760 } 00761 } 00762 00763 /* make sure all group node in ntree, which use ngroup, are sync'd */ 00764 void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *id) 00765 { 00766 /* check inputs and outputs, and remove or insert them */ 00767 if (node->id==id) { 00768 bNodeTree *ngroup= (bNodeTree*)node->id; 00769 group_verify_socket_list(ntree, node, &node->inputs, SOCK_IN, &ngroup->inputs); 00770 group_verify_socket_list(ntree, node, &node->outputs, SOCK_OUT, &ngroup->outputs); 00771 } 00772 } 00773 00774 struct bNodeTree *node_group_edit_get(bNode *node) 00775 { 00776 if (node->flag & NODE_GROUP_EDIT) 00777 return (bNodeTree*)node->id; 00778 else 00779 return NULL; 00780 } 00781 00782 struct bNodeTree *node_group_edit_set(bNode *node, int edit) 00783 { 00784 if (edit) { 00785 bNodeTree *ngroup= (bNodeTree*)node->id; 00786 if (ngroup) { 00787 if(ngroup->id.lib) 00788 ntreeMakeLocal(ngroup); 00789 00790 node->flag |= NODE_GROUP_EDIT; 00791 } 00792 return ngroup; 00793 } 00794 else { 00795 node->flag &= ~NODE_GROUP_EDIT; 00796 return NULL; 00797 } 00798 } 00799 00800 void node_group_edit_clear(bNode *node) 00801 { 00802 bNodeTree *ngroup= (bNodeTree*)node->id; 00803 bNode *inode; 00804 00805 node->flag &= ~NODE_GROUP_EDIT; 00806 00807 if (ngroup) 00808 for (inode=ngroup->nodes.first; inode; inode=inode->next) 00809 nodeGroupEditClear(inode); 00810 } 00811 00812 void node_group_link(bNodeTree *ntree, bNodeSocket *sock, int in_out) 00813 { 00814 node_group_expose_socket(ntree, sock, in_out); 00815 } 00816 00817 /**** For Loop ****/ 00818 00819 /* Essentially a group node with slightly different behavior. 00820 * The internal tree is executed several times, with each output being re-used 00821 * as an input in the next iteration. For this purpose, input and output socket 00822 * lists are kept identical! 00823 */ 00824 00825 bNodeTemplate node_forloop_template(bNode *node) 00826 { 00827 bNodeTemplate ntemp; 00828 ntemp.type = NODE_FORLOOP; 00829 ntemp.ngroup = (bNodeTree*)node->id; 00830 return ntemp; 00831 } 00832 00833 void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) 00834 { 00835 /* bNodeSocket *sock; */ /* UNUSED */ 00836 00837 node->id = (ID*)ntemp->ngroup; 00838 00839 /* sock = */ nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000); 00840 00841 /* NB: group socket input/output roles are inverted internally! 00842 * Group "inputs" work as outputs in links and vice versa. 00843 */ 00844 if (ntemp->ngroup) { 00845 bNodeSocket *gsock; 00846 for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next) 00847 node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock); 00848 for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next) 00849 node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock); 00850 } 00851 } 00852 00853 void node_forloop_init_tree(bNodeTree *ntree) 00854 { 00855 bNodeSocket *sock; 00856 sock = node_group_add_socket(ntree, "Iteration", SOCK_FLOAT, SOCK_IN); 00857 sock->flag |= SOCK_INTERNAL; 00858 } 00859 00860 static void loop_sync(bNodeTree *ntree, int sync_in_out) 00861 { 00862 bNodeSocket *sock, *sync, *nsync, *mirror; 00863 ListBase *sync_lb; 00864 00865 if (sync_in_out==SOCK_IN) { 00866 sock = ntree->outputs.first; 00867 00868 sync = ntree->inputs.first; 00869 sync_lb = &ntree->inputs; 00870 } 00871 else { 00872 sock = ntree->inputs.first; 00873 00874 sync = ntree->outputs.first; 00875 sync_lb = &ntree->outputs; 00876 } 00877 00878 /* NB: the sock->storage pointer is used here directly to store the own_index int 00879 * out the mirrored socket counterpart! 00880 */ 00881 00882 while (sock) { 00883 /* skip static and internal sockets on the sync side (preserves socket order!) */ 00884 while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC))) 00885 sync = sync->next; 00886 00887 if (sync && !(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) { 00888 if (sock->storage==NULL) { 00889 /* if mirror index is 0, the sockets is newly added and a new mirror must be created. */ 00890 mirror = node_group_expose_socket(ntree, sock, sync_in_out); 00891 /* store the mirror index */ 00892 sock->storage = SET_INT_IN_POINTER(mirror->own_index); 00893 mirror->storage = SET_INT_IN_POINTER(sock->own_index); 00894 /* move mirror to the right place */ 00895 BLI_remlink(sync_lb, mirror); 00896 if (sync) 00897 BLI_insertlinkbefore(sync_lb, sync, mirror); 00898 else 00899 BLI_addtail(sync_lb, mirror); 00900 } 00901 else { 00902 /* look up the mirror socket */ 00903 for (mirror=sync; mirror; mirror=mirror->next) 00904 if (mirror->own_index == GET_INT_FROM_POINTER(sock->storage)) 00905 break; 00906 /* make sure the name is the same (only for identification by user, no deeper meaning) */ 00907 BLI_strncpy(mirror->name, sock->name, sizeof(mirror->name)); 00908 /* fix the socket order if necessary */ 00909 if (mirror != sync) { 00910 BLI_remlink(sync_lb, mirror); 00911 BLI_insertlinkbefore(sync_lb, sync, mirror); 00912 } 00913 else 00914 sync = sync->next; 00915 } 00916 } 00917 00918 sock = sock->next; 00919 } 00920 00921 /* remaining sockets in sync_lb are leftovers from deleted sockets, remove them */ 00922 while (sync) { 00923 nsync = sync->next; 00924 if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) 00925 node_group_remove_socket(ntree, sync, sync_in_out); 00926 sync = nsync; 00927 } 00928 } 00929 00930 void node_loop_update_tree(bNodeTree *ngroup) 00931 { 00932 /* make sure inputs & outputs are identical */ 00933 if (ngroup->update & NTREE_UPDATE_GROUP_IN) 00934 loop_sync(ngroup, SOCK_OUT); 00935 if (ngroup->update & NTREE_UPDATE_GROUP_OUT) 00936 loop_sync(ngroup, SOCK_IN); 00937 } 00938 00939 void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) 00940 { 00941 /* bNodeSocket *sock; */ /* UNUSED */ 00942 00943 node->id = (ID*)ntemp->ngroup; 00944 00945 /* sock = */ nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1); 00946 00947 /* max iterations */ 00948 node->custom1 = 10000; 00949 00950 /* NB: group socket input/output roles are inverted internally! 00951 * Group "inputs" work as outputs in links and vice versa. 00952 */ 00953 if (ntemp->ngroup) { 00954 bNodeSocket *gsock; 00955 for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next) 00956 node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock); 00957 for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next) 00958 node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock); 00959 } 00960 } 00961 00962 void node_whileloop_init_tree(bNodeTree *ntree) 00963 { 00964 bNodeSocket *sock; 00965 sock = node_group_add_socket(ntree, "Condition", SOCK_FLOAT, SOCK_OUT); 00966 sock->flag |= SOCK_INTERNAL; 00967 } 00968 00969 bNodeTemplate node_whileloop_template(bNode *node) 00970 { 00971 bNodeTemplate ntemp; 00972 ntemp.type = NODE_WHILELOOP; 00973 ntemp.ngroup = (bNodeTree*)node->id; 00974 return ntemp; 00975 } 00976 00977 /**** FRAME ****/ 00978 00979 void register_node_type_frame(bNodeTreeType *ttype) 00980 { 00981 /* frame type is used for all tree types, needs dynamic allocation */ 00982 bNodeType *ntype= MEM_callocN(sizeof(bNodeType), "frame node type"); 00983 00984 node_type_base(ttype, ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT, NODE_BACKGROUND); 00985 node_type_size(ntype, 150, 100, 0); 00986 node_type_compatibility(ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); 00987 00988 ntype->needs_free = 1; 00989 nodeRegisterType(ttype, ntype); 00990 }