synched with trunk at revision 30597
[blender.git] / source / blender / blenkernel / intern / scene.c
index 8488d7a..429cbfe 100644 (file)
@@ -17,7 +17,7 @@
  *
  * 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.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifndef WIN32 
 #include <unistd.h>
 #else
 #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_curve_types.h"
 #include "DNA_group_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_material_types.h"
-#include "DNA_meta_types.h"
-#include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_userdef_types.h"
+#include "DNA_sequence_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"
-#include "BKE_constraint.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_group.h"
-#include "BKE_ipo.h"
 #include "BKE_idprop.h"
-#include "BKE_image.h"
-#include "BKE_key.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
 #include "BKE_object.h"
 #include "BKE_paint.h"
+#include "BKE_pointcache.h"
 #include "BKE_scene.h"
-#include "BKE_sequence.h"
+#include "BKE_sequencer.h"
 #include "BKE_world.h"
 #include "BKE_utildefines.h"
+#include "BKE_sound.h"
 
 //XXX #include "BIF_previewrender.h"
 //XXX #include "BIF_editseq.h"
@@ -89,7 +71,7 @@
 #include "BPY_extern.h"
 #endif
 
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_blenlib.h"
 
 //XXX #include "nla.h"
@@ -155,6 +137,8 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type)
                scen->theDag= NULL;
                scen->obedit= NULL;
                scen->toolsettings= MEM_dupallocN(sce->toolsettings);
+               scen->stats= NULL;
+               scen->fps_info= NULL;
 
                ts= scen->toolsettings;
                if(ts) {
@@ -214,22 +198,34 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type)
                scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
        }
        
+       if(sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
+               scen->r.ffcodecdata.properties= IDP_CopyProperty(sce->r.ffcodecdata.properties);
+       }
+
        /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
         * are done outside of blenkernel with ED_objects_single_users! */
 
-    /*  camera */
+       /*  camera */
        if(type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
-           ID_NEW(scen->camera);
+               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);
-        }
+               if(scen->world) {
+                       id_us_plus((ID *)scen->world);
+                       scen->world= copy_world(scen->world);
+               }
+
+               if(sce->ed) {
+                       scen->ed= MEM_callocN( sizeof(Editing), "addseq");
+                       scen->ed->seqbasep= &scen->ed->seqbase;
+                       seqbase_dupli_recursive(sce, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
+               }
        }
 
+       sound_create_scene(scen);
+
        return scen;
 }
 
@@ -244,6 +240,16 @@ void free_scene(Scene *sce)
                base= base->next;
        }
        /* do not free objects! */
+       
+       if(sce->gpd) {
+#if 0   // removed since this can be invalid memory when freeing everything
+               // since the grease pencil data is free'd before the scene.
+               // since grease pencil data is not (yet?), shared between objects
+               // its probably safe not to do this, some save and reload will free this.
+               sce->gpd->id.us--;
+#endif
+               sce->gpd= NULL;
+       }
 
        BLI_freelistN(&sce->base);
        seq_free_editing(sce);
@@ -299,6 +305,13 @@ void free_scene(Scene *sce)
                ntreeFreeTree(sce->nodetree);
                MEM_freeN(sce->nodetree);
        }
+
+       if(sce->stats)
+               MEM_freeN(sce->stats);
+       if(sce->fps_info)
+               MEM_freeN(sce->fps_info);
+
+       sound_destroy_scene(sce);
 }
 
 Scene *add_scene(char *name)
@@ -308,12 +321,13 @@ Scene *add_scene(char *name)
        int a;
 
        sce= alloc_libblock(&G.main->scene, ID_SCE, name);
-       sce->lay= 1;
+       sce->lay= sce->layact= 1;
        
        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.frame_step= 1;
        sce->r.xsch= 1920;
        sce->r.ysch= 1080;
        sce->r.xasp= 1;
@@ -338,8 +352,13 @@ Scene *add_scene(char *name)
        sce->r.bake_normal_space= R_BAKE_SPACE_TANGENT;
 
        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.stamp= R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_SCENE|R_STAMP_CAMERA|R_STAMP_RENDERTIME;
+       sce->r.stamp_font_id= 12;
+
+       sce->r.seq_prev_type= OB_SOLID;
+       sce->r.seq_rend_type= OB_SOLID;
+       sce->r.seq_flag= R_SEQ_GL_PREV;
+
        sce->r.threads= 1;
 
        sce->r.simplify_subsurf= 6;
@@ -350,6 +369,11 @@ Scene *add_scene(char *name)
        sce->r.cineonblack= 95;
        sce->r.cineonwhite= 685;
        sce->r.cineongamma= 1.7f;
+
+       sce->r.border.xmin= 0.0f;
+       sce->r.border.ymin= 0.0f;
+       sce->r.border.xmax= 1.0f;
+       sce->r.border.ymax= 1.0f;
        
        sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings),"Tool Settings Struct");
        sce->toolsettings->cornertype=1;
@@ -391,24 +415,36 @@ Scene *add_scene(char *name)
 
        sce->toolsettings->proportional_size = 1.0f;
 
+       sce->physics_settings.gravity[0] = 0.0f;
+       sce->physics_settings.gravity[1] = 0.0f;
+       sce->physics_settings.gravity[2] = -9.81f;
+       sce->physics_settings.flag = PHYS_GLOBAL_GRAVITY;
 
        sce->unit.scale_length = 1.0f;
 
        pset= &sce->toolsettings->particle;
-       pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER;
+       pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER|PE_AUTO_VELOCITY;
        pset->emitterdist= 0.25f;
        pset->totrekey= 5;
        pset->totaddkey= 5;
        pset->brushtype= PE_BRUSH_NONE;
+       pset->draw_step= 2;
+       pset->fade_frames= 2;
+       pset->selectmode= SCE_SELECT_PATH;
        for(a=0; a<PE_TOT_BRUSH; a++) {
-               pset->brush[a].strength= 50;
+               pset->brush[a].strength= 0.5;
                pset->brush[a].size= 50;
                pset->brush[a].step= 10;
+               pset->brush[a].count= 10;
        }
        pset->brush[PE_BRUSH_CUT].strength= 100;
        
        sce->jumpframe = 10;
-       sce->r.audio.mixrate = 44100;
+       sce->r.ffcodecdata.audio_mixrate = 44100;
+
+       sce->audio.distance_model = 2.0;
+       sce->audio.doppler_factor = 1.0;
+       sce->audio.speed_of_sound = 343.3;
 
        strcpy(sce->r.backbuf, "//backbuf");
        strcpy(sce->r.pic, U.renderdir);
@@ -422,6 +458,8 @@ Scene *add_scene(char *name)
        /* game data */
        sce->gm.stereoflag = STEREO_NOSTEREO;
        sce->gm.stereomode = STEREO_ANAGLYPH;
+       sce->gm.eyeseparation = 0.10;
+
        sce->gm.dome.angle = 180;
        sce->gm.dome.mode = DOME_FISHEYE;
        sce->gm.dome.res = 4;
@@ -442,6 +480,28 @@ Scene *add_scene(char *name)
        sce->gm.physubstep = 1;
        sce->gm.maxphystep = 5;
 
+       sce->gm.flag = GAME_DISPLAY_LISTS;
+       sce->gm.matmode = GAME_MAT_MULTITEX;
+
+       sce->gm.obstacleSimulation= OBSTSIMULATION_NONE;
+       sce->gm.levelHeight = 2.f;
+
+       sce->gm.recastData.cellsize = 0.3f;
+       sce->gm.recastData.cellheight = 0.2f;
+       sce->gm.recastData.agentmaxslope = M_PI/2;
+       sce->gm.recastData.agentmaxclimb = 0.9f;
+       sce->gm.recastData.agentheight = 2.0f;
+       sce->gm.recastData.agentradius = 0.6f;
+       sce->gm.recastData.edgemaxlen = 12.0f;
+       sce->gm.recastData.edgemaxerror = 1.3f;
+       sce->gm.recastData.regionminsize = 50.f;
+       sce->gm.recastData.regionmergesize = 20.f;
+       sce->gm.recastData.vertsperpoly = 6;
+       sce->gm.recastData.detailsampledist = 6.0f;
+       sce->gm.recastData.detailsamplemaxerror = 1.0f;
+
+       sound_create_scene(sce);
+
        return sce;
 }
 
@@ -510,18 +570,17 @@ void set_scene_bg(Scene *scene)
 }
 
 /* called from creator.c */
-void set_scene_name(char *name)
+Scene *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;
-               }
+       Scene *sce= (Scene *)find_id("SC", name);
+       if(sce) {
+               set_scene_bg(sce);
+               printf("Scene switch: '%s' in file: '%s'\n", name, G.sce);
+               return sce;
        }
-       
-       //XXX error("Can't find scene: %s", name);
+
+       printf("Can't find scene: '%s' in file: '%s'\n", name, G.sce);
+       return NULL;
 }
 
 void unlink_scene(Main *bmain, Scene *sce, Scene *newsce)
@@ -551,7 +610,7 @@ void unlink_scene(Main *bmain, Scene *sce, Scene *newsce)
 /* used by metaballs
  * doesnt return the original duplicated object, only dupli's
  */
-int next_object(Scene *scene, int val, Base **base, Object **ob)
+int next_object(Scene **scene, int val, Base **base, Object **ob)
 {
        static ListBase *duplilist= NULL;
        static DupliObject *dupob;
@@ -580,17 +639,21 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
 
                        /* the first base */
                        if(fase==F_START) {
-                               *base= scene->base.first;
+                               *base= (*scene)->base.first;
                                if(*base) {
                                        *ob= (*base)->object;
                                        fase= F_SCENE;
                                }
                                else {
-                                   /* exception: empty scene */
-                                       if(scene->set && scene->set->base.first) {
-                                               *base= scene->set->base.first;
-                                               *ob= (*base)->object;
-                                               fase= F_SET;
+                                       /* exception: empty scene */
+                                       while((*scene)->set) {
+                                               (*scene)= (*scene)->set;
+                                               if((*scene)->base.first) {
+                                                       *base= (*scene)->base.first;
+                                                       *ob= (*base)->object;
+                                                       fase= F_SCENE;
+                                                       break;
+                                               }
                                        }
                                }
                        }
@@ -600,11 +663,14 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
                                        if(*base) *ob= (*base)->object;
                                        else {
                                                if(fase==F_SCENE) {
-                                                       /* scene is finished, now do the set */
-                                                       if(scene->set && scene->set->base.first) {
-                                                               *base= scene->set->base.first;
-                                                               *ob= (*base)->object;
-                                                               fase= F_SET;
+                                                       /* (*scene) is finished, now do the set */
+                                                       while((*scene)->set) {
+                                                               (*scene)= (*scene)->set;
+                                                               if((*scene)->base.first) {
+                                                                       *base= (*scene)->base.first;
+                                                                       *ob= (*base)->object;
+                                                                       break;
+                                                               }
                                                        }
                                                }
                                        }
@@ -619,7 +685,7 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
                                                this enters eternal loop because of 
                                                makeDispListMBall getting called inside of group_duplilist */
                                                if((*base)->object->dup_group == NULL) {
-                                                       duplilist= object_duplilist(scene, (*base)->object);
+                                                       duplilist= object_duplilist((*scene), (*base)->object);
                                                        
                                                        dupob= duplilist->first;
 
@@ -631,7 +697,7 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
                                /* handle dupli's */
                                if(dupob) {
                                        
-                                       Mat4CpyMat4(dupob->ob->obmat, dupob->mat);
+                                       copy_m4_m4(dupob->ob->obmat, dupob->mat);
                                        
                                        (*base)->flag |= OB_FROMDUPLI;
                                        *ob= dupob->ob;
@@ -644,7 +710,7 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
                                        (*base)->flag &= ~OB_FROMDUPLI;
                                        
                                        for(dupob= duplilist->first; dupob; dupob= dupob->next) {
-                                               Mat4CpyMat4(dupob->ob->obmat, dupob->omat);
+                                               copy_m4_m4(dupob->ob->obmat, dupob->omat);
                                        }
                                        
                                        free_object_duplilist(duplilist);
@@ -655,6 +721,10 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
                }
        }
        
+       /* if(ob && *ob) {
+               printf("Scene: '%s', '%s'\n", (*scene)->id.name+2, (*ob)->id.name+2);
+       } */
+
        /* reset recursion test */
        in_next_object= 0;
        
@@ -672,6 +742,113 @@ Object *scene_find_camera(Scene *sc)
        return NULL;
 }
 
+#ifdef DURIAN_CAMERA_SWITCH
+Object *scene_camera_switch_find(Scene *scene)
+{
+       TimeMarker *m;
+       int cfra = scene->r.cfra;
+       int frame = -(MAXFRAME + 1);
+       Object *camera= NULL;
+
+       for (m= scene->markers.first; m; m= m->next) {
+               if(m->camera && (m->camera->restrictflag & OB_RESTRICT_RENDER)==0 && (m->frame <= cfra) && (m->frame > frame)) {
+                       camera= m->camera;
+                       frame= m->frame;
+
+                       if(frame == cfra)
+                               break;
+
+               }
+       }
+       return camera;
+}
+#endif
+
+int scene_camera_switch_update(Scene *scene)
+{
+#ifdef DURIAN_CAMERA_SWITCH
+       Object *camera= scene_camera_switch_find(scene);
+       if(camera) {
+               scene->camera= camera;
+               return 1;
+       }
+#endif
+       return 0;
+}
+
+char *scene_find_marker_name(Scene *scene, int frame)
+{
+       ListBase *markers= &scene->markers;
+       TimeMarker *m1, *m2;
+
+       /* search through markers for match */
+       for (m1=markers->first, m2=markers->last; m1 && m2; m1=m1->next, m2=m2->prev) {
+               if (m1->frame==frame)
+                       return m1->name;
+
+               if (m1 == m2)
+                       break;
+
+               if (m2->frame==frame)
+                       return m2->name;
+       }
+
+       return NULL;
+}
+
+/* return the current marker for this frame,
+we can have more then 1 marker per frame, this just returns the first :/ */
+char *scene_find_last_marker_name(Scene *scene, int frame)
+{
+       TimeMarker *marker, *best_marker = NULL;
+       int best_frame = -MAXFRAME*2;
+       for (marker= scene->markers.first; marker; marker= marker->next) {
+               if (marker->frame==frame) {
+                       return marker->name;
+               }
+
+               if ( marker->frame > best_frame && marker->frame < frame) {
+                       best_marker = marker;
+                       best_frame = marker->frame;
+               }
+       }
+
+       return best_marker ? best_marker->name : NULL;
+}
+
+/* markers need transforming from different parts of the code so have
+ * a generic function to do this */
+int scene_marker_tfm_translate(Scene *scene, int delta, int flag)
+{
+       TimeMarker *marker;
+       int tot= 0;
+
+       for (marker= scene->markers.first; marker; marker= marker->next) {
+               if ((marker->flag & flag) == flag) {
+                       marker->frame += delta;
+                       tot++;
+               }
+       }
+
+       return tot;
+}
+
+int scene_marker_tfm_extend(Scene *scene, int delta, int flag, int frame, char side)
+{
+       TimeMarker *marker;
+       int tot= 0;
+
+       for (marker= scene->markers.first; marker; marker= marker->next) {
+               if ((marker->flag & flag) == flag) {
+                       if((side=='L' && marker->frame < frame) || (side=='R' && marker->frame >= frame)) {
+                               marker->frame += delta;
+                               tot++;
+                       }
+               }
+       }
+
+       return tot;
+}
 
 Base *scene_add_base(Scene *sce, Object *ob)
 {
@@ -729,81 +906,108 @@ 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 */
+/* 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 */
+float BKE_curframe(Scene *scene)
 {
-       extern float bluroffs;  /* bad stuff borrowed from object.c */
-       extern float fieldoffs;
-       float ctime;
-       
-       ctime= (float)cfra;
-       ctime+= bluroffs+fieldoffs;
-       ctime*= scene->r.framelen;
-       
+       float ctime = scene->r.cfra;
+       ctime+= scene->r.subframe;
+       ctime*= scene->r.framelen;      
+
        return ctime;
 }
 
-static void scene_update(Scene *sce, unsigned int lay)
+static void scene_update_tagged_recursive(Scene *scene, Scene *scene_parent)
 {
        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 */
-                       // XXX old animation system
-               //if(ob->ipo && has_ipo_code(ob->ipo, OB_LAY) ) {
-               //      base->lay= ob->lay;
-               //}
+
+       /* sets first, we allow per definition current scene to have
+          dependencies on sets, but not the other way around. */
+       if(scene->set)
+               scene_update_tagged_recursive(scene->set, scene_parent);
+
+       for(base= scene->base.first; base; base= base->next) {
+               Object *ob= base->object;
+
+               object_handle_update(scene_parent, ob);
+
+               if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP))
+                       group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
+                       
+               /* always update layer, so that animating layers works */
+               base->lay= ob->lay;
        }
 }
 
+/* this is called in main loop, doing tagged updates before redraw */
+void scene_update_tagged(Scene *scene)
+{
+       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 */
+
+       scene_update_tagged_recursive(scene, scene);
+
+       /* recalc scene animation data here (for sequencer) */
+       {
+               float ctime = BKE_curframe(scene); 
+               AnimData *adt= BKE_animdata_from_id(&scene->id);
+
+               if(adt && (adt->recalc & ADT_RECALC_ANIM))
+                       BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, 0);
+       }
+
+       if(scene->physics_settings.quick_cache_step)
+               BKE_ptcache_quick_cache_all(scene);
+
+       /* in the future this should handle updates for all datablocks, not
+          only objects and scenes. - brecht */
+}
 
 /* applies changes right away, does all sets too */
 void scene_update_for_newframe(Scene *sce, unsigned int lay)
 {
-       Scene *scene= sce;
+       float ctime = BKE_curframe(sce);
+       Scene *sce_iter;
        
        /* clear animation overrides */
        // XXX TODO...
-       
-       /* 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);
 
-       scene_update(scene, lay);
+       for(sce_iter= sce; sce_iter; sce_iter= sce_iter->set) {
+               if(sce_iter->theDag==NULL)
+                       DAG_scene_sort(sce_iter);
+       }
+
+
+       /* Following 2 functions are recursive
+        * so dont call within 'scene_update_tagged_recursive' */
+       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);
+       /*...done with recusrive funcs */
+
+       /* object_handle_update() on all objects, groups and sets */
+       scene_update_tagged_recursive(sce, sce);
 }
 
 /* return default layer, also used to patch old files */
 void scene_add_render_layer(Scene *sce)
 {
        SceneRenderLayer *srl;
-       int tot= 1 + BLI_countlist(&sce->r.layers);
+//     int tot= 1 + BLI_countlist(&sce->r.layers);
        
        srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer");
-       sprintf(srl->name, "%d RenderLayer", tot);
+       strcpy(srl->name, "RenderLayer");
+       BLI_uniquename(&sce->r.layers, srl, "RenderLayer", '.', offsetof(SceneRenderLayer, name), sizeof(srl->name));
        BLI_addtail(&sce->r.layers, srl);
 
        /* note, this is also in render, pipeline.c, to make layer when scenedata doesnt have it */
@@ -816,7 +1020,7 @@ void scene_add_render_layer(Scene *sce)
 
 int get_render_subsurf_level(RenderData *r, int lvl)
 {
-       if(G.rt == 1 && (r->mode & R_SIMPLIFY))
+       if(r->mode & R_SIMPLIFY)
                return MIN2(r->simplify_subsurf, lvl);
        else
                return lvl;
@@ -824,7 +1028,7 @@ int get_render_subsurf_level(RenderData *r, int lvl)
 
 int get_render_child_particle_number(RenderData *r, int num)
 {
-       if(G.rt == 1 && (r->mode & R_SIMPLIFY))
+       if(r->mode & R_SIMPLIFY)
                return (int)(r->simplify_particles*num);
        else
                return num;
@@ -832,7 +1036,7 @@ int get_render_child_particle_number(RenderData *r, int num)
 
 int get_render_shadow_samples(RenderData *r, int samples)
 {
-       if(G.rt == 1 && (r->mode & R_SIMPLIFY) && samples > 0)
+       if((r->mode & R_SIMPLIFY) && samples > 0)
                return MIN2(r->simplify_shadowsamples, samples);
        else
                return samples;
@@ -840,20 +1044,32 @@ int get_render_shadow_samples(RenderData *r, int samples)
 
 float get_render_aosss_error(RenderData *r, float error)
 {
-       if(G.rt == 1 && (r->mode & R_SIMPLIFY))
+       if(r->mode & R_SIMPLIFY)
                return ((1.0f-r->simplify_aosss)*10.0f + 1.0f)*error;
        else
                return error;
 }
 
-void free_dome_warp_text(struct Text *txt)
+/* helper function for the SETLOOPER macro */
+Base *_setlooper_base_step(Scene **sce, Base *base)
 {
-       Scene *scene;
+    if(base && base->next) {
+        /* common case, step to the next */
+        return base->next;
+    }
+    else if(base==NULL && (*sce)->base.first) {
+        /* first time looping, return the scenes first base */
+        return (Base *)(*sce)->base.first;
+    }
+    else {
+        /* reached the end, get the next base in the set */
+        while((*sce= (*sce)->set)) {
+            base= (Base *)(*sce)->base.first;
+            if(base) {
+                return base;
+            }
+        }
+    }
 
-       scene = G.main->scene.first;
-       while(scene) {
-               if (scene->r.dometext == txt)
-                       scene->r.dometext = NULL;
-               scene = scene->id.next;
-       }
+    return NULL;
 }