diff options
Diffstat (limited to 'source/blender/blenkernel/intern/scene.c')
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 536 |
1 files changed, 536 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c new file mode 100644 index 00000000000..d1da1d4d1b6 --- /dev/null +++ b/source/blender/blenkernel/intern/scene.c @@ -0,0 +1,536 @@ + +/* scene.c MIXED MODEL + * + * jan 95 + * + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdio.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include "BLI_winstuff.h" +#include <io.h> +#endif +#include "MEM_guardedalloc.h" + +#include "nla.h" /* for __NLA : IMPORTANT Do not delete me yet! */ +#ifdef __NLA /* for __NLA : IMPORTANT Do not delete me yet! */ +#include "DNA_armature_types.h" /* for __NLA : IMPORTANT Do not delete me yet! */ +#include "BKE_armature.h" /* for __NLA : IMPORTANT Do not delete me yet! */ +#include "BKE_action.h" /* for __NLA : IMPORTANT Do not delete me yet! */ +#endif /* for __NLA : IMPORTANT Do not delete me yet! */ + +#include "DNA_constraint_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_scriptlink_types.h" +#include "DNA_meta_types.h" +#include "DNA_ika_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_group_types.h" +#include "DNA_curve_types.h" +#include "DNA_userdef_types.h" + +#include "BLI_blenlib.h" + +#include "BKE_bad_level_calls.h" +#include "BKE_utildefines.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_anim.h" + +#include "BKE_library.h" + +#include "BPY_extern.h" +#include "BKE_scene.h" +#include "BKE_world.h" +#include "BKE_ipo.h" +#include "BKE_ika.h" +#include "BKE_key.h" + +void free_avicodecdata(AviCodecData *acd) +{ + if (acd) { + if (acd->lpFormat){ + MEM_freeN(acd->lpFormat); + acd->lpFormat = NULL; + acd->cbFormat = 0; + } + if (acd->lpParms){ + MEM_freeN(acd->lpParms); + acd->lpParms = NULL; + acd->cbParms = 0; + } + } +} + +/* niet scene zelf vrijgeven */ +void free_scene(Scene *sce) +{ + Base *base; + + base= sce->base.first; + while(base) { + base->object->id.us--; + base= base->next; + } + /* pas op: niet objects vrijgeven! */ + + BLI_freelistN(&sce->base); + free_editing(sce->ed); + if(sce->radio) MEM_freeN(sce->radio); + if(sce->fcam) MEM_freeN(sce->fcam); + sce->radio= 0; + + BPY_free_scriptlink(&sce->scriptlink); + if (sce->r.avicodecdata) { + free_avicodecdata(sce->r.avicodecdata); + MEM_freeN(sce->r.avicodecdata); + sce->r.avicodecdata = NULL; + } +} + +Scene *add_scene(char *name) +{ + Scene *sce; + + sce= alloc_libblock(&G.main->scene, ID_SCE, name); + sce->lay= 1; + + sce->r.mode= R_GAMMA; + sce->r.cfra= 1; + sce->r.sfra= 1; + sce->r.efra= 250; + sce->r.xsch= 320; + sce->r.ysch= 256; + sce->r.xasp= 1; + sce->r.yasp= 1; + sce->r.xparts= 1; + sce->r.yparts= 1; + sce->r.size= 100; + sce->r.planes= 24; + sce->r.quality= 90; + sce->r.framapto= 100; + sce->r.images= 100; + sce->r.framelen= 1.0; + sce->r.frs_sec= 25; + + sce->r.xplay= 640; + sce->r.yplay= 480; + sce->r.freqplay= 60; + sce->r.depth= 32; + + sce->r.stereomode = 1; // no stereo + + strcpy(sce->r.backbuf, "//backbuf"); + strcpy(sce->r.pic, U.renderdir); + strcpy(sce->r.ftype, "//ftype"); + + BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f); + sce->r.osa= 8; + + return sce; +} + +int object_in_scene(Object *ob, Scene *sce) +{ + Base *base; + + base= sce->base.first; + while(base) { + if(base->object == ob) return 1; + base= base->next; + } + return 0; +} + +void sort_baselist(Scene *sce) +{ + /* alles in volgorde van parent en track */ + ListBase tempbase, noparentbase, notyetbase; + Base *base, *test=NULL; + Object *par; + int doit, domore= 0, lastdomore=1; + + + /* volgorde gelijk houden als er niets veranderd is! */ + /* hier waren problemen met campos array's: volgorde camera's is van belang */ + + while(domore!=lastdomore) { + + lastdomore= domore; + domore= 0; + tempbase.first= tempbase.last= 0; + noparentbase.first= noparentbase.last= 0; + notyetbase.first= notyetbase.last= 0; + + while( (base= sce->base.first) ) { + BLI_remlink(&sce->base, base); + + par= 0; + if(base->object->type==OB_IKA) { + Ika *ika= base->object->data; + par= ika->parent; + } + + if(par || base->object->parent || base->object->track) { + + doit= 0; + if(base->object->parent) doit++; + if(base->object->track) doit++; + + /* Count constraints */ + { + bConstraint *con; + for (con = base->object->constraints.first; con; con=con->next){ + switch (con->type){ + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data=con->data; + if (data->tar) doit++; + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data=con->data; + if (data->tar) doit++; + } + break; + case CONSTRAINT_TYPE_NULL: + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data=con->data; + if (data->tar) doit++; + + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data=con->data; + if (data->tar) doit++; + } + break; + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data=con->data; + if (data->tar) doit++; + } + break; + default: + break; + } + } + } + + if(par) doit++; + + test= tempbase.first; + while(test) { + + if(test->object==base->object->parent) doit--; + if(test->object==base->object->track) doit--; + if(test->object==par) doit--; + + /* Decrement constraints */ + { + bConstraint *con; + for (con = base->object->constraints.first; con; con=con->next){ + switch (con->type){ + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data=con->data; + if (test->object == data->tar && test->object!=base->object) doit--; + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data=con->data; + if (test->object == data->tar && test->object!=base->object) doit--; + } + break; + case CONSTRAINT_TYPE_NULL: + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data=con->data; + if (test->object == data->tar && test->object!=base->object) doit--; + + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data=con->data; + if (test->object == data->tar && test->object!=base->object) doit--; + } + break; + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data=con->data; + if (test->object == data->tar && test->object!=base->object) doit--; + } + break; + default: + break; + } + } + } + + if(doit==0) break; + test= test->next; + } + + if(test) BLI_insertlink(&tempbase, test, base); + else { + BLI_addhead(&tempbase, base); + domore++; + } + + } + else BLI_addtail(&noparentbase, base); + + } + sce->base= noparentbase; + addlisttolist(&sce->base, &tempbase); + addlisttolist(&sce->base, ¬yetbase); + + } +} + + +void set_scene_bg(Scene *sce) +{ + Base *base; + Object *ob; + Group *group; + GroupObject *go; + int flag; + + G.scene= sce; + + /* objecten deselecteren (voor dataselect) */ + ob= G.main->object.first; + while(ob) { + ob->flag &= ~(SELECT|OB_FROMGROUP); + ob= ob->id.next; + } + + /* group flags again */ + group= G.main->group.first; + while(group) { + go= group->gobject.first; + while(go) { + if(go->ob) go->ob->flag |= OB_FROMGROUP; + go= go->next; + } + group= group->id.next; + } + + /* baselijst sorteren */ + sort_baselist(sce); + + /* layers en flags uit bases naar objecten kopieeren */ + base= G.scene->base.first; + while(base) { + + base->object->lay= base->lay; + + base->flag &= ~OB_FROMGROUP; + flag= base->object->flag & OB_FROMGROUP; + base->flag |= flag; + + base->object->ctime= -1234567.0; /* forceer ipo */ + base= base->next; + } + + do_all_ipos(); /* layers/materials */ + + BPY_do_all_scripts(SCRIPT_FRAMECHANGED); + do_all_keys(); +#ifdef __NLA + do_all_actions(); +#endif + do_all_ikas(); + + +} + +void set_scene_name(char *name) +{ + Scene *sce; + + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (BLI_streq(name, sce->id.name+2)) { + set_scene_bg(sce); + return; + } + } + + error("Can't find scene: %s", name); +} + +/* used by metaballs + * doesnt return the original duplicated object, only dupli's + */ +int next_object(int val, Base **base, Object **ob) +{ + extern ListBase duplilist; + static Object *dupob; + static int fase; + int run_again=1; + + /* init */ + if(val==0) { + fase= F_START; + dupob= 0; + } + else { + + /* run_again is set when a duplilist has been ended */ + while(run_again) { + run_again= 0; + + + + /* de eerste base */ + if(fase==F_START) { + *base= G.scene->base.first; + if(*base) { + *ob= (*base)->object; + fase= F_SCENE; + } + else { + /* uitzondering: een lege scene */ + if(G.scene->set && G.scene->set->base.first) { + *base= G.scene->set->base.first; + *ob= (*base)->object; + fase= F_SET; + } + } + } + else { + if(*base && fase!=F_DUPLI) { + *base= (*base)->next; + if(*base) *ob= (*base)->object; + else { + if(fase==F_SCENE) { + /* de scene is klaar, we gaan door met de set */ + if(G.scene->set && G.scene->set->base.first) { + *base= G.scene->set->base.first; + *ob= (*base)->object; + fase= F_SET; + } + } + } + } + } + + if(*base == 0) fase= F_START; + else { + if(fase!=F_DUPLI) { + if( (*base)->object->transflag & OB_DUPLI) { + + make_duplilist(G.scene, (*base)->object); + dupob= duplilist.first; + + } + } + /* dupli's afhandelen */ + if(dupob) { + + *ob= dupob; + fase= F_DUPLI; + + dupob= dupob->id.next; + } + else if(fase==F_DUPLI) { + fase= F_SCENE; + free_duplilist(); + run_again= 1; + } + + } + } + } + + return fase; +} + +Object *scene_find_camera(Scene *sc) +{ + Base *base; + + for (base= sc->base.first; base; base= base->next) + if (base->object->type==OB_CAMERA) + return base->object; + + return NULL; +} + + +Base *scene_add_base(Scene *sce, Object *ob) +{ + Base *b= MEM_callocN(sizeof(*b), "scene_add_base"); + BLI_addhead(&sce->base, b); + + b->object= ob; + b->flag= ob->flag; + b->lay= ob->lay; + + return b; +} + +void scene_deselect_all(Scene *sce) +{ + Base *b; + + for (b= sce->base.first; b; b= b->next) { + b->flag&= ~SELECT; + b->object->flag= b->flag; + } +} + +void scene_select_base(Scene *sce, Base *selbase) +{ + scene_deselect_all(sce); + + selbase->flag |= SELECT; + selbase->object->flag= selbase->flag; + + sce->basact= selbase; +} |