Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/render/render_internal.c
| Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_blender_version.h" | #include "BKE_blender_version.h" | ||||
| #include "BKE_camera.h" | #include "BKE_camera.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_colortools.h" | #include "BKE_colortools.h" | ||||
| #include "BKE_depsgraph.h" | #include "BKE_depsgraph.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_localview.h" | |||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_sequencer.h" | #include "BKE_sequencer.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| Show All 26 Lines | |||||
| static int render_break(void *rjv); | static int render_break(void *rjv); | ||||
| typedef struct RenderJob { | typedef struct RenderJob { | ||||
| Main *main; | Main *main; | ||||
| Scene *scene; | Scene *scene; | ||||
| Scene *current_scene; | Scene *current_scene; | ||||
| Render *re; | Render *re; | ||||
| SceneRenderLayer *srl; | SceneRenderLayer *srl; | ||||
| LocalViewInfo *localview; | |||||
| struct Object *camera_override; | struct Object *camera_override; | ||||
| int lay_override; | int lay_override; | ||||
| bool v3d_override; | bool v3d_override; | ||||
| bool anim, write_still; | bool anim, write_still; | ||||
| Image *image; | Image *image; | ||||
| ImageUser iuser; | ImageUser iuser; | ||||
| bool image_outdated; | bool image_outdated; | ||||
| short *stop; | short *stop; | ||||
| ▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | |||||
| static int screen_render_exec(bContext *C, wmOperator *op) | static int screen_render_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| SceneRenderLayer *srl = NULL; | SceneRenderLayer *srl = NULL; | ||||
| Render *re; | Render *re; | ||||
| Image *ima; | Image *ima; | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| Main *mainp = CTX_data_main(C); | Main *mainp = CTX_data_main(C); | ||||
| unsigned int lay_override; | LocalViewInfo *localview = (v3d && v3d->localviewd) ? &v3d->localviewd->info : NULL; | ||||
| const unsigned int lay_override = (v3d && v3d->lay != scene->lay) ? v3d->lay : 0; | |||||
| const bool is_animation = RNA_boolean_get(op->ptr, "animation"); | const bool is_animation = RNA_boolean_get(op->ptr, "animation"); | ||||
| const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); | const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); | ||||
| struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; | struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; | ||||
| /* custom scene and single layer re-render */ | /* custom scene and single layer re-render */ | ||||
| screen_render_scene_layer_set(op, mainp, &scene, &srl); | screen_render_scene_layer_set(op, mainp, &scene, &srl); | ||||
| if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) { | if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) { | ||||
| BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected"); | BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| re = RE_NewRender(scene->id.name); | re = RE_NewRender(scene->id.name); | ||||
| lay_override = (v3d && v3d->lay != scene->lay) ? v3d->lay : 0; | |||||
| G.is_break = false; | G.is_break = false; | ||||
| RE_test_break_cb(re, NULL, render_break); | RE_test_break_cb(re, NULL, render_break); | ||||
| ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); | ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); | ||||
| BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); | BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); | ||||
| BKE_image_backup_render(scene, ima, true); | BKE_image_backup_render(scene, ima, true); | ||||
| /* cleanup sequencer caches before starting user triggered render. | /* cleanup sequencer caches before starting user triggered render. | ||||
| * otherwise, invalidated cache entries can make their way into | * otherwise, invalidated cache entries can make their way into | ||||
| * the output rendering. We can't put that into RE_BlenderFrame, | * the output rendering. We can't put that into RE_BlenderFrame, | ||||
| * since sequence rendering can call that recursively... (peter) */ | * since sequence rendering can call that recursively... (peter) */ | ||||
| BKE_sequencer_cache_cleanup(); | BKE_sequencer_cache_cleanup(); | ||||
| RE_SetReports(re, op->reports); | RE_SetReports(re, op->reports); | ||||
| BLI_begin_threaded_malloc(); | BLI_begin_threaded_malloc(); | ||||
| if (is_animation) | if (is_animation) | ||||
| RE_BlenderAnim(re, mainp, scene, camera_override, lay_override, scene->r.sfra, scene->r.efra, scene->r.frame_step); | RE_BlenderAnim(re, mainp, scene, localview, camera_override, lay_override, scene->r.sfra, scene->r.efra, scene->r.frame_step); | ||||
| else | else | ||||
| RE_BlenderFrame(re, mainp, scene, srl, camera_override, lay_override, scene->r.cfra, is_write_still); | RE_BlenderFrame(re, mainp, scene, srl, localview, camera_override, lay_override, scene->r.cfra, is_write_still); | ||||
| BLI_end_threaded_malloc(); | BLI_end_threaded_malloc(); | ||||
| RE_SetReports(re, NULL); | RE_SetReports(re, NULL); | ||||
| // no redraw needed, we leave state as we entered it | // no redraw needed, we leave state as we entered it | ||||
| ED_update_for_newframe(mainp, scene, 1); | ED_update_for_newframe(mainp, scene, 1); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); | WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); | ||||
| ▲ Show 20 Lines • Show All 256 Lines • ▼ Show 20 Lines | static void render_startjob(void *rjv, short *stop, short *do_update, float *progress) | ||||
| rj->stop = stop; | rj->stop = stop; | ||||
| rj->do_update = do_update; | rj->do_update = do_update; | ||||
| rj->progress = progress; | rj->progress = progress; | ||||
| RE_SetReports(rj->re, rj->reports); | RE_SetReports(rj->re, rj->reports); | ||||
| if (rj->anim) | if (rj->anim) | ||||
| RE_BlenderAnim(rj->re, rj->main, rj->scene, rj->camera_override, rj->lay_override, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step); | RE_BlenderAnim(rj->re, rj->main, rj->scene, rj->localview, rj->camera_override, rj->lay_override, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step); | ||||
| else | else | ||||
| RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->srl, rj->camera_override, rj->lay_override, rj->scene->r.cfra, rj->write_still); | RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->srl, rj->localview, rj->camera_override, rj->lay_override, rj->scene->r.cfra, rj->write_still); | ||||
| RE_SetReports(rj->re, NULL); | RE_SetReports(rj->re, NULL); | ||||
| } | } | ||||
| static void render_image_restore_layer(RenderJob *rj) | static void render_image_restore_layer(RenderJob *rj) | ||||
| { | { | ||||
| wmWindowManager *wm; | wmWindowManager *wm; | ||||
| ▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| Scene *scene = (Scene *) op->customdata; | Scene *scene = (Scene *) op->customdata; | ||||
| /* kill on cancel, because job is using op->reports */ | /* kill on cancel, because job is using op->reports */ | ||||
| WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER); | WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER); | ||||
| } | } | ||||
| static void clean_viewport_memory(Main *bmain, Scene *scene, int renderlay) | static void clean_viewport_memory(Main *bmain, Scene *scene, LocalViewInfo *localview, int renderlay) | ||||
| { | { | ||||
| Object *object; | Object *object; | ||||
| Scene *sce_iter; | Scene *sce_iter; | ||||
| Base *base; | Base *base; | ||||
| for (object = bmain->object.first; object; object = object->id.next) { | for (object = bmain->object.first; object; object = object->id.next) { | ||||
| object->id.tag |= LIB_TAG_DOIT; | object->id.tag |= LIB_TAG_DOIT; | ||||
| } | } | ||||
| for (SETLOOPER(scene, sce_iter, base)) { | for (SETLOOPER(scene, sce_iter, base)) { | ||||
| if ((base->lay & renderlay) == 0) { | if ((base->lay & renderlay) == 0 || BKE_localview_info_cmp(*localview, base->object->localview) == 0) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (RE_allow_render_generic_object(base->object)) { | if (RE_allow_render_generic_object(base->object)) { | ||||
| base->object->id.tag &= ~LIB_TAG_DOIT; | base->object->id.tag &= ~LIB_TAG_DOIT; | ||||
| } | } | ||||
| } | } | ||||
| for (SETLOOPER(scene, sce_iter, base)) { | for (SETLOOPER(scene, sce_iter, base)) { | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | if (RNA_struct_property_is_set(op->ptr, "layer")) | ||||
| jobflag |= WM_JOB_SUSPEND; | jobflag |= WM_JOB_SUSPEND; | ||||
| /* job custom data */ | /* job custom data */ | ||||
| rj = MEM_callocN(sizeof(RenderJob), "render job"); | rj = MEM_callocN(sizeof(RenderJob), "render job"); | ||||
| rj->main = mainp; | rj->main = mainp; | ||||
| rj->scene = scene; | rj->scene = scene; | ||||
| rj->current_scene = rj->scene; | rj->current_scene = rj->scene; | ||||
| rj->srl = srl; | rj->srl = srl; | ||||
| rj->localview = NULL; | |||||
| rj->camera_override = camera_override; | rj->camera_override = camera_override; | ||||
| rj->lay_override = 0; | rj->lay_override = 0; | ||||
| rj->anim = is_animation; | rj->anim = is_animation; | ||||
| rj->write_still = is_write_still && !is_animation; | rj->write_still = is_write_still && !is_animation; | ||||
| rj->iuser.scene = scene; | rj->iuser.scene = scene; | ||||
| rj->iuser.ok = 1; | rj->iuser.ok = 1; | ||||
| rj->reports = op->reports; | rj->reports = op->reports; | ||||
| rj->orig_layer = 0; | rj->orig_layer = 0; | ||||
| Show All 11 Lines | static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| if (v3d) { | if (v3d) { | ||||
| if (scene->lay != v3d->lay) { | if (scene->lay != v3d->lay) { | ||||
| rj->lay_override = v3d->lay; | rj->lay_override = v3d->lay; | ||||
| rj->v3d_override = true; | rj->v3d_override = true; | ||||
| } | } | ||||
| else if (camera_override && camera_override != scene->camera) | else if (camera_override && camera_override != scene->camera) | ||||
| rj->v3d_override = true; | rj->v3d_override = true; | ||||
| if (v3d->localvd) | if (v3d->localviewd) | ||||
| rj->lay_override |= v3d->localvd->lay; | rj->localview = &v3d->localviewd->info; | ||||
| } | } | ||||
| /* Lock the user interface depending on render settings. */ | /* Lock the user interface depending on render settings. */ | ||||
| if (scene->r.use_lock_interface) { | if (scene->r.use_lock_interface) { | ||||
| int renderlay = rj->lay_override ? rj->lay_override : scene->lay; | int renderlay = rj->lay_override ? rj->lay_override : scene->lay; | ||||
| WM_set_locked_interface(CTX_wm_manager(C), true); | WM_set_locked_interface(CTX_wm_manager(C), true); | ||||
| /* Set flag interface need to be unlocked. | /* Set flag interface need to be unlocked. | ||||
| * | * | ||||
| * This is so because we don't have copy of render settings | * This is so because we don't have copy of render settings | ||||
| * accessible from render job and copy is needed in case | * accessible from render job and copy is needed in case | ||||
| * of non-locked rendering, so we wouldn't try to unlock | * of non-locked rendering, so we wouldn't try to unlock | ||||
| * anything if option was initially unset but then was | * anything if option was initially unset but then was | ||||
| * enabled during rendering. | * enabled during rendering. | ||||
| */ | */ | ||||
| rj->interface_locked = true; | rj->interface_locked = true; | ||||
| /* Clean memory used by viewport? */ | /* Clean memory used by viewport? */ | ||||
| clean_viewport_memory(rj->main, scene, renderlay); | clean_viewport_memory(rj->main, scene, &v3d->localviewd->info, renderlay); | ||||
| } | } | ||||
| /* setup job */ | /* setup job */ | ||||
| if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render"; | if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render"; | ||||
| else name = "Render"; | else name = "Render"; | ||||
| wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, name, jobflag, WM_JOB_TYPE_RENDER); | wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, name, jobflag, WM_JOB_TYPE_RENDER); | ||||
| WM_jobs_customdata_set(wm_job, rj, render_freejob); | WM_jobs_customdata_set(wm_job, rj, render_freejob); | ||||
| ▲ Show 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress)) | ||||
| if (orth) | if (orth) | ||||
| RE_SetOrtho(re, &viewplane, clipsta, clipend); | RE_SetOrtho(re, &viewplane, clipsta, clipend); | ||||
| else | else | ||||
| RE_SetWindow(re, &viewplane, clipsta, clipend); | RE_SetWindow(re, &viewplane, clipsta, clipend); | ||||
| RE_SetPixelSize(re, pixsize); | RE_SetPixelSize(re, pixsize); | ||||
| if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) { | if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) { | ||||
| unsigned int lay = rp->scene->lay; | |||||
| /* allow localview render for objects with lights in normal layers */ | |||||
| if (rp->v3d->lay & 0xFF000000) | |||||
| lay |= rp->v3d->lay; | |||||
| else lay = rp->v3d->lay; | |||||
| RE_SetView(re, rp->viewmat); | RE_SetView(re, rp->viewmat); | ||||
| /* copying blender data while main thread is locked, to avoid crashes */ | /* copying blender data while main thread is locked, to avoid crashes */ | ||||
| WM_job_main_thread_lock_acquire(rp->job); | WM_job_main_thread_lock_acquire(rp->job); | ||||
| RE_Database_Free(re); | RE_Database_Free(re); | ||||
| RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view | RE_Database_FromScene(re, rp->bmain, rp->scene, rp->v3d->lay, 0); // 0= dont use camera view | ||||
| WM_job_main_thread_lock_release(rp->job); | WM_job_main_thread_lock_release(rp->job); | ||||
| /* do preprocessing like building raytree, shadows, volumes, SSS */ | /* do preprocessing like building raytree, shadows, volumes, SSS */ | ||||
| RE_Database_Preprocess(re); | RE_Database_Preprocess(re); | ||||
| /* conversion not completed, need to do it again */ | /* conversion not completed, need to do it again */ | ||||
| if (!rstats->convertdone) { | if (!rstats->convertdone) { | ||||
| if (render_view3d_is_valid(rp)) { | if (render_view3d_is_valid(rp)) { | ||||
| ▲ Show 20 Lines • Show All 407 Lines • Show Last 20 Lines | |||||