2.5/Posemode:
[blender-staging.git] / source / blender / blenkernel / intern / scene.c
index 3fc1d2a610310c7c4df584147fd0f4f4c30f0217..71271e77adfe20ff02f892e2caabf62bae51cb00 100644 (file)
@@ -43,6 +43,7 @@
 #endif
 #include "MEM_guardedalloc.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_armature_types.h"        
 #include "DNA_color_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_meta_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_scriptlink_types.h"
+#include "DNA_screen_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_userdef_types.h"
 
 #include "BKE_action.h"                        
 #include "BKE_anim.h"
+#include "BKE_animsys.h"
 #include "BKE_armature.h"              
 #include "BKE_colortools.h"
 #include "BKE_colortools.h"
@@ -75,7 +77,6 @@
 #include "BKE_node.h"
 #include "BKE_object.h"
 #include "BKE_scene.h"
-#include "BKE_sculpt.h"
 #include "BKE_sequence.h"
 #include "BKE_world.h"
 #include "BKE_utildefines.h"
@@ -124,7 +125,112 @@ void free_qtcodecdata(QuicktimeCodecData *qcd)
        }
 }
 
-/* copy_scene moved to src/header_info.c... should be back */
+Scene *copy_scene(Main *bmain, Scene *sce, int type)
+{
+       Scene *scen;
+       ToolSettings *ts;
+       Base *base, *obase;
+       
+       if(type == SCE_COPY_EMPTY) {
+               ListBase lb;
+               scen= add_scene(sce->id.name+2);
+               
+               lb= scen->r.layers;
+               scen->r= sce->r;
+               scen->r.layers= lb;
+       }
+       else {
+               scen= copy_libblock(sce);
+               BLI_duplicatelist(&(scen->base), &(sce->base));
+               
+               clear_id_newpoins();
+               
+               id_us_plus((ID *)scen->world);
+               id_us_plus((ID *)scen->set);
+               id_us_plus((ID *)scen->ima);
+               id_us_plus((ID *)scen->gm.dome.warptext);
+
+               scen->ed= NULL;
+               scen->theDag= NULL;
+               scen->obedit= NULL;
+               scen->toolsettings= MEM_dupallocN(sce->toolsettings);
+
+               ts= scen->toolsettings;
+               if(ts) {
+                       if(ts->vpaint) {
+                               ts->vpaint= MEM_dupallocN(ts->vpaint);
+                               ts->vpaint->paintcursor= NULL;
+                               ts->vpaint->vpaint_prev= NULL;
+                               ts->vpaint->wpaint_prev= NULL;
+                               id_us_plus((ID *)ts->vpaint->brush);
+                       }
+                       if(ts->wpaint) {
+                               ts->wpaint= MEM_dupallocN(ts->wpaint);
+                               ts->wpaint->paintcursor= NULL;
+                               ts->wpaint->vpaint_prev= NULL;
+                               ts->wpaint->wpaint_prev= NULL;
+                               id_us_plus((ID *)ts->wpaint->brush);
+                       }
+                       if(ts->sculpt) {
+                               ts->sculpt= MEM_dupallocN(ts->sculpt);
+                               id_us_plus((ID *)ts->sculpt->brush);
+                       }
+
+                       id_us_plus((ID *)ts->imapaint.brush);
+                       ts->imapaint.paintcursor= NULL;
+
+                       ts->particle.paintcursor= NULL;
+               }
+               
+               BLI_duplicatelist(&(scen->markers), &(sce->markers));
+               BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
+               BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers));
+               BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
+               
+               scen->nodetree= ntreeCopyTree(sce->nodetree, 0);
+               
+               obase= sce->base.first;
+               base= scen->base.first;
+               while(base) {
+                       id_us_plus(&base->object->id);
+                       if(obase==sce->basact) scen->basact= base;
+       
+                       obase= obase->next;
+                       base= base->next;
+               }
+       }
+       
+       /* make a private copy of the avicodecdata */
+       if(sce->r.avicodecdata) {
+               scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
+               scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
+               scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
+       }
+       
+       /* make a private copy of the qtcodecdata */
+       if(sce->r.qtcodecdata) {
+               scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
+               scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
+       }
+       
+       /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
+        * are done outside of blenkernel with ED_objects_single_users! */
+
+    /*  camera */
+       if(type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
+           ID_NEW(scen->camera);
+       }
+
+       /* world */
+       if(type == SCE_COPY_FULL) {
+        if(scen->world) {
+            id_us_plus((ID *)scen->world);
+            scen->world= copy_world(scen->world);
+        }
+       }
+
+       return scen;
+}
 
 /* do not free scene itself */
 void free_scene(Scene *sce)
@@ -139,13 +245,10 @@ void free_scene(Scene *sce)
        /* do not free objects! */
 
        BLI_freelistN(&sce->base);
-       seq_free_editing(sce->ed);
-       if(sce->radio) MEM_freeN(sce->radio);
-       sce->radio= 0;
-       
-#ifndef DISABLE_PYTHON
-       BPY_free_scriptlink(&sce->scriptlink);
-#endif
+       seq_free_editing(sce);
+
+       BKE_free_animdata((ID *)sce);
+       BKE_keyingsets_free(&sce->keyingsets);
        
        if (sce->r.avicodecdata) {
                free_avicodecdata(sce->r.avicodecdata);
@@ -172,6 +275,8 @@ void free_scene(Scene *sce)
                        MEM_freeN(sce->toolsettings->vpaint);
                if(sce->toolsettings->wpaint)
                        MEM_freeN(sce->toolsettings->wpaint);
+               if(sce->toolsettings->sculpt)
+                       MEM_freeN(sce->toolsettings->sculpt);
                
                MEM_freeN(sce->toolsettings);
                sce->toolsettings = NULL;       
@@ -186,8 +291,6 @@ void free_scene(Scene *sce)
                ntreeFreeTree(sce->nodetree);
                MEM_freeN(sce->nodetree);
        }
-
-       sculptdata_free(sce);
 }
 
 Scene *add_scene(char *name)
@@ -198,21 +301,18 @@ Scene *add_scene(char *name)
 
        sce= alloc_libblock(&G.main->scene, ID_SCE, name);
        sce->lay= 1;
-       sce->selectmode= SCE_SELECT_VERTEX;
-       sce->editbutsize= 0.1;
-       sce->autokey_mode= U.autokey_mode;
        
-       sce->r.mode= R_GAMMA;
+       sce->r.mode= R_GAMMA|R_OSA|R_SHADOW|R_SSS|R_ENVMAP|R_RAYTRACE;
        sce->r.cfra= 1;
        sce->r.sfra= 1;
        sce->r.efra= 250;
-       sce->r.xsch= 320;
-       sce->r.ysch= 256;
+       sce->r.xsch= 1920;
+       sce->r.ysch= 1080;
        sce->r.xasp= 1;
        sce->r.yasp= 1;
-       sce->r.xparts= 4;
-       sce->r.yparts= 4;
-       sce->r.size= 100;
+       sce->r.xparts= 8;
+       sce->r.yparts= 8;
+       sce->r.size= 25;
        sce->r.planes= 24;
        sce->r.quality= 90;
        sce->r.framapto= 100;
@@ -221,21 +321,18 @@ Scene *add_scene(char *name)
        sce->r.frs_sec= 25;
        sce->r.frs_sec_base= 1;
        sce->r.ocres = 128;
+       sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT;
        
        sce->r.bake_mode= 1;    /* prevent to include render stuff here */
-       sce->r.bake_filter= 2;
+       sce->r.bake_filter= 8;
        sce->r.bake_osa= 5;
        sce->r.bake_flag= R_BAKE_CLEAR;
        sce->r.bake_normal_space= R_BAKE_SPACE_TANGENT;
-       
-       sce->r.xplay= 640;
-       sce->r.yplay= 480;
-       sce->r.freqplay= 60;
-       sce->r.depth= 32;
+
+       sce->r.scemode= R_DOCOMP|R_DOSEQ|R_EXTENSION;
+       sce->r.stamp= R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_SCENE|R_STAMP_CAMERA;
        
        sce->r.threads= 1;
-       
-       sce->r.stereomode = 1;  // no stereo
 
        sce->r.simplify_subsurf= 6;
        sce->r.simplify_particles= 1.0f;
@@ -265,6 +362,10 @@ Scene *add_scene(char *name)
        sce->toolsettings->select_thresh= 0.01f;
        sce->toolsettings->jointrilimit = 0.8f;
 
+       sce->toolsettings->selectmode= SCE_SELECT_VERTEX;
+       sce->toolsettings->normalsize= 0.1;
+       sce->toolsettings->autokey_mode= U.autokey_mode;
+
        sce->toolsettings->skgen_resolution = 100;
        sce->toolsettings->skgen_threshold_internal     = 0.01f;
        sce->toolsettings->skgen_threshold_external     = 0.01f;
@@ -280,6 +381,11 @@ Scene *add_scene(char *name)
        sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
        sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
 
+       sce->toolsettings->proportional_size = 1.0f;
+
+
+       sce->unit.scale_length = 1.0f;
+
        pset= &sce->toolsettings->particle;
        pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER;
        pset->emitterdist= 0.25f;
@@ -302,11 +408,32 @@ Scene *add_scene(char *name)
        BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f);
        sce->r.osa= 8;
 
-       sculptdata_init(sce);
-
        /* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */
        scene_add_render_layer(sce);
        
+       /* game data */
+       sce->gm.stereoflag = STEREO_NOSTEREO;
+       sce->gm.stereomode = STEREO_ANAGLYPH;
+       sce->gm.dome.angle = 180;
+       sce->gm.dome.mode = DOME_FISHEYE;
+       sce->gm.dome.res = 4;
+       sce->gm.dome.resbuf = 1.0f;
+       sce->gm.dome.tilt = 0;
+
+       sce->gm.xplay= 800;
+       sce->gm.yplay= 600;
+       sce->gm.freqplay= 60;
+       sce->gm.depth= 32;
+
+       sce->gm.gravity= 9.8f;
+       sce->gm.physicsEngine= WOPHY_BULLET;
+       sce->gm.mode = 32; //XXX ugly harcoding, still not sure we should drop mode. 32 == 1 << 5 == use_occlusion_culling 
+       sce->gm.occlusionRes = 128;
+       sce->gm.ticrate = 60;
+       sce->gm.maxlogicstep = 5;
+       sce->gm.physubstep = 1;
+       sce->gm.maxphystep = 5;
+
        return sce;
 }
 
@@ -366,15 +493,12 @@ void set_scene_bg(Scene *scene)
                base->flag |= flag;
                
                /* not too nice... for recovering objects with lost data */
-               if(ob->pose==NULL) base->flag &= ~OB_POSEMODE;
+               //if(ob->pose==NULL) base->flag &= ~OB_POSEMODE;
                ob->flag= base->flag;
                
                ob->ctime= -1234567.0;  /* force ipo to be calculated later */
        }
        /* no full animation update, this to enable render code to work (render code calls own animation updates) */
-       
-       /* do we need FRAMECHANGED in set_scene? */
-//     if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED, 0);
 }
 
 /* called from creator.c */
@@ -392,6 +516,30 @@ void set_scene_name(char *name)
        //XXX error("Can't find scene: %s", name);
 }
 
+void unlink_scene(Main *bmain, Scene *sce, Scene *newsce)
+{
+       Scene *sce1;
+       bScreen *sc;
+
+       /* check all sets */
+       for(sce1= bmain->scene.first; sce1; sce1= sce1->id.next)
+               if(sce1->set == sce)
+                       sce1->set= NULL;
+       
+       /* check all sequences */
+       clear_scene_in_allseqs(sce);
+
+       /* check render layer nodes in other scenes */
+       clear_scene_in_nodes(bmain, sce);
+       
+       /* al screens */
+       for(sc= bmain->screen.first; sc; sc= sc->id.next)
+               if(sc->scene == sce)
+                       sc->scene= newsce;
+
+       free_libblock(&bmain->scene, sce);
+}
+
 /* used by metaballs
  * doesnt return the original duplicated object, only dupli's
  */
@@ -399,16 +547,25 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
 {
        static ListBase *duplilist= NULL;
        static DupliObject *dupob;
-       static int fase;
+       static int fase= F_START, in_next_object= 0;
        int run_again=1;
        
        /* init */
        if(val==0) {
                fase= F_START;
                dupob= NULL;
+               
+               /* XXX particle systems with metas+dupligroups call this recursively */
+               /* see bug #18725 */
+               if(in_next_object) {
+                       printf("ERROR: MetaBall generation called recursively, not supported\n");
+                       
+                       return F_ERROR;
+               }
        }
        else {
-
+               in_next_object= 1;
+               
                /* run_again is set when a duplilist has been ended */
                while(run_again) {
                        run_again= 0;
@@ -490,6 +647,9 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
                }
        }
        
+       /* reset recursion test */
+       in_next_object= 0;
+       
        return fase;
 }
 
@@ -561,41 +721,66 @@ int scene_check_setscene(Scene *sce)
        return 1;
 }
 
+/* This (evil) function is needed to cope with two legacy Blender rendering features
+* mblur (motion blur that renders 'subframes' and blurs them together), and fields 
+* rendering. Thus, the use of ugly globals from object.c
+*/
+// BAD... EVIL... JUJU...!!!!
+// XXX moved here temporarily
+float frame_to_float (Scene *scene, int cfra)          /* see also bsystem_time in object.c */
+{
+       extern float bluroffs;  /* bad stuff borrowed from object.c */
+       extern float fieldoffs;
+       float ctime;
+       
+       ctime= (float)cfra;
+       ctime+= bluroffs+fieldoffs;
+       ctime*= scene->r.framelen;
+       
+       return ctime;
+}
+
 static void scene_update(Scene *sce, unsigned int lay)
 {
        Base *base;
        Object *ob;
+       float ctime = frame_to_float(sce, sce->r.cfra); 
        
        if(sce->theDag==NULL)
                DAG_scene_sort(sce);
        
        DAG_scene_update_flags(sce, lay);   // only stuff that moves or needs display still
        
+       /* All 'standard' (i.e. without any dependencies) animation is handled here,
+               * with an 'local' to 'macro' order of evaluation. This should ensure that
+               * settings stored nestled within a hierarchy (i.e. settings in a Texture block
+           * can be overridden by settings from Scene, which owns the Texture through a hierarchy 
+           * such as Scene->World->MTex/Texture) can still get correctly overridden.
+               */
+       BKE_animsys_evaluate_all_animation(G.main, ctime);
+       
        for(base= sce->base.first; base; base= base->next) {
                ob= base->object;
                
                object_handle_update(sce, ob);   // bke_object.h
                
                /* only update layer when an ipo */
-               if(ob->ipo && has_ipo_code(ob->ipo, OB_LAY) ) {
-                       base->lay= ob->lay;
-               }
+                       // XXX old animation system
+               //if(ob->ipo && has_ipo_code(ob->ipo, OB_LAY) ) {
+               //      base->lay= ob->lay;
+               //}
        }
 }
 
+
 /* applies changes right away, does all sets too */
 void scene_update_for_newframe(Scene *sce, unsigned int lay)
 {
        Scene *scene= sce;
        
-       /* clears all BONE_UNKEYED flags for every pose's pchans */
-       framechange_poses_clear_unkeyed();
+       /* clear animation overrides */
+       // XXX TODO...
        
-       /* object ipos are calculated in where_is_object */
-       do_all_data_ipos(sce);
-#ifndef DISABLE_PYTHON
-       if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED, 0);
-#endif
        /* sets first, we allow per definition current scene to have dependencies on sets */
        for(sce= sce->set; sce; sce= sce->set)
                scene_update(sce, lay);
@@ -619,91 +804,6 @@ void scene_add_render_layer(Scene *sce)
        srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
 }
 
-/* Initialize 'permanent' sculpt data that is saved with file kept after
-   switching out of sculptmode. */
-void sculptdata_init(Scene *sce)
-{
-       SculptData *sd;
-
-       if(!sce)
-               return;
-
-       sd= &sce->sculptdata;
-
-       memset(sd, 0, sizeof(SculptData));
-
-       /* XXX: create preset brushes here
-       sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size =
-               sd->inflatebrush.size = sd->grabbrush.size =
-               sd->layerbrush.size = sd->flattenbrush.size = 50;
-       sd->drawbrush.strength = sd->smoothbrush.strength =
-               sd->pinchbrush.strength = sd->inflatebrush.strength =
-               sd->grabbrush.strength = sd->layerbrush.strength =
-               sd->flattenbrush.strength = 25;
-       sd->drawbrush.dir = sd->pinchbrush.dir = sd->inflatebrush.dir = sd->layerbrush.dir= 1;
-       sd->drawbrush.flag = sd->smoothbrush.flag =
-               sd->pinchbrush.flag = sd->inflatebrush.flag =
-               sd->layerbrush.flag = sd->flattenbrush.flag = 0;
-       sd->drawbrush.view= 0;
-       sd->brush_type= DRAW_BRUSH;
-       sd->texact= -1;
-       sd->texfade= 1;
-       sd->averaging= 1;
-       sd->texsep= 0;
-       sd->texrept= SCULPTREPT_DRAG;
-       sd->flags= SCULPT_DRAW_BRUSH;
-       sd->tablet_size=3;
-       sd->tablet_strength=10;
-       sd->rake=0;*/
-}
-
-void sculptdata_free(Scene *sce)
-{
-       SculptData *sd= &sce->sculptdata;
-       int a;
-
-       sculptsession_free(sce);
-
-       for(a=0; a<MAX_MTEX; a++) {
-               MTex *mtex= sd->mtex[a];
-               if(mtex) {
-                       if(mtex->tex) mtex->tex->id.us--;
-                       MEM_freeN(mtex);
-               }
-       }
-}
-
-void sculpt_vertexusers_free(SculptSession *ss)
-{
-       if(ss && ss->vertex_users){
-               MEM_freeN(ss->vertex_users);
-               MEM_freeN(ss->vertex_users_mem);
-               ss->vertex_users= NULL;
-               ss->vertex_users_mem= NULL;
-               ss->vertex_users_size= 0;
-       }
-}
-
-void sculptsession_free(Scene *sce)
-{
-       SculptSession *ss= sce->sculptdata.session;
-       if(ss) {
-               if(ss->projverts)
-                       MEM_freeN(ss->projverts);
-               if(ss->mats)
-                       MEM_freeN(ss->mats);
-
-               if(ss->radialcontrol)
-                       MEM_freeN(ss->radialcontrol);
-
-               sculpt_vertexusers_free(ss);
-               if(ss->texcache)
-                       MEM_freeN(ss->texcache);
-               MEM_freeN(ss);
-               sce->sculptdata.session= NULL;
-       }
-}
-
 /* render simplification */
 
 int get_render_subsurf_level(RenderData *r, int lvl)
@@ -738,3 +838,14 @@ float get_render_aosss_error(RenderData *r, float error)
                return error;
 }
 
+void free_dome_warp_text(struct Text *txt)
+{
+       Scene *scene;
+
+       scene = G.main->scene.first;
+       while(scene) {
+               if (scene->r.dometext == txt)
+                       scene->r.dometext = NULL;
+               scene = scene->id.next;
+       }
+}