/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 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 ***** */ /* scene.c MIXED MODEL * * jan 95 * * * Version: $Id: scene.c,v 1.7 2000/09/17 21:16:25 ton Exp $ */ #include "blender.h" #include "group.h" #include "ika.h" /* 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! */ freelistN(&sce->base); free_editing(sce->ed); if(sce->radio) freeN(sce->radio); if(sce->fcam) freeN(sce->fcam); sce->radio= 0; free_scriptlink(&sce->scriptlink); } 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; strcpy(sce->r.backbuf, "//backbuf"); strcpy(sce->r.pic, U.renderdir); strcpy(sce->r.ftype, "//ftype"); init_rctf(&sce->r.safety, 0.1, 0.9, 0.1, 0.9); sce->r.osa= 8; return sce; } Scene *copy_scene(Scene *sce, int level) { /* level 0: alle objects shared * level 1: alle objectdata shared * level 2: volledige kopie */ Scene *scen; ID *id; Base *base, *obase; Object *ob; Curve *cu; Mesh *me; MetaBall *mb; Material *ma; Lamp *la; int a; /* level 0 */ scen= copy_libblock(sce); duplicatelist(&(scen->base), &(sce->base)); clear_id_newpoins(); id_us_plus((ID *)scen->world); id_us_plus((ID *)scen->set); scen->ed= 0; scen->radio= 0; obase= sce->base.first; base= scen->base.first; while(base) { base->object->id.us++; if(obase==sce->basact) scen->basact= base; obase= obase->next; base= base->next; } if(level==0) return scen; /* level 1 */ G.scene= scen; single_object_users(0); /* camera */ ID_NEW(G.scene->camera); /* level 2 */ if(level>=2) { if(scen->world) { scen->world->id.us--; scen->world= copy_world(scen->world); } single_obdata_users(0); single_mat_users_expand(); single_tex_users_expand(); } clear_id_newpoins(); copy_scriptlink(&sce->scriptlink); return scen; } 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; 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) { 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++; 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--; if(doit==0) break; test= test->next; } if(test) insertlink(&tempbase, test, base); else { addhead(&tempbase, base); domore++; } } else 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= FIRSTBASE; 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 */ do_all_scripts(SCRIPT_FRAMECHANGED); do_all_keys(); do_all_ikas(); } void set_scene_name(char *name) { Scene *sce; char str[128]; sce= G.main->scene.first; while(sce) { if(strcmp(name, sce->id.name+2)==0) { set_scene_bg(sce); return; } sce= sce->id.next; } sprintf(str, "Can't find scene: %s", name); error(str); } /* 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= FIRSTBASE; 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; }