Merged changes in the trunk up to revision 42116.
[blender.git] / source / blender / blenkernel / intern / scene.c
index 101a10903c853bc26b97d411c45ac5bab7822026..33fb15faa56c1bda15e5505519284745e0abbadc 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -46,6 +44,7 @@
 
 #include "DNA_anim_types.h"
 #include "DNA_group_types.h"
+#include "DNA_node_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -79,6 +78,8 @@
 //XXX #include "BIF_previewrender.h"
 //XXX #include "BIF_editseq.h"
 
+#include "FRS_freestyle_config.h"
+
 //XXX #include "nla.h"
 
 #ifdef WIN32
@@ -128,7 +129,7 @@ Scene *copy_scene(Scene *sce, int type)
                scen->r.layers= lb;
        }
        else {
-               scen= copy_libblock(sce);
+               scen= copy_libblock(&sce->id);
                BLI_duplicatelist(&(scen->base), &(sce->base));
                
                clear_id_newpoins();
@@ -243,7 +244,8 @@ Scene *copy_scene(Scene *sce, int type)
 void free_scene(Scene *sce)
 {
        Base *base;
-
+       SceneRenderLayer *srl;
+       
        base= sce->base.first;
        while(base) {
                base->object->id.us--;
@@ -283,6 +285,10 @@ void free_scene(Scene *sce)
                sce->r.ffcodecdata.properties = NULL;
        }
        
+       for(srl= sce->r.layers.first; srl; srl= srl->next) {
+               FRS_free_freestyle_config(srl);
+       }
+       
        BLI_freelistN(&sce->markers);
        BLI_freelistN(&sce->transform_spaces);
        BLI_freelistN(&sce->r.layers);
@@ -348,9 +354,11 @@ Scene *add_scene(const char *name)
        sce->r.mblur_samples= 1;
        sce->r.filtertype= R_FILTER_MITCH;
        sce->r.size= 50;
-       sce->r.planes= 24;
-       sce->r.imtype= R_PNG;
-       sce->r.quality= 90;
+
+       sce->r.im_format.planes= R_IMF_PLANES_RGB;
+       sce->r.im_format.imtype= R_IMF_IMTYPE_PNG;
+       sce->r.im_format.quality= 90;
+
        sce->r.displaymode= R_OUTPUT_AREA;
        sce->r.framapto= 100;
        sce->r.images= 100;
@@ -485,7 +493,7 @@ Scene *add_scene(const char *name)
        sce->r.osa= 8;
 
        /* 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);
+       scene_add_render_layer(sce, NULL);
        
        /* game data */
        sce->gm.stereoflag = STEREO_NOSTEREO;
@@ -808,6 +816,8 @@ int scene_camera_switch_update(Scene *scene)
                scene->camera= camera;
                return 1;
        }
+#else
+       (void)scene;
 #endif
        return 0;
 }
@@ -910,15 +920,20 @@ int scene_check_setscene(Main *bmain, Scene *sce)
 }
 
 /* This function is needed to cope with fractional frames - including two Blender rendering features
-* mblur (motion blur that renders 'subframes' and blurs them together), and fields rendering. */
-
-/* see also bsystem_time in object.c */
+ * mblur (motion blur that renders 'subframes' and blurs them together), and fields rendering. 
+ */
 float BKE_curframe(Scene *scene)
 {
-       float ctime = scene->r.cfra;
-       ctime+= scene->r.subframe;
-       ctime*= scene->r.framelen;      
+       return BKE_frame_to_ctime(scene, scene->r.cfra);
+}
 
+/* This function is used to obtain arbitrary fractional frames */
+float BKE_frame_to_ctime(Scene *scene, const float frame)
+{
+       float ctime = frame;
+       ctime += scene->r.subframe;
+       ctime *= scene->r.framelen;     
+       
        return ctime;
 }
 
@@ -992,16 +1007,22 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
 /* this is called in main loop, doing tagged updates before redraw */
 void scene_update_tagged(Main *bmain, Scene *scene)
 {
+       /* keep this first */
+       BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
+
+       /* flush recalc flags to dependencies */
        DAG_ids_flush_tagged(bmain);
 
        scene->physics_settings.quick_cache_step= 0;
 
        /* update all objects: drivers, matrices, displists, etc. flags set
-          by depgraph or manual, no layer check here, gets correct flushed */
+          by depgraph or manual, no layer check here, gets correct flushed
 
+          in the future this should handle updates for all datablocks, not
+          only objects and scenes. - brecht */
        scene_update_tagged_recursive(bmain, scene, scene);
 
-       /* recalc scene animation data here (for sequencer) */
+       /* extra call here to recalc scene animation (for sequencer) */
        {
                AnimData *adt= BKE_animdata_from_id(&scene->id);
                float ctime = BKE_curframe(scene);
@@ -1010,13 +1031,15 @@ void scene_update_tagged(Main *bmain, Scene *scene)
                        BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0);
        }
        
+       /* quick point cache updates */
        if (scene->physics_settings.quick_cache_step)
                BKE_ptcache_quick_cache_all(bmain, scene);
 
+       /* notify editors about recalc */
        DAG_ids_check_recalc(bmain);
 
-       /* in the future this should handle updates for all datablocks, not
-          only objects and scenes. - brecht */
+       /* keep this last */
+       BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST);
 }
 
 void scene_clear_tagged(Main *bmain, Scene *UNUSED(scene))
@@ -1031,7 +1054,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
        Scene *sce_iter;
 
        /* keep this first */
-       BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_FRAME_CHANGE_PRE);
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
 
        sound_set_cfra(sce->r.cfra);
        
@@ -1043,6 +1067,10 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
                        DAG_scene_sort(bmain, sce_iter);
        }
 
+       /* flush recalc flags to dependencies, if we were only changing a frame
+          this would not be necessary, but if a user or a script has modified
+          some datablock before scene_update_tagged was called, we need the flush */
+       DAG_ids_flush_tagged(bmain);
 
        /* Following 2 functions are recursive
         * so dont call within 'scene_update_tagged_recursive' */
@@ -1061,17 +1089,22 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
        scene_update_tagged_recursive(bmain, sce, sce);
 
        /* keep this last */
-       BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_FRAME_CHANGE_POST);
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
+
+       DAG_ids_clear_recalc(bmain);
 }
 
 /* return default layer, also used to patch old files */
-void scene_add_render_layer(Scene *sce)
+SceneRenderLayer *scene_add_render_layer(Scene *sce, const char *name)
 {
        SceneRenderLayer *srl;
-//     int tot= 1 + BLI_countlist(&sce->r.layers);
-       
+
+       if(!name)
+               name= "RenderLayer";
+
        srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer");
-       strcpy(srl->name, "RenderLayer");
+       BLI_strncpy(srl->name, name, sizeof(srl->name));
        BLI_uniquename(&sce->r.layers, srl, "RenderLayer", '.', offsetof(SceneRenderLayer, name), sizeof(srl->name));
        BLI_addtail(&sce->r.layers, srl);
 
@@ -1079,6 +1112,46 @@ void scene_add_render_layer(Scene *sce)
        srl->lay= (1<<20) -1;
        srl->layflag= 0x7FFF;   /* solid ztra halo edge strand */
        srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
+       FRS_add_freestyle_config( srl );
+
+       return srl;
+}
+
+int scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *srl)
+{
+       const int act= BLI_findindex(&scene->r.layers, srl);
+       Scene *sce;
+
+       if (act == -1) {
+               return 0;
+       }
+       else if ( (scene->r.layers.first == scene->r.layers.last) &&
+                 (scene->r.layers.first == srl))
+       {
+               /* ensure 1 layer is kept */
+               return 0;
+       }
+
+       BLI_remlink(&scene->r.layers, srl);
+       MEM_freeN(srl);
+
+       scene->r.actlay= 0;
+
+       for(sce = bmain->scene.first; sce; sce = sce->id.next) {
+               if(sce->nodetree) {
+                       bNode *node;
+                       for(node = sce->nodetree->nodes.first; node; node = node->next) {
+                               if(node->type==CMP_NODE_R_LAYERS && (Scene*)node->id==scene) {
+                                       if(node->custom1==act)
+                                               node->custom1= 0;
+                                       else if(node->custom1>act)
+                                               node->custom1--;
+                               }
+                       }
+               }
+       }
+
+       return 1;
 }
 
 /* render simplification */
@@ -1142,6 +1215,6 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base)
 int scene_use_new_shading_nodes(Scene *scene)
 {
        RenderEngineType *type= RE_engines_find(scene->r.engine);
-       return (type->flag & RE_USE_SHADING_NODES);
+       return (type && type->flag & RE_USE_SHADING_NODES);
 }