diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2011-02-26 23:21:09 +0300 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2011-02-26 23:21:09 +0300 |
commit | 63b31ef91b562a1a4aa95991323555a140dd6ede (patch) | |
tree | 4287fcc7edc5e01efbd4b26d7c923c9b0cd8d830 /source/blender/blenkernel/intern | |
parent | 745e396d63ed15fa69203e04840597112498ec3b (diff) | |
parent | 2f0d93ba563ae2c87a088f21113d5559ab9abfc4 (diff) |
Merged changes in the trunk up to revision 35203.
Conflicts resolved:
source/creator/creator.c
source/blender/python/intern/bpy.c
Diffstat (limited to 'source/blender/blenkernel/intern')
55 files changed, 773 insertions, 691 deletions
diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c index b64efa811de..d2c00d21df3 100644 --- a/source/blender/blenkernel/intern/BME_Customdata.c +++ b/source/blender/blenkernel/intern/BME_Customdata.c @@ -1,4 +1,4 @@ -/** +/* * BME_customdata.c jan 2007 * * Custom Data functions for Bmesh diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c index e80d4827155..4f1102bb828 100644 --- a/source/blender/blenkernel/intern/BME_conversions.c +++ b/source/blender/blenkernel/intern/BME_conversions.c @@ -1,4 +1,4 @@ -/** +/* * BME_mesh.c jan 2007 * * BMesh mesh level functions. diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c index cd9429982dc..9d68866bc99 100644 --- a/source/blender/blenkernel/intern/BME_eulers.c +++ b/source/blender/blenkernel/intern/BME_eulers.c @@ -1,4 +1,4 @@ -/** +/* * BME_eulers.c jan 2007 * * BMesh Euler construction API. diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c index 1bb419937b0..ca5d0b412ed 100644 --- a/source/blender/blenkernel/intern/BME_mesh.c +++ b/source/blender/blenkernel/intern/BME_mesh.c @@ -1,4 +1,4 @@ -/** +/* * BME_mesh.c jan 2007 * * BMesh mesh level functions. diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c index 9463d22e3be..8970e7ff705 100644 --- a/source/blender/blenkernel/intern/BME_structure.c +++ b/source/blender/blenkernel/intern/BME_structure.c @@ -1,4 +1,4 @@ -/** +/* * BME_structure.c jan 2007 * * Low level routines for manipulating the BMesh structure. diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c index 0c8352ad8b0..2b28fb705fd 100644 --- a/source/blender/blenkernel/intern/BME_tools.c +++ b/source/blender/blenkernel/intern/BME_tools.c @@ -1,4 +1,4 @@ -/** +/* * BME_tools.c jan 2007 * * Functions for changing the topology of a mesh. diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 79e23b77306..ed636e95b96 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 328f2ccdc75..14a0f71f824 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 08d506f94b8..a8c369a9b7b 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1,4 +1,4 @@ -/** anim.c +/* anim.c * * * $Id$ diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index dead11c692c..2268a1535bd 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 3174954423f..49c151947a4 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h index 713194c9806..b14383378ab 100644 --- a/source/blender/blenkernel/intern/bmesh_private.h +++ b/source/blender/blenkernel/intern/bmesh_private.h @@ -1,4 +1,4 @@ -/** +/* * BME_private.h jan 2007 * * low level, 'private' function prototypes for bmesh kernel. diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c index aa0669903c5..1d4bdf8bf44 100644 --- a/source/blender/blenkernel/intern/bmfont.c +++ b/source/blender/blenkernel/intern/bmfont.c @@ -1,4 +1,4 @@ -/** +/* * bmfont.c * * 04-10-2000 frank diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 473be5a3ee0..15404acc105 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index db7b9b276a2..949be31354c 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -1,4 +1,4 @@ -/** +/* * * $Id$ * diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 39cb1346eb7..09f18514277 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1,29 +1,29 @@ -/* cloth.c -* -* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* The Original Code is Copyright (C) Blender Foundation -* All rights reserved. -* -* Contributor(s): Daniel Genrich -* -* ***** END GPL LICENSE BLOCK ***** -*/ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) Blender Foundation + * All rights reserved. + * + * Contributor(s): Daniel Genrich + * + * ***** END GPL LICENSE BLOCK ***** + */ #include "MEM_guardedalloc.h" diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 3c0453c82a5..623ba26e86d 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1,31 +1,31 @@ -/* collision.c -* -* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* The Original Code is Copyright (C) Blender Foundation -* All rights reserved. -* -* The Original Code is: all of this file. -* -* Contributor(s): none yet. -* -* ***** END GPL LICENSE BLOCK ***** -*/ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ #include "MEM_guardedalloc.h" diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e7efc09ec6e..827dddf34d3 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 58a7944f78b..a80b6dfab7d 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index d102a83d69f..c437c4fe61f 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 837c3bd8356..b59109c3f2a 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1936,11 +1936,6 @@ float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int return orco; } -void imagestodisplist(void) -{ - /* removed */ -} - /* this is confusing, there's also min_max_object, appplying the obmat... */ static void boundbox_displist(Object *ob) { diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index e7596001400..4a6638ff3a0 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -1,4 +1,5 @@ -/* exotic.c +/* + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -20,14 +21,15 @@ * All rights reserved. * * - * Contributor(s): + * Contributor(s): * - Martin DeMello * Added dxf_read_arc, dxf_read_ellipse and dxf_read_lwpolyline * Copyright (C) 2004 by Etheract Software Labs * * - Blender Foundation * - * ***** END GPL LICENSE BLOCK *****/ + * ***** END GPL LICENSE BLOCK **** + */ #include <stddef.h> #include "BLI_storage.h" diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index fc5aecb5def..b50943ba9f1 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index 3db9731310c..bb56a5b176a 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -1,6 +1,5 @@ -/** - * fluidsim.c - * +/* + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index e4aeb45a209..f979973f55d 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index c3e2d7ffcf4..abd7c12ff70 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index b575305171a..8ce3847bf08 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index e4086827e5d..c63d1e45da8 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 97fbcce1aec..b3119f317a5 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 8004f23c22a..207c667f335 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1,31 +1,31 @@ -/* implicit.c -* -* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* The Original Code is Copyright (C) Blender Foundation -* All rights reserved. -* -* The Original Code is: all of this file. -* -* Contributor(s): none yet. -* -* ***** END GPL LICENSE BLOCK ***** -*/ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ #include "MEM_guardedalloc.h" diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index bd7fdfebe97..b0f90ef8042 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -1,4 +1,4 @@ -/** +/* * lattice.c * * diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 28410a7cc0e..eab99eca7df 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index cd52a38140a..f56c72669e8 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -873,7 +873,7 @@ static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode if(ma!=basemat) { do_init_render_material(ma, r_mode, amb); basemat->texco |= ma->texco; - basemat->mode_l |= ma->mode_l; + basemat->mode_l |= ma->mode_l & ~(MA_TRANSP|MA_ZTRANSP|MA_RAYTRANSP); } } else if(node->type==NODE_GROUP) diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index d89bc3cd6f2..4f44875b7ea 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -1,4 +1,4 @@ -/** mball.c +/* mball.c * * MetaBalls are created from a single Object (with a name without number in it), * here the DispList and BoundBox also is located. diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index e5aacdf2cf9..8b0b7a041dc 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index db0c649d290..7439a47a746 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -247,6 +247,11 @@ int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *lastPossibleCag ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first; int i, cageIndex = -1; + if(lastPossibleCageIndex_r) { + /* ensure the value is initialized */ + *lastPossibleCageIndex_r= -1; + } + /* Find the last modifier acting on the cage. */ for (i=0; md; i++,md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index da0f3f8a448..df012c47f66 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 057d90dc8bb..320bead1c61 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -31,12 +31,18 @@ #include <Python.h> #endif +#include "MEM_guardedalloc.h" + #include <stdlib.h> #include <stddef.h> #include <string.h> +#include <limits.h> #include "DNA_anim_types.h" #include "DNA_action_types.h" +#include "DNA_node_types.h" + +#include "BLI_listbase.h" #include "RNA_access.h" @@ -45,6 +51,7 @@ #include "BKE_fcurve.h" #include "BKE_node.h" #include "BKE_utildefines.h" +#include "BKE_node.h" #include "PIL_time.h" @@ -64,22 +71,14 @@ ListBase node_all_textures = {NULL, NULL}; /* ************** Type stuff ********** */ -static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id) +static bNodeType *node_get_type(bNodeTree *ntree, int type, ID *id) { - if(type==NODE_GROUP) { - if(ngroup && GS(ngroup->id.name)==ID_NT) { - return ngroup->owntype; - } - return NULL; - } - else { - bNodeType *ntype = ntree->alltypes.first; - for(; ntype; ntype= ntype->next) - if(ntype->type==type && id==ntype->id ) - return ntype; - - return NULL; - } + bNodeType *ntype = ntree->alltypes.first; + for(; ntype; ntype= ntype->next) + if(ntype->type==type && id==ntype->id ) + return ntype; + + return NULL; } void ntreeInitTypes(bNodeTree *ntree) @@ -102,11 +101,11 @@ void ntreeInitTypes(bNodeTree *ntree) if(node->type==NODE_DYNAMIC) { bNodeType *stype= NULL; if(node->id==NULL) { /* empty script node */ - stype= node_get_type(ntree, node->type, NULL, NULL); + stype= node_get_type(ntree, node->type, NULL); } else { /* not an empty script node */ - stype= node_get_type(ntree, node->type, NULL, node->id); + stype= node_get_type(ntree, node->type, node->id); if(!stype) { - stype= node_get_type(ntree, node->type, NULL, NULL); + stype= node_get_type(ntree, node->type, NULL); /* needed info if the pynode script fails now: */ if (node->id) node->storage= ntree; } else { @@ -118,7 +117,7 @@ void ntreeInitTypes(bNodeTree *ntree) if(node->typeinfo) node->typeinfo->initfunc(node); } else { - node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id, NULL); + node->typeinfo= node_get_type(ntree, node->type, NULL); } if(node->typeinfo==NULL) { @@ -152,9 +151,6 @@ static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype) else sock->limit= stype->limit; sock->type= stype->type; - sock->to_index= stype->own_index; - sock->tosock= stype->internsock; - sock->ns.vec[0]= stype->val1; sock->ns.vec[1]= stype->val2; sock->ns.vec[2]= stype->val3; @@ -168,6 +164,30 @@ static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype) return sock; } +static bNodeSocket *node_add_group_socket(ListBase *lb, bNodeSocket *gsock) +{ + bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock"); + + /* make a copy of the group socket */ + *sock = *gsock; + sock->link = NULL; + sock->next = sock->prev = NULL; + sock->new_sock = NULL; + sock->ns.data = NULL; + + sock->own_index = gsock->own_index; + sock->groupsock = gsock; + /* XXX hack: group socket input/output roles are inverted internally, + * need to change the limit value when making actual node sockets from them. + */ + sock->limit = (gsock->limit==1 ? 0xFFF : 1); + + if(lb) + BLI_addtail(lb, sock); + + return sock; +} + static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock) { bNodeLink *link, *next; @@ -188,18 +208,16 @@ static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype) bNodeSocket *sock; for(sock= lb->first; sock; sock= sock->next) { - /* both indices are zero for non-groups, otherwise it's a unique index */ - if(sock->to_index==stype->own_index) - if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0) - break; + if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0) + break; } if(sock) { sock->type= stype->type; /* in future, read this from tydefs! */ if(stype->limit==0) sock->limit= 0xFFF; else sock->limit= stype->limit; + sock->ns.min= stype->min; sock->ns.max= stype->max; - sock->tosock= stype->internsock; BLI_remlink(lb, sock); @@ -210,6 +228,37 @@ static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype) } } +static bNodeSocket *verify_group_socket(ListBase *lb, bNodeSocket *gsock) +{ + bNodeSocket *sock; + + for(sock= lb->first; sock; sock= sock->next) { + if(sock->own_index==gsock->own_index) + break; + } + if(sock) { + sock->groupsock = gsock; + + strcpy(sock->name, gsock->name); + sock->type= gsock->type; + + /* XXX hack: group socket input/output roles are inverted internally, + * need to change the limit value when making actual node sockets from them. + */ + sock->limit = (gsock->limit==1 ? 0xFFF : 1); + + sock->ns.min= gsock->ns.min; + sock->ns.max= gsock->ns.max; + + BLI_remlink(lb, sock); + + return sock; + } + else { + return node_add_group_socket(NULL, gsock); + } +} + static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first) { bNodeSocketType *stype; @@ -238,15 +287,41 @@ static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType * } } -void nodeVerifyType(bNodeTree *ntree, bNode *node) +static void verify_group_socket_list(bNodeTree *ntree, ListBase *lb, ListBase *glb) { - bNodeType *ntype= node->typeinfo; + bNodeSocket *gsock; - if(ntype) { - /* might add some other verify stuff here */ - - verify_socket_list(ntree, &node->inputs, ntype->inputs); - verify_socket_list(ntree, &node->outputs, ntype->outputs); + /* step by step compare */ + for (gsock= glb->first; gsock; gsock=gsock->next) { + /* abusing new_sock pointer for verification here! only used inside this function */ + gsock->new_sock= verify_group_socket(lb, gsock); + } + /* leftovers are removed */ + while(lb->first) + node_rem_socket(ntree, lb, lb->first); + /* and we put back the verified sockets */ + for (gsock= glb->first; gsock; gsock=gsock->next) { + BLI_addtail(lb, gsock->new_sock); + gsock->new_sock = NULL; + } +} + +void nodeVerifyType(bNodeTree *ntree, bNode *node) +{ + /* node groups don't have static sock lists, but use external sockets from the tree instead */ + if (node->type==NODE_GROUP) { + bNodeTree *ngroup= (bNodeTree*)node->id; + if (ngroup) { + verify_group_socket_list(ntree, &node->inputs, &ngroup->inputs); + verify_group_socket_list(ntree, &node->outputs, &ngroup->outputs); + } + } + else { + bNodeType *ntype= node->typeinfo; + if(ntype) { + verify_socket_list(ntree, &node->inputs, ntype->inputs); + verify_socket_list(ntree, &node->outputs, ntype->outputs); + } } } @@ -283,176 +358,20 @@ void register_node_type_group(ListBase *lb) nodeRegisterType(lb, &ntype_group); } -/* tag internal sockets */ -static void group_tag_internal_sockets(bNodeTree *ngroup) +static bNodeSocket *find_group_node_input(bNode *gnode, bNodeSocket *gsock) { - bNode *node; bNodeSocket *sock; - bNodeLink *link; - - /* clear intern tag, but check already for hidden sockets */ - for(node= ngroup->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) - sock->intern= sock->flag & SOCK_HIDDEN; - for(sock= node->outputs.first; sock; sock= sock->next) - sock->intern= sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL); - } - /* set tag */ - for(link= ngroup->links.first; link; link= link->next) { - link->fromsock->intern= 1; - link->tosock->intern= 1; - } - - /* remove link pointer to external links (only happens on create group) */ - for(node= ngroup->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->intern==0) - sock->link= NULL; - } - - /* set all intern sockets to own_index zero, makes sure that later use won't mixup */ - for(node= ngroup->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->intern) - sock->own_index= 0; - for(sock= node->outputs.first; sock; sock= sock->next) - if(sock->intern) - sock->own_index= 0; - } -} - -/* after editing group, new sockets are zero */ -/* this routine ensures unique identifiers for zero sockets that are exposed */ -static void group_verify_own_indices(bNodeTree *ngroup) -{ - bNode *node; - bNodeSocket *sock; - - for(node= ngroup->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->own_index==0 && sock->intern==0) - sock->own_index= ++(ngroup->cur_index); - for(sock= node->outputs.first; sock; sock= sock->next) - if(sock->own_index==0 && sock->intern==0) - sock->own_index= ++(ngroup->cur_index); - } - //printf("internal index %d\n", ngroup->cur_index); -} - - -/* nodetrees can be used as groups, so we need typeinfo structs generated */ -void ntreeMakeOwnType(bNodeTree *ngroup) -{ - bNode *node; - bNodeSocket *sock; - int totin= 0, totout=0, a; - - /* tags socket when internal linked */ - group_tag_internal_sockets(ngroup); - - /* ensure all sockets have own unique id */ - group_verify_own_indices(ngroup); - - /* counting stats */ - for(node= ngroup->nodes.first; node; node= node->next) { - if(node->type==NODE_GROUP) - break; - for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->intern==0) - totin++; - for(sock= node->outputs.first; sock; sock= sock->next) - if(sock->intern==0) - totout++; - } - /* debug: nodetrees in nodetrees not handled yet */ - if(node) { - printf("group in group, not supported yet\n"); - return; - } - - /* free own type struct */ - if(ngroup->owntype) { - if(ngroup->owntype->inputs) - MEM_freeN(ngroup->owntype->inputs); - if(ngroup->owntype->outputs) - MEM_freeN(ngroup->owntype->outputs); - MEM_freeN(ngroup->owntype); - } - - /* make own type struct */ - ngroup->owntype= MEM_callocN(sizeof(bNodeType), "group type"); - *ngroup->owntype= ntype_group; /* copy data, for init */ - - /* input type arrays */ - if(totin) { - bNodeSocketType *stype; - bNodeSocketType *inputs= MEM_callocN(sizeof(bNodeSocketType)*(totin+1), "bNodeSocketType"); - a= 0; - - for(node= ngroup->nodes.first; node; node= node->next) { - /* nodes are presumed fully verified, stype and socket list are in sync */ - stype= node->typeinfo->inputs; - for(sock= node->inputs.first; sock; sock= sock->next, stype++) { - if(sock->intern==0) { - /* debug only print */ - if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name); - - inputs[a]= *stype; - inputs[a].own_index= sock->own_index; - inputs[a].internsock= sock; - a++; - } - } - } - inputs[a].type= -1; /* terminator code */ - ngroup->owntype->inputs= inputs; - } - - /* output type arrays */ - if(totout) { - bNodeSocketType *stype; - bNodeSocketType *outputs= MEM_callocN(sizeof(bNodeSocketType)*(totout+1), "bNodeSocketType"); - a= 0; - - for(node= ngroup->nodes.first; node; node= node->next) { - /* nodes are presumed fully verified, stype and socket list are in sync */ - stype= node->typeinfo->outputs; - for(sock= node->outputs.first; sock; sock= sock->next, stype++) { - if(sock->intern==0) { - /* debug only print */ - if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name); - - outputs[a]= *stype; - outputs[a].own_index= sock->own_index; - outputs[a].internsock= sock; - a++; - } - } - } - outputs[a].type= -1; /* terminator code */ - ngroup->owntype->outputs= outputs; - } - - /* voila, the nodetree has the full definition for generating group-node instances! */ -} - - -static bNodeSocket *groupnode_find_tosock(bNode *gnode, int index) -{ - bNodeSocket *sock; - - for(sock= gnode->inputs.first; sock; sock= sock->next) - if(sock->to_index==index) + for (sock=gnode->inputs.first; sock; sock=sock->next) + if (sock->groupsock == gsock) return sock; return NULL; } -static bNodeSocket *groupnode_find_fromsock(bNode *gnode, int index) +static bNodeSocket *find_group_node_output(bNode *gnode, bNodeSocket *gsock) { bNodeSocket *sock; - - for(sock= gnode->outputs.first; sock; sock= sock->next) - if(sock->to_index==index) + for (sock=gnode->outputs.first; sock; sock=sock->next) + if (sock->groupsock == gsock) return sock; return NULL; } @@ -461,8 +380,8 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) { bNodeLink *link, *linkn; bNode *node, *gnode, *nextn; - bNodeSocket *sock; bNodeTree *ngroup; + bNodeSocket *gsock; ListBase anim_basepaths = {NULL, NULL}; float min[2], max[2]; int totnode=0; @@ -485,9 +404,9 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) /* check if all connections are OK, no unselected node has both inputs and outputs to a selection */ for(link= ntree->links.first; link; link= link->next) { - if(link->fromnode->flag & NODE_SELECT) + if(link->fromnode && link->tonode && link->fromnode->flag & NODE_SELECT) link->tonode->done |= 1; - if(link->tonode->flag & NODE_SELECT) + if(link->fromnode && link->tonode && link->tonode->flag & NODE_SELECT) link->fromnode->done |= 2; } @@ -526,26 +445,9 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) node->locx-= 0.5f*(min[0]+max[0]); node->locy-= 0.5f*(min[1]+max[1]); - - /* set socket own_index to zero since it can still have a value - * from being in a group before, otherwise it doesn't get a unique - * index in group_verify_own_indices */ - for(sock= node->inputs.first; sock; sock= sock->next) - sock->own_index= 0; - for(sock= node->outputs.first; sock; sock= sock->next) - sock->own_index= 0; } } - /* move links over */ - for(link= ntree->links.first; link; link= linkn) { - linkn= link->next; - if(link->fromnode->flag & link->tonode->flag & NODE_SELECT) { - BLI_remlink(&ntree->links, link); - BLI_addtail(&ngroup->links, link); - } - } - /* move animation data over */ if (ntree->adt) { LinkData *ld, *ldn=NULL; @@ -561,9 +463,6 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) } } - /* now we can make own group typeinfo */ - ntreeMakeOwnType(ngroup); - /* make group node */ gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup, NULL); gnode->locx= 0.5f*(min[0]+max[0]); @@ -573,35 +472,29 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) for(link= ntree->links.first; link; link= linkn) { linkn= link->next; - if(link->tonode->flag & NODE_SELECT) { - link->tonode= gnode; - sock= groupnode_find_tosock(gnode, link->tosock->own_index); - if(sock==NULL) { - nodeRemLink(ntree, link); - printf("Removed link, cannot mix internal and external sockets in group\n"); - } - else link->tosock= sock; + if(link->fromnode && link->tonode && (link->fromnode->flag & link->tonode->flag & NODE_SELECT)) { + BLI_remlink(&ntree->links, link); + BLI_addtail(&ngroup->links, link); } - else if(link->fromnode->flag & NODE_SELECT) { - link->fromnode= gnode; - sock= groupnode_find_fromsock(gnode, link->fromsock->own_index); - if(sock==NULL) { - nodeRemLink(ntree, link); - printf("Removed link, cannot mix internal and external sockets in group\n"); - } - else link->fromsock= sock; + else if(link->tonode && (link->tonode->flag & NODE_SELECT)) { + gsock = nodeGroupExposeSocket(ngroup, link->tosock, SOCK_IN); + link->tosock->link = nodeAddLink(ngroup, NULL, gsock, link->tonode, link->tosock); + link->tosock = node_add_group_socket(&gnode->inputs, gsock); + link->tonode = gnode; } - } - - /* initialize variables of unused input sockets */ - for(node= ngroup->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->intern==0) { - bNodeSocket *nsock= groupnode_find_tosock(gnode, sock->own_index); - if(nsock) { - QUATCOPY(nsock->ns.vec, sock->ns.vec); - } + else if(link->fromnode && (link->fromnode->flag & NODE_SELECT)) { + /* search for existing group node socket */ + for (gsock=ngroup->outputs.first; gsock; gsock=gsock->next) + if (gsock->link && gsock->link->fromsock==link->fromsock) + break; + if (!gsock) { + gsock = nodeGroupExposeSocket(ngroup, link->fromsock, SOCK_OUT); + gsock->link = nodeAddLink(ngroup, link->fromnode, link->fromsock, NULL, gsock); + link->fromsock = node_add_group_socket(&gnode->outputs, gsock); } + else + link->fromsock = find_group_node_output(gnode, gsock); + link->fromnode = gnode; } } @@ -611,41 +504,21 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) return gnode; } -/* note: ungroup: group_indices zero! */ - /* here's a nasty little one, need to check users... */ /* should become callbackable... */ -void nodeVerifyGroup(bNodeTree *ngroup) +void nodeGroupVerify(bNodeTree *ngroup) { - /* XXX nodeVerifyGroup is sometimes called for non-group trees. - * This is not the best way to check if a tree is a group, - * trees should get their own flag for this! - */ - if (!ngroup->owntype) - return; - /* group changed, so we rebuild the type definition */ - ntreeMakeOwnType(ngroup); +// ntreeMakeGroupSockets(ngroup); if(ngroup->type==NTREE_SHADER) { Material *ma; for(ma= G.main->mat.first; ma; ma= ma->id.next) { if(ma->nodetree) { bNode *node; - - /* find if group is in tree */ for(node= ma->nodetree->nodes.first; node; node= node->next) if(node->id == (ID *)ngroup) - break; - - if(node) { - /* set all type pointers OK */ - ntreeInitTypes(ma->nodetree); - - for(node= ma->nodetree->nodes.first; node; node= node->next) - if(node->id == (ID *)ngroup) - nodeVerifyType(ma->nodetree, node); - } + nodeVerifyType(ma->nodetree, node); } } } @@ -654,20 +527,9 @@ void nodeVerifyGroup(bNodeTree *ngroup) for(sce= G.main->scene.first; sce; sce= sce->id.next) { if(sce->nodetree) { bNode *node; - - /* find if group is in tree */ for(node= sce->nodetree->nodes.first; node; node= node->next) if(node->id == (ID *)ngroup) - break; - - if(node) { - /* set all type pointers OK */ - ntreeInitTypes(sce->nodetree); - - for(node= sce->nodetree->nodes.first; node; node= node->next) - if(node->id == (ID *)ngroup) - nodeVerifyType(sce->nodetree, node); - } + nodeVerifyType(sce->nodetree, node); } } } @@ -676,20 +538,9 @@ void nodeVerifyGroup(bNodeTree *ngroup) for(tx= G.main->tex.first; tx; tx= tx->id.next) { if(tx->nodetree) { bNode *node; - - /* find if group is in tree */ for(node= tx->nodetree->nodes.first; node; node= node->next) if(node->id == (ID *)ngroup) - break; - - if(node) { - /* set all type pointers OK */ - ntreeInitTypes(tx->nodetree); - - for(node= tx->nodetree->nodes.first; node; node= node->next) - if(node->id == (ID *)ngroup) - nodeVerifyType(tx->nodetree, node); - } + nodeVerifyType(tx->nodetree, node); } } } @@ -716,15 +567,15 @@ void nodeGroupSocketUseFlags(bNodeTree *ngroup) for(ma= G.main->mat.first; ma; ma= ma->id.next) { if(ma->nodetree) { for(node= ma->nodetree->nodes.first; node; node= node->next) { - if(node->id==(ID *)ngroup) { + if(node->id==&ngroup->id) { for(sock= node->inputs.first; sock; sock= sock->next) if(sock->link) - if(sock->tosock) - sock->tosock->flag |= SOCK_IN_USE; + if(sock->groupsock) + sock->groupsock->flag |= SOCK_IN_USE; for(sock= node->outputs.first; sock; sock= sock->next) if(nodeCountSocketLinks(ma->nodetree, sock)) - if(sock->tosock) - sock->tosock->flag |= SOCK_IN_USE; + if(sock->groupsock) + sock->groupsock->flag |= SOCK_IN_USE; } } } @@ -738,12 +589,12 @@ void nodeGroupSocketUseFlags(bNodeTree *ngroup) if(node->id==(ID *)ngroup) { for(sock= node->inputs.first; sock; sock= sock->next) if(sock->link) - if(sock->tosock) - sock->tosock->flag |= SOCK_IN_USE; + if(sock->groupsock) + sock->groupsock->flag |= SOCK_IN_USE; for(sock= node->outputs.first; sock; sock= sock->next) if(nodeCountSocketLinks(sce->nodetree, sock)) - if(sock->tosock) - sock->tosock->flag |= SOCK_IN_USE; + if(sock->groupsock) + sock->groupsock->flag |= SOCK_IN_USE; } } } @@ -757,12 +608,12 @@ void nodeGroupSocketUseFlags(bNodeTree *ngroup) if(node->id==(ID *)ngroup) { for(sock= node->inputs.first; sock; sock= sock->next) if(sock->link) - if(sock->tosock) - sock->tosock->flag |= SOCK_IN_USE; + if(sock->groupsock) + sock->groupsock->flag |= SOCK_IN_USE; for(sock= node->outputs.first; sock; sock= sock->next) if(nodeCountSocketLinks(tx->nodetree, sock)) - if(sock->tosock) - sock->tosock->flag |= SOCK_IN_USE; + if(sock->groupsock) + sock->groupsock->flag |= SOCK_IN_USE; } } } @@ -777,21 +628,27 @@ bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name) } /* finds a node based on given socket */ -int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex) +int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex, int *in_out) { bNode *node; bNodeSocket *tsock; int index= 0; for(node= ntree->nodes.first; node; node= node->next) { - for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++) - if(tsock==sock) + for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++) { + if(tsock==sock) { + if (in_out) *in_out= SOCK_IN; break; + } + } if(tsock) break; - for(index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++) - if(tsock==sock) + for(index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++) { + if(tsock==sock) { + if (in_out) *in_out= SOCK_OUT; break; + } + } if(tsock) break; } @@ -813,7 +670,6 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode) bNode *node, *nextn; bNodeTree *ngroup, *wgroup; ListBase anim_basepaths = {NULL, NULL}; - int index; ngroup= (bNodeTree *)gnode->id; if(ngroup==NULL) return 0; @@ -855,7 +711,66 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode) node->flag |= NODE_SELECT; } - /* and the internal links */ + + /* restore external links to and from the gnode */ + for(link= ntree->links.first; link; link= link->next) { + if (link->fromnode==gnode) { + if (link->fromsock->groupsock) { + bNodeSocket *gsock= link->fromsock->groupsock; + if (gsock->link) { + if (gsock->link->fromnode) { + /* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */ + link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL); + link->fromsock = gsock->link->fromsock->new_sock; + } + else { + /* group output directly maps to group input */ + bNodeSocket *insock= find_group_node_input(gnode, gsock->link->fromsock); + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + } + } + else { + /* constant group output: copy the stack value to the external socket. + * the link is kept here until all possible external users have been fixed. + */ + QUATCOPY(link->tosock->ns.vec, gsock->ns.vec); + } + } + } + } + /* remove internal output links, these are not used anymore */ + for(link=wgroup->links.first; link; link= linkn) { + linkn = link->next; + if (!link->tonode) + nodeRemLink(wgroup, link); + } + /* restore links from internal nodes */ + for(link= wgroup->links.first; link; link= link->next) { + /* indicates link to group input */ + if (!link->fromnode) { + /* NB: can't use find_group_node_input here, + * because gnode sockets still point to the old tree! + */ + bNodeSocket *insock; + for (insock= gnode->inputs.first; insock; insock= insock->next) + if (insock->groupsock->new_sock == link->fromsock) + break; + if (insock->link) { + link->fromnode = insock->link->fromnode; + link->fromsock = insock->link->fromsock; + } + else { + /* uses group constant input. copy the input value and remove the dead link. */ + QUATCOPY(link->tosock->ns.vec, insock->ns.vec); + nodeRemLink(wgroup, link); + } + } + } + + /* add internal links to the ntree */ for(link= wgroup->links.first; link; link= linkn) { linkn= link->next; BLI_remlink(&wgroup->links, link); @@ -884,44 +799,22 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode) /* free temp action too */ free_libblock(&G.main->action, waction); } - - /* restore links to and from the gnode */ - for(link= ntree->links.first; link; link= link->next) { - if(link->tonode==gnode) { - /* link->tosock->tosock is on the node we look for */ - nodeFindNode(ngroup, link->tosock->tosock, &nextn, &index); - if(nextn==NULL) printf("wrong stuff!\n"); - else if(nextn->new_node==NULL) printf("wrong stuff too!\n"); - else { - link->tonode= nextn->new_node; - link->tosock= BLI_findlink(&link->tonode->inputs, index); - } - } - else if(link->fromnode==gnode) { - /* link->fromsock->tosock is on the node we look for */ - nodeFindNode(ngroup, link->fromsock->tosock, &nextn, &index); - if(nextn==NULL) printf("1 wrong stuff!\n"); - else if(nextn->new_node==NULL) printf("1 wrong stuff too!\n"); - else { - link->fromnode= nextn->new_node; - link->fromsock= BLI_findlink(&link->fromnode->outputs, index); - } - } - } - - /* remove the gnode & work tree */ - free_libblock(&G.main->nodetree, wgroup); + /* delete the group instance. this also removes old input links! */ nodeFreeNode(ntree, gnode); + /* free the group tree (takes care of user count) */ + free_libblock(&G.main->nodetree, wgroup); + /* solve order goes fine, but the level tags not... doing it twice works for now. solve this once */ + /* XXX is this still necessary with new groups? it may have been caused by non-updated sock->link pointers. lukas */ ntreeSolveOrder(ntree); ntreeSolveOrder(ntree); return 1; } -void nodeCopyGroup(bNode *gnode) +void nodeGroupCopy(bNode *gnode) { bNodeSocket *sock; @@ -930,34 +823,115 @@ void nodeCopyGroup(bNode *gnode) /* new_sock was set in nodeCopyNode */ for(sock=gnode->inputs.first; sock; sock=sock->next) - if(sock->tosock) - sock->tosock= sock->tosock->new_sock; + if(sock->groupsock) + sock->groupsock= sock->groupsock->new_sock; for(sock=gnode->outputs.first; sock; sock=sock->next) - if(sock->tosock) - sock->tosock= sock->tosock->new_sock; + if(sock->groupsock) + sock->groupsock= sock->groupsock->new_sock; +} + +bNodeSocket *nodeGroupAddSocket(bNodeTree *ngroup, const char *name, int type, int in_out) +{ + bNodeSocket *gsock = MEM_callocN(sizeof(bNodeSocket), "bNodeSocket"); + + strncpy(gsock->name, name, sizeof(gsock->name)); + gsock->type = type; + gsock->ns.sockettype = type; + gsock->ns.min = INT_MIN; + gsock->ns.max = INT_MAX; + zero_v4(gsock->ns.vec); + gsock->ns.data = NULL; + gsock->flag = 0; + + gsock->next = gsock->prev = NULL; + gsock->new_sock = NULL; + gsock->link = NULL; + gsock->ns.data = NULL; + /* assign new unique index */ + gsock->own_index = ngroup->cur_index++; + gsock->limit = (in_out==SOCK_IN ? 0xFFF : 1); + + BLI_addtail(in_out==SOCK_IN ? &ngroup->inputs : &ngroup->outputs, gsock); + + return gsock; +} + +bNodeSocket *nodeGroupExposeSocket(bNodeTree *ngroup, bNodeSocket *sock, int in_out) +{ + bNodeSocket *gsock= nodeGroupAddSocket(ngroup, sock->name, sock->type, in_out); + /* initialize the default socket value */ + QUATCOPY(gsock->ns.vec, sock->ns.vec); + return gsock; +} + +void nodeGroupExposeAllSockets(bNodeTree *ngroup) +{ + bNode *node; + bNodeSocket *sock, *gsock; + + for (node=ngroup->nodes.first; node; node=node->next) { + for (sock=node->inputs.first; sock; sock=sock->next) { + if (!sock->link && !(sock->flag & SOCK_HIDDEN)) { + gsock = nodeGroupAddSocket(ngroup, sock->name, sock->type, SOCK_IN); + /* initialize the default socket value */ + QUATCOPY(gsock->ns.vec, sock->ns.vec); + sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); + } + } + for (sock=node->outputs.first; sock; sock=sock->next) { + if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) { + gsock = nodeGroupAddSocket(ngroup, sock->name, sock->type, SOCK_OUT); + /* initialize the default socket value */ + QUATCOPY(gsock->ns.vec, sock->ns.vec); + gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); + } + } + } +} + +void nodeGroupRemoveSocket(bNodeTree *ngroup, bNodeSocket *gsock, int in_out) +{ + nodeRemSocketLinks(ngroup, gsock); + switch (in_out) { + case SOCK_IN: BLI_remlink(&ngroup->inputs, gsock); break; + case SOCK_OUT: BLI_remlink(&ngroup->outputs, gsock); break; + } } /* ************** Add stuff ********** */ void nodeAddSockets(bNode *node, bNodeType *ntype) { - bNodeSocketType *stype; - - if(ntype->inputs) { - stype= ntype->inputs; - while(stype->type != -1) { - node_add_socket_type(&node->inputs, stype); - stype++; + if (node->type==NODE_GROUP) { + bNodeTree *ntree= (bNodeTree*)node->id; + if (ntree) { + bNodeSocket *gsock; + for (gsock=ntree->inputs.first; gsock; gsock=gsock->next) + node_add_group_socket(&node->inputs, gsock); + for (gsock=ntree->outputs.first; gsock; gsock=gsock->next) + node_add_group_socket(&node->outputs, gsock); } } - if(ntype->outputs) { - stype= ntype->outputs; - while(stype->type != -1) { - node_add_socket_type(&node->outputs, stype); - stype++; + else { + bNodeSocketType *stype; + + if(ntype->inputs) { + stype= ntype->inputs; + while(stype->type != -1) { + node_add_socket_type(&node->inputs, stype); + stype++; + } + } + if(ntype->outputs) { + stype= ntype->outputs; + while(stype->type != -1) { + node_add_socket_type(&node->outputs, stype); + stype++; + } } } } + /* Find the first available, non-duplicate name for a given node */ void nodeUniqueName(bNodeTree *ntree, bNode *node) { @@ -986,7 +960,7 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id) ntype= ntype->next; } } else - ntype= node_get_type(ntree, type, ngroup, id); + ntype= node_get_type(ntree, type, id); node= MEM_callocN(sizeof(bNode), "new node"); BLI_addtail(&ntree->nodes, node); @@ -1050,7 +1024,7 @@ void nodeUpdateType(bNodeTree *ntree, bNode* node, bNodeType *ntype) /* keep socket listorder identical, for copying links */ /* ntree is the target tree */ -bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal) +bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) { bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node"); bNodeSocket *sock, *oldsock; @@ -1064,15 +1038,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal) oldsock= node->inputs.first; for(sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) { oldsock->new_sock= sock; - if(internal) - sock->own_index= 0; } BLI_duplicatelist(&nnode->outputs, &node->outputs); oldsock= node->outputs.first; for(sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) { - if(internal) - sock->own_index= 0; sock->stack_index= 0; sock->ns.data= NULL; oldsock->new_sock= sock; @@ -1098,7 +1068,7 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNodeLink *link= NULL; int from= 0, to= 0; - if(fromsock) { + if(fromnode) { /* test valid input */ for(sock= fromnode->outputs.first; sock; sock= sock->next) if(sock==fromsock) @@ -1113,7 +1083,7 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, from= -1; /* OK but flip */ } } - if(tosock) { + if(tonode) { for(sock= tonode->inputs.first; sock; sock= sock->next) if(sock==tosock) break; @@ -1199,9 +1169,8 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) { bNodeTree *newtree; bNode *node, *nnode, *last; - bNodeLink *link, *nlink; - bNodeSocket *sock; - int a; + bNodeLink *link; + bNodeSocket *gsock, *oldgsock; if(ntree==NULL) return NULL; @@ -1220,45 +1189,34 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) last = ntree->nodes.last; for(node= ntree->nodes.first; node; node= node->next) { node->new_node= NULL; - nnode= nodeCopyNode(newtree, node, 0); /* sets node->new */ - - /* make sure we don't copy new nodes again! */ - if (node==last) - break; + nnode= nodeCopyNode(newtree, node); /* sets node->new */ + if(node==last) break; } - /* check for copying links */ - for(link= ntree->links.first; link; link= link->next) { - if(link->fromnode==NULL || link->tonode==NULL); - else if(link->fromnode->new_node && link->tonode->new_node) { - nlink= nodeAddLink(newtree, link->fromnode->new_node, NULL, link->tonode->new_node, NULL); - /* sockets were copied in order */ - for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) { - if(sock==link->fromsock) - break; - } - nlink->fromsock= BLI_findlink(&link->fromnode->new_node->outputs, a); - - for(a=0, sock= link->tonode->inputs.first; sock; sock= sock->next, a++) { - if(sock==link->tosock) - break; - } - nlink->tosock= BLI_findlink(&link->tonode->new_node->inputs, a); - } + /* socket definition for group usage */ + BLI_duplicatelist(&newtree->inputs, &ntree->inputs); + 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); } - /* own type definition for group usage */ - if(ntree->owntype) { - newtree->owntype= MEM_dupallocN(ntree->owntype); - if(ntree->owntype->inputs) - newtree->owntype->inputs= MEM_dupallocN(ntree->owntype->inputs); - if(ntree->owntype->outputs) - newtree->owntype->outputs= MEM_dupallocN(ntree->owntype->outputs); + 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); + } + + /* copy links */ + BLI_duplicatelist(&newtree->links, &ntree->links); + for(link= newtree->links.first; link; link= link->next) { + link->fromnode = (link->fromnode ? link->fromnode->new_node : NULL); + link->fromsock = (link->fromsock ? link->fromsock->new_sock : NULL); + link->tonode = (link->tonode ? link->tonode->new_node : NULL); + link->tosock = (link->tosock ? link->tosock->new_sock : NULL); + /* update the link socket's pointer */ + if (link->tosock) + link->tosock->link = link; } - - /* weird this is required... there seem to be link pointers wrong still? */ - /* anyhoo, doing this solves crashes on copying entire tree (copy scene) and delete nodes */ - ntreeSolveOrder(newtree); return newtree; } @@ -1397,7 +1355,8 @@ void nodeUnlinkNode(bNodeTree *ntree, bNode *node) if(link->fromnode==node) { lb= &node->outputs; - NodeTagChanged(ntree, link->tonode); + if (link->tonode) + NodeTagChanged(ntree, link->tonode); } else if(link->tonode==node) lb= &node->inputs; @@ -1467,13 +1426,8 @@ void ntreeFreeTree(bNodeTree *ntree) nodeFreeNode(ntree, node); } - if(ntree->owntype) { - if(ntree->owntype->inputs) - MEM_freeN(ntree->owntype->inputs); - if(ntree->owntype->outputs) - MEM_freeN(ntree->owntype->outputs); - MEM_freeN(ntree->owntype); - } + BLI_freelistN(&ntree->inputs); + BLI_freelistN(&ntree->outputs); } void ntreeFreeCache(bNodeTree *ntree) @@ -1807,7 +1761,7 @@ static int node_recurs_check(bNode *node, bNode ***nsort, int level) if(sock->link) { has_inputlinks= 1; fromnode= sock->link->fromnode; - if(fromnode->done==0) { + if(fromnode && fromnode->done==0) { fromnode->level= node_recurs_check(fromnode, nsort, level); } } @@ -1893,6 +1847,9 @@ void ntreeSolveOrder(bNodeTree *ntree) for(sock= node->inputs.first; sock; sock= sock->next) sock->link= NULL; } + /* clear group socket links */ + for(sock= ntree->outputs.first; sock; sock= sock->next) + sock->link= NULL; if(totnode==0) return; @@ -1970,33 +1927,40 @@ int NodeTagIDChanged(bNodeTree *ntree, ID *id) /* ******************* executing ************* */ +/* for a given socket, find the actual stack entry */ +static bNodeStack *get_socket_stack(bNodeStack *stack, bNodeSocket *sock, bNodeStack **gin) +{ + switch (sock->stack_type) { + case SOCK_STACK_LOCAL: + return stack + sock->stack_index; + case SOCK_STACK_EXTERN: + return (gin ? gin[sock->stack_index] : NULL); + case SOCK_STACK_CONST: + return sock->stack_ptr; + } + return NULL; +} + /* see notes at ntreeBeginExecTree */ -static void group_node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin, bNodeStack **gout) +static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin) { bNodeSocket *sock; /* build pointer stack */ - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->intern) { - /* yep, intern can have link or is hidden socket */ - if(sock->link) - *(in++)= stack + sock->link->fromsock->stack_index; - else - *(in++)= &sock->ns; + if (in) { + for(sock= node->inputs.first; sock; sock= sock->next) { + *(in++) = get_socket_stack(stack, sock, gin); } - else - *(in++)= gin[sock->stack_index_ext]; } - for(sock= node->outputs.first; sock; sock= sock->next) { - if(sock->intern) - *(out++)= stack + sock->stack_index; - else - *(out++)= gout[sock->stack_index_ext]; + if (out) { + for(sock= node->outputs.first; sock; sock= sock->next) { + *(out++) = get_socket_stack(stack, sock, gin); + } } } -static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in, bNodeStack **out) +static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in) { bNode *node; bNodeTree *ntree= (bNodeTree *)gnode->id; @@ -2009,7 +1973,7 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod for(node= ntree->nodes.first; node; node= node->next) { if(node->typeinfo->execfunc) { - group_node_get_stack(node, stack, nsin, nsout, in, out); + node_get_stack(node, stack, nsin, nsout, in); /* for groups, only execute outputs for edited group */ if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { @@ -2021,19 +1985,27 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod } } - /* free internal group output nodes */ - if(ntree->type==NTREE_COMPOSIT) { - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->execfunc) { - bNodeSocket *sock; - - for(sock= node->outputs.first; sock; sock= sock->next) { - if(sock->intern) { - bNodeStack *ns= stack + sock->stack_index; - if(ns->data) { - free_compbuf(ns->data); - ns->data= NULL; - } + /* free internal buffers */ + if (ntree->type==NTREE_COMPOSIT) { + bNodeSocket *sock; + bNodeStack *ns; + for (sock=ntree->outputs.first; sock; sock=sock->next) { + /* use the hasoutput flag to tag external sockets */ + if (sock->stack_type==SOCK_STACK_LOCAL) { + ns= get_socket_stack(stack, sock, in); + ns->hasoutput = 0; + } + } + /* now free all stacks that are not used from outside */ + for (node=ntree->nodes.first; node; node=node->next) { + for (sock=node->outputs.first; sock; sock=sock->next) { + if (sock->stack_type==SOCK_STACK_LOCAL ) { + ns= get_socket_stack(stack, sock, in); + if (ns->hasoutput!=0 && ns->data) { + free_compbuf(ns->data); + ns->data = NULL; + /* reset the flag */ + ns->hasoutput = 1; } } } @@ -2041,37 +2013,134 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod } } +static int set_stack_indexes_default(bNode *node, int index) +{ + bNodeSocket *sock; + + for (sock=node->inputs.first; sock; sock=sock->next) { + if (sock->link && sock->link->fromsock) { + sock->stack_type = sock->link->fromsock->stack_type; + sock->stack_index = sock->link->fromsock->stack_index; + sock->stack_ptr = sock->link->fromsock->stack_ptr; + } + else { + sock->stack_type = SOCK_STACK_CONST; + sock->stack_index = -1; + sock->stack_ptr = &sock->ns; + } + } + + for (sock=node->outputs.first; sock; sock=sock->next) { + sock->stack_type = SOCK_STACK_LOCAL; + sock->stack_index = index++; + sock->stack_ptr = NULL; + } + + return index; +} + +static int ntree_begin_exec_tree(bNodeTree *ntree); +static int set_stack_indexes_group(bNode *node, int index) +{ + bNodeTree *ngroup= (bNodeTree*)node->id; + bNodeSocket *sock; + + if((ngroup->init & NTREE_TYPE_INIT)==0) + ntreeInitTypes(ngroup); + + node->stack_index = index; + index += ntree_begin_exec_tree(ngroup); + + for (sock=node->inputs.first; sock; sock=sock->next) { + if (sock->link && sock->link->fromsock) { + sock->stack_type = sock->link->fromsock->stack_type; + sock->stack_index = sock->link->fromsock->stack_index; + sock->stack_ptr = sock->link->fromsock->stack_ptr; + } + else { + sock->stack_type = SOCK_STACK_CONST; + sock->stack_index = -1; + sock->stack_ptr = &sock->ns; + } + } + + /* identify group node outputs from internal group sockets */ + for(sock= node->outputs.first; sock; sock= sock->next) { + if (sock->groupsock) { + bNodeSocket *insock, *gsock = sock->groupsock; + switch (gsock->stack_type) { + case SOCK_STACK_EXTERN: + /* extern stack is resolved for this group node instance */ + insock= find_group_node_input(node, gsock->link->fromsock); + sock->stack_type = insock->stack_type; + sock->stack_index = insock->stack_index; + sock->stack_ptr = insock->stack_ptr; + break; + case SOCK_STACK_LOCAL: + sock->stack_type = SOCK_STACK_LOCAL; + /* local stack index must be offset by group node instance */ + sock->stack_index = gsock->stack_index + node->stack_index; + sock->stack_ptr = NULL; + break; + case SOCK_STACK_CONST: + sock->stack_type = SOCK_STACK_CONST; + sock->stack_index = -1; + sock->stack_ptr = gsock->stack_ptr; + break; + } + } + else { + sock->stack_type = SOCK_STACK_LOCAL; + sock->stack_index = index++; + sock->stack_ptr = NULL; + } + } + + return index; +} + /* recursively called for groups */ /* we set all trees on own local indices, but put a total counter in the groups, so each instance of a group has own stack */ static int ntree_begin_exec_tree(bNodeTree *ntree) { bNode *node; - bNodeSocket *sock; - int index= 0, index_in= 0, index_out= 0; + bNodeSocket *gsock; + int index= 0, i; if((ntree->init & NTREE_TYPE_INIT)==0) ntreeInitTypes(ntree); + /* group inputs are numbered 0..totinputs, so external stack can easily be addressed */ + i = 0; + for(gsock=ntree->inputs.first; gsock; gsock = gsock->next) { + gsock->stack_type = SOCK_STACK_EXTERN; + gsock->stack_index = i++; + gsock->stack_ptr = NULL; + } + /* create indices for stack, check preview */ for(node= ntree->nodes.first; node; node= node->next) { - - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->intern==0) - sock->stack_index_ext= index_in++; - } - - for(sock= node->outputs.first; sock; sock= sock->next) { - sock->stack_index= index++; - if(sock->intern==0) - sock->stack_index_ext= index_out++; + /* XXX can this be done by a generic one-for-all function? + * otherwise should use node-type callback. + */ + if(node->type==NODE_GROUP) + index = set_stack_indexes_group(node, index); + else + index = set_stack_indexes_default(node, index); + } + + /* group outputs */ + for(gsock=ntree->outputs.first; gsock; gsock = gsock->next) { + if (gsock->link && gsock->link->fromsock) { + gsock->stack_type = gsock->link->fromsock->stack_type; + gsock->stack_index = gsock->link->fromsock->stack_index; + gsock->stack_ptr = gsock->link->fromsock->stack_ptr; } - - if(node->type==NODE_GROUP) { - if(node->id) { - node->stack_index= index; - index+= ntree_begin_exec_tree((bNodeTree *)node->id); - } + else { + gsock->stack_type = SOCK_STACK_CONST; + gsock->stack_index = -1; + gsock->stack_ptr = &gsock->ns; } } @@ -2079,7 +2148,7 @@ static int ntree_begin_exec_tree(bNodeTree *ntree) } /* copy socket compbufs to stack, initialize usage of curve nodes */ -static void composit_begin_exec(bNodeTree *ntree, int is_group) +static void composit_begin_exec(bNodeTree *ntree, bNodeStack *stack) { bNode *node; bNodeSocket *sock; @@ -2089,16 +2158,14 @@ static void composit_begin_exec(bNodeTree *ntree, int is_group) /* initialize needed for groups */ node->exec= 0; - if(is_group==0) { - for(sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns= ntree->stack + sock->stack_index; - - if(sock->ns.data) { - ns->data= sock->ns.data; - sock->ns.data= NULL; - } + for(sock= node->outputs.first; sock; sock= sock->next) { + bNodeStack *ns= get_socket_stack(stack, sock, NULL); + if(ns && sock->ns.data) { + ns->data= sock->ns.data; + sock->ns.data= NULL; } } + /* cannot initialize them while using in threads */ if(ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) { curvemapping_initialize(node->storage); @@ -2106,74 +2173,60 @@ static void composit_begin_exec(bNodeTree *ntree, int is_group) curvemapping_premultiply(node->storage, 0); } if(node->type==NODE_GROUP) - composit_begin_exec((bNodeTree *)node->id, 1); + composit_begin_exec((bNodeTree *)node->id, stack + node->stack_index); } } /* copy stack compbufs to sockets */ -static void composit_end_exec(bNodeTree *ntree, int is_group) +static void composit_end_exec(bNodeTree *ntree, bNodeStack *stack) { bNode *node; bNodeStack *ns; - int a; for(node= ntree->nodes.first; node; node= node->next) { - if(is_group==0) { - bNodeSocket *sock; + bNodeSocket *sock; - for(sock= node->outputs.first; sock; sock= sock->next) { - ns= ntree->stack + sock->stack_index; - if(ns->data) { - sock->ns.data= ns->data; - ns->data= NULL; - } + for(sock= node->outputs.first; sock; sock= sock->next) { + ns = get_socket_stack(stack, sock, NULL); + if(ns && ns->data) { + sock->ns.data= ns->data; + ns->data= NULL; } } + if(node->type==CMP_NODE_CURVE_RGB) curvemapping_premultiply(node->storage, 1); if(node->type==NODE_GROUP) - composit_end_exec((bNodeTree *)node->id, 1); + composit_end_exec((bNodeTree *)node->id, stack + node->stack_index); node->need_exec= 0; } - - if(is_group==0) { - /* internally, group buffers are not stored */ - for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) { - if(ns->data) { - printf("freed leftover buffer from stack\n"); - free_compbuf(ns->data); - ns->data= NULL; - } - } - } } -static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack) +static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack, bNodeStack **gin) { bNodeTree *ntree= (bNodeTree *)gnode->id; bNode *node; + bNodeSocket *sock; stack+= gnode->stack_index; for(node= ntree->nodes.first; node; node= node->next) { if(node->typeinfo->execfunc) { - bNodeSocket *sock; - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->intern) { - if(sock->link) { - bNodeStack *ns= stack + sock->link->fromsock->stack_index; - ns->hasoutput= 1; - ns->sockettype= sock->link->fromsock->type; - } - else - sock->ns.sockettype= sock->type; - } + bNodeStack *ns = get_socket_stack(stack, sock, gin); + ns->hasoutput= 1; } } + + /* set stack types (for local stack entries) */ + for(sock= node->outputs.first; sock; sock= sock->next) { + bNodeStack *ns = get_socket_stack(stack, sock, NULL); + if (ns) + ns->sockettype = sock->type; + } } } @@ -2231,6 +2284,8 @@ static void tex_end_exec(bNodeTree *ntree) void ntreeBeginExecTree(bNodeTree *ntree) { + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + /* let's make it sure */ if(ntree->init & NTREE_EXEC_INIT) return; @@ -2262,13 +2317,16 @@ void ntreeBeginExecTree(bNodeTree *ntree) node->need_exec= 1; for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->link) { - ns= ntree->stack + sock->link->fromsock->stack_index; - ns->hasoutput= 1; - ns->sockettype= sock->link->fromsock->type; + ns = get_socket_stack(ntree->stack, sock, NULL); + if (ns) { + ns->hasoutput = 1; + + /* sock type is needed to detect rgba or value or vector types */ + if(sock->link) + ns->sockettype= sock->link->fromsock->type; + else + sock->ns.sockettype= sock->type; } - else - sock->ns.sockettype= sock->type; if(sock->link) { bNodeLink *link= sock->link; @@ -2282,13 +2340,21 @@ void ntreeBeginExecTree(bNodeTree *ntree) } } - if(node->type==NODE_GROUP && node->id) - group_tag_used_outputs(node, ntree->stack); + /* set stack types (for local stack entries) */ + for(sock= node->outputs.first; sock; sock= sock->next) { + ns = get_socket_stack(ntree->stack, sock, NULL); + if (ns) + ns->sockettype = sock->type; + } + if(node->type==NODE_GROUP && node->id) { + node_get_stack(node, ntree->stack, nsin, NULL, NULL); + group_tag_used_outputs(node, ntree->stack, nsin); + } } if(ntree->type==NTREE_COMPOSIT) - composit_begin_exec(ntree, 0); + composit_begin_exec(ntree, ntree->stack); } ntree->init |= NTREE_EXEC_INIT; @@ -2296,14 +2362,24 @@ void ntreeBeginExecTree(bNodeTree *ntree) void ntreeEndExecTree(bNodeTree *ntree) { + bNodeStack *ns; if(ntree->init & NTREE_EXEC_INIT) { bNodeThreadStack *nts; int a; /* another callback candidate! */ - if(ntree->type==NTREE_COMPOSIT) - composit_end_exec(ntree, 0); + if(ntree->type==NTREE_COMPOSIT) { + composit_end_exec(ntree, ntree->stack); + + for(ns= ntree->stack, a=0; a<ntree->stacksize; a++, ns++) { + if(ns->data) { + printf("freed leftover buffer from stack\n"); + free_compbuf(ns->data); + ns->data= NULL; + } + } + } else if(ntree->type==NTREE_TEXTURE) tex_end_exec(ntree); @@ -2327,23 +2403,6 @@ void ntreeEndExecTree(bNodeTree *ntree) } } -static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out) -{ - bNodeSocket *sock; - - /* build pointer stack */ - for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->link) - *(in++)= stack + sock->link->fromsock->stack_index; - else - *(in++)= &sock->ns; - } - - for(sock= node->outputs.first; sock; sock= sock->next) { - *(out++)= stack + sock->stack_index; - } -} - /* nodes are presorted, so exec is in order of list */ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread) { @@ -2356,7 +2415,7 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread) /* only when initialized */ if((ntree->init & NTREE_EXEC_INIT)==0) ntreeBeginExecTree(ntree); - + /* composite does 1 node per thread, so no multiple stacks needed */ if(ntree->type==NTREE_COMPOSIT) { stack= ntree->stack; @@ -2369,12 +2428,12 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread) for(node= ntree->nodes.first; node; node= node->next) { if(node->need_exec) { if(node->typeinfo->execfunc) { - node_get_stack(node, stack, nsin, nsout); + node_get_stack(node, stack, nsin, nsout, NULL); node->typeinfo->execfunc(callerdata, node, nsin, nsout); } else if(node->type==NODE_GROUP && node->id) { - node_get_stack(node, stack, nsin, nsout); - node_group_execute(stack, callerdata, node, nsin, nsout); + node_get_stack(node, stack, nsin, NULL, NULL); + node_group_execute(stack, callerdata, node, nsin); } } } @@ -2420,7 +2479,7 @@ static void *exec_composite_node(void *node_v) bNode *node= node_v; ThreadData *thd= (ThreadData *)node->threaddata; - node_get_stack(node, thd->stack, nsin, nsout); + node_get_stack(node, thd->stack, nsin, nsout, NULL); if((node->flag & NODE_MUTED) && (!node_only_value(node))) { /* viewers we execute, for feedback to user */ @@ -2433,7 +2492,7 @@ static void *exec_composite_node(void *node_v) node->typeinfo->execfunc(thd->rd, node, nsin, nsout); } else if(node->type==NODE_GROUP && node->id) { - node_group_execute(thd->stack, thd->rd, node, nsin, nsout); + node_group_execute(thd->stack, thd->rd, node, nsin); } node->exec |= NODE_READY; @@ -2461,7 +2520,7 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) for(node= ntree->nodes.first; node; node= node->next) { int a; - node_get_stack(node, thd->stack, nsin, nsout); + node_get_stack(node, thd->stack, nsin, nsout, NULL); /* test the outputs */ /* skip value-only nodes (should be in type!) */ @@ -2526,7 +2585,7 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd) for(node= ntree->nodes.first; node; node= node->next) { if(node->need_exec==0 && node_only_value(node)) { if(node->typeinfo->execfunc) { - node_get_stack(node, thd->stack, nsin, nsout); + node_get_stack(node, thd->stack, nsin, nsout, NULL); node->typeinfo->execfunc(thd->rd, node, nsin, nsout); } } @@ -2564,8 +2623,8 @@ static void freeExecutableNode(bNodeTree *ntree) for(node= ntree->nodes.first; node; node= node->next) { if(node->exec & NODE_FREEBUFS) { for(sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns= ntree->stack + sock->stack_index; - if(ns->data) { + bNodeStack *ns= get_socket_stack(ntree->stack, sock, NULL); + if(ns && ns->data) { free_compbuf(ns->data); ns->data= NULL; // printf("freed buf node %s \n", node->name); @@ -2585,7 +2644,7 @@ static bNode *getExecutableNode(bNodeTree *ntree) /* input sockets should be ready */ for(sock= node->inputs.first; sock; sock= sock->next) { - if(sock->link) + if(sock->link && sock->link->fromnode) if((sock->link->fromnode->exec & NODE_READY)==0) break; } @@ -2656,7 +2715,6 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) if(BLI_available_threads(&threads)) { node= getExecutableNode(ntree); if(node) { - if(ntree->progress && totnode) ntree->progress(ntree->prh, (1.0 - curnode/(float)totnode)); if(ntree->stats_draw) { @@ -2923,7 +2981,7 @@ static void data_from_gpu_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack } } -static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *gnode, bNodeStack **in, bNodeStack **out) +static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *gnode, bNodeStack **in) { bNode *node; bNodeTree *ntree= (bNodeTree *)gnode->id; @@ -2938,7 +2996,7 @@ static void gpu_node_group_execute(bNodeStack *stack, GPUMaterial *mat, bNode *g for(node= ntree->nodes.first; node; node= node->next) { if(node->typeinfo->gpufunc) { - group_node_get_stack(node, stack, nsin, nsout, in, out); + node_get_stack(node, stack, nsin, nsout, in); doit = 0; @@ -2976,15 +3034,15 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat) for(node= ntree->nodes.first; node; node= node->next) { if(node->typeinfo->gpufunc) { - node_get_stack(node, stack, nsin, nsout); + node_get_stack(node, stack, nsin, nsout, NULL); gpu_from_node_stack(&node->inputs, nsin, gpuin); gpu_from_node_stack(&node->outputs, nsout, gpuout); if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) data_from_gpu_stack(&node->outputs, nsout, gpuout); } else if(node->type==NODE_GROUP && node->id) { - node_get_stack(node, stack, nsin, nsout); - gpu_node_group_execute(stack, mat, node, nsin, nsout); + node_get_stack(node, stack, nsin, nsout, NULL); + gpu_node_group_execute(stack, mat, node, nsin); } } @@ -3413,7 +3471,7 @@ static void registerShaderNodes(ListBase *ntypelist) register_node_type_sh_value(ntypelist); register_node_type_sh_rgb(ntypelist); register_node_type_sh_texture(ntypelist); - register_node_type_sh_dynamic(ntypelist); +// register_node_type_sh_dynamic(ntypelist); register_node_type_sh_invert(ntypelist); register_node_type_sh_seprgb(ntypelist); register_node_type_sh_combrgb(ntypelist); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 1fc0a2259fb..981b3b31e71 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -1,4 +1,4 @@ -/** +/* * blenkernel/packedFile.c - (cleaned up mar-01 nzc) * * $Id$ diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 853338d0722..e53888127f2 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1,4 +1,6 @@ /* + * $Id$ + * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -23,7 +25,7 @@ * Contributor(s): none yet. * * ***** END GPL LICENSE BLOCK ***** - */ + */ #include "DNA_object_types.h" diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index c1a6558aea3..fd792168c6b 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2286,6 +2286,10 @@ static void particle_fluidsim(ParticleSystem *psys, int own_psys, ParticleData * /* pressure and near pressure */ for(n=own_psys?1:0; n<neighbours; n++) { + /* disregard particles at the exact same location */ + if(ptn[n].dist < FLT_EPSILON) + continue; + sub_v3_v3(ptn[n].co, pa->prev_state.co); mul_v3_fl(ptn[n].co, 1.f/ptn[n].dist); q = ptn[n].dist/h; @@ -2305,6 +2309,10 @@ static void particle_fluidsim(ParticleSystem *psys, int own_psys, ParticleData * /* main calculations */ for(n=own_psys?1:0; n<neighbours; n++) { + /* disregard particles at the exact same location */ + if(ptn[n].dist < FLT_EPSILON) + continue; + npa = psys->particles + ptn[n].index; rij = ptn[n].dist; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index b7ece436ee2..6ea14606660 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1,4 +1,5 @@ -/** +/* + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -19,7 +20,7 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * -* Contributor(s): Campbell Barton <ideasman42@gmail.com> + * Contributor(s): Campbell Barton <ideasman42@gmail.com> * * ***** END GPL LICENSE BLOCK ***** */ diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 044e1350be1..fa2e867d483 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index c8ef834fbbb..c004e254572 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 1c40ef020be..df81bcd1593 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index da90ce4a715..7ddd1fbd6bb 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 2785878fb08..83e28db771a 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -193,7 +193,7 @@ void seq_free_sequence(Scene *scene, Sequence *seq) if (ed->act_seq==seq) ed->act_seq= NULL; - if(seq->scene_sound) + if(seq->scene_sound && ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) sound_remove_scene_sound(scene, seq->scene_sound); seq_free_animdata(scene, seq); @@ -3399,6 +3399,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine) seq->mul= 1.0; seq->blend_opacity = 100.0; seq->volume = 1.0f; + seq->scene_sound = NULL; return seq; } diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index a75bc2164c3..53fefa685b9 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -1,5 +1,5 @@ -/** - * shrinkwrap.c +/* + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c index 1d5f9b4c463..8917d2946bd 100644 --- a/source/blender/blenkernel/intern/sketch.c +++ b/source/blender/blenkernel/intern/sketch.c @@ -1,4 +1,4 @@ -/** +/* * * $Id$ * diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 1d80e989da4..b2d3ddf2e52 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1,4 +1,4 @@ -/** +/* * smoke.c * * $Id$ diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 0889f490e79..5697c29db5d 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -2251,8 +2251,16 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) if(!ob->sculpt) return NULL; - if(ob->sculpt->pbvh) + if(ob->sculpt->pbvh) { + /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm + but this can be freed on ccgdm release, this updates the pointers + when the ccgdm gets remade, the assumption is that the topology + does not change. */ + ccgdm_create_grids(dm); + BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces); + ccgdm->pbvh = ob->sculpt->pbvh; + } if(ccgdm->pbvh) return ccgdm->pbvh; diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c index 7ec6d84d285..052b545cfb4 100644 --- a/source/blender/blenkernel/intern/suggestions.c +++ b/source/blender/blenkernel/intern/suggestions.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index c3a34e1942f..b071f2c9da5 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -1,4 +1,5 @@ -/** +/* + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index e946ce06aa2..1c1febf2609 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -1,4 +1,4 @@ -/** +/* * Functions for writing avi-format files. * Added interface for generic movie support (ton) * diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index bb00e6de5ce..f3b759113ff 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -1,4 +1,6 @@ /* + * $Id$ + * * ffmpeg-write support * * Partial Copyright (c) 2006 Peter Schlaile |