Color Management, Stage 2: Switch color pipeline to use OpenColorIO
[blender.git] / source / blender / blenkernel / intern / scene.c
index ca5ebdc3ee31c530b86766ee2524bc9ee9041e28..2dec72560a228f0d69bbbb539ce00b34cf8a9450 100644 (file)
@@ -57,6 +57,7 @@
 
 #include "BKE_anim.h"
 #include "BKE_animsys.h"
+#include "BKE_colortools.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_group.h"
@@ -76,6 +77,8 @@
 
 #include "RE_engine.h"
 
+#include "IMB_colormanagement.h"
+
 //XXX #include "BIF_previewrender.h"
 //XXX #include "BIF_editseq.h"
 
@@ -132,6 +135,8 @@ Scene *BKE_scene_copy(Scene *sce, int type)
                MEM_freeN(scen->toolsettings);
        }
        else {
+               ImageFormatData *im_format, *im_formatn;
+
                scen = BKE_libblock_copy(&sce->id);
                BLI_duplicatelist(&(scen->base), &(sce->base));
                
@@ -153,7 +158,8 @@ Scene *BKE_scene_copy(Scene *sce, int type)
                BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
 
                if (sce->nodetree) {
-                       scen->nodetree = ntreeCopyTree(sce->nodetree); /* copies actions */
+                       /* ID's are managed on both copy and switch */
+                       scen->nodetree = ntreeCopyTree(sce->nodetree);
                        ntreeSwitchID(scen->nodetree, &sce->id, &scen->id);
                }
 
@@ -166,6 +172,13 @@ Scene *BKE_scene_copy(Scene *sce, int type)
                        obase = obase->next;
                        base = base->next;
                }
+
+               /* copy color management settings */
+               im_format = &sce->r.im_format;
+               im_formatn = &scen->r.im_format;
+
+               BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings);
+               BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings);
        }
 
        /* tool settings */
@@ -178,21 +191,21 @@ Scene *BKE_scene_copy(Scene *sce, int type)
                        ts->vpaint->paintcursor = NULL;
                        ts->vpaint->vpaint_prev = NULL;
                        ts->vpaint->wpaint_prev = NULL;
-                       copy_paint(&ts->vpaint->paint, &ts->vpaint->paint);
+                       BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint);
                }
                if (ts->wpaint) {
                        ts->wpaint = MEM_dupallocN(ts->wpaint);
                        ts->wpaint->paintcursor = NULL;
                        ts->wpaint->vpaint_prev = NULL;
                        ts->wpaint->wpaint_prev = NULL;
-                       copy_paint(&ts->wpaint->paint, &ts->wpaint->paint);
+                       BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint);
                }
                if (ts->sculpt) {
                        ts->sculpt = MEM_dupallocN(ts->sculpt);
-                       copy_paint(&ts->sculpt->paint, &ts->sculpt->paint);
+                       BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint);
                }
 
-               copy_paint(&ts->imapaint.paint, &ts->imapaint.paint);
+               BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint);
                ts->imapaint.paintcursor = NULL;
                ts->particle.paintcursor = NULL;
        }
@@ -237,7 +250,7 @@ Scene *BKE_scene_copy(Scene *sce, int type)
                if (sce->ed) {
                        scen->ed = MEM_callocN(sizeof(Editing), "addseq");
                        scen->ed->seqbasep = &scen->ed->seqbase;
-                       seqbase_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
+                       BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
                }
        }
 
@@ -257,17 +270,17 @@ void BKE_scene_free(Scene *sce)
        /* 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 freed 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.
+#if 0   /* removed since this can be invalid memory when freeing everything */
+               /* since the grease pencil data is freed 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);
+       BKE_sequencer_editing_free(sce);
 
        BKE_free_animdata((ID *)sce);
        BKE_keyingsets_free(&sce->keyingsets);
@@ -294,22 +307,22 @@ void BKE_scene_free(Scene *sce)
        
        if (sce->toolsettings) {
                if (sce->toolsettings->vpaint) {
-                       free_paint(&sce->toolsettings->vpaint->paint);
+                       BKE_paint_free(&sce->toolsettings->vpaint->paint);
                        MEM_freeN(sce->toolsettings->vpaint);
                }
                if (sce->toolsettings->wpaint) {
-                       free_paint(&sce->toolsettings->wpaint->paint);
+                       BKE_paint_free(&sce->toolsettings->wpaint->paint);
                        MEM_freeN(sce->toolsettings->wpaint);
                }
                if (sce->toolsettings->sculpt) {
-                       free_paint(&sce->toolsettings->sculpt->paint);
+                       BKE_paint_free(&sce->toolsettings->sculpt->paint);
                        MEM_freeN(sce->toolsettings->sculpt);
                }
                if (sce->toolsettings->uvsculpt) {
-                       free_paint(&sce->toolsettings->uvsculpt->paint);
+                       BKE_paint_free(&sce->toolsettings->uvsculpt->paint);
                        MEM_freeN(sce->toolsettings->uvsculpt);
                }
-               free_paint(&sce->toolsettings->imapaint.paint);
+               BKE_paint_free(&sce->toolsettings->imapaint.paint);
 
                MEM_freeN(sce->toolsettings);
                sce->toolsettings = NULL;       
@@ -331,6 +344,8 @@ void BKE_scene_free(Scene *sce)
                MEM_freeN(sce->fps_info);
 
        sound_destroy_scene(sce);
+
+       BKE_color_managed_view_settings_free(&sce->view_settings);
 }
 
 Scene *BKE_scene_add(const char *name)
@@ -371,7 +386,14 @@ Scene *BKE_scene_add(const char *name)
        sce->r.frs_sec_base = 1;
        sce->r.edgeint = 10;
        sce->r.ocres = 128;
+
+       /* OCIO_TODO: for forwards compatibiliy only, so if no tonecurve are used,
+        *            images would look in the same way as in current blender
+        *
+        *            perhaps at some point should be completely deprecated?
+        */
        sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT;
+
        sce->r.gauss = 1.0;
        
        /* deprecated but keep for upwards compat */
@@ -487,7 +509,7 @@ Scene *BKE_scene_add(const char *name)
 
        BLI_strncpy(sce->r.pic, U.renderdir, sizeof(sce->r.pic));
 
-       BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f);
+       BLI_rctf_init(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f);
        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 */
@@ -517,6 +539,9 @@ Scene *BKE_scene_add(const char *name)
        sce->gm.maxlogicstep = 5;
        sce->gm.physubstep = 1;
        sce->gm.maxphystep = 5;
+       sce->gm.lineardeactthreshold = 0.8f;
+       sce->gm.angulardeactthreshold = 1.0f;
+       sce->gm.deactivationtime = 0.0f;
 
        sce->gm.flag = GAME_DISPLAY_LISTS;
        sce->gm.matmode = GAME_MAT_MULTITEX;
@@ -542,19 +567,15 @@ Scene *BKE_scene_add(const char *name)
 
        sound_create_scene(sce);
 
+       BKE_color_managed_display_settings_init(&sce->display_settings);
+       BKE_color_managed_view_settings_init(&sce->view_settings);
+
        return sce;
 }
 
 Base *BKE_scene_base_find(Scene *scene, Object *ob)
 {
-       Base *base;
-       
-       base = scene->base.first;
-       while (base) {
-               if (base->object == ob) return base;
-               base = base->next;
-       }
-       return NULL;
+       return BLI_findptr(&scene->base, ob, offsetof(Base, object));
 }
 
 void BKE_scene_set_background(Main *bmain, Scene *scene)
@@ -579,10 +600,10 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
 
        /* group flags again */
        for (group = bmain->group.first; group; group = group->id.next) {
-               go = group->gobject.first;
-               while (go) {
-                       if (go->ob) go->ob->flag |= OB_FROMGROUP;
-                       go = go->next;
+               for (go = group->gobject.first; go; go = go->next) {
+                       if (go->ob) {
+                               go->ob->flag |= OB_FROMGROUP;
+                       }
                }
        }
 
@@ -605,10 +626,8 @@ void BKE_scene_set_background(Main *bmain, 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) */
 }
@@ -638,7 +657,7 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
                        sce1->set = NULL;
        
        /* check all sequences */
-       clear_scene_in_allseqs(bmain, sce);
+       BKE_sequencer_clear_scene_in_allseqs(bmain, sce);
 
        /* check render layer nodes in other scenes */
        clear_scene_in_nodes(bmain, sce);
@@ -951,9 +970,9 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
        if (scene->adt && scene->adt->drivers.first) {
                BKE_animsys_evaluate_animdata(scene, &scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS);
        }
-       
+
        /* world */
-       // TODO: what about world textures? but then those have nodes too...
+       /* TODO: what about world textures? but then those have nodes too... */
        if (scene->world) {
                ID *wid = (ID *)scene->world;
                AnimData *adt = BKE_animdata_from_id(wid);
@@ -1004,7 +1023,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
        sound_update_scene(scene);
 
        /* update masking curves */
-       BKE_mask_update_scene(bmain, scene);
+       BKE_mask_update_scene(bmain, scene, FALSE);
 }
 
 /* this is called in main loop, doing tagged updates before redraw */
@@ -1017,6 +1036,11 @@ void BKE_scene_update_tagged(Main *bmain, Scene *scene)
        DAG_ids_flush_tagged(bmain);
 
        scene->physics_settings.quick_cache_step = 0;
+       
+       /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later 
+        * when trying to find materials with drivers that need evaluating [#32017] 
+        */
+       tag_main_idcode(bmain, ID_MA, FALSE);
 
        /* update all objects: drivers, matrices, displists, etc. flags set
         * by depgraph or manual, no layer check here, gets correct flushed
@@ -1059,7 +1083,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
        sound_set_cfra(sce->r.cfra);
        
        /* clear animation overrides */
-       // XXX TODO...
+       /* XXX TODO... */
 
        for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set) {
                if (sce_iter->theDag == NULL)
@@ -1075,7 +1099,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
         * so don't call within 'scene_update_tagged_recursive' */
        DAG_scene_update_flags(bmain, sce, lay, TRUE);   // only stuff that moves or needs display still
 
-       BKE_mask_evaluate_all_masks(bmain, ctime);
+       BKE_mask_evaluate_all_masks(bmain, ctime, TRUE);
 
        /* All 'standard' (i.e. without any dependencies) animation is handled here,
         * with an 'local' to 'macro' order of evaluation. This should ensure that
@@ -1240,3 +1264,19 @@ void BKE_scene_base_flag_from_objects(struct Scene *scene)
                base = base->next;
        }
 }
+
+void BKE_scene_disable_color_management(Scene *scene)
+{
+       ColorManagedDisplaySettings *display_settings = &scene->display_settings;
+       ColorManagedViewSettings *view_settings = &scene->view_settings;
+       const char *view;
+
+       /* NOTE: None display with Default view should always exist in OCIO configuration, otherwise it wouldn't work as expected */
+       BLI_strncpy(display_settings->display_device, "None", sizeof(display_settings->display_device));
+
+       view = IMB_colormanagement_view_get_default_name(display_settings->display_device);
+
+       if (view) {
+               BLI_strncpy(view_settings->view_transform, view, sizeof(view_settings->view_transform));
+       }
+}