Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/render/render_internal.c')
-rw-r--r--source/blender/editors/render/render_internal.c137
1 files changed, 102 insertions, 35 deletions
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 083202e5a03..341f56667fa 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -34,6 +34,7 @@
#include "BLI_math.h"
#include "BLI_threads.h"
#include "BLI_rand.h"
+#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
@@ -43,6 +44,7 @@
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_node.h"
#include "BKE_multires.h"
#include "BKE_report.h"
#include "BKE_sequencer.h"
@@ -347,6 +349,8 @@ static ScrArea *find_area_showing_r_result(bContext *C)
break;
}
}
+ if(sa)
+ break;
}
return sa;
@@ -388,7 +392,7 @@ static ScrArea *find_empty_image_area(bContext *C)
}
#endif // XXX not used
-static void render_error_reports(void *reports, char *str)
+static void render_error_reports(void *reports, const char *str)
{
BKE_report(reports, RPT_ERROR, str);
}
@@ -401,7 +405,14 @@ static int screen_render_exec(bContext *C, wmOperator *op)
Image *ima;
View3D *v3d= CTX_wm_view3d(C);
Main *mainp= CTX_data_main(C);
- int lay= (v3d)? v3d->lay: scene->lay;
+ unsigned int lay= (v3d)? v3d->lay: scene->lay;
+ const short is_animation= RNA_boolean_get(op->ptr, "animation");
+ const short is_write_still= RNA_boolean_get(op->ptr, "write_still");
+
+ if(!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.imtype)) {
+ BKE_report(op->reports, RPT_ERROR, "Can't write a single file with an animation format selected.");
+ return OPERATOR_CANCELLED;
+ }
if(re==NULL) {
re= RE_NewRender(scene->id.name);
@@ -421,13 +432,13 @@ static int screen_render_exec(bContext *C, wmOperator *op)
since sequence rendering can call that recursively... (peter) */
seq_stripelem_cache_cleanup();
- if(RNA_boolean_get(op->ptr, "animation"))
+ if(is_animation)
RE_BlenderAnim(re, mainp, scene, lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports);
else
- RE_BlenderFrame(re, mainp, scene, NULL, lay, scene->r.cfra);
+ RE_BlenderFrame(re, mainp, scene, NULL, lay, scene->r.cfra, is_write_still);
// no redraw needed, we leave state as we entered it
- ED_update_for_newframe(C, 1);
+ ED_update_for_newframe(mainp, scene, CTX_wm_screen(C), 1);
WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
@@ -441,7 +452,7 @@ typedef struct RenderJob {
wmWindow *win;
SceneRenderLayer *srl;
int lay;
- int anim;
+ short anim, write_still;
Image *image;
ImageUser iuser;
short *stop;
@@ -568,16 +579,35 @@ static void render_startjob(void *rjv, short *stop, short *do_update, float *pro
if(rj->anim)
RE_BlenderAnim(rj->re, rj->main, rj->scene, rj->lay, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step, rj->reports);
else
- RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->srl, rj->lay, rj->scene->r.cfra);
+ RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->srl, rj->lay, rj->scene->r.cfra, rj->write_still);
}
static void render_endjob(void *rjv)
{
- RenderJob *rj= rjv;
+ RenderJob *rj= rjv;
+
+ /* this render may be used again by the sequencer without the active 'Render' where the callbacks
+ * would be re-assigned. assign dummy callbacks to avoid referencing freed renderjobs bug [#24508] */
+ RE_InitRenderCB(rj->re);
if(rj->main != G.main)
free_main(rj->main);
+ /* else the frame will not update for the original value */
+ if(!(rj->scene->r.scemode & R_NO_FRAME_UPDATE))
+ ED_update_for_newframe(G.main, rj->scene, rj->win->screen, 1);
+
+ /* XXX above function sets all tags in nodes */
+ ntreeClearTags(rj->scene->nodetree);
+
+ /* potentially set by caller */
+ rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
+
+ if(rj->srl) {
+ NodeTagIDChanged(rj->scene->nodetree, &rj->scene->id);
+ WM_main_add_notifier(NC_NODE|NA_EDITED, rj->scene);
+ }
+
/* XXX render stability hack */
G.rendering = 0;
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -596,7 +626,7 @@ static int render_breakjob(void *rjv)
}
/* catch esc */
-static int screen_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_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))) {
@@ -625,11 +655,23 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
wmJob *steve;
RenderJob *rj;
Image *ima;
-
+ int jobflag;
+ const short is_animation= RNA_boolean_get(op->ptr, "animation");
+ const short is_write_still= RNA_boolean_get(op->ptr, "write_still");
+
/* only one render job at a time */
if(WM_jobs_test(CTX_wm_manager(C), scene))
return OPERATOR_CANCELLED;
+ if(!RE_is_rendering_allowed(scene, op->reports, render_error_reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if(!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.imtype)) {
+ BKE_report(op->reports, RPT_ERROR, "Can't write a single file with an animation format selected.");
+ return OPERATOR_CANCELLED;
+ }
+
/* stop all running jobs, currently previews frustrate Render */
WM_jobs_stop_all(CTX_wm_manager(C));
@@ -667,6 +709,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* ensure at least 1 area shows result */
screen_set_image_output(C, event->x, event->y);
+ jobflag= WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS;
+
/* single layer re-render */
if(RNA_property_is_set(op->ptr, "layer")) {
SceneRenderLayer *rl;
@@ -678,11 +722,12 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
scn = (Scene *)BLI_findstring(&mainp->scene, scene_name, offsetof(ID, name) + 2);
rl = (SceneRenderLayer *)BLI_findstring(&scene->r.layers, rl_name, offsetof(SceneRenderLayer, name));
-
+
if (scn && rl) {
scene = scn;
srl = rl;
}
+ jobflag |= WM_JOB_SUSPEND;
}
/* job custom data */
@@ -692,13 +737,14 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
rj->win= CTX_wm_window(C);
rj->srl = srl;
rj->lay = (v3d)? v3d->lay: scene->lay;
- rj->anim= RNA_boolean_get(op->ptr, "animation");
+ rj->anim= is_animation;
+ rj->write_still= is_write_still && !is_animation;
rj->iuser.scene= scene;
rj->iuser.ok= 1;
rj->reports= op->reports;
/* setup job */
- steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Render", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Render", jobflag);
WM_jobs_customdata(steve, rj, render_freejob);
WM_jobs_timer(steve, 0.2, NC_SCENE|ND_RENDER_RESULT, 0);
WM_jobs_callbacks(steve, render_startjob, NULL, NULL, render_endjob);
@@ -753,7 +799,8 @@ void RENDER_OT_render(wmOperatorType *ot)
ot->poll= ED_operator_screenactive;
- RNA_def_boolean(ot->srna, "animation", 0, "Animation", "");
+ RNA_def_boolean(ot->srna, "animation", 0, "Animation", "Render files from the animation range of this scene");
+ RNA_def_boolean(ot->srna, "write_still", 0, "Write Image", "Save rendered the image to the output path (used only when animation is disabled)");
RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render");
RNA_def_string(ot->srna, "scene", "", 19, "Scene", "Re-render single layer in this scene");
}
@@ -763,14 +810,14 @@ void RENDER_OT_render(wmOperatorType *ot)
/* *********************** cancel render viewer *************** */
-static int render_view_cancel_exec(bContext *C, wmOperator *unused)
+static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
{
wmWindow *win= CTX_wm_window(C);
ScrArea *sa= CTX_wm_area(C);
SpaceImage *sima= sa->spacedata.first;
/* test if we have a temp screen in front */
- if(CTX_wm_window(C)->screen->full==SCREENTEMP) {
+ if(CTX_wm_window(C)->screen->temp) {
wm_window_lower(CTX_wm_window(C));
return OPERATOR_FINISHED;
}
@@ -810,33 +857,53 @@ void RENDER_OT_view_cancel(struct wmOperatorType *ot)
/* *********************** show render viewer *************** */
-static int render_view_show_invoke(bContext *C, wmOperator *unused, wmEvent *event)
+static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(unused), wmEvent *event)
{
ScrArea *sa= find_area_showing_r_result(C);
- /* test if we have a temp screen in front */
- if(CTX_wm_window(C)->screen->full==SCREENTEMP) {
+ /* test if we have a temp screen active */
+ if(CTX_wm_window(C)->screen->temp) {
wm_window_lower(CTX_wm_window(C));
}
- /* determine if render already shows */
- else if(sa) {
- SpaceImage *sima= sa->spacedata.first;
-
- if(sima->flag & SI_PREVSPACE) {
- sima->flag &= ~SI_PREVSPACE;
-
- if(sima->flag & SI_FULLWINDOW) {
- sima->flag &= ~SI_FULLWINDOW;
- ED_screen_full_prevspace(C, sa);
+ else {
+ /* is there another window? */
+ wmWindow *win;
+
+ for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) {
+ if(win->screen->temp) {
+ wm_window_raise(win);
+ return OPERATOR_FINISHED;
}
- else if(sima->next) {
- ED_area_newspace(C, sa, sima->next->spacetype);
- ED_area_tag_redraw(sa);
+ }
+
+ /* determine if render already shows */
+ if(sa) {
+ /* but don't close it when rendering */
+ if(!G.rendering) {
+ SpaceImage *sima= sa->spacedata.first;
+
+ if(sima->flag & SI_PREVSPACE) {
+ sima->flag &= ~SI_PREVSPACE;
+
+ if(sima->flag & SI_FULLWINDOW) {
+ sima->flag &= ~SI_FULLWINDOW;
+ ED_screen_full_prevspace(C, sa);
+ }
+ else if(sima->next) {
+ /* workaround for case of double prevspace, render window
+ with a file browser on top of it (same as in ED_area_prevspace) */
+ if(sima->next->spacetype == SPACE_FILE && sima->next->next)
+ ED_area_newspace(C, sa, sima->next->next->spacetype);
+ else
+ ED_area_newspace(C, sa, sima->next->spacetype);
+ ED_area_tag_redraw(sa);
+ }
+ }
}
}
- }
- else {
- screen_set_image_output(C, event->x, event->y);
+ else {
+ screen_set_image_output(C, event->x, event->y);
+ }
}
return OPERATOR_FINISHED;