Revision: 36496 http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36496 Author: lukastoenne Date: 2011-05-05 10:03:54 +0000 (Thu, 05 May 2011) Log Message: ----------- Fixed memory bug when copying node trees, group tree sockets did not duplicate their default button values. Added correct cloning of socket default values when exposing a group socket. Added simple conversion of socket default values when ungrouping a group (this will be part of a more sophisticated converter system in the future).
Modified Paths: -------------- branches/particles-2010/source/blender/blenkernel/intern/node.c branches/particles-2010/source/blender/nodes/intern/node_common.c Modified: branches/particles-2010/source/blender/blenkernel/intern/node.c =================================================================== --- branches/particles-2010/source/blender/blenkernel/intern/node.c 2011-05-05 09:43:45 UTC (rev 36495) +++ branches/particles-2010/source/blender/blenkernel/intern/node.c 2011-05-05 10:03:54 UTC (rev 36496) @@ -579,8 +579,7 @@ oldsock->new_sock= sock; sock->stack_index= 0; - if (sock->default_value) - sock->default_value = MEM_dupallocN(sock->default_value); + sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); if (sock->panel) sock->panel = sock->panel->new_panel; @@ -592,8 +591,7 @@ oldsock->new_sock= sock; sock->stack_index= 0; - if (sock->default_value) - sock->default_value = MEM_dupallocN(sock->default_value); + sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); if (sock->panel) sock->panel = sock->panel->new_panel; @@ -841,11 +839,13 @@ for(gsock= newtree->inputs.first, oldgsock= ntree->inputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { oldgsock->new_sock= gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); + gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL); } BLI_duplicatelist(&newtree->outputs, &ntree->outputs); for(gsock= newtree->outputs.first, oldgsock= ntree->outputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { oldgsock->new_sock= gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); + gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL); } /* copy links */ Modified: branches/particles-2010/source/blender/nodes/intern/node_common.c =================================================================== --- branches/particles-2010/source/blender/nodes/intern/node_common.c 2011-05-05 09:43:45 UTC (rev 36495) +++ branches/particles-2010/source/blender/nodes/intern/node_common.c 2011-05-05 10:03:54 UTC (rev 36496) @@ -235,6 +235,184 @@ return gnode; } +/* 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. + */ +static void convert_socket_value(bNodeSocket *from, bNodeSocket *to) +{ + /* 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_VALUE: + case SOCK_FLOAT: + switch (to->type) { + case SOCK_VALUE: + 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; + } + break; + case SOCK_INT: + switch (to->type) { + case SOCK_VALUE: + 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_VALUE: + 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_VALUE: + 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_VALUE: + 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; + } + break; + } +} + +static void copy_socket_value(bNodeSocket *from, bNodeSocket *to) +{ + /* 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; + + if (from->type != to->type) + return; + + switch (from->type) { + case SOCK_VALUE: + case SOCK_FLOAT: + *tofloat = *fromfloat; + break; + case SOCK_INT: + *toint = *fromint; + break; + case SOCK_BOOLEAN: + *tobool = *frombool; + break; + case SOCK_VECTOR: + *tovector = *fromvector; + break; + case SOCK_RGBA: + *torgba = *fromrgba; + break; + } +} + /* returns 1 if its OK */ int node_group_ungroup(bNodeTree *ntree, bNode *gnode) { @@ -305,9 +483,8 @@ } } else { - /* XXX TODO: copy the default input value from the group socket default (gsock->default_value) - * to the external socket (link->tosock->default_value). This may require conversion! - */ + /* copy the default input value from the group socket default to the external socket */ + convert_socket_value(gsock, link->tosock); } } } @@ -334,9 +511,8 @@ link->fromsock = insock->link->fromsock; } else { - /* XXX TODO: copy the default input value from the group node socket default (insock->default_value) - * to the internal socket (link->tosock->default_value). This may require conversion! - */ + /* copy the default input value from the group node socket default to the internal socket */ + convert_socket_value(insock, link->tosock); nodeRemLink(wgroup, link); } } @@ -414,7 +590,8 @@ { bNodeSocket *gsock= node_group_add_socket(ngroup, sock->name, sock->type, in_out); - /* XXX TODO: initialize the default value. */ + /* initialize the default value. */ + copy_socket_value(sock, gsock); return gsock; } @@ -429,7 +606,8 @@ if (!sock->link && !(sock->flag & SOCK_HIDDEN)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN); - /* XXX TODO: initialize the default value. */ + /* initialize the default value. */ + copy_socket_value(sock, gsock); sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); } @@ -438,7 +616,8 @@ if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT); - /* XXX TODO: initialize the default value. */ + /* initialize the default value. */ + copy_socket_value(sock, gsock); gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); } _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs