doxygen: blender/editors tagged.
[blender.git] / source / blender / editors / object / object_bake.c
index 9a9461da62e52443def258588af7cd12716e6c31..31ef6f55fddad3b6af4a5ac301811617cdc00619 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/editors/object/object_bake.c
+ *  \ingroup edobj
+ */
+
+
 /*
        meshtools.c: no editmode (violated already :), tools operating on meshes
 */
 
 #include "BLI_blenlib.h"
 #include "BLI_threads.h"
+#include "BLI_utildefines.h"
 
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
 #include "BKE_main.h"
-#include "BKE_object.h"
-#include "BKE_utildefines.h"
+#include "BKE_multires.h"
 #include "BKE_report.h"
 
 #include "RE_pipeline.h"
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "ED_object.h"
+
+#include "object_intern.h"
 
 /* ****************** render BAKING ********************** */
 
 /* threaded break test */
-static int thread_break(void *unused)
+static int thread_break(void *UNUSED(arg))
 {
        return G.afbreek;
 }
@@ -94,6 +102,7 @@ static ScrArea *biggest_image_area(bScreen *screen)
 
 typedef struct BakeRender {
        Render *re;
+       Main *main;
        Scene *scene;
        struct Object *actob;
        int tot, ready;
@@ -102,7 +111,8 @@ typedef struct BakeRender {
 
        short *stop;
        short *do_update;
-
+       float *progress;
+       
        ListBase threads;
 
        /* backup */
@@ -114,7 +124,7 @@ typedef struct BakeRender {
 } BakeRender;
 
 /* use by exec and invoke */
-int test_bake_internal(bContext *C, ReportList *reports)
+static int test_bake_internal(bContext *C, ReportList *reports)
 {
        Scene *scene= CTX_data_scene(C);
 
@@ -137,7 +147,14 @@ static void init_bake_internal(BakeRender *bkr, bContext *C)
 {
        Scene *scene= CTX_data_scene(C);
 
+       /* flush multires changes (for sculpt) */
+       multires_force_render_update(CTX_data_active_object(C));
+
+       /* get editmode results */
+       ED_object_exit_editmode(C, 0);  /* 0 = does not exit editmode */
+
        bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */
+       bkr->main= CTX_data_main(C);
        bkr->scene= scene;
        bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
        bkr->re= RE_NewRender("_Bake View_");
@@ -185,27 +202,29 @@ static void *do_bake_render(void *bake_v)
 {
        BakeRender *bkr= bake_v;
 
-       bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL);
+       bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress);
        bkr->ready= 1;
 
        return NULL;
 }
 
-static void bake_startjob(void *bkv, short *stop, short *do_update)
+static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress)
 {
        BakeRender *bkr= bkv;
        Scene *scene= bkr->scene;
+       Main *bmain= bkr->main;
 
        bkr->stop= stop;
        bkr->do_update= do_update;
+       bkr->progress= progress;
 
        RE_test_break_cb(bkr->re, NULL, thread_break);
        G.afbreek= 0;   /* blender_test_break uses this global */
 
-       RE_Database_Baking(bkr->re, scene, scene->lay, scene->r.bake_mode, bkr->actob);
+       RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob);
 
        /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
-       bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update);
+       bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress);
 }
 
 static void bake_update(void *bkv)
@@ -222,15 +241,15 @@ static void bake_update(void *bkv)
 static void bake_freejob(void *bkv)
 {
        BakeRender *bkr= bkv;
-       BLI_end_threads(&bkr->threads);
        finish_bake_internal(bkr);
 
-       if(bkr->tot==0) BKE_report(bkr->reports, RPT_ERROR, "No Images found to bake to");
+       if(bkr->tot==0) BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to");
        MEM_freeN(bkr);
+       G.rendering = 0;
 }
 
 /* catch esc */
-static int objects_bake_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
 {
        /* no running blender, remove handler and pass through */
        if(0==WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C)))
@@ -245,10 +264,14 @@ static int objects_bake_render_modal(bContext *C, wmOperator *op, wmEvent *event
        return OPERATOR_PASS_THROUGH;
 }
 
-static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *_event)
+static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event))
 {
        Scene *scene= CTX_data_scene(C);
 
+       /* only one render job at a time */
+       if(WM_jobs_test(CTX_wm_manager(C), scene))
+               return OPERATOR_CANCELLED;
+       
        if(test_bake_internal(C, op->reports)==0) {
                return OPERATOR_CANCELLED;
        }
@@ -260,12 +283,13 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *_eve
                bkr->reports= op->reports;
 
                /* setup job */
-               steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY);
+               steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
                WM_jobs_customdata(steve, bkr, bake_freejob);
                WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
                WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
 
                G.afbreek= 0;
+               G.rendering = 1;
 
                WM_jobs_start(CTX_wm_manager(C), steve);
 
@@ -282,6 +306,7 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *_eve
 
 static int bake_image_exec(bContext *C, wmOperator *op)
 {
+       Main *bmain= CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
 
 
@@ -290,9 +315,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
        }
        else {
                ListBase threads;
-               BakeRender bkr;
-
-               memset(&bkr, 0, sizeof(bkr));
+               BakeRender bkr= {0};
 
                init_bake_internal(&bkr, C);
                bkr.reports= op->reports;
@@ -300,7 +323,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
                RE_test_break_cb(bkr.re, NULL, thread_break);
                G.afbreek= 0;   /* blender_test_break uses this global */
 
-               RE_Database_Baking(bkr.re, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
+               RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
 
                /* baking itself is threaded, cannot use test_break in threads  */
                BLI_init_threads(&threads, do_bake_render, 1);
@@ -318,7 +341,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
                }
                BLI_end_threads(&threads);
 
-               if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No Images found to bake to");
+               if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
 
                finish_bake_internal(&bkr);
        }