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')
-rw-r--r--source/blender/editors/render/CMakeLists.txt62
-rw-r--r--source/blender/editors/render/render_intern.h2
-rw-r--r--source/blender/editors/render/render_internal.c1792
-rw-r--r--source/blender/editors/render/render_opengl.c1879
-rw-r--r--source/blender/editors/render/render_ops.c92
-rw-r--r--source/blender/editors/render/render_preview.c2221
-rw-r--r--source/blender/editors/render/render_shading.c2551
-rw-r--r--source/blender/editors/render/render_update.c387
-rw-r--r--source/blender/editors/render/render_view.c521
9 files changed, 4848 insertions, 4659 deletions
diff --git a/source/blender/editors/render/CMakeLists.txt b/source/blender/editors/render/CMakeLists.txt
index dee56d7f2fa..5d414c3af0f 100644
--- a/source/blender/editors/render/CMakeLists.txt
+++ b/source/blender/editors/render/CMakeLists.txt
@@ -16,58 +16,58 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenkernel
- ../../blenlib
- ../../blenloader
- ../../blentranslation
- ../../depsgraph
- ../../draw
- ../../gpu
- ../../imbuf
- ../../bmesh
- ../../makesdna
- ../../makesrna
- ../../render/extern/include
- ../../windowmanager
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
+ ../include
+ ../../blenkernel
+ ../../blenlib
+ ../../blenloader
+ ../../blentranslation
+ ../../depsgraph
+ ../../draw
+ ../../gpu
+ ../../imbuf
+ ../../bmesh
+ ../../makesdna
+ ../../makesrna
+ ../../render/extern/include
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- render_internal.c
- render_opengl.c
- render_ops.c
- render_preview.c
- render_shading.c
- render_update.c
- render_view.c
+ render_internal.c
+ render_opengl.c
+ render_ops.c
+ render_preview.c
+ render_shading.c
+ render_update.c
+ render_view.c
- render_intern.h
+ render_intern.h
)
set(LIB
)
if(WITH_HEADLESS)
- add_definitions(-DWITH_HEADLESS)
+ add_definitions(-DWITH_HEADLESS)
endif()
add_definitions(${GL_DEFINITIONS})
if(WITH_FREESTYLE)
- list(APPEND INC
- ../../freestyle
- )
- add_definitions(-DWITH_FREESTYLE)
+ list(APPEND INC
+ ../../freestyle
+ )
+ add_definitions(-DWITH_FREESTYLE)
endif()
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
blender_add_lib(bf_editor_render "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index 88f6df50420..1e03d986e3e 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -21,7 +21,6 @@
* \ingroup edrend
*/
-
#ifndef __RENDER_INTERN_H__
#define __RENDER_INTERN_H__
@@ -75,7 +74,6 @@ void SCENE_OT_freestyle_modifier_copy(struct wmOperatorType *ot);
void SCENE_OT_freestyle_stroke_material_create(struct wmOperatorType *ot);
#endif
-
void TEXTURE_OT_slot_copy(struct wmOperatorType *ot);
void TEXTURE_OT_slot_paste(struct wmOperatorType *ot);
void TEXTURE_OT_slot_move(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index b5546bd7b90..6df1ba5e0aa 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -21,7 +21,6 @@
* \ingroup edrend
*/
-
#include <math.h>
#include <string.h>
#include <stddef.h>
@@ -92,160 +91,175 @@
static int render_break(void *rjv);
typedef struct RenderJob {
- Main *main;
- Scene *scene;
- ViewLayer *single_layer;
- Scene *current_scene;
- /* TODO(sergey): Should not be needed once engine will have own
- * depsgraph and copy-on-write will be implemented.
- */
- Depsgraph *depsgraph;
- Render *re;
- struct Object *camera_override;
- bool v3d_override;
- bool anim, write_still;
- Image *image;
- ImageUser iuser;
- bool image_outdated;
- short *stop;
- short *do_update;
- float *progress;
- ReportList *reports;
- int orig_layer;
- int last_layer;
- ScrArea *sa;
- ColorManagedViewSettings view_settings;
- ColorManagedDisplaySettings display_settings;
- bool supports_glsl_draw;
- bool interface_locked;
+ Main *main;
+ Scene *scene;
+ ViewLayer *single_layer;
+ Scene *current_scene;
+ /* TODO(sergey): Should not be needed once engine will have own
+ * depsgraph and copy-on-write will be implemented.
+ */
+ Depsgraph *depsgraph;
+ Render *re;
+ struct Object *camera_override;
+ bool v3d_override;
+ bool anim, write_still;
+ Image *image;
+ ImageUser iuser;
+ bool image_outdated;
+ short *stop;
+ short *do_update;
+ float *progress;
+ ReportList *reports;
+ int orig_layer;
+ int last_layer;
+ ScrArea *sa;
+ ColorManagedViewSettings view_settings;
+ ColorManagedDisplaySettings display_settings;
+ bool supports_glsl_draw;
+ bool interface_locked;
} RenderJob;
/* called inside thread! */
-static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect, const char *viewname)
+static void image_buffer_rect_update(RenderJob *rj,
+ RenderResult *rr,
+ ImBuf *ibuf,
+ ImageUser *iuser,
+ volatile rcti *renrect,
+ const char *viewname)
{
- Scene *scene = rj->scene;
- const float *rectf = NULL;
- int ymin, ymax, xmin, xmax;
- int rymin, rxmin;
- int linear_stride, linear_offset_x, linear_offset_y;
- ColorManagedViewSettings *view_settings;
- ColorManagedDisplaySettings *display_settings;
-
- /* Exception for exr tiles -- display buffer conversion happens here,
- * NOT in the color management pipeline.
- */
- if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID &&
- rr->do_exr_tile == false)
- {
- /* The whole image buffer it so be color managed again anyway. */
- return;
- }
-
- /* if renrect argument, we only refresh scanlines */
- if (renrect) {
- /* if (ymax == recty), rendering of layer is ready,
- * we should not draw, other things happen... */
- if (rr->renlay == NULL || renrect->ymax >= rr->recty)
- return;
-
- /* xmin here is first subrect x coord, xmax defines subrect width */
- xmin = renrect->xmin + rr->crop;
- xmax = renrect->xmax - xmin + rr->crop;
- if (xmax < 2)
- return;
-
- ymin = renrect->ymin + rr->crop;
- ymax = renrect->ymax - ymin + rr->crop;
- if (ymax < 2)
- return;
- renrect->ymin = renrect->ymax;
-
- }
- else {
- xmin = ymin = rr->crop;
- xmax = rr->rectx - 2 * rr->crop;
- ymax = rr->recty - 2 * rr->crop;
- }
-
- /* xmin ymin is in tile coords. transform to ibuf */
- rxmin = rr->tilerect.xmin + xmin;
- if (rxmin >= ibuf->x) return;
- rymin = rr->tilerect.ymin + ymin;
- if (rymin >= ibuf->y) return;
-
- if (rxmin + xmax > ibuf->x)
- xmax = ibuf->x - rxmin;
- if (rymin + ymax > ibuf->y)
- ymax = ibuf->y - rymin;
-
- if (xmax < 1 || ymax < 1) return;
-
- /* The thing here is, the logic below (which was default behavior
- * of how rectf is acquiring since forever) gives float buffer for
- * composite output only. This buffer can not be used for other
- * passes obviously.
- *
- * We might try finding corresponding for pass buffer in render result
- * (which is actually missing when rendering with Cycles, who only
- * writes all the passes when the tile is finished) or use float
- * buffer from image buffer as reference, which is easier to use and
- * contains all the data we need anyway.
- * - sergey -
- */
- /* TODO(sergey): Need to check has_combined here? */
- if (iuser->pass == 0) {
- RenderView *rv;
- const int view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
- rv = RE_RenderViewGetById(rr, view_id);
-
- /* find current float rect for display, first case is after composite... still weak */
- if (rv->rectf)
- rectf = rv->rectf;
- else {
- if (rv->rect32) {
- /* special case, currently only happens with sequencer rendering,
- * which updates the whole frame, so we can only mark display buffer
- * as invalid here (sergey)
- */
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
- return;
- }
- else {
- if (rr->renlay == NULL) return;
- rectf = RE_RenderLayerGetPass(rr->renlay, RE_PASSNAME_COMBINED, viewname);
- }
- }
- if (rectf == NULL) return;
-
- rectf += 4 * (rr->rectx * ymin + xmin);
- linear_stride = rr->rectx;
- linear_offset_x = rxmin;
- linear_offset_y = rymin;
- }
- else {
- rectf = ibuf->rect_float;
- linear_stride = ibuf->x;
- linear_offset_x = 0;
- linear_offset_y = 0;
- }
-
- if (rr->do_exr_tile) {
- /* We don't support changing color management settings during rendering
- * when using Save Buffers option.
- */
- view_settings = &rj->view_settings;
- display_settings = &rj->display_settings;
- }
- else {
- view_settings = &scene->view_settings;
- display_settings = &scene->display_settings;
- }
-
- IMB_partial_display_buffer_update(ibuf, rectf, NULL,
- linear_stride, linear_offset_x, linear_offset_y,
- view_settings, display_settings,
- rxmin, rymin, rxmin + xmax, rymin + ymax,
- rr->do_exr_tile);
+ Scene *scene = rj->scene;
+ const float *rectf = NULL;
+ int ymin, ymax, xmin, xmax;
+ int rymin, rxmin;
+ int linear_stride, linear_offset_x, linear_offset_y;
+ ColorManagedViewSettings *view_settings;
+ ColorManagedDisplaySettings *display_settings;
+
+ /* Exception for exr tiles -- display buffer conversion happens here,
+ * NOT in the color management pipeline.
+ */
+ if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID && rr->do_exr_tile == false) {
+ /* The whole image buffer it so be color managed again anyway. */
+ return;
+ }
+
+ /* if renrect argument, we only refresh scanlines */
+ if (renrect) {
+ /* if (ymax == recty), rendering of layer is ready,
+ * we should not draw, other things happen... */
+ if (rr->renlay == NULL || renrect->ymax >= rr->recty)
+ return;
+
+ /* xmin here is first subrect x coord, xmax defines subrect width */
+ xmin = renrect->xmin + rr->crop;
+ xmax = renrect->xmax - xmin + rr->crop;
+ if (xmax < 2)
+ return;
+
+ ymin = renrect->ymin + rr->crop;
+ ymax = renrect->ymax - ymin + rr->crop;
+ if (ymax < 2)
+ return;
+ renrect->ymin = renrect->ymax;
+ }
+ else {
+ xmin = ymin = rr->crop;
+ xmax = rr->rectx - 2 * rr->crop;
+ ymax = rr->recty - 2 * rr->crop;
+ }
+
+ /* xmin ymin is in tile coords. transform to ibuf */
+ rxmin = rr->tilerect.xmin + xmin;
+ if (rxmin >= ibuf->x)
+ return;
+ rymin = rr->tilerect.ymin + ymin;
+ if (rymin >= ibuf->y)
+ return;
+
+ if (rxmin + xmax > ibuf->x)
+ xmax = ibuf->x - rxmin;
+ if (rymin + ymax > ibuf->y)
+ ymax = ibuf->y - rymin;
+
+ if (xmax < 1 || ymax < 1)
+ return;
+
+ /* The thing here is, the logic below (which was default behavior
+ * of how rectf is acquiring since forever) gives float buffer for
+ * composite output only. This buffer can not be used for other
+ * passes obviously.
+ *
+ * We might try finding corresponding for pass buffer in render result
+ * (which is actually missing when rendering with Cycles, who only
+ * writes all the passes when the tile is finished) or use float
+ * buffer from image buffer as reference, which is easier to use and
+ * contains all the data we need anyway.
+ * - sergey -
+ */
+ /* TODO(sergey): Need to check has_combined here? */
+ if (iuser->pass == 0) {
+ RenderView *rv;
+ const int view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
+ rv = RE_RenderViewGetById(rr, view_id);
+
+ /* find current float rect for display, first case is after composite... still weak */
+ if (rv->rectf)
+ rectf = rv->rectf;
+ else {
+ if (rv->rect32) {
+ /* special case, currently only happens with sequencer rendering,
+ * which updates the whole frame, so we can only mark display buffer
+ * as invalid here (sergey)
+ */
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ return;
+ }
+ else {
+ if (rr->renlay == NULL)
+ return;
+ rectf = RE_RenderLayerGetPass(rr->renlay, RE_PASSNAME_COMBINED, viewname);
+ }
+ }
+ if (rectf == NULL)
+ return;
+
+ rectf += 4 * (rr->rectx * ymin + xmin);
+ linear_stride = rr->rectx;
+ linear_offset_x = rxmin;
+ linear_offset_y = rymin;
+ }
+ else {
+ rectf = ibuf->rect_float;
+ linear_stride = ibuf->x;
+ linear_offset_x = 0;
+ linear_offset_y = 0;
+ }
+
+ if (rr->do_exr_tile) {
+ /* We don't support changing color management settings during rendering
+ * when using Save Buffers option.
+ */
+ view_settings = &rj->view_settings;
+ display_settings = &rj->display_settings;
+ }
+ else {
+ view_settings = &scene->view_settings;
+ display_settings = &scene->display_settings;
+ }
+
+ IMB_partial_display_buffer_update(ibuf,
+ rectf,
+ NULL,
+ linear_stride,
+ linear_offset_x,
+ linear_offset_y,
+ view_settings,
+ display_settings,
+ rxmin,
+ rymin,
+ rxmin + xmax,
+ rymin + ymax,
+ rr->do_exr_tile);
}
/* ****************************** render invoking ***************** */
@@ -253,108 +267,118 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
/* set callbacks, exported to sequence render too.
* Only call in foreground (UI) renders. */
-static void screen_render_single_layer_set(wmOperator *op, Main *mainp, ViewLayer *active_layer, Scene **scene, ViewLayer **single_layer)
+static void screen_render_single_layer_set(
+ wmOperator *op, Main *mainp, ViewLayer *active_layer, Scene **scene, ViewLayer **single_layer)
{
- /* single layer re-render */
- if (RNA_struct_property_is_set(op->ptr, "scene")) {
- Scene *scn;
- char scene_name[MAX_ID_NAME - 2];
-
- RNA_string_get(op->ptr, "scene", scene_name);
- scn = (Scene *)BLI_findstring(&mainp->scenes, scene_name, offsetof(ID, name) + 2);
-
- if (scn) {
- /* camera switch wont have updated */
- scn->r.cfra = (*scene)->r.cfra;
- BKE_scene_camera_switch_update(scn);
-
- *scene = scn;
- }
- }
-
- if (RNA_struct_property_is_set(op->ptr, "layer")) {
- ViewLayer *rl;
- char rl_name[RE_MAXNAME];
-
- RNA_string_get(op->ptr, "layer", rl_name);
- rl = (ViewLayer *)BLI_findstring(&(*scene)->view_layers, rl_name, offsetof(ViewLayer, name));
-
- if (rl)
- *single_layer = rl;
- }
- else if (((*scene)->r.scemode & R_SINGLE_LAYER) && active_layer) {
- *single_layer = active_layer;
- }
+ /* single layer re-render */
+ if (RNA_struct_property_is_set(op->ptr, "scene")) {
+ Scene *scn;
+ char scene_name[MAX_ID_NAME - 2];
+
+ RNA_string_get(op->ptr, "scene", scene_name);
+ scn = (Scene *)BLI_findstring(&mainp->scenes, scene_name, offsetof(ID, name) + 2);
+
+ if (scn) {
+ /* camera switch wont have updated */
+ scn->r.cfra = (*scene)->r.cfra;
+ BKE_scene_camera_switch_update(scn);
+
+ *scene = scn;
+ }
+ }
+
+ if (RNA_struct_property_is_set(op->ptr, "layer")) {
+ ViewLayer *rl;
+ char rl_name[RE_MAXNAME];
+
+ RNA_string_get(op->ptr, "layer", rl_name);
+ rl = (ViewLayer *)BLI_findstring(&(*scene)->view_layers, rl_name, offsetof(ViewLayer, name));
+
+ if (rl)
+ *single_layer = rl;
+ }
+ else if (((*scene)->r.scemode & R_SINGLE_LAYER) && active_layer) {
+ *single_layer = active_layer;
+ }
}
/* executes blocking render */
static int screen_render_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- RenderEngineType *re_type = RE_engines_find(scene->r.engine);
- ViewLayer *active_layer = CTX_data_view_layer(C);
- ViewLayer *single_layer = NULL;
- Render *re;
- Image *ima;
- View3D *v3d = CTX_wm_view3d(C);
- Main *mainp = CTX_data_main(C);
- const bool is_animation = RNA_boolean_get(op->ptr, "animation");
- const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
- struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
-
- /* Cannot do render if there is not this function. */
- if (re_type->render == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- /* custom scene and single layer re-render */
- screen_render_single_layer_set(op, mainp, active_layer, &scene, &single_layer);
-
- 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");
- return OPERATOR_CANCELLED;
- }
-
- re = RE_NewSceneRender(scene);
-
- G.is_break = false;
- RE_test_break_cb(re, NULL, render_break);
-
- ima = BKE_image_verify_viewer(mainp, IMA_TYPE_R_RESULT, "Render Result");
- BKE_image_signal(mainp, ima, NULL, IMA_SIGNAL_FREE);
- BKE_image_backup_render(scene, ima, true);
-
- /* cleanup sequencer caches before starting user triggered render.
- * otherwise, invalidated cache entries can make their way into
- * the output rendering. We can't put that into RE_BlenderFrame,
- * since sequence rendering can call that recursively... (peter) */
- BKE_sequencer_cache_cleanup();
-
- RE_SetReports(re, op->reports);
-
- BLI_threaded_malloc_begin();
- if (is_animation)
- RE_BlenderAnim(re, mainp, scene, single_layer, camera_override, scene->r.sfra, scene->r.efra, scene->r.frame_step);
- else
- RE_BlenderFrame(re, mainp, scene, single_layer, camera_override, scene->r.cfra, is_write_still);
- BLI_threaded_malloc_end();
-
- RE_SetReports(re, NULL);
-
- // no redraw needed, we leave state as we entered it
- ED_update_for_newframe(mainp, CTX_data_depsgraph(C));
-
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ RenderEngineType *re_type = RE_engines_find(scene->r.engine);
+ ViewLayer *active_layer = CTX_data_view_layer(C);
+ ViewLayer *single_layer = NULL;
+ Render *re;
+ Image *ima;
+ View3D *v3d = CTX_wm_view3d(C);
+ Main *mainp = CTX_data_main(C);
+ const bool is_animation = RNA_boolean_get(op->ptr, "animation");
+ const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
+ struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
+
+ /* Cannot do render if there is not this function. */
+ if (re_type->render == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* custom scene and single layer re-render */
+ screen_render_single_layer_set(op, mainp, active_layer, &scene, &single_layer);
+
+ 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");
+ return OPERATOR_CANCELLED;
+ }
+
+ re = RE_NewSceneRender(scene);
+
+ G.is_break = false;
+ RE_test_break_cb(re, NULL, render_break);
+
+ ima = BKE_image_verify_viewer(mainp, IMA_TYPE_R_RESULT, "Render Result");
+ BKE_image_signal(mainp, ima, NULL, IMA_SIGNAL_FREE);
+ BKE_image_backup_render(scene, ima, true);
+
+ /* cleanup sequencer caches before starting user triggered render.
+ * otherwise, invalidated cache entries can make their way into
+ * the output rendering. We can't put that into RE_BlenderFrame,
+ * since sequence rendering can call that recursively... (peter) */
+ BKE_sequencer_cache_cleanup();
+
+ RE_SetReports(re, op->reports);
+
+ BLI_threaded_malloc_begin();
+ if (is_animation)
+ RE_BlenderAnim(re,
+ mainp,
+ scene,
+ single_layer,
+ camera_override,
+ scene->r.sfra,
+ scene->r.efra,
+ scene->r.frame_step);
+ else
+ RE_BlenderFrame(
+ re, mainp, scene, single_layer, camera_override, scene->r.cfra, is_write_still);
+ BLI_threaded_malloc_end();
+
+ RE_SetReports(re, NULL);
+
+ // no redraw needed, we leave state as we entered it
+ ED_update_for_newframe(mainp, CTX_data_depsgraph(C));
+
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
+
+ return OPERATOR_FINISHED;
}
static void render_freejob(void *rjv)
{
- RenderJob *rj = rjv;
+ RenderJob *rj = rjv;
- BKE_color_managed_view_settings_free(&rj->view_settings);
- MEM_freeN(rj);
+ BKE_color_managed_view_settings_free(&rj->view_settings);
+ MEM_freeN(rj);
}
/* str is IMA_MAX_RENDER_TEXT in size */
@@ -364,124 +388,130 @@ static void make_renderinfo_string(const RenderStats *rs,
const char *error,
char *str)
{
- char info_time_str[32]; // used to be extern to header_info.c
- uintptr_t mem_in_use, mmap_in_use, peak_memory;
- float megs_used_memory, mmap_used_memory, megs_peak_memory;
- char *spos = str;
-
- mem_in_use = MEM_get_memory_in_use();
- mmap_in_use = MEM_get_mapped_memory_in_use();
- peak_memory = MEM_get_peak_memory();
-
- megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
- mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
- megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
-
- /* local view */
- if (rs->localview)
- spos += sprintf(spos, "%s | ", IFACE_("3D Local View"));
- else if (v3d_override)
- spos += sprintf(spos, "%s | ", IFACE_("3D View"));
-
- /* frame number */
- spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra));
-
- /* previous and elapsed time */
- BLI_timecode_string_from_time_simple(info_time_str, sizeof(info_time_str), rs->lastframetime);
-
- if (rs->infostr && rs->infostr[0]) {
- if (rs->lastframetime != 0.0)
- spos += sprintf(spos, IFACE_("| Last:%s "), info_time_str);
- else
- spos += sprintf(spos, "| ");
-
- BLI_timecode_string_from_time_simple(info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime);
- }
- else
- spos += sprintf(spos, "| ");
-
- spos += sprintf(spos, IFACE_("Time:%s "), info_time_str);
-
- /* statistics */
- if (rs->statstr) {
- if (rs->statstr[0]) {
- spos += sprintf(spos, "| %s ", rs->statstr);
- }
- }
- else {
- if (rs->totvert || rs->totface || rs->tothalo || rs->totstrand || rs->totlamp)
- spos += sprintf(spos, "| ");
-
- if (rs->totvert) spos += sprintf(spos, IFACE_("Ve:%d "), rs->totvert);
- if (rs->totface) spos += sprintf(spos, IFACE_("Fa:%d "), rs->totface);
- if (rs->tothalo) spos += sprintf(spos, IFACE_("Ha:%d "), rs->tothalo);
- if (rs->totstrand) spos += sprintf(spos, IFACE_("St:%d "), rs->totstrand);
- if (rs->totlamp) spos += sprintf(spos, IFACE_("Li:%d "), rs->totlamp);
-
- if (rs->mem_peak == 0.0f)
- spos += sprintf(spos, IFACE_("| Mem:%.2fM (%.2fM, Peak %.2fM) "),
- megs_used_memory, mmap_used_memory, megs_peak_memory);
- else
- spos += sprintf(spos, IFACE_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
-
- if (rs->curfield)
- spos += sprintf(spos, IFACE_("Field %d "), rs->curfield);
- if (rs->curblur)
- spos += sprintf(spos, IFACE_("Blur %d "), rs->curblur);
- }
-
- /* full sample */
- if (rs->curfsa)
- spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa);
-
- /* extra info */
- if (rs->infostr && rs->infostr[0]) {
- spos += sprintf(spos, "| %s ", rs->infostr);
- }
- else if (error && error[0]) {
- spos += sprintf(spos, "| %s ", error);
- }
-
- /* very weak... but 512 characters is quite safe */
- if (spos >= str + IMA_MAX_RENDER_TEXT)
- if (G.debug & G_DEBUG)
- printf("WARNING! renderwin text beyond limit\n");
-
+ char info_time_str[32]; // used to be extern to header_info.c
+ uintptr_t mem_in_use, mmap_in_use, peak_memory;
+ float megs_used_memory, mmap_used_memory, megs_peak_memory;
+ char *spos = str;
+
+ mem_in_use = MEM_get_memory_in_use();
+ mmap_in_use = MEM_get_mapped_memory_in_use();
+ peak_memory = MEM_get_peak_memory();
+
+ megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
+ mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
+ megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
+
+ /* local view */
+ if (rs->localview)
+ spos += sprintf(spos, "%s | ", IFACE_("3D Local View"));
+ else if (v3d_override)
+ spos += sprintf(spos, "%s | ", IFACE_("3D View"));
+
+ /* frame number */
+ spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra));
+
+ /* previous and elapsed time */
+ BLI_timecode_string_from_time_simple(info_time_str, sizeof(info_time_str), rs->lastframetime);
+
+ if (rs->infostr && rs->infostr[0]) {
+ if (rs->lastframetime != 0.0)
+ spos += sprintf(spos, IFACE_("| Last:%s "), info_time_str);
+ else
+ spos += sprintf(spos, "| ");
+
+ BLI_timecode_string_from_time_simple(
+ info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime);
+ }
+ else
+ spos += sprintf(spos, "| ");
+
+ spos += sprintf(spos, IFACE_("Time:%s "), info_time_str);
+
+ /* statistics */
+ if (rs->statstr) {
+ if (rs->statstr[0]) {
+ spos += sprintf(spos, "| %s ", rs->statstr);
+ }
+ }
+ else {
+ if (rs->totvert || rs->totface || rs->tothalo || rs->totstrand || rs->totlamp)
+ spos += sprintf(spos, "| ");
+
+ if (rs->totvert)
+ spos += sprintf(spos, IFACE_("Ve:%d "), rs->totvert);
+ if (rs->totface)
+ spos += sprintf(spos, IFACE_("Fa:%d "), rs->totface);
+ if (rs->tothalo)
+ spos += sprintf(spos, IFACE_("Ha:%d "), rs->tothalo);
+ if (rs->totstrand)
+ spos += sprintf(spos, IFACE_("St:%d "), rs->totstrand);
+ if (rs->totlamp)
+ spos += sprintf(spos, IFACE_("Li:%d "), rs->totlamp);
+
+ if (rs->mem_peak == 0.0f)
+ spos += sprintf(spos,
+ IFACE_("| Mem:%.2fM (%.2fM, Peak %.2fM) "),
+ megs_used_memory,
+ mmap_used_memory,
+ megs_peak_memory);
+ else
+ spos += sprintf(spos, IFACE_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
+
+ if (rs->curfield)
+ spos += sprintf(spos, IFACE_("Field %d "), rs->curfield);
+ if (rs->curblur)
+ spos += sprintf(spos, IFACE_("Blur %d "), rs->curblur);
+ }
+
+ /* full sample */
+ if (rs->curfsa)
+ spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa);
+
+ /* extra info */
+ if (rs->infostr && rs->infostr[0]) {
+ spos += sprintf(spos, "| %s ", rs->infostr);
+ }
+ else if (error && error[0]) {
+ spos += sprintf(spos, "| %s ", error);
+ }
+
+ /* very weak... but 512 characters is quite safe */
+ if (spos >= str + IMA_MAX_RENDER_TEXT)
+ if (G.debug & G_DEBUG)
+ printf("WARNING! renderwin text beyond limit\n");
}
static void image_renderinfo_cb(void *rjv, RenderStats *rs)
{
- RenderJob *rj = rjv;
- RenderResult *rr;
-
- rr = RE_AcquireResultRead(rj->re);
+ RenderJob *rj = rjv;
+ RenderResult *rr;
- if (rr) {
- /* malloc OK here, stats_draw is not in tile threads */
- if (rr->text == NULL)
- rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
+ rr = RE_AcquireResultRead(rj->re);
- make_renderinfo_string(rs, rj->scene, rj->v3d_override,
- rr->error, rr->text);
- }
+ if (rr) {
+ /* malloc OK here, stats_draw is not in tile threads */
+ if (rr->text == NULL)
+ rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
- RE_ReleaseResult(rj->re);
+ make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->error, rr->text);
+ }
- /* make jobs timer to send notifier */
- *(rj->do_update) = true;
+ RE_ReleaseResult(rj->re);
+ /* make jobs timer to send notifier */
+ *(rj->do_update) = true;
}
static void render_progress_update(void *rjv, float progress)
{
- RenderJob *rj = rjv;
+ RenderJob *rj = rjv;
- if (rj->progress && *rj->progress != progress) {
- *rj->progress = progress;
+ if (rj->progress && *rj->progress != progress) {
+ *rj->progress = progress;
- /* make jobs timer to send notifier */
- *(rj->do_update) = true;
- }
+ /* make jobs timer to send notifier */
+ *(rj->do_update) = true;
+ }
}
/* Not totally reliable, but works fine in most of cases and
@@ -491,615 +521,645 @@ static void render_progress_update(void *rjv, float progress)
*/
static void render_image_update_pass_and_layer(RenderJob *rj, RenderResult *rr, ImageUser *iuser)
{
- wmWindowManager *wm;
- ScrArea *first_sa = NULL, *matched_sa = NULL;
-
- /* image window, compo node users */
- for (wm = rj->main->wm.first; wm && matched_sa == NULL; wm = wm->id.next) { /* only 1 wm */
- wmWindow *win;
- for (win = wm->windows.first; win && matched_sa == NULL; win = win->next) {
- const bScreen *screen = WM_window_get_active_screen(win);
-
- for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
- if (sa->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = sa->spacedata.first;
- // sa->spacedata might be empty when toggling fullscreen mode.
- if (sima != NULL && sima->image == rj->image) {
- if (first_sa == NULL) {
- first_sa = sa;
- }
- if (sa == rj->sa) {
- matched_sa = sa;
- break;
- }
- }
- }
- }
- }
- }
-
- if (matched_sa == NULL) {
- matched_sa = first_sa;
- }
-
- if (matched_sa) {
- SpaceImage *sima = matched_sa->spacedata.first;
- RenderResult *main_rr = RE_AcquireResultRead(rj->re);
-
- /* TODO(sergey): is there faster way to get the layer index? */
- if (rr->renlay) {
- int layer = BLI_findstringindex(&main_rr->layers,
- (char *)rr->renlay->name,
- offsetof(RenderLayer, name));
- sima->iuser.layer = layer;
- rj->last_layer = layer;
- }
-
- iuser->pass = sima->iuser.pass;
- iuser->layer = sima->iuser.layer;
-
- RE_ReleaseResult(rj->re);
- }
+ wmWindowManager *wm;
+ ScrArea *first_sa = NULL, *matched_sa = NULL;
+
+ /* image window, compo node users */
+ for (wm = rj->main->wm.first; wm && matched_sa == NULL; wm = wm->id.next) { /* only 1 wm */
+ wmWindow *win;
+ for (win = wm->windows.first; win && matched_sa == NULL; win = win->next) {
+ const bScreen *screen = WM_window_get_active_screen(win);
+
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = sa->spacedata.first;
+ // sa->spacedata might be empty when toggling fullscreen mode.
+ if (sima != NULL && sima->image == rj->image) {
+ if (first_sa == NULL) {
+ first_sa = sa;
+ }
+ if (sa == rj->sa) {
+ matched_sa = sa;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (matched_sa == NULL) {
+ matched_sa = first_sa;
+ }
+
+ if (matched_sa) {
+ SpaceImage *sima = matched_sa->spacedata.first;
+ RenderResult *main_rr = RE_AcquireResultRead(rj->re);
+
+ /* TODO(sergey): is there faster way to get the layer index? */
+ if (rr->renlay) {
+ int layer = BLI_findstringindex(
+ &main_rr->layers, (char *)rr->renlay->name, offsetof(RenderLayer, name));
+ sima->iuser.layer = layer;
+ rj->last_layer = layer;
+ }
+
+ iuser->pass = sima->iuser.pass;
+ iuser->layer = sima->iuser.layer;
+
+ RE_ReleaseResult(rj->re);
+ }
}
static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect)
{
- RenderJob *rj = rjv;
- Image *ima = rj->image;
- ImBuf *ibuf;
- void *lock;
- const char *viewname = RE_GetActiveRenderView(rj->re);
-
- /* only update if we are displaying the slot being rendered */
- if (ima->render_slot != ima->last_render_slot) {
- rj->image_outdated = true;
- return;
- }
- else if (rj->image_outdated) {
- /* update entire render */
- rj->image_outdated = false;
- BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_COLORMANAGE);
- *(rj->do_update) = true;
- return;
- }
-
- if (rr == NULL)
- return;
-
- /* update part of render */
- render_image_update_pass_and_layer(rj, rr, &rj->iuser);
- ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
- if (ibuf) {
- /* Don't waste time on CPU side color management if
- * image will be displayed using GLSL.
- *
- * Need to update rect if Save Buffers enabled because in
- * this case GLSL doesn't have original float buffer to
- * operate with.
- */
- if (rr->do_exr_tile ||
- !rj->supports_glsl_draw ||
- ibuf->channels == 1 ||
- U.image_draw_method != IMAGE_DRAW_METHOD_GLSL)
- {
- image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname);
- }
-
- /* make jobs timer to send notifier */
- *(rj->do_update) = true;
- }
- BKE_image_release_ibuf(ima, ibuf, lock);
+ RenderJob *rj = rjv;
+ Image *ima = rj->image;
+ ImBuf *ibuf;
+ void *lock;
+ const char *viewname = RE_GetActiveRenderView(rj->re);
+
+ /* only update if we are displaying the slot being rendered */
+ if (ima->render_slot != ima->last_render_slot) {
+ rj->image_outdated = true;
+ return;
+ }
+ else if (rj->image_outdated) {
+ /* update entire render */
+ rj->image_outdated = false;
+ BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_COLORMANAGE);
+ *(rj->do_update) = true;
+ return;
+ }
+
+ if (rr == NULL)
+ return;
+
+ /* update part of render */
+ render_image_update_pass_and_layer(rj, rr, &rj->iuser);
+ ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
+ if (ibuf) {
+ /* Don't waste time on CPU side color management if
+ * image will be displayed using GLSL.
+ *
+ * Need to update rect if Save Buffers enabled because in
+ * this case GLSL doesn't have original float buffer to
+ * operate with.
+ */
+ if (rr->do_exr_tile || !rj->supports_glsl_draw || ibuf->channels == 1 ||
+ U.image_draw_method != IMAGE_DRAW_METHOD_GLSL) {
+ image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname);
+ }
+
+ /* make jobs timer to send notifier */
+ *(rj->do_update) = true;
+ }
+ BKE_image_release_ibuf(ima, ibuf, lock);
}
static void current_scene_update(void *rjv, Scene *scene)
{
- RenderJob *rj = rjv;
- rj->current_scene = scene;
- rj->iuser.scene = scene;
+ RenderJob *rj = rjv;
+ rj->current_scene = scene;
+ rj->iuser.scene = scene;
}
static void render_startjob(void *rjv, short *stop, short *do_update, float *progress)
{
- RenderJob *rj = rjv;
-
- rj->stop = stop;
- rj->do_update = do_update;
- rj->progress = progress;
-
- RE_SetReports(rj->re, rj->reports);
-
- if (rj->anim)
- RE_BlenderAnim(rj->re, rj->main, rj->scene, rj->single_layer, rj->camera_override, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step);
- else
- RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->single_layer, rj->camera_override, rj->scene->r.cfra, rj->write_still);
-
- RE_SetReports(rj->re, NULL);
+ RenderJob *rj = rjv;
+
+ rj->stop = stop;
+ rj->do_update = do_update;
+ rj->progress = progress;
+
+ RE_SetReports(rj->re, rj->reports);
+
+ if (rj->anim)
+ RE_BlenderAnim(rj->re,
+ rj->main,
+ rj->scene,
+ rj->single_layer,
+ rj->camera_override,
+ rj->scene->r.sfra,
+ rj->scene->r.efra,
+ rj->scene->r.frame_step);
+ else
+ RE_BlenderFrame(rj->re,
+ rj->main,
+ rj->scene,
+ rj->single_layer,
+ rj->camera_override,
+ rj->scene->r.cfra,
+ rj->write_still);
+
+ RE_SetReports(rj->re, NULL);
}
static void render_image_restore_layer(RenderJob *rj)
{
- wmWindowManager *wm;
-
- /* image window, compo node users */
- for (wm = rj->main->wm.first; wm; wm = wm->id.next) { /* only 1 wm */
- wmWindow *win;
- for (win = wm->windows.first; win; win = win->next) {
- const bScreen *screen = WM_window_get_active_screen(win);
-
- for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
- if (sa == rj->sa) {
- if (sa->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = sa->spacedata.first;
-
- if (RE_HasSingleLayer(rj->re)) {
- /* For single layer renders keep the active layer
- * visible, or show the compositing result. */
- RenderResult *rr = RE_AcquireResultRead(rj->re);
- if (RE_HasCombinedLayer(rr)) {
- sima->iuser.layer = 0;
- }
- RE_ReleaseResult(rj->re);
- }
- else {
- /* For multiple layer render, set back the layer
- * that was set at the start of rendering. */
- sima->iuser.layer = rj->orig_layer;
- }
- }
- return;
- }
- }
- }
- }
+ wmWindowManager *wm;
+
+ /* image window, compo node users */
+ for (wm = rj->main->wm.first; wm; wm = wm->id.next) { /* only 1 wm */
+ wmWindow *win;
+ for (win = wm->windows.first; win; win = win->next) {
+ const bScreen *screen = WM_window_get_active_screen(win);
+
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa == rj->sa) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = sa->spacedata.first;
+
+ if (RE_HasSingleLayer(rj->re)) {
+ /* For single layer renders keep the active layer
+ * visible, or show the compositing result. */
+ RenderResult *rr = RE_AcquireResultRead(rj->re);
+ if (RE_HasCombinedLayer(rr)) {
+ sima->iuser.layer = 0;
+ }
+ RE_ReleaseResult(rj->re);
+ }
+ else {
+ /* For multiple layer render, set back the layer
+ * that was set at the start of rendering. */
+ sima->iuser.layer = rj->orig_layer;
+ }
+ }
+ return;
+ }
+ }
+ }
+ }
}
static void render_endjob(void *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 T24508. */
- RE_InitRenderCB(rj->re);
-
- if (rj->main != G_MAIN)
- BKE_main_free(rj->main);
-
- /* else the frame will not update for the original value */
- if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
- /* possible this fails of loading new file while rendering */
- if (G_MAIN->wm.first) {
- ED_update_for_newframe(G_MAIN, rj->depsgraph);
- }
- }
-
- /* XXX above function sets all tags in nodes */
- ntreeCompositClearTags(rj->scene->nodetree);
-
- /* potentially set by caller */
- rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
-
- if (rj->single_layer) {
- nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
- WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
- }
-
- if (rj->sa) {
- render_image_restore_layer(rj);
- }
-
- /* XXX render stability hack */
- G.is_rendering = false;
- WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL);
-
- /* Partial render result will always update display buffer
- * for first render layer only. This is nice because you'll
- * see render progress during rendering, but it ends up in
- * wrong display buffer shown after rendering.
- *
- * The code below will mark display buffer as invalid after
- * rendering in case multiple layers were rendered, which
- * ensures display buffer matches render layer after
- * rendering.
- *
- * Perhaps proper way would be to toggle active render
- * layer in image editor and job, so we always display
- * layer being currently rendered. But this is not so much
- * trivial at this moment, especially because of external
- * engine API, so lets use simple and robust way for now
- * - sergey -
- */
- if (rj->scene->view_layers.first != rj->scene->view_layers.last ||
- rj->image_outdated)
- {
- void *lock;
- Image *ima = rj->image;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
-
- if (ibuf)
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- BKE_image_release_ibuf(ima, ibuf, lock);
- }
-
- /* Finally unlock the user interface (if it was locked). */
- if (rj->interface_locked) {
- /* Interface was locked, so window manager couldn't have been changed
- * and using one from Global will unlock exactly the same manager as
- * was locked before running the job.
- */
- WM_set_locked_interface(G_MAIN->wm.first, false);
- DEG_on_visible_update(G_MAIN, false);
- }
+ 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 T24508. */
+ RE_InitRenderCB(rj->re);
+
+ if (rj->main != G_MAIN)
+ BKE_main_free(rj->main);
+
+ /* else the frame will not update for the original value */
+ if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
+ /* possible this fails of loading new file while rendering */
+ if (G_MAIN->wm.first) {
+ ED_update_for_newframe(G_MAIN, rj->depsgraph);
+ }
+ }
+
+ /* XXX above function sets all tags in nodes */
+ ntreeCompositClearTags(rj->scene->nodetree);
+
+ /* potentially set by caller */
+ rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
+
+ if (rj->single_layer) {
+ nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
+ WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
+ }
+
+ if (rj->sa) {
+ render_image_restore_layer(rj);
+ }
+
+ /* XXX render stability hack */
+ G.is_rendering = false;
+ WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL);
+
+ /* Partial render result will always update display buffer
+ * for first render layer only. This is nice because you'll
+ * see render progress during rendering, but it ends up in
+ * wrong display buffer shown after rendering.
+ *
+ * The code below will mark display buffer as invalid after
+ * rendering in case multiple layers were rendered, which
+ * ensures display buffer matches render layer after
+ * rendering.
+ *
+ * Perhaps proper way would be to toggle active render
+ * layer in image editor and job, so we always display
+ * layer being currently rendered. But this is not so much
+ * trivial at this moment, especially because of external
+ * engine API, so lets use simple and robust way for now
+ * - sergey -
+ */
+ if (rj->scene->view_layers.first != rj->scene->view_layers.last || rj->image_outdated) {
+ void *lock;
+ Image *ima = rj->image;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
+
+ if (ibuf)
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
+
+ /* Finally unlock the user interface (if it was locked). */
+ if (rj->interface_locked) {
+ /* Interface was locked, so window manager couldn't have been changed
+ * and using one from Global will unlock exactly the same manager as
+ * was locked before running the job.
+ */
+ WM_set_locked_interface(G_MAIN->wm.first, false);
+ DEG_on_visible_update(G_MAIN, false);
+ }
}
/* called by render, check job 'stop' value or the global */
static int render_breakjob(void *rjv)
{
- RenderJob *rj = rjv;
+ RenderJob *rj = rjv;
- if (G.is_break)
- return 1;
- if (rj->stop && *(rj->stop))
- return 1;
- return 0;
+ if (G.is_break)
+ return 1;
+ if (rj->stop && *(rj->stop))
+ return 1;
+ return 0;
}
/* for exec() when there is no render job
* note: this wont check for the escape key being pressed, but doing so isnt threadsafe */
static int render_break(void *UNUSED(rjv))
{
- if (G.is_break)
- return 1;
- return 0;
+ if (G.is_break)
+ return 1;
+ return 0;
}
/* runs in thread, no cursor setting here works. careful with notifiers too (malloc conflicts) */
/* maybe need a way to get job send notifier? */
static void render_drawlock(void *rjv, int lock)
{
- RenderJob *rj = rjv;
+ RenderJob *rj = rjv;
- /* If interface is locked, renderer callback shall do nothing. */
- if (!rj->interface_locked) {
- BKE_spacedata_draw_locks(lock);
- }
+ /* If interface is locked, renderer callback shall do nothing. */
+ if (!rj->interface_locked) {
+ BKE_spacedata_draw_locks(lock);
+ }
}
/* catch esc */
static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- Scene *scene = (Scene *) op->customdata;
-
- /* no running blender, remove handler and pass through */
- if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
- }
-
- /* running render */
- switch (event->type) {
- case ESCKEY:
- return OPERATOR_RUNNING_MODAL;
- }
- return OPERATOR_PASS_THROUGH;
+ Scene *scene = (Scene *)op->customdata;
+
+ /* no running blender, remove handler and pass through */
+ if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ }
+
+ /* running render */
+ switch (event->type) {
+ case ESCKEY:
+ return OPERATOR_RUNNING_MODAL;
+ }
+ return OPERATOR_PASS_THROUGH;
}
static void screen_render_cancel(bContext *C, wmOperator *op)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- Scene *scene = (Scene *) op->customdata;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ Scene *scene = (Scene *)op->customdata;
- /* kill on cancel, because job is using op->reports */
- WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
+ /* kill on cancel, because job is using op->reports */
+ WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
}
static void clean_viewport_memory_base(Base *base)
{
- if ((base->flag & BASE_VISIBLE) == 0) {
- return;
- }
+ if ((base->flag & BASE_VISIBLE) == 0) {
+ return;
+ }
- Object *object = base->object;
+ Object *object = base->object;
- if (object->id.tag & LIB_TAG_DOIT) {
- return;
- }
+ if (object->id.tag & LIB_TAG_DOIT) {
+ return;
+ }
- object->id.tag &= ~LIB_TAG_DOIT;
- if (RE_allow_render_generic_object(object)) {
- BKE_object_free_derived_caches(object);
- }
+ object->id.tag &= ~LIB_TAG_DOIT;
+ if (RE_allow_render_generic_object(object)) {
+ BKE_object_free_derived_caches(object);
+ }
}
static void clean_viewport_memory(Main *bmain, Scene *scene)
{
- Scene *sce_iter;
- Base *base;
-
- /* Tag all the available objects. */
- BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
-
- /* Go over all the visible objects. */
- for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
- for (wmWindow *win = wm->windows.first; win; win = win->next) {
- ViewLayer *view_layer = WM_window_get_active_view_layer(win);
-
- for (base = view_layer->object_bases.first; base; base = base->next) {
- clean_viewport_memory_base(base);
- }
- }
- }
-
- for (SETLOOPER_SET_ONLY(scene, sce_iter, base)) {
- clean_viewport_memory_base(base);
- }
+ Scene *sce_iter;
+ Base *base;
+
+ /* Tag all the available objects. */
+ BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
+
+ /* Go over all the visible objects. */
+ for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ ViewLayer *view_layer = WM_window_get_active_view_layer(win);
+
+ for (base = view_layer->object_bases.first; base; base = base->next) {
+ clean_viewport_memory_base(base);
+ }
+ }
+ }
+
+ for (SETLOOPER_SET_ONLY(scene, sce_iter, base)) {
+ clean_viewport_memory_base(base);
+ }
}
/* using context, starts job */
static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- /* new render clears all callbacks */
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *active_layer = CTX_data_view_layer(C);
- ViewLayer *single_layer = NULL;
- RenderEngineType *re_type = RE_engines_find(scene->r.engine);
- Render *re;
- wmJob *wm_job;
- RenderJob *rj;
- Image *ima;
- int jobflag;
- const bool is_animation = RNA_boolean_get(op->ptr, "animation");
- const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
- const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport");
- View3D *v3d = use_viewport ? CTX_wm_view3d(C) : NULL;
- struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
- const char *name;
- ScrArea *sa;
-
- /* Cannot do render if there is not this function. */
- if (re_type->render == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- /* custom scene and single layer re-render */
- screen_render_single_layer_set(op, bmain, active_layer, &scene, &single_layer);
-
- /* only one render job at a time */
- if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER))
- return OPERATOR_CANCELLED;
-
- if (!RE_is_rendering_allowed(scene, single_layer, camera_override, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- 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");
- return OPERATOR_CANCELLED;
- }
-
- /* stop all running jobs, except screen one. currently previews frustrate Render */
- WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C));
-
- /* cancel animation playback */
- if (ED_screen_animation_playing(CTX_wm_manager(C)))
- ED_screen_animation_play(C, 0, 0);
-
- /* handle UI stuff */
- WM_cursor_wait(1);
-
- /* flush sculpt and editmode changes */
- ED_editors_flush_edits(bmain, true);
-
- /* cleanup sequencer caches before starting user triggered render.
- * otherwise, invalidated cache entries can make their way into
- * the output rendering. We can't put that into RE_BlenderFrame,
- * since sequence rendering can call that recursively... (peter) */
- BKE_sequencer_cache_cleanup();
-
- // store spare
- // get view3d layer, local layer, make this nice api call to render
- // store spare
-
- /* ensure at least 1 area shows result */
- sa = render_view_open(C, event->x, event->y, op->reports);
-
- jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS;
-
- if (RNA_struct_property_is_set(op->ptr, "layer"))
- jobflag |= WM_JOB_SUSPEND;
-
- /* job custom data */
- rj = MEM_callocN(sizeof(RenderJob), "render job");
- rj->main = bmain;
- rj->scene = scene;
- rj->current_scene = rj->scene;
- rj->single_layer = single_layer;
- /* TODO(sergey): Render engine should be using own depsgraph. */
- rj->depsgraph = CTX_data_depsgraph(C);
- rj->camera_override = camera_override;
- rj->anim = is_animation;
- rj->write_still = is_write_still && !is_animation;
- rj->iuser.scene = scene;
- rj->iuser.ok = 1;
- rj->reports = op->reports;
- rj->orig_layer = 0;
- rj->last_layer = 0;
- rj->sa = sa;
- rj->supports_glsl_draw = IMB_colormanagement_support_glsl_draw(&scene->view_settings);
-
- BKE_color_managed_display_settings_copy(&rj->display_settings, &scene->display_settings);
- BKE_color_managed_view_settings_copy(&rj->view_settings, &scene->view_settings);
-
- if (sa) {
- SpaceImage *sima = sa->spacedata.first;
- rj->orig_layer = sima->iuser.layer;
- }
-
- if (v3d) {
- if (camera_override && camera_override != scene->camera)
- rj->v3d_override = true;
- }
-
- /* Lock the user interface depending on render settings. */
- if (scene->r.use_lock_interface) {
- WM_set_locked_interface(CTX_wm_manager(C), true);
-
- /* Set flag interface need to be unlocked.
- *
- * This is so because we don't have copy of render settings
- * accessible from render job and copy is needed in case
- * of non-locked rendering, so we wouldn't try to unlock
- * anything if option was initially unset but then was
- * enabled during rendering.
- */
- rj->interface_locked = true;
-
- /* Clean memory used by viewport? */
- clean_viewport_memory(rj->main, scene);
- }
-
- /* setup job */
- if (RE_seq_render_active(scene, &scene->r)) name = "Sequence 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_jobs_customdata_set(wm_job, rj, render_freejob);
- WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0);
- WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob);
-
- /* get a render result image, and make sure it is empty */
- ima = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
- BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_FREE);
- BKE_image_backup_render(rj->scene, ima, true);
- rj->image = ima;
-
- /* setup new render */
- re = RE_NewSceneRender(scene);
- RE_test_break_cb(re, rj, render_breakjob);
- RE_draw_lock_cb(re, rj, render_drawlock);
- RE_display_update_cb(re, rj, image_rect_update);
- RE_current_scene_update_cb(re, rj, current_scene_update);
- RE_stats_draw_cb(re, rj, image_renderinfo_cb);
- RE_progress_cb(re, rj, render_progress_update);
- RE_gl_context_create(re);
-
- rj->re = re;
- G.is_break = false;
-
- /* store actual owner of job, so modal operator could check for it,
- * the reason of this is that active scene could change when rendering
- * several layers from compositor [#31800]
- */
- op->customdata = scene;
-
- WM_jobs_start(CTX_wm_manager(C), wm_job);
-
- WM_cursor_wait(0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
-
- /* we set G.is_rendering here already instead of only in the job, this ensure
- * main loop or other scene updates are disabled in time, since they may
- * have started before the job thread */
- G.is_rendering = true;
-
- /* add modal handler for ESC */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
+ /* new render clears all callbacks */
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *active_layer = CTX_data_view_layer(C);
+ ViewLayer *single_layer = NULL;
+ RenderEngineType *re_type = RE_engines_find(scene->r.engine);
+ Render *re;
+ wmJob *wm_job;
+ RenderJob *rj;
+ Image *ima;
+ int jobflag;
+ const bool is_animation = RNA_boolean_get(op->ptr, "animation");
+ const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
+ const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport");
+ View3D *v3d = use_viewport ? CTX_wm_view3d(C) : NULL;
+ struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
+ const char *name;
+ ScrArea *sa;
+
+ /* Cannot do render if there is not this function. */
+ if (re_type->render == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* custom scene and single layer re-render */
+ screen_render_single_layer_set(op, bmain, active_layer, &scene, &single_layer);
+
+ /* only one render job at a time */
+ if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER))
+ return OPERATOR_CANCELLED;
+
+ if (!RE_is_rendering_allowed(scene, single_layer, camera_override, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ 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");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* stop all running jobs, except screen one. currently previews frustrate Render */
+ WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C));
+
+ /* cancel animation playback */
+ if (ED_screen_animation_playing(CTX_wm_manager(C)))
+ ED_screen_animation_play(C, 0, 0);
+
+ /* handle UI stuff */
+ WM_cursor_wait(1);
+
+ /* flush sculpt and editmode changes */
+ ED_editors_flush_edits(bmain, true);
+
+ /* cleanup sequencer caches before starting user triggered render.
+ * otherwise, invalidated cache entries can make their way into
+ * the output rendering. We can't put that into RE_BlenderFrame,
+ * since sequence rendering can call that recursively... (peter) */
+ BKE_sequencer_cache_cleanup();
+
+ // store spare
+ // get view3d layer, local layer, make this nice api call to render
+ // store spare
+
+ /* ensure at least 1 area shows result */
+ sa = render_view_open(C, event->x, event->y, op->reports);
+
+ jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS;
+
+ if (RNA_struct_property_is_set(op->ptr, "layer"))
+ jobflag |= WM_JOB_SUSPEND;
+
+ /* job custom data */
+ rj = MEM_callocN(sizeof(RenderJob), "render job");
+ rj->main = bmain;
+ rj->scene = scene;
+ rj->current_scene = rj->scene;
+ rj->single_layer = single_layer;
+ /* TODO(sergey): Render engine should be using own depsgraph. */
+ rj->depsgraph = CTX_data_depsgraph(C);
+ rj->camera_override = camera_override;
+ rj->anim = is_animation;
+ rj->write_still = is_write_still && !is_animation;
+ rj->iuser.scene = scene;
+ rj->iuser.ok = 1;
+ rj->reports = op->reports;
+ rj->orig_layer = 0;
+ rj->last_layer = 0;
+ rj->sa = sa;
+ rj->supports_glsl_draw = IMB_colormanagement_support_glsl_draw(&scene->view_settings);
+
+ BKE_color_managed_display_settings_copy(&rj->display_settings, &scene->display_settings);
+ BKE_color_managed_view_settings_copy(&rj->view_settings, &scene->view_settings);
+
+ if (sa) {
+ SpaceImage *sima = sa->spacedata.first;
+ rj->orig_layer = sima->iuser.layer;
+ }
+
+ if (v3d) {
+ if (camera_override && camera_override != scene->camera)
+ rj->v3d_override = true;
+ }
+
+ /* Lock the user interface depending on render settings. */
+ if (scene->r.use_lock_interface) {
+ WM_set_locked_interface(CTX_wm_manager(C), true);
+
+ /* Set flag interface need to be unlocked.
+ *
+ * This is so because we don't have copy of render settings
+ * accessible from render job and copy is needed in case
+ * of non-locked rendering, so we wouldn't try to unlock
+ * anything if option was initially unset but then was
+ * enabled during rendering.
+ */
+ rj->interface_locked = true;
+
+ /* Clean memory used by viewport? */
+ clean_viewport_memory(rj->main, scene);
+ }
+
+ /* setup job */
+ if (RE_seq_render_active(scene, &scene->r))
+ name = "Sequence 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_jobs_customdata_set(wm_job, rj, render_freejob);
+ WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0);
+ WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob);
+
+ /* get a render result image, and make sure it is empty */
+ ima = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
+ BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_FREE);
+ BKE_image_backup_render(rj->scene, ima, true);
+ rj->image = ima;
+
+ /* setup new render */
+ re = RE_NewSceneRender(scene);
+ RE_test_break_cb(re, rj, render_breakjob);
+ RE_draw_lock_cb(re, rj, render_drawlock);
+ RE_display_update_cb(re, rj, image_rect_update);
+ RE_current_scene_update_cb(re, rj, current_scene_update);
+ RE_stats_draw_cb(re, rj, image_renderinfo_cb);
+ RE_progress_cb(re, rj, render_progress_update);
+ RE_gl_context_create(re);
+
+ rj->re = re;
+ G.is_break = false;
+
+ /* store actual owner of job, so modal operator could check for it,
+ * the reason of this is that active scene could change when rendering
+ * several layers from compositor [#31800]
+ */
+ op->customdata = scene;
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+
+ WM_cursor_wait(0);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
+
+ /* we set G.is_rendering here already instead of only in the job, this ensure
+ * main loop or other scene updates are disabled in time, since they may
+ * have started before the job thread */
+ G.is_rendering = true;
+
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
}
/* contextual render, using current scene, view3d? */
void RENDER_OT_render(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Render";
- ot->description = "Render active scene";
- ot->idname = "RENDER_OT_render";
-
- /* api callbacks */
- ot->invoke = screen_render_invoke;
- ot->modal = screen_render_modal;
- ot->cancel = screen_render_cancel;
- ot->exec = screen_render_exec;
-
- /*ot->poll = ED_operator_screenactive;*/ /* this isn't needed, causes failer in background mode */
-
- prop = RNA_def_boolean(ot->srna, "animation", 0, "Animation", "Render files from the animation range of this scene");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- RNA_def_boolean(ot->srna, "write_still", 0, "Write Image", "Save rendered the image to the output path (used only when animation is disabled)");
- prop = RNA_def_boolean(ot->srna, "use_viewport", 0, "Use 3D Viewport", "When inside a 3D viewport, use layers and camera of the viewport");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_string(ot->srna, "layer", NULL, RE_MAXNAME, "Render Layer", "Single render layer to re-render (used only when animation is disabled)");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_string(ot->srna, "scene", NULL, MAX_ID_NAME - 2, "Scene", "Scene to render, current scene if not specified");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Render";
+ ot->description = "Render active scene";
+ ot->idname = "RENDER_OT_render";
+
+ /* api callbacks */
+ ot->invoke = screen_render_invoke;
+ ot->modal = screen_render_modal;
+ ot->cancel = screen_render_cancel;
+ ot->exec = screen_render_exec;
+
+ /*ot->poll = ED_operator_screenactive;*/ /* this isn't needed, causes failer in background mode */
+
+ prop = RNA_def_boolean(ot->srna,
+ "animation",
+ 0,
+ "Animation",
+ "Render files from the animation range of this scene");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ RNA_def_boolean(
+ ot->srna,
+ "write_still",
+ 0,
+ "Write Image",
+ "Save rendered the image to the output path (used only when animation is disabled)");
+ prop = RNA_def_boolean(ot->srna,
+ "use_viewport",
+ 0,
+ "Use 3D Viewport",
+ "When inside a 3D viewport, use layers and camera of the viewport");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna,
+ "layer",
+ NULL,
+ RE_MAXNAME,
+ "Render Layer",
+ "Single render layer to re-render (used only when animation is disabled)");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_string(ot->srna,
+ "scene",
+ NULL,
+ MAX_ID_NAME - 2,
+ "Scene",
+ "Scene to render, current scene if not specified");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-
Scene *ED_render_job_get_scene(const bContext *C)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
- if (rj)
- return rj->scene;
+ if (rj)
+ return rj->scene;
- return NULL;
+ return NULL;
}
Scene *ED_render_job_get_current_scene(const bContext *C)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
- if (rj) {
- return rj->current_scene;
- }
- return NULL;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
+ if (rj) {
+ return rj->current_scene;
+ }
+ return NULL;
}
-
/* Motion blur curve preset */
static int render_shutter_curve_preset_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- CurveMapping *mblur_shutter_curve = &scene->r.mblur_shutter_curve;
- CurveMap *cm = mblur_shutter_curve->cm;
- int preset = RNA_enum_get(op->ptr, "shape");
-
- cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
- mblur_shutter_curve->preset = preset;
- curvemap_reset(cm,
- &mblur_shutter_curve->clipr,
- mblur_shutter_curve->preset,
- CURVEMAP_SLOPE_POS_NEG);
- curvemapping_changed(mblur_shutter_curve, false);
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ CurveMapping *mblur_shutter_curve = &scene->r.mblur_shutter_curve;
+ CurveMap *cm = mblur_shutter_curve->cm;
+ int preset = RNA_enum_get(op->ptr, "shape");
+
+ cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ mblur_shutter_curve->preset = preset;
+ curvemap_reset(
+ cm, &mblur_shutter_curve->clipr, mblur_shutter_curve->preset, CURVEMAP_SLOPE_POS_NEG);
+ curvemapping_changed(mblur_shutter_curve, false);
+
+ return OPERATOR_FINISHED;
}
void RENDER_OT_shutter_curve_preset(wmOperatorType *ot)
{
- PropertyRNA *prop;
- static const EnumPropertyItem prop_shape_items[] = {
- {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""},
- {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""},
- {CURVE_PRESET_MAX, "MAX", 0, "Max", ""},
- {CURVE_PRESET_LINE, "LINE", 0, "Line", ""},
- {CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""},
- {CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
- ot->name = "Shutter Curve Preset";
- ot->description = "Set shutter curve";
- ot->idname = "RENDER_OT_shutter_curve_preset";
-
- ot->exec = render_shutter_curve_preset_exec;
-
- prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
- RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ PropertyRNA *prop;
+ static const EnumPropertyItem prop_shape_items[] = {
+ {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""},
+ {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""},
+ {CURVE_PRESET_MAX, "MAX", 0, "Max", ""},
+ {CURVE_PRESET_LINE, "LINE", 0, "Line", ""},
+ {CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""},
+ {CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ ot->name = "Shutter Curve Preset";
+ ot->description = "Set shutter curve";
+ ot->idname = "RENDER_OT_shutter_curve_preset";
+
+ ot->exec = render_shutter_curve_preset_exec;
+
+ prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
+ RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
}
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 3fdc34bd9c9..6862881de59 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -21,7 +21,6 @@
* \ingroup edrend
*/
-
#include <math.h>
#include <string.h>
#include <stddef.h>
@@ -88,1039 +87,1079 @@
#define MAX_SCHEDULED_FRAMES 8
typedef struct OGLRender {
- Main *bmain;
- Render *re;
- Scene *scene;
- WorkSpace *workspace;
- ViewLayer *view_layer;
- Depsgraph *depsgraph;
-
- View3D *v3d;
- RegionView3D *rv3d;
- ARegion *ar;
-
- ScrArea *prevsa;
- ARegion *prevar;
-
- int views_len; /* multi-view views */
-
- bool is_sequencer;
- SpaceSeq *sseq;
- struct {
- ImBuf **ibufs_arr;
- } seq_data;
-
-
- Image *ima;
- ImageUser iuser;
-
- GPUOffScreen *ofs;
- int ofs_samples;
- bool ofs_full_samples;
- int sizex, sizey;
- int write_still;
-
- ReportList *reports;
- bMovieHandle *mh;
- int cfrao, nfra;
-
- int totvideos;
-
- /* quick lookup */
- int view_id;
-
- /* wm vars for timer and progress cursor */
- wmWindowManager *wm;
- wmWindow *win;
-
- wmTimer *timer; /* use to check if running modal or not (invoke'd or exec'd)*/
- void **movie_ctx_arr;
-
- TaskScheduler *task_scheduler;
- TaskPool *task_pool;
- bool pool_ok;
- bool is_animation;
- SpinLock reports_lock;
- unsigned int num_scheduled_frames;
- ThreadMutex task_mutex;
- ThreadCondition task_condition;
+ Main *bmain;
+ Render *re;
+ Scene *scene;
+ WorkSpace *workspace;
+ ViewLayer *view_layer;
+ Depsgraph *depsgraph;
+
+ View3D *v3d;
+ RegionView3D *rv3d;
+ ARegion *ar;
+
+ ScrArea *prevsa;
+ ARegion *prevar;
+
+ int views_len; /* multi-view views */
+
+ bool is_sequencer;
+ SpaceSeq *sseq;
+ struct {
+ ImBuf **ibufs_arr;
+ } seq_data;
+
+ Image *ima;
+ ImageUser iuser;
+
+ GPUOffScreen *ofs;
+ int ofs_samples;
+ bool ofs_full_samples;
+ int sizex, sizey;
+ int write_still;
+
+ ReportList *reports;
+ bMovieHandle *mh;
+ int cfrao, nfra;
+
+ int totvideos;
+
+ /* quick lookup */
+ int view_id;
+
+ /* wm vars for timer and progress cursor */
+ wmWindowManager *wm;
+ wmWindow *win;
+
+ wmTimer *timer; /* use to check if running modal or not (invoke'd or exec'd)*/
+ void **movie_ctx_arr;
+
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
+ bool pool_ok;
+ bool is_animation;
+ SpinLock reports_lock;
+ unsigned int num_scheduled_frames;
+ ThreadMutex task_mutex;
+ ThreadCondition task_condition;
#ifdef DEBUG_TIME
- double time_start;
+ double time_start;
#endif
} OGLRender;
static bool screen_opengl_is_multiview(OGLRender *oglrender)
{
- View3D *v3d = oglrender->v3d;
- RegionView3D *rv3d = oglrender->rv3d;
- RenderData *rd = &oglrender->scene->r;
+ View3D *v3d = oglrender->v3d;
+ RegionView3D *rv3d = oglrender->rv3d;
+ RenderData *rd = &oglrender->scene->r;
- if ((rd == NULL) || ((v3d != NULL) && (rv3d == NULL)))
- return false;
+ if ((rd == NULL) || ((v3d != NULL) && (rv3d == NULL)))
+ return false;
- return (rd->scemode & R_MULTIVIEW) && ((v3d == NULL) || (rv3d->persp == RV3D_CAMOB && v3d->camera));
+ return (rd->scemode & R_MULTIVIEW) &&
+ ((v3d == NULL) || (rv3d->persp == RV3D_CAMOB && v3d->camera));
}
static void screen_opengl_views_setup(OGLRender *oglrender)
{
- RenderResult *rr;
- RenderView *rv;
- SceneRenderView *srv;
- bool is_multiview;
- Object *camera;
- View3D *v3d = oglrender->v3d;
-
- RenderData *rd = &oglrender->scene->r;
-
- rr = RE_AcquireResultWrite(oglrender->re);
-
- is_multiview = screen_opengl_is_multiview(oglrender);
-
- if (!is_multiview) {
- /* we only have one view when multiview is off */
- rv = rr->views.first;
-
- if (rv == NULL) {
- rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
- BLI_addtail(&rr->views, rv);
- }
-
- while (rv->next) {
- RenderView *rv_del = rv->next;
- BLI_remlink(&rr->views, rv_del);
-
- if (rv_del->rectf)
- MEM_freeN(rv_del->rectf);
-
- if (rv_del->rectz)
- MEM_freeN(rv_del->rectz);
-
- if (rv_del->rect32)
- MEM_freeN(rv_del->rect32);
-
- MEM_freeN(rv_del);
- }
- }
- else {
- if (v3d) {
- RE_SetOverrideCamera(oglrender->re, V3D_CAMERA_SCENE(oglrender->scene, v3d));
- }
-
- /* remove all the views that are not needed */
- rv = rr->views.last;
- while (rv) {
- srv = BLI_findstring(&rd->views, rv->name, offsetof(SceneRenderView, name));
- if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
- rv = rv->prev;
- }
- else {
- RenderView *rv_del = rv;
- rv = rv_del->prev;
-
- BLI_remlink(&rr->views, rv_del);
-
- if (rv_del->rectf)
- MEM_freeN(rv_del->rectf);
-
- if (rv_del->rectz)
- MEM_freeN(rv_del->rectz);
-
- if (rv_del->rect32)
- MEM_freeN(rv_del->rect32);
-
- MEM_freeN(rv_del);
- }
- }
-
- /* create all the views that are needed */
- for (srv = rd->views.first; srv; srv = srv->next) {
- if (BKE_scene_multiview_is_render_view_active(rd, srv) == false)
- continue;
-
- rv = BLI_findstring(&rr->views, srv->name, offsetof(SceneRenderView, name));
-
- if (rv == NULL) {
- rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
- BLI_strncpy(rv->name, srv->name, sizeof(rv->name));
- BLI_addtail(&rr->views, rv);
- }
- }
- }
-
- if (!(is_multiview && BKE_scene_multiview_is_stereo3d(rd)))
- oglrender->iuser.flag &= ~IMA_SHOW_STEREO;
-
- /* will only work for non multiview correctly */
- if (v3d) {
- camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, "new opengl render view");
- BKE_render_result_stamp_info(oglrender->scene, camera, rr, false);
- }
- else {
- BKE_render_result_stamp_info(oglrender->scene, oglrender->scene->camera, rr, false);
- }
-
- RE_ReleaseResult(oglrender->re);
+ RenderResult *rr;
+ RenderView *rv;
+ SceneRenderView *srv;
+ bool is_multiview;
+ Object *camera;
+ View3D *v3d = oglrender->v3d;
+
+ RenderData *rd = &oglrender->scene->r;
+
+ rr = RE_AcquireResultWrite(oglrender->re);
+
+ is_multiview = screen_opengl_is_multiview(oglrender);
+
+ if (!is_multiview) {
+ /* we only have one view when multiview is off */
+ rv = rr->views.first;
+
+ if (rv == NULL) {
+ rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
+ BLI_addtail(&rr->views, rv);
+ }
+
+ while (rv->next) {
+ RenderView *rv_del = rv->next;
+ BLI_remlink(&rr->views, rv_del);
+
+ if (rv_del->rectf)
+ MEM_freeN(rv_del->rectf);
+
+ if (rv_del->rectz)
+ MEM_freeN(rv_del->rectz);
+
+ if (rv_del->rect32)
+ MEM_freeN(rv_del->rect32);
+
+ MEM_freeN(rv_del);
+ }
+ }
+ else {
+ if (v3d) {
+ RE_SetOverrideCamera(oglrender->re, V3D_CAMERA_SCENE(oglrender->scene, v3d));
+ }
+
+ /* remove all the views that are not needed */
+ rv = rr->views.last;
+ while (rv) {
+ srv = BLI_findstring(&rd->views, rv->name, offsetof(SceneRenderView, name));
+ if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
+ rv = rv->prev;
+ }
+ else {
+ RenderView *rv_del = rv;
+ rv = rv_del->prev;
+
+ BLI_remlink(&rr->views, rv_del);
+
+ if (rv_del->rectf)
+ MEM_freeN(rv_del->rectf);
+
+ if (rv_del->rectz)
+ MEM_freeN(rv_del->rectz);
+
+ if (rv_del->rect32)
+ MEM_freeN(rv_del->rect32);
+
+ MEM_freeN(rv_del);
+ }
+ }
+
+ /* create all the views that are needed */
+ for (srv = rd->views.first; srv; srv = srv->next) {
+ if (BKE_scene_multiview_is_render_view_active(rd, srv) == false)
+ continue;
+
+ rv = BLI_findstring(&rr->views, srv->name, offsetof(SceneRenderView, name));
+
+ if (rv == NULL) {
+ rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
+ BLI_strncpy(rv->name, srv->name, sizeof(rv->name));
+ BLI_addtail(&rr->views, rv);
+ }
+ }
+ }
+
+ if (!(is_multiview && BKE_scene_multiview_is_stereo3d(rd)))
+ oglrender->iuser.flag &= ~IMA_SHOW_STEREO;
+
+ /* will only work for non multiview correctly */
+ if (v3d) {
+ camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, "new opengl render view");
+ BKE_render_result_stamp_info(oglrender->scene, camera, rr, false);
+ }
+ else {
+ BKE_render_result_stamp_info(oglrender->scene, oglrender->scene->camera, rr, false);
+ }
+
+ RE_ReleaseResult(oglrender->re);
}
static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, RenderResult *rr)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Scene *scene = oglrender->scene;
- ARegion *ar = oglrender->ar;
- View3D *v3d = oglrender->v3d;
- RegionView3D *rv3d = oglrender->rv3d;
- Object *camera = NULL;
- int sizex = oglrender->sizex;
- int sizey = oglrender->sizey;
- const short view_context = (v3d != NULL);
- bool draw_sky = (scene->r.alphamode == R_ADDSKY);
- float *rectf = NULL;
- const char *viewname = RE_GetActiveRenderView(oglrender->re);
- ImBuf *ibuf_result = NULL;
-
- if (oglrender->is_sequencer) {
- SpaceSeq *sseq = oglrender->sseq;
- struct bGPdata *gpd = (sseq && (sseq->flag & SEQ_SHOW_GPENCIL)) ? sseq->gpd : NULL;
-
- /* use pre-calculated ImBuf (avoids deadlock), see: */
- ImBuf *ibuf = oglrender->seq_data.ibufs_arr[oglrender->view_id];
-
- if (ibuf) {
- ImBuf *out = IMB_dupImBuf(ibuf);
- IMB_freeImBuf(ibuf);
- /* OpenGL render is considered to be preview and should be
- * as fast as possible. So currently we're making sure sequencer
- * result is always byte to simplify color management pipeline.
- *
- * TODO(sergey): In the case of output to float container (EXR)
- * it actually makes sense to keep float buffer instead.
- */
- if (out->rect_float != NULL) {
- IMB_rect_from_float(out);
- imb_freerectfloatImBuf(out);
- }
- BLI_assert((oglrender->sizex == ibuf->x) && (oglrender->sizey == ibuf->y));
- RE_render_result_rect_from_ibuf(rr, &scene->r, out, oglrender->view_id);
- IMB_freeImBuf(out);
- }
- else if (gpd) {
- /* If there are no strips, Grease Pencil still needs a buffer to draw on */
- ImBuf *out = IMB_allocImBuf(oglrender->sizex, oglrender->sizey, 32, IB_rect);
- RE_render_result_rect_from_ibuf(rr, &scene->r, out, oglrender->view_id);
- IMB_freeImBuf(out);
- }
-
- if (gpd) {
- int i;
- unsigned char *gp_rect;
- unsigned char *render_rect = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32;
-
- DRW_opengl_context_enable();
- GPU_offscreen_bind(oglrender->ofs, true);
-
- GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
- GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT);
-
- wmOrtho2(0, sizex, 0, sizey);
- GPU_matrix_translate_2f(sizex / 2, sizey / 2);
-
- G.f |= G_FLAG_RENDER_VIEWPORT;
- ED_annotation_draw_ex(
- scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
- G.f &= ~G_FLAG_RENDER_VIEWPORT;
-
- gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
- GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect);
-
- for (i = 0; i < sizex * sizey * 4; i += 4) {
- blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]);
- }
- GPU_offscreen_unbind(oglrender->ofs, true);
- DRW_opengl_context_disable();
-
- MEM_freeN(gp_rect);
- }
- }
- else {
- /* shouldnt suddenly give errors mid-render but possible */
- char err_out[256] = "unknown";
- ImBuf *ibuf_view;
- const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
-
- unsigned int draw_flags = V3D_OFSDRAW_NONE;
- draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0;
-
- if (view_context) {
- ibuf_view = ED_view3d_draw_offscreen_imbuf(
- depsgraph, scene, v3d->shading.type,
- v3d, ar, sizex, sizey,
- IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname,
- oglrender->ofs, err_out);
-
- /* for stamp only */
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, viewname);
- }
- }
- else {
- draw_flags |= V3D_OFSDRAW_USE_GPENCIL;
- ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(
- depsgraph, scene, OB_SOLID,
- scene->camera, oglrender->sizex, oglrender->sizey,
- IB_rectfloat, draw_flags,
- alpha_mode, oglrender->ofs_samples, viewname,
- oglrender->ofs, err_out);
- camera = scene->camera;
- }
-
- if (ibuf_view) {
- ibuf_result = ibuf_view;
- rectf = (float *)ibuf_view->rect_float;
- }
- else {
- fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
- }
- }
-
- if (ibuf_result != NULL) {
- if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
- BKE_image_stamp_buf(scene, camera, NULL, NULL, rectf, rr->rectx, rr->recty, 4);
- }
- RE_render_result_rect_from_ibuf(rr, &scene->r, ibuf_result, oglrender->view_id);
- IMB_freeImBuf(ibuf_result);
- }
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Scene *scene = oglrender->scene;
+ ARegion *ar = oglrender->ar;
+ View3D *v3d = oglrender->v3d;
+ RegionView3D *rv3d = oglrender->rv3d;
+ Object *camera = NULL;
+ int sizex = oglrender->sizex;
+ int sizey = oglrender->sizey;
+ const short view_context = (v3d != NULL);
+ bool draw_sky = (scene->r.alphamode == R_ADDSKY);
+ float *rectf = NULL;
+ const char *viewname = RE_GetActiveRenderView(oglrender->re);
+ ImBuf *ibuf_result = NULL;
+
+ if (oglrender->is_sequencer) {
+ SpaceSeq *sseq = oglrender->sseq;
+ struct bGPdata *gpd = (sseq && (sseq->flag & SEQ_SHOW_GPENCIL)) ? sseq->gpd : NULL;
+
+ /* use pre-calculated ImBuf (avoids deadlock), see: */
+ ImBuf *ibuf = oglrender->seq_data.ibufs_arr[oglrender->view_id];
+
+ if (ibuf) {
+ ImBuf *out = IMB_dupImBuf(ibuf);
+ IMB_freeImBuf(ibuf);
+ /* OpenGL render is considered to be preview and should be
+ * as fast as possible. So currently we're making sure sequencer
+ * result is always byte to simplify color management pipeline.
+ *
+ * TODO(sergey): In the case of output to float container (EXR)
+ * it actually makes sense to keep float buffer instead.
+ */
+ if (out->rect_float != NULL) {
+ IMB_rect_from_float(out);
+ imb_freerectfloatImBuf(out);
+ }
+ BLI_assert((oglrender->sizex == ibuf->x) && (oglrender->sizey == ibuf->y));
+ RE_render_result_rect_from_ibuf(rr, &scene->r, out, oglrender->view_id);
+ IMB_freeImBuf(out);
+ }
+ else if (gpd) {
+ /* If there are no strips, Grease Pencil still needs a buffer to draw on */
+ ImBuf *out = IMB_allocImBuf(oglrender->sizex, oglrender->sizey, 32, IB_rect);
+ RE_render_result_rect_from_ibuf(rr, &scene->r, out, oglrender->view_id);
+ IMB_freeImBuf(out);
+ }
+
+ if (gpd) {
+ int i;
+ unsigned char *gp_rect;
+ unsigned char *render_rect =
+ (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32;
+
+ DRW_opengl_context_enable();
+ GPU_offscreen_bind(oglrender->ofs, true);
+
+ GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
+ GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT);
+
+ wmOrtho2(0, sizex, 0, sizey);
+ GPU_matrix_translate_2f(sizex / 2, sizey / 2);
+
+ G.f |= G_FLAG_RENDER_VIEWPORT;
+ ED_annotation_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
+ G.f &= ~G_FLAG_RENDER_VIEWPORT;
+
+ gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
+ GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect);
+
+ for (i = 0; i < sizex * sizey * 4; i += 4) {
+ blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]);
+ }
+ GPU_offscreen_unbind(oglrender->ofs, true);
+ DRW_opengl_context_disable();
+
+ MEM_freeN(gp_rect);
+ }
+ }
+ else {
+ /* shouldnt suddenly give errors mid-render but possible */
+ char err_out[256] = "unknown";
+ ImBuf *ibuf_view;
+ const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
+
+ unsigned int draw_flags = V3D_OFSDRAW_NONE;
+ draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0;
+
+ if (view_context) {
+ ibuf_view = ED_view3d_draw_offscreen_imbuf(depsgraph,
+ scene,
+ v3d->shading.type,
+ v3d,
+ ar,
+ sizex,
+ sizey,
+ IB_rectfloat,
+ draw_flags,
+ alpha_mode,
+ oglrender->ofs_samples,
+ viewname,
+ oglrender->ofs,
+ err_out);
+
+ /* for stamp only */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, viewname);
+ }
+ }
+ else {
+ draw_flags |= V3D_OFSDRAW_USE_GPENCIL;
+ ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(depsgraph,
+ scene,
+ OB_SOLID,
+ scene->camera,
+ oglrender->sizex,
+ oglrender->sizey,
+ IB_rectfloat,
+ draw_flags,
+ alpha_mode,
+ oglrender->ofs_samples,
+ viewname,
+ oglrender->ofs,
+ err_out);
+ camera = scene->camera;
+ }
+
+ if (ibuf_view) {
+ ibuf_result = ibuf_view;
+ rectf = (float *)ibuf_view->rect_float;
+ }
+ else {
+ fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
+ }
+ }
+
+ if (ibuf_result != NULL) {
+ if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
+ BKE_image_stamp_buf(scene, camera, NULL, NULL, rectf, rr->rectx, rr->recty, 4);
+ }
+ RE_render_result_rect_from_ibuf(rr, &scene->r, ibuf_result, oglrender->view_id);
+ IMB_freeImBuf(ibuf_result);
+ }
}
static void screen_opengl_render_write(OGLRender *oglrender)
{
- Scene *scene = oglrender->scene;
- RenderResult *rr;
- bool ok;
- char name[FILE_MAX];
-
- rr = RE_AcquireResultRead(oglrender->re);
-
- BKE_image_path_from_imformat(
- name, scene->r.pic, BKE_main_blendfile_path(oglrender->bmain), scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false, NULL);
-
- /* write images as individual images or stereo */
- BKE_render_result_stamp_info(scene, scene->camera, rr, false);
- ok = RE_WriteRenderViewsImage(oglrender->reports, rr, scene, false, name);
-
- RE_ReleaseResultImage(oglrender->re);
-
- if (ok) printf("OpenGL Render written to '%s'\n", name);
- else printf("OpenGL Render failed to write '%s'\n", name);
+ Scene *scene = oglrender->scene;
+ RenderResult *rr;
+ bool ok;
+ char name[FILE_MAX];
+
+ rr = RE_AcquireResultRead(oglrender->re);
+
+ BKE_image_path_from_imformat(name,
+ scene->r.pic,
+ BKE_main_blendfile_path(oglrender->bmain),
+ scene->r.cfra,
+ &scene->r.im_format,
+ (scene->r.scemode & R_EXTENSION) != 0,
+ false,
+ NULL);
+
+ /* write images as individual images or stereo */
+ BKE_render_result_stamp_info(scene, scene->camera, rr, false);
+ ok = RE_WriteRenderViewsImage(oglrender->reports, rr, scene, false, name);
+
+ RE_ReleaseResultImage(oglrender->re);
+
+ if (ok)
+ printf("OpenGL Render written to '%s'\n", name);
+ else
+ printf("OpenGL Render failed to write '%s'\n", name);
}
static void UNUSED_FUNCTION(addAlphaOverFloat)(float dest[4], const float source[4])
{
- /* d = s + (1-alpha_s)d*/
- float mul;
-
- mul = 1.0f - source[3];
+ /* d = s + (1-alpha_s)d*/
+ float mul;
- dest[0] = (mul * dest[0]) + source[0];
- dest[1] = (mul * dest[1]) + source[1];
- dest[2] = (mul * dest[2]) + source[2];
- dest[3] = (mul * dest[3]) + source[3];
+ mul = 1.0f - source[3];
+ dest[0] = (mul * dest[0]) + source[0];
+ dest[1] = (mul * dest[1]) + source[1];
+ dest[2] = (mul * dest[2]) + source[2];
+ dest[3] = (mul * dest[3]) + source[3];
}
static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender)
{
- RenderResult *rr;
- RenderView *rv;
- int view_id;
- ImBuf *ibuf;
- void *lock;
-
- if (oglrender->is_sequencer) {
- Scene *scene = oglrender->scene;
-
- SeqRenderData context;
- SpaceSeq *sseq = oglrender->sseq;
- int chanshown = sseq ? sseq->chanshown : 0;
-
- BKE_sequencer_new_render_data(
- oglrender->bmain, oglrender->depsgraph, scene,
- oglrender->sizex, oglrender->sizey, 100.0f, false,
- &context);
-
- for (view_id = 0; view_id < oglrender->views_len; view_id++) {
- context.view_id = view_id;
- context.gpu_offscreen = oglrender->ofs;
- context.gpu_full_samples = oglrender->ofs_full_samples;
-
- oglrender->seq_data.ibufs_arr[view_id] = BKE_sequencer_give_ibuf(&context, CFRA, chanshown);
- }
- }
-
- rr = RE_AcquireResultRead(oglrender->re);
- for (rv = rr->views.first, view_id = 0; rv; rv = rv->next, view_id++) {
- BLI_assert(view_id < oglrender->views_len);
- RE_SetActiveRenderView(oglrender->re, rv->name);
- oglrender->view_id = view_id;
- /* render composite */
- screen_opengl_render_doit(C, oglrender, rr);
- }
-
- RE_ReleaseResult(oglrender->re);
-
- ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
- if (ibuf) {
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
- }
- BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
-
- if (oglrender->write_still) {
- screen_opengl_render_write(oglrender);
- }
+ RenderResult *rr;
+ RenderView *rv;
+ int view_id;
+ ImBuf *ibuf;
+ void *lock;
+
+ if (oglrender->is_sequencer) {
+ Scene *scene = oglrender->scene;
+
+ SeqRenderData context;
+ SpaceSeq *sseq = oglrender->sseq;
+ int chanshown = sseq ? sseq->chanshown : 0;
+
+ BKE_sequencer_new_render_data(oglrender->bmain,
+ oglrender->depsgraph,
+ scene,
+ oglrender->sizex,
+ oglrender->sizey,
+ 100.0f,
+ false,
+ &context);
+
+ for (view_id = 0; view_id < oglrender->views_len; view_id++) {
+ context.view_id = view_id;
+ context.gpu_offscreen = oglrender->ofs;
+ context.gpu_full_samples = oglrender->ofs_full_samples;
+
+ oglrender->seq_data.ibufs_arr[view_id] = BKE_sequencer_give_ibuf(&context, CFRA, chanshown);
+ }
+ }
+
+ rr = RE_AcquireResultRead(oglrender->re);
+ for (rv = rr->views.first, view_id = 0; rv; rv = rv->next, view_id++) {
+ BLI_assert(view_id < oglrender->views_len);
+ RE_SetActiveRenderView(oglrender->re, rv->name);
+ oglrender->view_id = view_id;
+ /* render composite */
+ screen_opengl_render_doit(C, oglrender, rr);
+ }
+
+ RE_ReleaseResult(oglrender->re);
+
+ ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
+ if (ibuf) {
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ }
+ BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
+
+ if (oglrender->write_still) {
+ screen_opengl_render_write(oglrender);
+ }
}
static bool screen_opengl_fullsample_enabled(Scene *scene)
{
- if (scene->r.scemode & R_FULL_SAMPLE) {
- return true;
- }
- else {
- /* XXX TODO:
- * Technically if the hardware supports MSAA we could keep using Blender 2.7x approach.
- * However anti-aliasing without full_sample is not playing well even in 2.7x.
- *
- * For example, if you enable depth of field, there is aliasing, even if the viewport is fine.
- * For 2.8x this is more complicated because so many things rely on shader.
- * So until we fix the gpu_framebuffer anti-aliasing suupport we need to force full sample.
- */
- return true;
- }
+ if (scene->r.scemode & R_FULL_SAMPLE) {
+ return true;
+ }
+ else {
+ /* XXX TODO:
+ * Technically if the hardware supports MSAA we could keep using Blender 2.7x approach.
+ * However anti-aliasing without full_sample is not playing well even in 2.7x.
+ *
+ * For example, if you enable depth of field, there is aliasing, even if the viewport is fine.
+ * For 2.8x this is more complicated because so many things rely on shader.
+ * So until we fix the gpu_framebuffer anti-aliasing suupport we need to force full sample.
+ */
+ return true;
+ }
}
static bool screen_opengl_render_init(bContext *C, wmOperator *op)
{
- /* new render clears all callbacks */
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- WorkSpace *workspace = CTX_wm_workspace(C);
-
- Scene *scene = CTX_data_scene(C);
- ScrArea *prevsa = CTX_wm_area(C);
- ARegion *prevar = CTX_wm_region(C);
- GPUOffScreen *ofs;
- OGLRender *oglrender;
- int sizex, sizey;
- const int samples = (scene->r.mode & R_OSA) ? scene->r.osa : 0;
- const bool full_samples = (samples != 0) && screen_opengl_fullsample_enabled(scene);
- bool is_view_context = RNA_boolean_get(op->ptr, "view_context");
- const bool is_animation = RNA_boolean_get(op->ptr, "animation");
- const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer");
- const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
- char err_out[256] = "unknown";
-
- if (G.background) {
- BKE_report(op->reports, RPT_ERROR, "Cannot use OpenGL render in background mode (no opengl context)");
- return false;
- }
-
- /* only one render job at a time */
- if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER))
- return false;
-
- if (is_sequencer) {
- is_view_context = false;
- }
- else {
- /* ensure we have a 3d view */
- if (!ED_view3d_context_activate(C)) {
- RNA_boolean_set(op->ptr, "view_context", false);
- is_view_context = false;
- }
-
- if (!is_view_context && scene->camera == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Scene has no camera");
- return false;
- }
- }
-
- 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");
- return false;
- }
-
- /* stop all running jobs, except screen one. currently previews frustrate Render */
- WM_jobs_kill_all_except(wm, CTX_wm_screen(C));
-
- /* create offscreen buffer */
- sizex = (scene->r.size * scene->r.xsch) / 100;
- sizey = (scene->r.size * scene->r.ysch) / 100;
-
- /* corrects render size with actual size, not every card supports non-power-of-two dimensions */
- DRW_opengl_context_enable(); /* Offscreen creation needs to be done in DRW context. */
- ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, true, err_out);
- DRW_opengl_context_disable();
-
- if (!ofs) {
- BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
- return false;
- }
-
- /* allocate opengl render */
- oglrender = MEM_callocN(sizeof(OGLRender), "OGLRender");
- op->customdata = oglrender;
-
- oglrender->ofs = ofs;
- oglrender->ofs_samples = samples;
- oglrender->ofs_full_samples = full_samples;
- oglrender->sizex = sizex;
- oglrender->sizey = sizey;
- oglrender->bmain = CTX_data_main(C);
- oglrender->scene = scene;
- oglrender->workspace = workspace;
- oglrender->view_layer = CTX_data_view_layer(C);
- oglrender->depsgraph = CTX_data_depsgraph(C);
- oglrender->cfrao = scene->r.cfra;
-
- oglrender->write_still = is_write_still && !is_animation;
- oglrender->is_animation = is_animation;
-
- oglrender->views_len = BKE_scene_multiview_num_views_get(&scene->r);
-
- oglrender->is_sequencer = is_sequencer;
- if (is_sequencer) {
- oglrender->sseq = CTX_wm_space_seq(C);
- ImBuf **ibufs_arr = MEM_callocN(sizeof(*ibufs_arr) * oglrender->views_len, __func__);
- oglrender->seq_data.ibufs_arr = ibufs_arr;
- }
-
- oglrender->prevsa = prevsa;
- oglrender->prevar = prevar;
-
- if (is_view_context) {
- /* so quad view renders camera */
- ED_view3d_context_user_region(C, &oglrender->v3d, &oglrender->ar);
-
- oglrender->rv3d = oglrender->ar->regiondata;
-
- /* MUST be cleared on exit */
- memset(&oglrender->scene->customdata_mask_modal, 0, sizeof(oglrender->scene->customdata_mask_modal));
- ED_view3d_datamask(C, oglrender->scene, oglrender->v3d, &oglrender->scene->customdata_mask_modal);
-
- /* apply immediately in case we're rendering from a script,
- * running notifiers again will overwrite */
- CustomData_MeshMasks_update(&oglrender->scene->customdata_mask, &oglrender->scene->customdata_mask_modal);
- }
-
- /* create render */
- oglrender->re = RE_NewSceneRender(scene);
-
- /* create image and image user */
- oglrender->ima = BKE_image_verify_viewer(oglrender->bmain, IMA_TYPE_R_RESULT, "Render Result");
- BKE_image_signal(oglrender->bmain, oglrender->ima, NULL, IMA_SIGNAL_FREE);
- BKE_image_backup_render(oglrender->scene, oglrender->ima, true);
-
- oglrender->iuser.scene = scene;
- oglrender->iuser.ok = 1;
-
- /* create render result */
- RE_InitState(oglrender->re, NULL, &scene->r, &scene->view_layers, NULL, sizex, sizey, NULL);
-
- /* create render views */
- screen_opengl_views_setup(oglrender);
-
- /* wm vars */
- oglrender->wm = wm;
- oglrender->win = win;
-
- oglrender->totvideos = 0;
- oglrender->mh = NULL;
- oglrender->movie_ctx_arr = NULL;
-
- if (is_animation) {
- TaskScheduler *task_scheduler = BLI_task_scheduler_get();
- if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
- task_scheduler = BLI_task_scheduler_create(1);
- oglrender->task_scheduler = task_scheduler;
- oglrender->task_pool = BLI_task_pool_create_background(task_scheduler,
- oglrender);
- }
- else {
- oglrender->task_scheduler = NULL;
- oglrender->task_pool = BLI_task_pool_create(task_scheduler,
- oglrender);
- }
- oglrender->pool_ok = true;
- BLI_spin_init(&oglrender->reports_lock);
- }
- else {
- oglrender->task_scheduler = NULL;
- oglrender->task_pool = NULL;
- }
- oglrender->num_scheduled_frames = 0;
- BLI_mutex_init(&oglrender->task_mutex);
- BLI_condition_init(&oglrender->task_condition);
+ /* new render clears all callbacks */
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+
+ Scene *scene = CTX_data_scene(C);
+ ScrArea *prevsa = CTX_wm_area(C);
+ ARegion *prevar = CTX_wm_region(C);
+ GPUOffScreen *ofs;
+ OGLRender *oglrender;
+ int sizex, sizey;
+ const int samples = (scene->r.mode & R_OSA) ? scene->r.osa : 0;
+ const bool full_samples = (samples != 0) && screen_opengl_fullsample_enabled(scene);
+ bool is_view_context = RNA_boolean_get(op->ptr, "view_context");
+ const bool is_animation = RNA_boolean_get(op->ptr, "animation");
+ const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer");
+ const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
+ char err_out[256] = "unknown";
+
+ if (G.background) {
+ BKE_report(
+ op->reports, RPT_ERROR, "Cannot use OpenGL render in background mode (no opengl context)");
+ return false;
+ }
+
+ /* only one render job at a time */
+ if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER))
+ return false;
+
+ if (is_sequencer) {
+ is_view_context = false;
+ }
+ else {
+ /* ensure we have a 3d view */
+ if (!ED_view3d_context_activate(C)) {
+ RNA_boolean_set(op->ptr, "view_context", false);
+ is_view_context = false;
+ }
+
+ if (!is_view_context && scene->camera == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Scene has no camera");
+ return false;
+ }
+ }
+
+ 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");
+ return false;
+ }
+
+ /* stop all running jobs, except screen one. currently previews frustrate Render */
+ WM_jobs_kill_all_except(wm, CTX_wm_screen(C));
+
+ /* create offscreen buffer */
+ sizex = (scene->r.size * scene->r.xsch) / 100;
+ sizey = (scene->r.size * scene->r.ysch) / 100;
+
+ /* corrects render size with actual size, not every card supports non-power-of-two dimensions */
+ DRW_opengl_context_enable(); /* Offscreen creation needs to be done in DRW context. */
+ ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, true, err_out);
+ DRW_opengl_context_disable();
+
+ if (!ofs) {
+ BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
+ return false;
+ }
+
+ /* allocate opengl render */
+ oglrender = MEM_callocN(sizeof(OGLRender), "OGLRender");
+ op->customdata = oglrender;
+
+ oglrender->ofs = ofs;
+ oglrender->ofs_samples = samples;
+ oglrender->ofs_full_samples = full_samples;
+ oglrender->sizex = sizex;
+ oglrender->sizey = sizey;
+ oglrender->bmain = CTX_data_main(C);
+ oglrender->scene = scene;
+ oglrender->workspace = workspace;
+ oglrender->view_layer = CTX_data_view_layer(C);
+ oglrender->depsgraph = CTX_data_depsgraph(C);
+ oglrender->cfrao = scene->r.cfra;
+
+ oglrender->write_still = is_write_still && !is_animation;
+ oglrender->is_animation = is_animation;
+
+ oglrender->views_len = BKE_scene_multiview_num_views_get(&scene->r);
+
+ oglrender->is_sequencer = is_sequencer;
+ if (is_sequencer) {
+ oglrender->sseq = CTX_wm_space_seq(C);
+ ImBuf **ibufs_arr = MEM_callocN(sizeof(*ibufs_arr) * oglrender->views_len, __func__);
+ oglrender->seq_data.ibufs_arr = ibufs_arr;
+ }
+
+ oglrender->prevsa = prevsa;
+ oglrender->prevar = prevar;
+
+ if (is_view_context) {
+ /* so quad view renders camera */
+ ED_view3d_context_user_region(C, &oglrender->v3d, &oglrender->ar);
+
+ oglrender->rv3d = oglrender->ar->regiondata;
+
+ /* MUST be cleared on exit */
+ memset(&oglrender->scene->customdata_mask_modal,
+ 0,
+ sizeof(oglrender->scene->customdata_mask_modal));
+ ED_view3d_datamask(
+ C, oglrender->scene, oglrender->v3d, &oglrender->scene->customdata_mask_modal);
+
+ /* apply immediately in case we're rendering from a script,
+ * running notifiers again will overwrite */
+ CustomData_MeshMasks_update(&oglrender->scene->customdata_mask,
+ &oglrender->scene->customdata_mask_modal);
+ }
+
+ /* create render */
+ oglrender->re = RE_NewSceneRender(scene);
+
+ /* create image and image user */
+ oglrender->ima = BKE_image_verify_viewer(oglrender->bmain, IMA_TYPE_R_RESULT, "Render Result");
+ BKE_image_signal(oglrender->bmain, oglrender->ima, NULL, IMA_SIGNAL_FREE);
+ BKE_image_backup_render(oglrender->scene, oglrender->ima, true);
+
+ oglrender->iuser.scene = scene;
+ oglrender->iuser.ok = 1;
+
+ /* create render result */
+ RE_InitState(oglrender->re, NULL, &scene->r, &scene->view_layers, NULL, sizex, sizey, NULL);
+
+ /* create render views */
+ screen_opengl_views_setup(oglrender);
+
+ /* wm vars */
+ oglrender->wm = wm;
+ oglrender->win = win;
+
+ oglrender->totvideos = 0;
+ oglrender->mh = NULL;
+ oglrender->movie_ctx_arr = NULL;
+
+ if (is_animation) {
+ TaskScheduler *task_scheduler = BLI_task_scheduler_get();
+ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
+ task_scheduler = BLI_task_scheduler_create(1);
+ oglrender->task_scheduler = task_scheduler;
+ oglrender->task_pool = BLI_task_pool_create_background(task_scheduler, oglrender);
+ }
+ else {
+ oglrender->task_scheduler = NULL;
+ oglrender->task_pool = BLI_task_pool_create(task_scheduler, oglrender);
+ }
+ oglrender->pool_ok = true;
+ BLI_spin_init(&oglrender->reports_lock);
+ }
+ else {
+ oglrender->task_scheduler = NULL;
+ oglrender->task_pool = NULL;
+ }
+ oglrender->num_scheduled_frames = 0;
+ BLI_mutex_init(&oglrender->task_mutex);
+ BLI_condition_init(&oglrender->task_condition);
#ifdef DEBUG_TIME
- oglrender->time_start = PIL_check_seconds_timer();
+ oglrender->time_start = PIL_check_seconds_timer();
#endif
- return true;
+ return true;
}
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = oglrender->scene;
- int i;
-
- if (oglrender->is_animation) {
- /* Trickery part for movie output:
- *
- * We MUST write frames in an exact order, so we only let background
- * thread to work on that, and main thread is simply waits for that
- * thread to do all the dirty work.
- *
- * After this loop is done work_and_wait() will have nothing to do,
- * so we don't run into wrong order of frames written to the stream.
- */
- if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
- BLI_mutex_lock(&oglrender->task_mutex);
- while (oglrender->num_scheduled_frames > 0) {
- BLI_condition_wait(&oglrender->task_condition,
- &oglrender->task_mutex);
- }
- BLI_mutex_unlock(&oglrender->task_mutex);
- }
- BLI_task_pool_work_and_wait(oglrender->task_pool);
- BLI_task_pool_free(oglrender->task_pool);
- /* Depending on various things we might or might not use global scheduler. */
- if (oglrender->task_scheduler != NULL) {
- BLI_task_scheduler_free(oglrender->task_scheduler);
- }
- BLI_spin_end(&oglrender->reports_lock);
- }
- BLI_mutex_end(&oglrender->task_mutex);
- BLI_condition_end(&oglrender->task_condition);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = oglrender->scene;
+ int i;
+
+ if (oglrender->is_animation) {
+ /* Trickery part for movie output:
+ *
+ * We MUST write frames in an exact order, so we only let background
+ * thread to work on that, and main thread is simply waits for that
+ * thread to do all the dirty work.
+ *
+ * After this loop is done work_and_wait() will have nothing to do,
+ * so we don't run into wrong order of frames written to the stream.
+ */
+ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
+ BLI_mutex_lock(&oglrender->task_mutex);
+ while (oglrender->num_scheduled_frames > 0) {
+ BLI_condition_wait(&oglrender->task_condition, &oglrender->task_mutex);
+ }
+ BLI_mutex_unlock(&oglrender->task_mutex);
+ }
+ BLI_task_pool_work_and_wait(oglrender->task_pool);
+ BLI_task_pool_free(oglrender->task_pool);
+ /* Depending on various things we might or might not use global scheduler. */
+ if (oglrender->task_scheduler != NULL) {
+ BLI_task_scheduler_free(oglrender->task_scheduler);
+ }
+ BLI_spin_end(&oglrender->reports_lock);
+ }
+ BLI_mutex_end(&oglrender->task_mutex);
+ BLI_condition_end(&oglrender->task_condition);
#ifdef DEBUG_TIME
- printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start);
+ printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start);
#endif
- if (oglrender->mh) {
- if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
- for (i = 0; i < oglrender->totvideos; i++) {
- oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]);
- oglrender->mh->context_free(oglrender->movie_ctx_arr[i]);
- }
- }
+ if (oglrender->mh) {
+ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
+ for (i = 0; i < oglrender->totvideos; i++) {
+ oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]);
+ oglrender->mh->context_free(oglrender->movie_ctx_arr[i]);
+ }
+ }
- if (oglrender->movie_ctx_arr) {
- MEM_freeN(oglrender->movie_ctx_arr);
- }
- }
+ if (oglrender->movie_ctx_arr) {
+ MEM_freeN(oglrender->movie_ctx_arr);
+ }
+ }
- if (oglrender->timer) { /* exec will not have a timer */
- Depsgraph *depsgraph = oglrender->depsgraph;
- scene->r.cfra = oglrender->cfrao;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ if (oglrender->timer) { /* exec will not have a timer */
+ Depsgraph *depsgraph = oglrender->depsgraph;
+ scene->r.cfra = oglrender->cfrao;
+ BKE_scene_graph_update_for_newframe(depsgraph, bmain);
- WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
- }
+ WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
+ }
- WM_cursor_modal_restore(oglrender->win);
+ WM_cursor_modal_restore(oglrender->win);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
- DRW_opengl_context_enable();
- GPU_offscreen_free(oglrender->ofs);
- DRW_opengl_context_disable();
+ DRW_opengl_context_enable();
+ GPU_offscreen_free(oglrender->ofs);
+ DRW_opengl_context_disable();
- if (oglrender->is_sequencer) {
- MEM_freeN(oglrender->seq_data.ibufs_arr);
- }
+ if (oglrender->is_sequencer) {
+ MEM_freeN(oglrender->seq_data.ibufs_arr);
+ }
- memset(&oglrender->scene->customdata_mask_modal, 0, sizeof(oglrender->scene->customdata_mask_modal));
+ memset(&oglrender->scene->customdata_mask_modal,
+ 0,
+ sizeof(oglrender->scene->customdata_mask_modal));
- CTX_wm_area_set(C, oglrender->prevsa);
- CTX_wm_region_set(C, oglrender->prevar);
+ CTX_wm_area_set(C, oglrender->prevsa);
+ CTX_wm_region_set(C, oglrender->prevar);
- MEM_freeN(oglrender);
+ MEM_freeN(oglrender);
}
static void screen_opengl_render_cancel(bContext *C, wmOperator *op)
{
- screen_opengl_render_end(C, op->customdata);
+ screen_opengl_render_end(C, op->customdata);
}
/* share between invoke and exec */
static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
{
- /* initialize animation */
- OGLRender *oglrender;
- Scene *scene;
-
- oglrender = op->customdata;
- scene = oglrender->scene;
- oglrender->totvideos = BKE_scene_multiview_num_videos_get(&scene->r);
-
- oglrender->reports = op->reports;
-
- if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
- size_t width, height;
- int i;
-
- BKE_scene_multiview_videos_dimensions_get(&scene->r, oglrender->sizex, oglrender->sizey, &width, &height);
- oglrender->mh = BKE_movie_handle_get(scene->r.im_format.imtype);
-
- if (oglrender->mh == NULL) {
- BKE_report(oglrender->reports, RPT_ERROR, "Movie format unsupported");
- screen_opengl_render_end(C, oglrender);
- return false;
- }
-
- oglrender->movie_ctx_arr = MEM_mallocN(sizeof(void *) * oglrender->totvideos, "Movies");
-
- for (i = 0; i < oglrender->totvideos; i++) {
- const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, i);
-
- oglrender->movie_ctx_arr[i] = oglrender->mh->context_create();
- if (!oglrender->mh->start_movie(oglrender->movie_ctx_arr[i], scene, &scene->r, oglrender->sizex,
- oglrender->sizey, oglrender->reports, PRVRANGEON != 0, suffix))
- {
- screen_opengl_render_end(C, oglrender);
- return false;
- }
- }
- }
-
- oglrender->cfrao = scene->r.cfra;
- oglrender->nfra = PSFRA;
- scene->r.cfra = PSFRA;
-
- return true;
+ /* initialize animation */
+ OGLRender *oglrender;
+ Scene *scene;
+
+ oglrender = op->customdata;
+ scene = oglrender->scene;
+ oglrender->totvideos = BKE_scene_multiview_num_videos_get(&scene->r);
+
+ oglrender->reports = op->reports;
+
+ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
+ size_t width, height;
+ int i;
+
+ BKE_scene_multiview_videos_dimensions_get(
+ &scene->r, oglrender->sizex, oglrender->sizey, &width, &height);
+ oglrender->mh = BKE_movie_handle_get(scene->r.im_format.imtype);
+
+ if (oglrender->mh == NULL) {
+ BKE_report(oglrender->reports, RPT_ERROR, "Movie format unsupported");
+ screen_opengl_render_end(C, oglrender);
+ return false;
+ }
+
+ oglrender->movie_ctx_arr = MEM_mallocN(sizeof(void *) * oglrender->totvideos, "Movies");
+
+ for (i = 0; i < oglrender->totvideos; i++) {
+ const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, i);
+
+ oglrender->movie_ctx_arr[i] = oglrender->mh->context_create();
+ if (!oglrender->mh->start_movie(oglrender->movie_ctx_arr[i],
+ scene,
+ &scene->r,
+ oglrender->sizex,
+ oglrender->sizey,
+ oglrender->reports,
+ PRVRANGEON != 0,
+ suffix)) {
+ screen_opengl_render_end(C, oglrender);
+ return false;
+ }
+ }
+ }
+
+ oglrender->cfrao = scene->r.cfra;
+ oglrender->nfra = PSFRA;
+ scene->r.cfra = PSFRA;
+
+ return true;
}
typedef struct WriteTaskData {
- RenderResult *rr;
- Scene tmp_scene;
+ RenderResult *rr;
+ Scene tmp_scene;
} WriteTaskData;
-static void write_result_func(TaskPool * __restrict pool,
- void *task_data_v,
- int UNUSED(thread_id))
+static void write_result_func(TaskPool *__restrict pool, void *task_data_v, int UNUSED(thread_id))
{
- OGLRender *oglrender = (OGLRender *) BLI_task_pool_userdata(pool);
- WriteTaskData *task_data = (WriteTaskData *) task_data_v;
- Scene *scene = &task_data->tmp_scene;
- RenderResult *rr = task_data->rr;
- const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
- const int cfra = scene->r.cfra;
- bool ok;
- /* Don't attempt to write if we've got an error. */
- if (!oglrender->pool_ok) {
- RE_FreeRenderResult(rr);
- BLI_mutex_lock(&oglrender->task_mutex);
- oglrender->num_scheduled_frames--;
- BLI_condition_notify_all(&oglrender->task_condition);
- BLI_mutex_unlock(&oglrender->task_mutex);
- return;
- }
- /* Construct local thread0safe copy of reports structure which we can
- * safely pass to the underlying functions.
- */
- ReportList reports;
- BKE_reports_init(&reports, oglrender->reports->flag & ~RPT_PRINT);
- /* Do actual save logic here, depending on the file format.
- *
- * NOTE: We have to construct temporary scene with proper scene->r.cfra.
- * This is because underlying calls do not use r.cfra but use scene
- * for that.
- */
- if (is_movie) {
- ok = RE_WriteRenderViewsMovie(&reports,
- rr,
- scene,
- &scene->r,
- oglrender->mh,
- oglrender->movie_ctx_arr,
- oglrender->totvideos,
- PRVRANGEON != 0);
- }
- else {
- /* TODO(sergey): We can in theory save some CPU ticks here because we
- * calculate file name again here.
- */
- char name[FILE_MAX];
- BKE_image_path_from_imformat(name,
- scene->r.pic,
- BKE_main_blendfile_path(oglrender->bmain),
- cfra,
- &scene->r.im_format,
- (scene->r.scemode & R_EXTENSION) != 0,
- true,
- NULL);
-
- BKE_render_result_stamp_info(scene, scene->camera, rr, false);
- ok = RE_WriteRenderViewsImage(NULL, rr, scene, true, name);
- if (!ok) {
- BKE_reportf(&reports,
- RPT_ERROR,
- "Write error: cannot save %s",
- name);
- }
- }
- if (reports.list.first != NULL) {
- BLI_spin_lock(&oglrender->reports_lock);
- for (Report *report = reports.list.first;
- report != NULL;
- report = report->next)
- {
- BKE_report(oglrender->reports,
- report->type,
- report->message);
- }
- BLI_spin_unlock(&oglrender->reports_lock);
- }
- if (!ok) {
- oglrender->pool_ok = false;
- }
- RE_FreeRenderResult(rr);
- BLI_mutex_lock(&oglrender->task_mutex);
- oglrender->num_scheduled_frames--;
- BLI_condition_notify_all(&oglrender->task_condition);
- BLI_mutex_unlock(&oglrender->task_mutex);
+ OGLRender *oglrender = (OGLRender *)BLI_task_pool_userdata(pool);
+ WriteTaskData *task_data = (WriteTaskData *)task_data_v;
+ Scene *scene = &task_data->tmp_scene;
+ RenderResult *rr = task_data->rr;
+ const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
+ const int cfra = scene->r.cfra;
+ bool ok;
+ /* Don't attempt to write if we've got an error. */
+ if (!oglrender->pool_ok) {
+ RE_FreeRenderResult(rr);
+ BLI_mutex_lock(&oglrender->task_mutex);
+ oglrender->num_scheduled_frames--;
+ BLI_condition_notify_all(&oglrender->task_condition);
+ BLI_mutex_unlock(&oglrender->task_mutex);
+ return;
+ }
+ /* Construct local thread0safe copy of reports structure which we can
+ * safely pass to the underlying functions.
+ */
+ ReportList reports;
+ BKE_reports_init(&reports, oglrender->reports->flag & ~RPT_PRINT);
+ /* Do actual save logic here, depending on the file format.
+ *
+ * NOTE: We have to construct temporary scene with proper scene->r.cfra.
+ * This is because underlying calls do not use r.cfra but use scene
+ * for that.
+ */
+ if (is_movie) {
+ ok = RE_WriteRenderViewsMovie(&reports,
+ rr,
+ scene,
+ &scene->r,
+ oglrender->mh,
+ oglrender->movie_ctx_arr,
+ oglrender->totvideos,
+ PRVRANGEON != 0);
+ }
+ else {
+ /* TODO(sergey): We can in theory save some CPU ticks here because we
+ * calculate file name again here.
+ */
+ char name[FILE_MAX];
+ BKE_image_path_from_imformat(name,
+ scene->r.pic,
+ BKE_main_blendfile_path(oglrender->bmain),
+ cfra,
+ &scene->r.im_format,
+ (scene->r.scemode & R_EXTENSION) != 0,
+ true,
+ NULL);
+
+ BKE_render_result_stamp_info(scene, scene->camera, rr, false);
+ ok = RE_WriteRenderViewsImage(NULL, rr, scene, true, name);
+ if (!ok) {
+ BKE_reportf(&reports, RPT_ERROR, "Write error: cannot save %s", name);
+ }
+ }
+ if (reports.list.first != NULL) {
+ BLI_spin_lock(&oglrender->reports_lock);
+ for (Report *report = reports.list.first; report != NULL; report = report->next) {
+ BKE_report(oglrender->reports, report->type, report->message);
+ }
+ BLI_spin_unlock(&oglrender->reports_lock);
+ }
+ if (!ok) {
+ oglrender->pool_ok = false;
+ }
+ RE_FreeRenderResult(rr);
+ BLI_mutex_lock(&oglrender->task_mutex);
+ oglrender->num_scheduled_frames--;
+ BLI_condition_notify_all(&oglrender->task_condition);
+ BLI_mutex_unlock(&oglrender->task_mutex);
}
static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr)
{
- if (!oglrender->pool_ok) {
- RE_FreeRenderResult(rr);
- return false;
- }
- Scene *scene = oglrender->scene;
- WriteTaskData *task_data = MEM_mallocN(sizeof(WriteTaskData), "write task data");
- task_data->rr = rr;
- task_data->tmp_scene = *scene;
- BLI_mutex_lock(&oglrender->task_mutex);
- oglrender->num_scheduled_frames++;
- if (oglrender->num_scheduled_frames > MAX_SCHEDULED_FRAMES) {
- BLI_condition_wait(&oglrender->task_condition,
- &oglrender->task_mutex);
- }
- BLI_mutex_unlock(&oglrender->task_mutex);
- BLI_task_pool_push(oglrender->task_pool,
- write_result_func,
- task_data,
- true,
- TASK_PRIORITY_LOW);
- return true;
+ if (!oglrender->pool_ok) {
+ RE_FreeRenderResult(rr);
+ return false;
+ }
+ Scene *scene = oglrender->scene;
+ WriteTaskData *task_data = MEM_mallocN(sizeof(WriteTaskData), "write task data");
+ task_data->rr = rr;
+ task_data->tmp_scene = *scene;
+ BLI_mutex_lock(&oglrender->task_mutex);
+ oglrender->num_scheduled_frames++;
+ if (oglrender->num_scheduled_frames > MAX_SCHEDULED_FRAMES) {
+ BLI_condition_wait(&oglrender->task_condition, &oglrender->task_mutex);
+ }
+ BLI_mutex_unlock(&oglrender->task_mutex);
+ BLI_task_pool_push(oglrender->task_pool, write_result_func, task_data, true, TASK_PRIORITY_LOW);
+ return true;
}
static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- OGLRender *oglrender = op->customdata;
- Scene *scene = oglrender->scene;
- Depsgraph *depsgraph = oglrender->depsgraph;
- char name[FILE_MAX];
- bool ok = false;
- const bool view_context = (oglrender->v3d != NULL);
- bool is_movie;
- RenderResult *rr;
-
- /* go to next frame */
- if (CFRA < oglrender->nfra)
- CFRA++;
- while (CFRA < oglrender->nfra) {
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
- CFRA++;
- }
-
- is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
-
- if (!is_movie) {
- BKE_image_path_from_imformat(
- name, scene->r.pic, BKE_main_blendfile_path(oglrender->bmain), scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true, NULL);
-
- if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
- BLI_spin_lock(&oglrender->reports_lock);
- BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
- BLI_spin_unlock(&oglrender->reports_lock);
- ok = true;
- goto finally;
- }
- }
-
- WM_cursor_time(oglrender->win, scene->r.cfra);
-
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
-
- if (view_context) {
- if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
- /* since BKE_scene_graph_update_for_newframe() is used rather
- * then ED_update_for_newframe() the camera needs to be set */
- if (BKE_scene_camera_switch_update(scene)) {
- oglrender->v3d->camera = scene->camera;
- }
- }
- }
- else {
- BKE_scene_camera_switch_update(scene);
- }
-
- /* render into offscreen buffer */
- screen_opengl_render_apply(C, oglrender);
-
- /* save to disk */
- rr = RE_AcquireResultRead(oglrender->re);
- RenderResult *new_rr = RE_DuplicateRenderResult(rr);
- RE_ReleaseResult(oglrender->re);
-
- ok = schedule_write_result(oglrender, new_rr);
-
-finally: /* Step the frame and bail early if needed */
-
- /* go to next frame */
- oglrender->nfra += scene->r.frame_step;
-
- /* stop at the end or on error */
- if (CFRA >= PEFRA || !ok) {
- screen_opengl_render_end(C, op->customdata);
- return 0;
- }
-
- return 1;
+ Main *bmain = CTX_data_main(C);
+ OGLRender *oglrender = op->customdata;
+ Scene *scene = oglrender->scene;
+ Depsgraph *depsgraph = oglrender->depsgraph;
+ char name[FILE_MAX];
+ bool ok = false;
+ const bool view_context = (oglrender->v3d != NULL);
+ bool is_movie;
+ RenderResult *rr;
+
+ /* go to next frame */
+ if (CFRA < oglrender->nfra)
+ CFRA++;
+ while (CFRA < oglrender->nfra) {
+ BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ CFRA++;
+ }
+
+ is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
+
+ if (!is_movie) {
+ BKE_image_path_from_imformat(name,
+ scene->r.pic,
+ BKE_main_blendfile_path(oglrender->bmain),
+ scene->r.cfra,
+ &scene->r.im_format,
+ (scene->r.scemode & R_EXTENSION) != 0,
+ true,
+ NULL);
+
+ if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
+ BLI_spin_lock(&oglrender->reports_lock);
+ BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
+ BLI_spin_unlock(&oglrender->reports_lock);
+ ok = true;
+ goto finally;
+ }
+ }
+
+ WM_cursor_time(oglrender->win, scene->r.cfra);
+
+ BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+
+ if (view_context) {
+ if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera &&
+ oglrender->v3d->scenelock) {
+ /* since BKE_scene_graph_update_for_newframe() is used rather
+ * then ED_update_for_newframe() the camera needs to be set */
+ if (BKE_scene_camera_switch_update(scene)) {
+ oglrender->v3d->camera = scene->camera;
+ }
+ }
+ }
+ else {
+ BKE_scene_camera_switch_update(scene);
+ }
+
+ /* render into offscreen buffer */
+ screen_opengl_render_apply(C, oglrender);
+
+ /* save to disk */
+ rr = RE_AcquireResultRead(oglrender->re);
+ RenderResult *new_rr = RE_DuplicateRenderResult(rr);
+ RE_ReleaseResult(oglrender->re);
+
+ ok = schedule_write_result(oglrender, new_rr);
+
+finally: /* Step the frame and bail early if needed */
+
+ /* go to next frame */
+ oglrender->nfra += scene->r.frame_step;
+
+ /* stop at the end or on error */
+ if (CFRA >= PEFRA || !ok) {
+ screen_opengl_render_end(C, op->customdata);
+ return 0;
+ }
+
+ return 1;
}
-
static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- OGLRender *oglrender = op->customdata;
- const bool anim = RNA_boolean_get(op->ptr, "animation");
- bool ret;
-
- switch (event->type) {
- case ESCKEY:
- /* cancel */
- oglrender->pool_ok = false; /* Flag pool for cancel. */
- screen_opengl_render_end(C, op->customdata);
- return OPERATOR_FINISHED;
- case TIMER:
- /* render frame? */
- if (oglrender->timer == event->customdata)
- break;
- ATTR_FALLTHROUGH;
- default:
- /* nothing to do */
- return OPERATOR_RUNNING_MODAL;
- }
-
- /* run first because screen_opengl_render_anim_step can free oglrender */
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
-
- if (anim == 0) {
- screen_opengl_render_apply(C, op->customdata);
- screen_opengl_render_end(C, op->customdata);
- return OPERATOR_FINISHED;
- }
- else {
- ret = screen_opengl_render_anim_step(C, op);
- }
-
- /* stop at the end or on error */
- if (ret == false) {
- return OPERATOR_FINISHED;
- }
-
- return OPERATOR_RUNNING_MODAL;
+ OGLRender *oglrender = op->customdata;
+ const bool anim = RNA_boolean_get(op->ptr, "animation");
+ bool ret;
+
+ switch (event->type) {
+ case ESCKEY:
+ /* cancel */
+ oglrender->pool_ok = false; /* Flag pool for cancel. */
+ screen_opengl_render_end(C, op->customdata);
+ return OPERATOR_FINISHED;
+ case TIMER:
+ /* render frame? */
+ if (oglrender->timer == event->customdata)
+ break;
+ ATTR_FALLTHROUGH;
+ default:
+ /* nothing to do */
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ /* run first because screen_opengl_render_anim_step can free oglrender */
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
+
+ if (anim == 0) {
+ screen_opengl_render_apply(C, op->customdata);
+ screen_opengl_render_end(C, op->customdata);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ ret = screen_opengl_render_anim_step(C, op);
+ }
+
+ /* stop at the end or on error */
+ if (ret == false) {
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- OGLRender *oglrender;
- const bool anim = RNA_boolean_get(op->ptr, "animation");
+ OGLRender *oglrender;
+ const bool anim = RNA_boolean_get(op->ptr, "animation");
- if (!screen_opengl_render_init(C, op))
- return OPERATOR_CANCELLED;
+ if (!screen_opengl_render_init(C, op))
+ return OPERATOR_CANCELLED;
- if (anim) {
- if (!screen_opengl_render_anim_initialize(C, op))
- return OPERATOR_CANCELLED;
- }
+ if (anim) {
+ if (!screen_opengl_render_anim_initialize(C, op))
+ return OPERATOR_CANCELLED;
+ }
- oglrender = op->customdata;
- render_view_open(C, event->x, event->y, op->reports);
+ oglrender = op->customdata;
+ render_view_open(C, event->x, event->y, op->reports);
- /* view may be changed above (R_OUTPUT_WINDOW) */
- oglrender->win = CTX_wm_window(C);
+ /* view may be changed above (R_OUTPUT_WINDOW) */
+ oglrender->win = CTX_wm_window(C);
- WM_event_add_modal_handler(C, op);
- oglrender->timer = WM_event_add_timer(oglrender->wm, oglrender->win, TIMER, 0.01f);
+ WM_event_add_modal_handler(C, op);
+ oglrender->timer = WM_event_add_timer(oglrender->wm, oglrender->win, TIMER, 0.01f);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
/* executes blocking render */
static int screen_opengl_render_exec(bContext *C, wmOperator *op)
{
- const bool is_animation = RNA_boolean_get(op->ptr, "animation");
+ const bool is_animation = RNA_boolean_get(op->ptr, "animation");
- if (!screen_opengl_render_init(C, op))
- return OPERATOR_CANCELLED;
+ if (!screen_opengl_render_init(C, op))
+ return OPERATOR_CANCELLED;
- if (!is_animation) { /* same as invoke */
- /* render image */
- screen_opengl_render_apply(C, op->customdata);
- screen_opengl_render_end(C, op->customdata);
+ if (!is_animation) { /* same as invoke */
+ /* render image */
+ screen_opengl_render_apply(C, op->customdata);
+ screen_opengl_render_end(C, op->customdata);
- return OPERATOR_FINISHED;
- }
- else {
- bool ret = true;
+ return OPERATOR_FINISHED;
+ }
+ else {
+ bool ret = true;
- if (!screen_opengl_render_anim_initialize(C, op))
- return OPERATOR_CANCELLED;
+ if (!screen_opengl_render_anim_initialize(C, op))
+ return OPERATOR_CANCELLED;
- while (ret) {
- ret = screen_opengl_render_anim_step(C, op);
- }
- }
+ while (ret) {
+ ret = screen_opengl_render_anim_step(C, op);
+ }
+ }
- /* no redraw needed, we leave state as we entered it */
-// ED_update_for_newframe(C);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, CTX_data_scene(C));
+ /* no redraw needed, we leave state as we entered it */
+ // ED_update_for_newframe(C);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, CTX_data_scene(C));
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void RENDER_OT_opengl(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Viewport Render";
- ot->description = "Take a snapshot of the active viewport";
- ot->idname = "RENDER_OT_opengl";
-
- /* api callbacks */
- ot->invoke = screen_opengl_render_invoke;
- ot->exec = screen_opengl_render_exec; /* blocking */
- ot->modal = screen_opengl_render_modal;
- ot->cancel = screen_opengl_render_cancel;
-
- ot->poll = ED_operator_screenactive;
-
- prop = RNA_def_boolean(ot->srna, "animation", 0, "Animation", "Render files from the animation range of this scene");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "sequencer", 0, "Sequencer", "Render using the sequencer's OpenGL display");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = 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_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "view_context", 1, "View Context", "Use the current 3D view for rendering, else use scene settings");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Viewport Render";
+ ot->description = "Take a snapshot of the active viewport";
+ ot->idname = "RENDER_OT_opengl";
+
+ /* api callbacks */
+ ot->invoke = screen_opengl_render_invoke;
+ ot->exec = screen_opengl_render_exec; /* blocking */
+ ot->modal = screen_opengl_render_modal;
+ ot->cancel = screen_opengl_render_cancel;
+
+ ot->poll = ED_operator_screenactive;
+
+ prop = RNA_def_boolean(ot->srna,
+ "animation",
+ 0,
+ "Animation",
+ "Render files from the animation range of this scene");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "sequencer", 0, "Sequencer", "Render using the sequencer's OpenGL display");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = 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_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna,
+ "view_context",
+ 1,
+ "View Context",
+ "Use the current 3D view for rendering, else use scene settings");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* function for getting an opengl buffer from a View3D, used by sequencer */
diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c
index ad3a5a161ac..b77f5c2bbad 100644
--- a/source/blender/editors/render/render_ops.c
+++ b/source/blender/editors/render/render_ops.c
@@ -29,66 +29,66 @@
#include "WM_api.h"
-#include "render_intern.h" // own include
+#include "render_intern.h" // own include
/***************************** render ***********************************/
void ED_operatortypes_render(void)
{
- WM_operatortype_append(OBJECT_OT_material_slot_add);
- WM_operatortype_append(OBJECT_OT_material_slot_remove);
- WM_operatortype_append(OBJECT_OT_material_slot_assign);
- WM_operatortype_append(OBJECT_OT_material_slot_select);
- WM_operatortype_append(OBJECT_OT_material_slot_deselect);
- WM_operatortype_append(OBJECT_OT_material_slot_copy);
- WM_operatortype_append(OBJECT_OT_material_slot_move);
+ WM_operatortype_append(OBJECT_OT_material_slot_add);
+ WM_operatortype_append(OBJECT_OT_material_slot_remove);
+ WM_operatortype_append(OBJECT_OT_material_slot_assign);
+ WM_operatortype_append(OBJECT_OT_material_slot_select);
+ WM_operatortype_append(OBJECT_OT_material_slot_deselect);
+ WM_operatortype_append(OBJECT_OT_material_slot_copy);
+ WM_operatortype_append(OBJECT_OT_material_slot_move);
- WM_operatortype_append(MATERIAL_OT_new);
- WM_operatortype_append(TEXTURE_OT_new);
- WM_operatortype_append(WORLD_OT_new);
+ WM_operatortype_append(MATERIAL_OT_new);
+ WM_operatortype_append(TEXTURE_OT_new);
+ WM_operatortype_append(WORLD_OT_new);
- WM_operatortype_append(MATERIAL_OT_copy);
- WM_operatortype_append(MATERIAL_OT_paste);
+ WM_operatortype_append(MATERIAL_OT_copy);
+ WM_operatortype_append(MATERIAL_OT_paste);
- WM_operatortype_append(SCENE_OT_view_layer_add);
- WM_operatortype_append(SCENE_OT_view_layer_remove);
+ WM_operatortype_append(SCENE_OT_view_layer_add);
+ WM_operatortype_append(SCENE_OT_view_layer_remove);
- WM_operatortype_append(SCENE_OT_render_view_add);
- WM_operatortype_append(SCENE_OT_render_view_remove);
+ WM_operatortype_append(SCENE_OT_render_view_add);
+ WM_operatortype_append(SCENE_OT_render_view_remove);
- WM_operatortype_append(SCENE_OT_light_cache_bake);
- WM_operatortype_append(SCENE_OT_light_cache_free);
+ WM_operatortype_append(SCENE_OT_light_cache_bake);
+ WM_operatortype_append(SCENE_OT_light_cache_free);
#ifdef WITH_FREESTYLE
- WM_operatortype_append(SCENE_OT_freestyle_module_add);
- WM_operatortype_append(SCENE_OT_freestyle_module_remove);
- WM_operatortype_append(SCENE_OT_freestyle_module_move);
- WM_operatortype_append(SCENE_OT_freestyle_lineset_add);
- WM_operatortype_append(SCENE_OT_freestyle_lineset_copy);
- WM_operatortype_append(SCENE_OT_freestyle_lineset_paste);
- WM_operatortype_append(SCENE_OT_freestyle_lineset_remove);
- WM_operatortype_append(SCENE_OT_freestyle_lineset_move);
- WM_operatortype_append(SCENE_OT_freestyle_linestyle_new);
- WM_operatortype_append(SCENE_OT_freestyle_color_modifier_add);
- WM_operatortype_append(SCENE_OT_freestyle_alpha_modifier_add);
- WM_operatortype_append(SCENE_OT_freestyle_thickness_modifier_add);
- WM_operatortype_append(SCENE_OT_freestyle_geometry_modifier_add);
- WM_operatortype_append(SCENE_OT_freestyle_modifier_remove);
- WM_operatortype_append(SCENE_OT_freestyle_modifier_move);
- WM_operatortype_append(SCENE_OT_freestyle_modifier_copy);
- WM_operatortype_append(SCENE_OT_freestyle_stroke_material_create);
+ WM_operatortype_append(SCENE_OT_freestyle_module_add);
+ WM_operatortype_append(SCENE_OT_freestyle_module_remove);
+ WM_operatortype_append(SCENE_OT_freestyle_module_move);
+ WM_operatortype_append(SCENE_OT_freestyle_lineset_add);
+ WM_operatortype_append(SCENE_OT_freestyle_lineset_copy);
+ WM_operatortype_append(SCENE_OT_freestyle_lineset_paste);
+ WM_operatortype_append(SCENE_OT_freestyle_lineset_remove);
+ WM_operatortype_append(SCENE_OT_freestyle_lineset_move);
+ WM_operatortype_append(SCENE_OT_freestyle_linestyle_new);
+ WM_operatortype_append(SCENE_OT_freestyle_color_modifier_add);
+ WM_operatortype_append(SCENE_OT_freestyle_alpha_modifier_add);
+ WM_operatortype_append(SCENE_OT_freestyle_thickness_modifier_add);
+ WM_operatortype_append(SCENE_OT_freestyle_geometry_modifier_add);
+ WM_operatortype_append(SCENE_OT_freestyle_modifier_remove);
+ WM_operatortype_append(SCENE_OT_freestyle_modifier_move);
+ WM_operatortype_append(SCENE_OT_freestyle_modifier_copy);
+ WM_operatortype_append(SCENE_OT_freestyle_stroke_material_create);
#endif
- WM_operatortype_append(TEXTURE_OT_slot_copy);
- WM_operatortype_append(TEXTURE_OT_slot_paste);
- WM_operatortype_append(TEXTURE_OT_slot_move);
+ WM_operatortype_append(TEXTURE_OT_slot_copy);
+ WM_operatortype_append(TEXTURE_OT_slot_paste);
+ WM_operatortype_append(TEXTURE_OT_slot_move);
- /* render_internal.c */
- WM_operatortype_append(RENDER_OT_view_show);
- WM_operatortype_append(RENDER_OT_render);
- WM_operatortype_append(RENDER_OT_view_cancel);
- WM_operatortype_append(RENDER_OT_shutter_curve_preset);
+ /* render_internal.c */
+ WM_operatortype_append(RENDER_OT_view_show);
+ WM_operatortype_append(RENDER_OT_render);
+ WM_operatortype_append(RENDER_OT_view_cancel);
+ WM_operatortype_append(RENDER_OT_shutter_curve_preset);
- /* render_opengl.c */
- WM_operatortype_append(RENDER_OT_opengl);
+ /* render_opengl.c */
+ WM_operatortype_append(RENDER_OT_opengl);
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 77b24a1b4d9..c62d6530c6b 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -21,7 +21,6 @@
* \ingroup edrend
*/
-
/* global includes */
#include <stdlib.h>
@@ -29,9 +28,9 @@
#include <string.h>
#ifndef WIN32
-#include <unistd.h>
+# include <unistd.h>
#else
-#include <io.h>
+# include <io.h>
#endif
#include "MEM_guardedalloc.h"
@@ -102,89 +101,90 @@
ImBuf *get_brush_icon(Brush *brush)
{
- static const int flags = IB_rect | IB_multilayer | IB_metadata;
+ static const int flags = IB_rect | IB_multilayer | IB_metadata;
- char path[FILE_MAX];
- const char *folder;
+ char path[FILE_MAX];
+ const char *folder;
- if (!(brush->icon_imbuf)) {
- if (brush->flag & BRUSH_CUSTOM_ICON) {
+ if (!(brush->icon_imbuf)) {
+ if (brush->flag & BRUSH_CUSTOM_ICON) {
- if (brush->icon_filepath[0]) {
- // first use the path directly to try and load the file
+ if (brush->icon_filepath[0]) {
+ // first use the path directly to try and load the file
- BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath));
- BLI_path_abs(path, BKE_main_blendfile_path_from_global());
+ BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath));
+ BLI_path_abs(path, BKE_main_blendfile_path_from_global());
- /* use default colorspaces for brushes */
- brush->icon_imbuf = IMB_loadiffname(path, flags, NULL);
+ /* use default colorspaces for brushes */
+ brush->icon_imbuf = IMB_loadiffname(path, flags, NULL);
- // otherwise lets try to find it in other directories
- if (!(brush->icon_imbuf)) {
- folder = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons");
+ // otherwise lets try to find it in other directories
+ if (!(brush->icon_imbuf)) {
+ folder = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons");
- BLI_make_file_string(BKE_main_blendfile_path_from_global(), path, folder, brush->icon_filepath);
+ BLI_make_file_string(
+ BKE_main_blendfile_path_from_global(), path, folder, brush->icon_filepath);
- if (path[0]) {
- /* use fefault color spaces */
- brush->icon_imbuf = IMB_loadiffname(path, flags, NULL);
- }
- }
+ if (path[0]) {
+ /* use fefault color spaces */
+ brush->icon_imbuf = IMB_loadiffname(path, flags, NULL);
+ }
+ }
- if (brush->icon_imbuf)
- BKE_icon_changed(BKE_icon_id_ensure(&brush->id));
- }
- }
- }
+ if (brush->icon_imbuf)
+ BKE_icon_changed(BKE_icon_id_ensure(&brush->id));
+ }
+ }
+ }
- if (!(brush->icon_imbuf))
- brush->id.icon_id = 0;
+ if (!(brush->icon_imbuf))
+ brush->id.icon_id = 0;
- return brush->icon_imbuf;
+ return brush->icon_imbuf;
}
typedef struct ShaderPreview {
- /* from wmJob */
- void *owner;
- short *stop, *do_update;
-
- Scene *scene;
- Depsgraph *depsgraph;
- ID *id, *id_copy;
- ID *parent;
- MTex *slot;
-
- /* datablocks with nodes need full copy during preview render, glsl uses it too */
- Material *matcopy;
- Tex *texcopy;
- Light *lampcopy;
- World *worldcopy;
-
- /** Copy of the active objects #Object.color */
- float color[4];
-
- int sizex, sizey;
- unsigned int *pr_rect;
- int pr_method;
- bool own_id_copy;
-
- Main *bmain;
- Main *pr_main;
+ /* from wmJob */
+ void *owner;
+ short *stop, *do_update;
+
+ Scene *scene;
+ Depsgraph *depsgraph;
+ ID *id, *id_copy;
+ ID *parent;
+ MTex *slot;
+
+ /* datablocks with nodes need full copy during preview render, glsl uses it too */
+ Material *matcopy;
+ Tex *texcopy;
+ Light *lampcopy;
+ World *worldcopy;
+
+ /** Copy of the active objects #Object.color */
+ float color[4];
+
+ int sizex, sizey;
+ unsigned int *pr_rect;
+ int pr_method;
+ bool own_id_copy;
+
+ Main *bmain;
+ Main *pr_main;
} ShaderPreview;
typedef struct IconPreviewSize {
- struct IconPreviewSize *next, *prev;
- int sizex, sizey;
- unsigned int *rect;
+ struct IconPreviewSize *next, *prev;
+ int sizex, sizey;
+ unsigned int *rect;
} IconPreviewSize;
typedef struct IconPreview {
- Main *bmain;
- Scene *scene;
- Depsgraph *depsgraph;
- void *owner;
- ID *id, *id_copy;
- ListBase sizes;
+ Main *bmain;
+ Scene *scene;
+ Depsgraph *depsgraph;
+ void *owner;
+ ID *id, *id_copy;
+ ListBase sizes;
} IconPreview;
/* *************************** Preview for buttons *********************** */
@@ -195,1195 +195,1242 @@ static Main *G_pr_main_grease_pencil = NULL;
#ifndef WITH_HEADLESS
static Main *load_main_from_memory(const void *blend, int blend_size)
{
- const int fileflags = G.fileflags;
- Main *bmain = NULL;
- BlendFileData *bfd;
+ const int fileflags = G.fileflags;
+ Main *bmain = NULL;
+ BlendFileData *bfd;
- G.fileflags |= G_FILE_NO_UI;
- bfd = BLO_read_from_memory(blend, blend_size, BLO_READ_SKIP_NONE, NULL);
- if (bfd) {
- bmain = bfd->main;
+ G.fileflags |= G_FILE_NO_UI;
+ bfd = BLO_read_from_memory(blend, blend_size, BLO_READ_SKIP_NONE, NULL);
+ if (bfd) {
+ bmain = bfd->main;
- MEM_freeN(bfd);
- }
- G.fileflags = fileflags;
+ MEM_freeN(bfd);
+ }
+ G.fileflags = fileflags;
- return bmain;
+ return bmain;
}
#endif
void ED_preview_ensure_dbase(void)
{
#ifndef WITH_HEADLESS
- static bool base_initialized = false;
- BLI_assert(BLI_thread_is_main());
- if (!base_initialized) {
- G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
- G_pr_main_grease_pencil = load_main_from_memory(datatoc_preview_grease_pencil_blend, datatoc_preview_grease_pencil_blend_size);
- base_initialized = true;
- }
+ static bool base_initialized = false;
+ BLI_assert(BLI_thread_is_main());
+ if (!base_initialized) {
+ G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
+ G_pr_main_grease_pencil = load_main_from_memory(datatoc_preview_grease_pencil_blend,
+ datatoc_preview_grease_pencil_blend_size);
+ base_initialized = true;
+ }
#endif
}
static bool check_engine_supports_preview(Scene *scene)
{
- RenderEngineType *type = RE_engines_find(scene->r.engine);
- return (type->flag & RE_USE_PREVIEW) != 0;
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ return (type->flag & RE_USE_PREVIEW) != 0;
}
void ED_preview_free_dbase(void)
{
- if (G_pr_main)
- BKE_main_free(G_pr_main);
+ if (G_pr_main)
+ BKE_main_free(G_pr_main);
- if (G_pr_main_grease_pencil)
- BKE_main_free(G_pr_main_grease_pencil);
+ if (G_pr_main_grease_pencil)
+ BKE_main_free(G_pr_main_grease_pencil);
}
static Scene *preview_get_scene(Main *pr_main)
{
- if (pr_main == NULL) return NULL;
+ if (pr_main == NULL)
+ return NULL;
- return pr_main->scenes.first;
+ return pr_main->scenes.first;
}
static const char *preview_collection_name(const char pr_type)
{
- switch (pr_type) {
- case MA_FLAT:
- return "Flat";
- case MA_SPHERE:
- return "Sphere";
- case MA_CUBE:
- return "Cube";
- case MA_SHADERBALL:
- return "Shader Ball";
- case MA_CLOTH:
- return "Cloth";
- case MA_FLUID:
- return "Fluid";
- case MA_SPHERE_A:
- return "World Shader Ball";
- case MA_LAMP:
- return "Lamp";
- case MA_SKY:
- return "Sky";
- case MA_HAIR:
- return "Hair";
- case MA_ATMOS:
- return "Atmosphere";
- default:
- BLI_assert(!"Unknown preview type");
- return "";
- }
+ switch (pr_type) {
+ case MA_FLAT:
+ return "Flat";
+ case MA_SPHERE:
+ return "Sphere";
+ case MA_CUBE:
+ return "Cube";
+ case MA_SHADERBALL:
+ return "Shader Ball";
+ case MA_CLOTH:
+ return "Cloth";
+ case MA_FLUID:
+ return "Fluid";
+ case MA_SPHERE_A:
+ return "World Shader Ball";
+ case MA_LAMP:
+ return "Lamp";
+ case MA_SKY:
+ return "Sky";
+ case MA_HAIR:
+ return "Hair";
+ case MA_ATMOS:
+ return "Atmosphere";
+ default:
+ BLI_assert(!"Unknown preview type");
+ return "";
+ }
}
-static void set_preview_visibility(Scene *scene, ViewLayer *view_layer, char pr_type, int pr_method)
+static void set_preview_visibility(Scene *scene,
+ ViewLayer *view_layer,
+ char pr_type,
+ int pr_method)
{
- /* Set appropriate layer as visibile. */
- LayerCollection *lc = view_layer->layer_collections.first;
- const char *collection_name = preview_collection_name(pr_type);
-
- for (lc = lc->layer_collections.first; lc; lc = lc->next) {
- if (STREQ(lc->collection->id.name + 2, collection_name)) {
- lc->collection->flag &= ~COLLECTION_RESTRICT_RENDER;
- }
- else {
- lc->collection->flag |= COLLECTION_RESTRICT_RENDER;
- }
- }
-
- /* Hide floor for icon renders. */
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (STREQ(base->object->id.name + 2, "Floor")) {
- if (pr_method == PR_ICON_RENDER) {
- base->object->restrictflag |= OB_RESTRICT_RENDER;
- }
- else {
- base->object->restrictflag &= ~OB_RESTRICT_RENDER;
- }
- }
- }
-
- BKE_layer_collection_sync(scene, view_layer);
+ /* Set appropriate layer as visibile. */
+ LayerCollection *lc = view_layer->layer_collections.first;
+ const char *collection_name = preview_collection_name(pr_type);
+
+ for (lc = lc->layer_collections.first; lc; lc = lc->next) {
+ if (STREQ(lc->collection->id.name + 2, collection_name)) {
+ lc->collection->flag &= ~COLLECTION_RESTRICT_RENDER;
+ }
+ else {
+ lc->collection->flag |= COLLECTION_RESTRICT_RENDER;
+ }
+ }
+
+ /* Hide floor for icon renders. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (STREQ(base->object->id.name + 2, "Floor")) {
+ if (pr_method == PR_ICON_RENDER) {
+ base->object->restrictflag |= OB_RESTRICT_RENDER;
+ }
+ else {
+ base->object->restrictflag &= ~OB_RESTRICT_RENDER;
+ }
+ }
+ }
+
+ BKE_layer_collection_sync(scene, view_layer);
}
static World *preview_get_localized_world(ShaderPreview *sp, World *world)
{
- if (world == NULL) {
- return NULL;
- }
- if (sp->worldcopy != NULL) {
- return sp->worldcopy;
- }
- sp->worldcopy = BKE_world_localize(world);
- BLI_addtail(&sp->pr_main->worlds, sp->worldcopy);
- return sp->worldcopy;
+ if (world == NULL) {
+ return NULL;
+ }
+ if (sp->worldcopy != NULL) {
+ return sp->worldcopy;
+ }
+ sp->worldcopy = BKE_world_localize(world);
+ BLI_addtail(&sp->pr_main->worlds, sp->worldcopy);
+ return sp->worldcopy;
}
static ID *duplicate_ids(ID *id, Depsgraph *depsgraph)
{
- if (id == NULL) {
- /* Non-ID preview render. */
- return NULL;
- }
-
- ID *id_eval = id;
-
- if (depsgraph) {
- id_eval = DEG_get_evaluated_id(depsgraph, id);
- }
-
- switch (GS(id->name)) {
- case ID_MA:
- return (ID *)BKE_material_localize((Material *)id_eval);
- case ID_TE:
- return (ID *)BKE_texture_localize((Tex *)id_eval);
- case ID_LA:
- return (ID *)BKE_light_localize((Light *)id_eval);
- case ID_WO:
- return (ID *)BKE_world_localize((World *)id_eval);
- case ID_IM:
- case ID_BR:
- case ID_SCR:
- return NULL;
- default:
- BLI_assert(!"ID type preview not supported.");
- return NULL;
- }
+ if (id == NULL) {
+ /* Non-ID preview render. */
+ return NULL;
+ }
+
+ ID *id_eval = id;
+
+ if (depsgraph) {
+ id_eval = DEG_get_evaluated_id(depsgraph, id);
+ }
+
+ switch (GS(id->name)) {
+ case ID_MA:
+ return (ID *)BKE_material_localize((Material *)id_eval);
+ case ID_TE:
+ return (ID *)BKE_texture_localize((Tex *)id_eval);
+ case ID_LA:
+ return (ID *)BKE_light_localize((Light *)id_eval);
+ case ID_WO:
+ return (ID *)BKE_world_localize((World *)id_eval);
+ case ID_IM:
+ case ID_BR:
+ case ID_SCR:
+ return NULL;
+ default:
+ BLI_assert(!"ID type preview not supported.");
+ return NULL;
+ }
}
/* call this with a pointer to initialize preview scene */
/* call this with NULL to restore assigned ID pointers in preview scene */
-static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp)
+static Scene *preview_prepare_scene(
+ Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp)
{
- Scene *sce;
- Main *pr_main = sp->pr_main;
-
- memcpy(pr_main->name, BKE_main_blendfile_path(bmain), sizeof(pr_main->name));
-
- sce = preview_get_scene(pr_main);
- if (sce) {
- ViewLayer *view_layer = sce->view_layers.first;
-
- /* this flag tells render to not execute depsgraph or ipos etc */
- sce->r.scemode |= R_BUTS_PREVIEW;
- /* set world always back, is used now */
- sce->world = pr_main->worlds.first;
- /* now: exposure copy */
- if (scene->world) {
- sce->world->exp = scene->world->exp;
- sce->world->range = scene->world->range;
- }
-
- sce->r.color_mgt_flag = scene->r.color_mgt_flag;
- BKE_color_managed_display_settings_copy(&sce->display_settings, &scene->display_settings);
-
- BKE_color_managed_view_settings_free(&sce->view_settings);
- BKE_color_managed_view_settings_copy(&sce->view_settings, &scene->view_settings);
-
- /* prevent overhead for small renders and icons (32) */
- if (id && sp->sizex < 40) {
- sce->r.tilex = sce->r.tiley = 64;
- }
- else {
- sce->r.tilex = sce->r.xsch / 4;
- sce->r.tiley = sce->r.ysch / 4;
- }
-
- if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO)
- sce->r.alphamode = R_ALPHAPREMUL;
- else
- sce->r.alphamode = R_ADDSKY;
-
- sce->r.cfra = scene->r.cfra;
-
- if (id_type == ID_TE) {
- /* Texture is not actually rendered with engine, just set dummy value. */
- BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(sce->r.engine));
- }
- else {
- BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine));
- }
-
- if (id_type == ID_MA) {
- Material *mat = NULL, *origmat = (Material *)id;
-
- if (origmat) {
- /* work on a copy */
- BLI_assert(sp->id_copy != NULL);
- mat = sp->matcopy = (Material *)sp->id_copy;
- sp->id_copy = NULL;
- BLI_addtail(&pr_main->materials, mat);
-
- /* Use current scene world for lighting. */
- if (mat->pr_flag == MA_PREVIEW_WORLD && sp->pr_method == PR_BUTS_RENDER) {
- /* Use current scene world to light sphere. */
- sce->world = preview_get_localized_world(sp, scene->world);
- }
- else if (sce->world) {
- /* Use a default world color. Using the current
- * scene world can be slow if it has big textures. */
- sce->world->use_nodes = false;
- sce->world->horr = 0.05f;
- sce->world->horg = 0.05f;
- sce->world->horb = 0.05f;
- }
-
- set_preview_visibility(sce, view_layer, mat->pr_type, sp->pr_method);
-
- if (sp->pr_method != PR_ICON_RENDER) {
- if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) {
- /* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, true);
- /* WATCH: Accessing origmat is not safe! */
- BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, true);
- }
- }
- }
- else {
- sce->r.mode &= ~(R_OSA);
- }
-
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (base->object->id.name[2] == 'p') {
- /* copy over object color, in case material uses it */
- copy_v4_v4(base->object->color, sp->color);
-
- if (OB_TYPE_SUPPORT_MATERIAL(base->object->type)) {
- /* don't use assign_material, it changed mat->id.us, which shows in the UI */
- Material ***matar = give_matarar(base->object);
- int actcol = max_ii(base->object->actcol - 1, 0);
-
- if (matar && actcol < base->object->totcol)
- (*matar)[actcol] = mat;
- }
- else if (base->object->type == OB_LAMP) {
- base->flag |= BASE_VISIBLE;
- }
- }
- }
- }
- else if (id_type == ID_TE) {
- Tex *tex = NULL, *origtex = (Tex *)id;
-
- if (origtex) {
- BLI_assert(sp->id_copy != NULL);
- tex = sp->texcopy = (Tex *)sp->id_copy;
- sp->id_copy = NULL;
- BLI_addtail(&pr_main->textures, tex);
- }
-
- if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) {
- /* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, true);
- /* WATCH: Accessing origtex is not safe! */
- BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true);
- }
- }
- else if (id_type == ID_LA) {
- Light *la = NULL, *origla = (Light *)id;
-
- /* work on a copy */
- if (origla) {
- BLI_assert(sp->id_copy != NULL);
- la = sp->lampcopy = (Light *)sp->id_copy;
- sp->id_copy = NULL;
- BLI_addtail(&pr_main->lights, la);
- }
-
- set_preview_visibility(sce, view_layer, MA_LAMP, sp->pr_method);
-
- if (sce->world) {
- /* Only use lighting from the light. */
- sce->world->use_nodes = false;
- sce->world->horr = 0.0f;
- sce->world->horg = 0.0f;
- sce->world->horb = 0.0f;
- }
-
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (base->object->id.name[2] == 'p') {
- if (base->object->type == OB_LAMP)
- base->object->data = la;
- }
- }
-
- if (la && la->nodetree && sp->pr_method == PR_NODE_RENDER) {
- /* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, true);
- /* WATCH: Accessing origla is not safe! */
- BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true);
- }
- }
- else if (id_type == ID_WO) {
- World *wrld = NULL, *origwrld = (World *)id;
-
- if (origwrld) {
- BLI_assert(sp->id_copy != NULL);
- wrld = sp->worldcopy = (World *)sp->id_copy;
- sp->id_copy = NULL;
- BLI_addtail(&pr_main->worlds, wrld);
- }
-
- set_preview_visibility(sce, view_layer, MA_SKY, sp->pr_method);
- sce->world = wrld;
-
- if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) {
- /* two previews, they get copied by wmJob */
- BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, true);
- /* WATCH: Accessing origwrld is not safe! */
- BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, true);
- }
- }
-
- return sce;
- }
-
- return NULL;
+ Scene *sce;
+ Main *pr_main = sp->pr_main;
+
+ memcpy(pr_main->name, BKE_main_blendfile_path(bmain), sizeof(pr_main->name));
+
+ sce = preview_get_scene(pr_main);
+ if (sce) {
+ ViewLayer *view_layer = sce->view_layers.first;
+
+ /* this flag tells render to not execute depsgraph or ipos etc */
+ sce->r.scemode |= R_BUTS_PREVIEW;
+ /* set world always back, is used now */
+ sce->world = pr_main->worlds.first;
+ /* now: exposure copy */
+ if (scene->world) {
+ sce->world->exp = scene->world->exp;
+ sce->world->range = scene->world->range;
+ }
+
+ sce->r.color_mgt_flag = scene->r.color_mgt_flag;
+ BKE_color_managed_display_settings_copy(&sce->display_settings, &scene->display_settings);
+
+ BKE_color_managed_view_settings_free(&sce->view_settings);
+ BKE_color_managed_view_settings_copy(&sce->view_settings, &scene->view_settings);
+
+ /* prevent overhead for small renders and icons (32) */
+ if (id && sp->sizex < 40) {
+ sce->r.tilex = sce->r.tiley = 64;
+ }
+ else {
+ sce->r.tilex = sce->r.xsch / 4;
+ sce->r.tiley = sce->r.ysch / 4;
+ }
+
+ if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO)
+ sce->r.alphamode = R_ALPHAPREMUL;
+ else
+ sce->r.alphamode = R_ADDSKY;
+
+ sce->r.cfra = scene->r.cfra;
+
+ if (id_type == ID_TE) {
+ /* Texture is not actually rendered with engine, just set dummy value. */
+ BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(sce->r.engine));
+ }
+ else {
+ BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine));
+ }
+
+ if (id_type == ID_MA) {
+ Material *mat = NULL, *origmat = (Material *)id;
+
+ if (origmat) {
+ /* work on a copy */
+ BLI_assert(sp->id_copy != NULL);
+ mat = sp->matcopy = (Material *)sp->id_copy;
+ sp->id_copy = NULL;
+ BLI_addtail(&pr_main->materials, mat);
+
+ /* Use current scene world for lighting. */
+ if (mat->pr_flag == MA_PREVIEW_WORLD && sp->pr_method == PR_BUTS_RENDER) {
+ /* Use current scene world to light sphere. */
+ sce->world = preview_get_localized_world(sp, scene->world);
+ }
+ else if (sce->world) {
+ /* Use a default world color. Using the current
+ * scene world can be slow if it has big textures. */
+ sce->world->use_nodes = false;
+ sce->world->horr = 0.05f;
+ sce->world->horg = 0.05f;
+ sce->world->horb = 0.05f;
+ }
+
+ set_preview_visibility(sce, view_layer, mat->pr_type, sp->pr_method);
+
+ if (sp->pr_method != PR_ICON_RENDER) {
+ if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) {
+ /* two previews, they get copied by wmJob */
+ BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origmat is not safe! */
+ BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, true);
+ }
+ }
+ }
+ else {
+ sce->r.mode &= ~(R_OSA);
+ }
+
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (base->object->id.name[2] == 'p') {
+ /* copy over object color, in case material uses it */
+ copy_v4_v4(base->object->color, sp->color);
+
+ if (OB_TYPE_SUPPORT_MATERIAL(base->object->type)) {
+ /* don't use assign_material, it changed mat->id.us, which shows in the UI */
+ Material ***matar = give_matarar(base->object);
+ int actcol = max_ii(base->object->actcol - 1, 0);
+
+ if (matar && actcol < base->object->totcol)
+ (*matar)[actcol] = mat;
+ }
+ else if (base->object->type == OB_LAMP) {
+ base->flag |= BASE_VISIBLE;
+ }
+ }
+ }
+ }
+ else if (id_type == ID_TE) {
+ Tex *tex = NULL, *origtex = (Tex *)id;
+
+ if (origtex) {
+ BLI_assert(sp->id_copy != NULL);
+ tex = sp->texcopy = (Tex *)sp->id_copy;
+ sp->id_copy = NULL;
+ BLI_addtail(&pr_main->textures, tex);
+ }
+
+ if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) {
+ /* two previews, they get copied by wmJob */
+ BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origtex is not safe! */
+ BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true);
+ }
+ }
+ else if (id_type == ID_LA) {
+ Light *la = NULL, *origla = (Light *)id;
+
+ /* work on a copy */
+ if (origla) {
+ BLI_assert(sp->id_copy != NULL);
+ la = sp->lampcopy = (Light *)sp->id_copy;
+ sp->id_copy = NULL;
+ BLI_addtail(&pr_main->lights, la);
+ }
+
+ set_preview_visibility(sce, view_layer, MA_LAMP, sp->pr_method);
+
+ if (sce->world) {
+ /* Only use lighting from the light. */
+ sce->world->use_nodes = false;
+ sce->world->horr = 0.0f;
+ sce->world->horg = 0.0f;
+ sce->world->horb = 0.0f;
+ }
+
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (base->object->id.name[2] == 'p') {
+ if (base->object->type == OB_LAMP)
+ base->object->data = la;
+ }
+ }
+
+ if (la && la->nodetree && sp->pr_method == PR_NODE_RENDER) {
+ /* two previews, they get copied by wmJob */
+ BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origla is not safe! */
+ BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true);
+ }
+ }
+ else if (id_type == ID_WO) {
+ World *wrld = NULL, *origwrld = (World *)id;
+
+ if (origwrld) {
+ BLI_assert(sp->id_copy != NULL);
+ wrld = sp->worldcopy = (World *)sp->id_copy;
+ sp->id_copy = NULL;
+ BLI_addtail(&pr_main->worlds, wrld);
+ }
+
+ set_preview_visibility(sce, view_layer, MA_SKY, sp->pr_method);
+ sce->world = wrld;
+
+ if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) {
+ /* two previews, they get copied by wmJob */
+ BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, true);
+ /* WATCH: Accessing origwrld is not safe! */
+ BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, true);
+ }
+ }
+
+ return sce;
+ }
+
+ return NULL;
}
/* new UI convention: draw is in pixel space already. */
/* uses UI_BTYPE_ROUNDBOX button in block to get the rect */
static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect)
{
- Render *re;
- RenderView *rv;
- RenderResult rres;
- char name[32];
- int offx = 0;
- int newx = BLI_rcti_size_x(rect);
- int newy = BLI_rcti_size_y(rect);
- bool ok = false;
-
- if (!split || first) sprintf(name, "Preview %p", (void *)sa);
- else sprintf(name, "SecondPreview %p", (void *)sa);
-
- if (split) {
- if (first) {
- offx = 0;
- newx = newx / 2;
- }
- else {
- offx = newx / 2;
- newx = newx - newx / 2;
- }
- }
-
- /* test if something rendered ok */
- re = RE_GetRender(name);
-
- if (re == NULL)
- return false;
-
- RE_AcquireResultImageViews(re, &rres);
-
- if (!BLI_listbase_is_empty(&rres.views)) {
- /* material preview only needs monoscopy (view 0) */
- rv = RE_RenderViewGetById(&rres, 0);
- }
- else {
- /* possible the job clears the views but we're still drawing T45496 */
- rv = NULL;
- }
-
- if (rv && rv->rectf) {
-
- if (ABS(rres.rectx - newx) < 2 && ABS(rres.recty - newy) < 2) {
-
- newrect->xmax = max_ii(newrect->xmax, rect->xmin + rres.rectx + offx);
- newrect->ymax = max_ii(newrect->ymax, rect->ymin + rres.recty);
-
- if (rres.rectx && rres.recty) {
- unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
- float fx = rect->xmin + offx;
- float fy = rect->ymin;
-
- /* material preview only needs monoscopy (view 0) */
- if (re)
- RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte, 0);
-
- IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(&state, fx, fy, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect_byte,
- 1.0f, 1.0f, NULL);
-
- MEM_freeN(rect_byte);
-
- ok = 1;
- }
- }
- }
-
- RE_ReleaseResultImageViews(re, &rres);
-
- return ok;
+ Render *re;
+ RenderView *rv;
+ RenderResult rres;
+ char name[32];
+ int offx = 0;
+ int newx = BLI_rcti_size_x(rect);
+ int newy = BLI_rcti_size_y(rect);
+ bool ok = false;
+
+ if (!split || first)
+ sprintf(name, "Preview %p", (void *)sa);
+ else
+ sprintf(name, "SecondPreview %p", (void *)sa);
+
+ if (split) {
+ if (first) {
+ offx = 0;
+ newx = newx / 2;
+ }
+ else {
+ offx = newx / 2;
+ newx = newx - newx / 2;
+ }
+ }
+
+ /* test if something rendered ok */
+ re = RE_GetRender(name);
+
+ if (re == NULL)
+ return false;
+
+ RE_AcquireResultImageViews(re, &rres);
+
+ if (!BLI_listbase_is_empty(&rres.views)) {
+ /* material preview only needs monoscopy (view 0) */
+ rv = RE_RenderViewGetById(&rres, 0);
+ }
+ else {
+ /* possible the job clears the views but we're still drawing T45496 */
+ rv = NULL;
+ }
+
+ if (rv && rv->rectf) {
+
+ if (ABS(rres.rectx - newx) < 2 && ABS(rres.recty - newy) < 2) {
+
+ newrect->xmax = max_ii(newrect->xmax, rect->xmin + rres.rectx + offx);
+ newrect->ymax = max_ii(newrect->ymax, rect->ymin + rres.recty);
+
+ if (rres.rectx && rres.recty) {
+ unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int),
+ "ed_preview_draw_rect");
+ float fx = rect->xmin + offx;
+ float fy = rect->ymin;
+
+ /* material preview only needs monoscopy (view 0) */
+ if (re)
+ RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte, 0);
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state,
+ fx,
+ fy,
+ rres.rectx,
+ rres.recty,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ GL_NEAREST,
+ rect_byte,
+ 1.0f,
+ 1.0f,
+ NULL);
+
+ MEM_freeN(rect_byte);
+
+ ok = 1;
+ }
+ }
+ }
+
+ RE_ReleaseResultImageViews(re, &rres);
+
+ return ok;
}
void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, rcti *rect)
{
- if (idp) {
- wmWindowManager *wm = CTX_wm_manager(C);
- ScrArea *sa = CTX_wm_area(C);
- ID *id = (ID *)idp;
- ID *parent = (ID *)parentp;
- MTex *slot = (MTex *)slotp;
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- ShaderPreview *sp = WM_jobs_customdata(wm, sa);
- rcti newrect;
- int ok;
- int newx = BLI_rcti_size_x(rect);
- int newy = BLI_rcti_size_y(rect);
-
- newrect.xmin = rect->xmin;
- newrect.xmax = rect->xmin;
- newrect.ymin = rect->ymin;
- newrect.ymax = rect->ymin;
-
- if (parent) {
- ok = ed_preview_draw_rect(sa, 1, 1, rect, &newrect);
- ok &= ed_preview_draw_rect(sa, 1, 0, rect, &newrect);
- }
- else
- ok = ed_preview_draw_rect(sa, 0, 0, rect, &newrect);
-
- if (ok)
- *rect = newrect;
-
- /* start a new preview render job if signaled through sbuts->preview,
- * if no render result was found and no preview render job is running,
- * or if the job is running and the size of preview changed */
- if ((sbuts != NULL && sbuts->preview) ||
- (!ok && !WM_jobs_test(wm, sa, WM_JOB_TYPE_RENDER_PREVIEW)) ||
- (sp && (ABS(sp->sizex - newx) >= 2 || ABS(sp->sizey - newy) > 2)))
- {
- if (sbuts != NULL) {
- sbuts->preview = 0;
- }
- ED_preview_shader_job(C, sa, id, parent, slot, newx, newy, PR_BUTS_RENDER);
- }
- }
+ if (idp) {
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ID *id = (ID *)idp;
+ ID *parent = (ID *)parentp;
+ MTex *slot = (MTex *)slotp;
+ SpaceProperties *sbuts = CTX_wm_space_properties(C);
+ ShaderPreview *sp = WM_jobs_customdata(wm, sa);
+ rcti newrect;
+ int ok;
+ int newx = BLI_rcti_size_x(rect);
+ int newy = BLI_rcti_size_y(rect);
+
+ newrect.xmin = rect->xmin;
+ newrect.xmax = rect->xmin;
+ newrect.ymin = rect->ymin;
+ newrect.ymax = rect->ymin;
+
+ if (parent) {
+ ok = ed_preview_draw_rect(sa, 1, 1, rect, &newrect);
+ ok &= ed_preview_draw_rect(sa, 1, 0, rect, &newrect);
+ }
+ else
+ ok = ed_preview_draw_rect(sa, 0, 0, rect, &newrect);
+
+ if (ok)
+ *rect = newrect;
+
+ /* start a new preview render job if signaled through sbuts->preview,
+ * if no render result was found and no preview render job is running,
+ * or if the job is running and the size of preview changed */
+ if ((sbuts != NULL && sbuts->preview) ||
+ (!ok && !WM_jobs_test(wm, sa, WM_JOB_TYPE_RENDER_PREVIEW)) ||
+ (sp && (ABS(sp->sizex - newx) >= 2 || ABS(sp->sizey - newy) > 2))) {
+ if (sbuts != NULL) {
+ sbuts->preview = 0;
+ }
+ ED_preview_shader_job(C, sa, id, parent, slot, newx, newy, PR_BUTS_RENDER);
+ }
+ }
}
/* **************************** new shader preview system ****************** */
/* inside thread, called by renderer, sets job update value */
-static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
+static void shader_preview_update(void *spv,
+ RenderResult *UNUSED(rr),
+ volatile struct rcti *UNUSED(rect))
{
- ShaderPreview *sp = spv;
+ ShaderPreview *sp = spv;
- *(sp->do_update) = true;
+ *(sp->do_update) = true;
}
/* called by renderer, checks job value */
static int shader_preview_break(void *spv)
{
- ShaderPreview *sp = spv;
+ ShaderPreview *sp = spv;
- return *(sp->stop);
+ return *(sp->stop);
}
/* outside thread, called before redraw notifiers, it moves finished preview over */
static void shader_preview_updatejob(void *spv)
{
- ShaderPreview *sp = spv;
-
- if (sp->id) {
- if (sp->pr_method == PR_NODE_RENDER) {
- if (GS(sp->id->name) == ID_MA) {
- Material *mat = (Material *)sp->id;
-
- if (sp->matcopy && mat->nodetree && sp->matcopy->nodetree)
- ntreeLocalSync(sp->matcopy->nodetree, mat->nodetree);
- }
- else if (GS(sp->id->name) == ID_TE) {
- Tex *tex = (Tex *)sp->id;
-
- if (sp->texcopy && tex->nodetree && sp->texcopy->nodetree)
- ntreeLocalSync(sp->texcopy->nodetree, tex->nodetree);
- }
- else if (GS(sp->id->name) == ID_WO) {
- World *wrld = (World *)sp->id;
-
- if (sp->worldcopy && wrld->nodetree && sp->worldcopy->nodetree)
- ntreeLocalSync(sp->worldcopy->nodetree, wrld->nodetree);
- }
- else if (GS(sp->id->name) == ID_LA) {
- Light *la = (Light *)sp->id;
-
- if (sp->lampcopy && la->nodetree && sp->lampcopy->nodetree)
- ntreeLocalSync(sp->lampcopy->nodetree, la->nodetree);
- }
- }
- }
+ ShaderPreview *sp = spv;
+
+ if (sp->id) {
+ if (sp->pr_method == PR_NODE_RENDER) {
+ if (GS(sp->id->name) == ID_MA) {
+ Material *mat = (Material *)sp->id;
+
+ if (sp->matcopy && mat->nodetree && sp->matcopy->nodetree)
+ ntreeLocalSync(sp->matcopy->nodetree, mat->nodetree);
+ }
+ else if (GS(sp->id->name) == ID_TE) {
+ Tex *tex = (Tex *)sp->id;
+
+ if (sp->texcopy && tex->nodetree && sp->texcopy->nodetree)
+ ntreeLocalSync(sp->texcopy->nodetree, tex->nodetree);
+ }
+ else if (GS(sp->id->name) == ID_WO) {
+ World *wrld = (World *)sp->id;
+
+ if (sp->worldcopy && wrld->nodetree && sp->worldcopy->nodetree)
+ ntreeLocalSync(sp->worldcopy->nodetree, wrld->nodetree);
+ }
+ else if (GS(sp->id->name) == ID_LA) {
+ Light *la = (Light *)sp->id;
+
+ if (sp->lampcopy && la->nodetree && sp->lampcopy->nodetree)
+ ntreeLocalSync(sp->lampcopy->nodetree, la->nodetree);
+ }
+ }
+ }
}
/* Renders texture directly to render buffer. */
static void shader_preview_texture(ShaderPreview *sp, Tex *tex, Scene *sce, Render *re)
{
- /* Setup output buffer. */
- int width = sp->sizex;
- int height = sp->sizey;
-
- /* This is needed otherwise no RenderResult is created. */
- sce->r.scemode &= ~R_BUTS_PREVIEW;
- RE_InitState(re, NULL, &sce->r, &sce->view_layers, NULL, width, height, NULL);
- RE_SetScene(re, sce);
-
- /* Create buffer in empty RenderView created in the init step. */
- RenderResult *rr = RE_AcquireResultWrite(re);
- RenderView *rv = (RenderView *)rr->views.first;
- rv->rectf = MEM_callocN(sizeof(float) * 4 * width * height, "texture render result");
- RE_ReleaseResult(re);
-
- /* Get texture image pool (if any) */
- struct ImagePool *img_pool = BKE_image_pool_new();
- BKE_texture_fetch_images_for_pool(tex, img_pool);
-
- /* Fill in image buffer. */
- float *rect_float = rv->rectf;
- float tex_coord[3] = {0.0f, 0.0f, 0.0f};
- bool color_manage = true;
-
- for (int y = 0; y < height; y++) {
- /* Tex coords between -1.0f and 1.0f. */
- tex_coord[1] = ((float)y / (float)height) * 2.0f - 1.0f;
-
- for (int x = 0; x < width; x++) {
- tex_coord[0] = ((float)x / (float)height) * 2.0f - 1.0f;
-
- /* Evaluate texture at tex_coord .*/
- TexResult texres = {0};
- BKE_texture_get_value_ex(sce, tex, tex_coord, &texres, img_pool, color_manage);
-
- rect_float[0] = texres.tr;
- rect_float[1] = texres.tg;
- rect_float[2] = texres.tb;
- rect_float[3] = 1.0f;
-
- rect_float += 4;
- }
-
- /* Check if we should cancel texture preview. */
- if (shader_preview_break(sp)) {
- break;
- }
- }
-
- BKE_image_pool_free(img_pool);
+ /* Setup output buffer. */
+ int width = sp->sizex;
+ int height = sp->sizey;
+
+ /* This is needed otherwise no RenderResult is created. */
+ sce->r.scemode &= ~R_BUTS_PREVIEW;
+ RE_InitState(re, NULL, &sce->r, &sce->view_layers, NULL, width, height, NULL);
+ RE_SetScene(re, sce);
+
+ /* Create buffer in empty RenderView created in the init step. */
+ RenderResult *rr = RE_AcquireResultWrite(re);
+ RenderView *rv = (RenderView *)rr->views.first;
+ rv->rectf = MEM_callocN(sizeof(float) * 4 * width * height, "texture render result");
+ RE_ReleaseResult(re);
+
+ /* Get texture image pool (if any) */
+ struct ImagePool *img_pool = BKE_image_pool_new();
+ BKE_texture_fetch_images_for_pool(tex, img_pool);
+
+ /* Fill in image buffer. */
+ float *rect_float = rv->rectf;
+ float tex_coord[3] = {0.0f, 0.0f, 0.0f};
+ bool color_manage = true;
+
+ for (int y = 0; y < height; y++) {
+ /* Tex coords between -1.0f and 1.0f. */
+ tex_coord[1] = ((float)y / (float)height) * 2.0f - 1.0f;
+
+ for (int x = 0; x < width; x++) {
+ tex_coord[0] = ((float)x / (float)height) * 2.0f - 1.0f;
+
+ /* Evaluate texture at tex_coord .*/
+ TexResult texres = {0};
+ BKE_texture_get_value_ex(sce, tex, tex_coord, &texres, img_pool, color_manage);
+
+ rect_float[0] = texres.tr;
+ rect_float[1] = texres.tg;
+ rect_float[2] = texres.tb;
+ rect_float[3] = 1.0f;
+
+ rect_float += 4;
+ }
+
+ /* Check if we should cancel texture preview. */
+ if (shader_preview_break(sp)) {
+ break;
+ }
+ }
+
+ BKE_image_pool_free(img_pool);
}
static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int first)
{
- Render *re;
- Scene *sce;
- float oldlens;
- short idtype = GS(id->name);
- char name[32];
- int sizex;
- Main *pr_main = sp->pr_main;
- ID *id_eval = id;
-
- if (sp->depsgraph) {
- id_eval = DEG_get_evaluated_id(sp->depsgraph, id);
- }
-
- /* in case of split preview, use border render */
- if (split) {
- if (first) sizex = sp->sizex / 2;
- else sizex = sp->sizex - sp->sizex / 2;
- }
- else {
- sizex = sp->sizex;
- }
-
- /* we have to set preview variables first */
- sce = preview_get_scene(pr_main);
- if (sce) {
- sce->r.xsch = sizex;
- sce->r.ysch = sp->sizey;
- sce->r.size = 100;
- }
-
-
- /* get the stuff from the builtin preview dbase */
- sce = preview_prepare_scene(sp->bmain, sp->scene, id_eval, idtype, sp);
- if (sce == NULL) return;
-
- if (!split || first) sprintf(name, "Preview %p", sp->owner);
- else sprintf(name, "SecondPreview %p", sp->owner);
- re = RE_GetRender(name);
-
- /* full refreshed render from first tile */
- if (re == NULL)
- re = RE_NewRender(name);
-
- /* sce->r gets copied in RE_InitState! */
- sce->r.scemode &= ~(R_MATNODE_PREVIEW | R_TEXNODE_PREVIEW);
- sce->r.scemode &= ~R_NO_IMAGE_LOAD;
-
- if (sp->pr_method == PR_ICON_RENDER) {
- sce->r.scemode |= R_NO_IMAGE_LOAD;
- sce->r.mode |= R_OSA;
- }
- else if (sp->pr_method == PR_NODE_RENDER) {
- if (idtype == ID_MA) sce->r.scemode |= R_MATNODE_PREVIEW;
- else if (idtype == ID_TE) sce->r.scemode |= R_TEXNODE_PREVIEW;
- sce->r.mode &= ~R_OSA;
- }
- else { /* PR_BUTS_RENDER */
- sce->r.mode |= R_OSA;
- }
-
-
- /* callbacs are cleared on GetRender() */
- if (ELEM(sp->pr_method, PR_BUTS_RENDER, PR_NODE_RENDER)) {
- RE_display_update_cb(re, sp, shader_preview_update);
- }
- /* set this for all previews, default is react to G.is_break still */
- RE_test_break_cb(re, sp, shader_preview_break);
-
- /* lens adjust */
- oldlens = ((Camera *)sce->camera->data)->lens;
- if (sizex > sp->sizey)
- ((Camera *)sce->camera->data)->lens *= (float)sp->sizey / (float)sizex;
-
- /* entire cycle for render engine */
- if (idtype == ID_TE) {
- shader_preview_texture(sp, (Tex *)id, sce, re);
- }
- else {
- /* Render preview scene */
- RE_PreviewRender(re, pr_main, sce);
- }
-
- ((Camera *)sce->camera->data)->lens = oldlens;
-
- /* handle results */
- if (sp->pr_method == PR_ICON_RENDER) {
- // char *rct= (char *)(sp->pr_rect + 32*16 + 16);
-
- if (sp->pr_rect)
- RE_ResultGet32(re, sp->pr_rect);
- }
-
- /* unassign the pointers, reset vars */
- preview_prepare_scene(sp->bmain, sp->scene, NULL, GS(id->name), sp);
-
- /* XXX bad exception, end-exec is not being called in render, because it uses local main */
-// if (idtype == ID_TE) {
-// Tex *tex= (Tex *)id;
-// if (tex->use_nodes && tex->nodetree)
-// ntreeEndExecTree(tex->nodetree);
-// }
-
+ Render *re;
+ Scene *sce;
+ float oldlens;
+ short idtype = GS(id->name);
+ char name[32];
+ int sizex;
+ Main *pr_main = sp->pr_main;
+ ID *id_eval = id;
+
+ if (sp->depsgraph) {
+ id_eval = DEG_get_evaluated_id(sp->depsgraph, id);
+ }
+
+ /* in case of split preview, use border render */
+ if (split) {
+ if (first)
+ sizex = sp->sizex / 2;
+ else
+ sizex = sp->sizex - sp->sizex / 2;
+ }
+ else {
+ sizex = sp->sizex;
+ }
+
+ /* we have to set preview variables first */
+ sce = preview_get_scene(pr_main);
+ if (sce) {
+ sce->r.xsch = sizex;
+ sce->r.ysch = sp->sizey;
+ sce->r.size = 100;
+ }
+
+ /* get the stuff from the builtin preview dbase */
+ sce = preview_prepare_scene(sp->bmain, sp->scene, id_eval, idtype, sp);
+ if (sce == NULL)
+ return;
+
+ if (!split || first)
+ sprintf(name, "Preview %p", sp->owner);
+ else
+ sprintf(name, "SecondPreview %p", sp->owner);
+ re = RE_GetRender(name);
+
+ /* full refreshed render from first tile */
+ if (re == NULL)
+ re = RE_NewRender(name);
+
+ /* sce->r gets copied in RE_InitState! */
+ sce->r.scemode &= ~(R_MATNODE_PREVIEW | R_TEXNODE_PREVIEW);
+ sce->r.scemode &= ~R_NO_IMAGE_LOAD;
+
+ if (sp->pr_method == PR_ICON_RENDER) {
+ sce->r.scemode |= R_NO_IMAGE_LOAD;
+ sce->r.mode |= R_OSA;
+ }
+ else if (sp->pr_method == PR_NODE_RENDER) {
+ if (idtype == ID_MA)
+ sce->r.scemode |= R_MATNODE_PREVIEW;
+ else if (idtype == ID_TE)
+ sce->r.scemode |= R_TEXNODE_PREVIEW;
+ sce->r.mode &= ~R_OSA;
+ }
+ else { /* PR_BUTS_RENDER */
+ sce->r.mode |= R_OSA;
+ }
+
+ /* callbacs are cleared on GetRender() */
+ if (ELEM(sp->pr_method, PR_BUTS_RENDER, PR_NODE_RENDER)) {
+ RE_display_update_cb(re, sp, shader_preview_update);
+ }
+ /* set this for all previews, default is react to G.is_break still */
+ RE_test_break_cb(re, sp, shader_preview_break);
+
+ /* lens adjust */
+ oldlens = ((Camera *)sce->camera->data)->lens;
+ if (sizex > sp->sizey)
+ ((Camera *)sce->camera->data)->lens *= (float)sp->sizey / (float)sizex;
+
+ /* entire cycle for render engine */
+ if (idtype == ID_TE) {
+ shader_preview_texture(sp, (Tex *)id, sce, re);
+ }
+ else {
+ /* Render preview scene */
+ RE_PreviewRender(re, pr_main, sce);
+ }
+
+ ((Camera *)sce->camera->data)->lens = oldlens;
+
+ /* handle results */
+ if (sp->pr_method == PR_ICON_RENDER) {
+ // char *rct= (char *)(sp->pr_rect + 32*16 + 16);
+
+ if (sp->pr_rect)
+ RE_ResultGet32(re, sp->pr_rect);
+ }
+
+ /* unassign the pointers, reset vars */
+ preview_prepare_scene(sp->bmain, sp->scene, NULL, GS(id->name), sp);
+
+ /* XXX bad exception, end-exec is not being called in render, because it uses local main */
+ // if (idtype == ID_TE) {
+ // Tex *tex= (Tex *)id;
+ // if (tex->use_nodes && tex->nodetree)
+ // ntreeEndExecTree(tex->nodetree);
+ // }
}
/* runs inside thread for material and icons */
static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
{
- ShaderPreview *sp = customdata;
+ ShaderPreview *sp = customdata;
- sp->stop = stop;
- sp->do_update = do_update;
+ sp->stop = stop;
+ sp->do_update = do_update;
- if (sp->parent) {
- shader_preview_render(sp, sp->id, 1, 1);
- shader_preview_render(sp, sp->parent, 1, 0);
- }
- else
- shader_preview_render(sp, sp->id, 0, 0);
+ if (sp->parent) {
+ shader_preview_render(sp, sp->id, 1, 1);
+ shader_preview_render(sp, sp->parent, 1, 0);
+ }
+ else
+ shader_preview_render(sp, sp->id, 0, 0);
- *do_update = true;
+ *do_update = true;
}
static void shader_preview_free(void *customdata)
{
- ShaderPreview *sp = customdata;
- Main *pr_main = sp->pr_main;
-
- if (sp->matcopy) {
- sp->id_copy = (ID *)sp->matcopy;
- BLI_remlink(&pr_main->materials, sp->matcopy);
- }
- if (sp->texcopy) {
- sp->id_copy = (ID *)sp->texcopy;
- BLI_remlink(&pr_main->textures, sp->texcopy);
- }
- if (sp->worldcopy) {
- sp->id_copy = (ID *)sp->worldcopy;
- BLI_remlink(&pr_main->worlds, sp->worldcopy);
- }
- if (sp->lampcopy) {
- sp->id_copy = (ID *)sp->lampcopy;
- BLI_remlink(&pr_main->lights, sp->lampcopy);
- }
- if (sp->id_copy) {
- /* node previews */
- shader_preview_updatejob(sp);
- }
- if (sp->id_copy && sp->own_id_copy) {
- struct IDProperty *properties;
- /* get rid of copied ID */
- properties = IDP_GetProperties(sp->id_copy, false);
- if (properties) {
- IDP_FreeProperty_ex(properties, false);
- MEM_freeN(properties);
- }
- switch (GS(sp->id_copy->name)) {
- case ID_MA:
- BKE_material_free((Material *)sp->id_copy);
- break;
- case ID_TE:
- BKE_texture_free((Tex *)sp->id_copy);
- break;
- case ID_LA:
- BKE_light_free((Light *)sp->id_copy);
- break;
- case ID_WO:
- BKE_world_free((World *)sp->id_copy);
- break;
- default:
- BLI_assert(!"ID type preview not supported.");
- break;
- }
- MEM_freeN(sp->id_copy);
- }
-
- MEM_freeN(sp);
+ ShaderPreview *sp = customdata;
+ Main *pr_main = sp->pr_main;
+
+ if (sp->matcopy) {
+ sp->id_copy = (ID *)sp->matcopy;
+ BLI_remlink(&pr_main->materials, sp->matcopy);
+ }
+ if (sp->texcopy) {
+ sp->id_copy = (ID *)sp->texcopy;
+ BLI_remlink(&pr_main->textures, sp->texcopy);
+ }
+ if (sp->worldcopy) {
+ sp->id_copy = (ID *)sp->worldcopy;
+ BLI_remlink(&pr_main->worlds, sp->worldcopy);
+ }
+ if (sp->lampcopy) {
+ sp->id_copy = (ID *)sp->lampcopy;
+ BLI_remlink(&pr_main->lights, sp->lampcopy);
+ }
+ if (sp->id_copy) {
+ /* node previews */
+ shader_preview_updatejob(sp);
+ }
+ if (sp->id_copy && sp->own_id_copy) {
+ struct IDProperty *properties;
+ /* get rid of copied ID */
+ properties = IDP_GetProperties(sp->id_copy, false);
+ if (properties) {
+ IDP_FreeProperty_ex(properties, false);
+ MEM_freeN(properties);
+ }
+ switch (GS(sp->id_copy->name)) {
+ case ID_MA:
+ BKE_material_free((Material *)sp->id_copy);
+ break;
+ case ID_TE:
+ BKE_texture_free((Tex *)sp->id_copy);
+ break;
+ case ID_LA:
+ BKE_light_free((Light *)sp->id_copy);
+ break;
+ case ID_WO:
+ BKE_world_free((World *)sp->id_copy);
+ break;
+ default:
+ BLI_assert(!"ID type preview not supported.");
+ break;
+ }
+ MEM_freeN(sp->id_copy);
+ }
+
+ MEM_freeN(sp);
}
/* ************************* icon preview ********************** */
static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
{
- struct ImBuf *ima;
- unsigned int *drect, *srect;
- float scaledx, scaledy;
- short ex, ey, dx, dy;
+ struct ImBuf *ima;
+ unsigned int *drect, *srect;
+ float scaledx, scaledy;
+ short ex, ey, dx, dy;
- /* paranoia test */
- if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL))
- return;
+ /* paranoia test */
+ if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL))
+ return;
- /* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
- ima = IMB_dupImBuf(ibuf);
+ /* waste of cpu cyles... but the imbuf API has no other way to scale fast (ton) */
+ ima = IMB_dupImBuf(ibuf);
- if (!ima)
- return;
+ if (!ima)
+ return;
- if (ima->x > ima->y) {
- scaledx = (float)w;
- scaledy = ( (float)ima->y / (float)ima->x) * (float)w;
- }
- else {
- scaledx = ( (float)ima->x / (float)ima->y) * (float)h;
- scaledy = (float)h;
- }
+ if (ima->x > ima->y) {
+ scaledx = (float)w;
+ scaledy = ((float)ima->y / (float)ima->x) * (float)w;
+ }
+ else {
+ scaledx = ((float)ima->x / (float)ima->y) * (float)h;
+ scaledy = (float)h;
+ }
- ex = (short)scaledx;
- ey = (short)scaledy;
+ ex = (short)scaledx;
+ ey = (short)scaledy;
- dx = (w - ex) / 2;
- dy = (h - ey) / 2;
+ dx = (w - ex) / 2;
+ dy = (h - ey) / 2;
- IMB_scalefastImBuf(ima, ex, ey);
+ IMB_scalefastImBuf(ima, ex, ey);
- /* if needed, convert to 32 bits */
- if (ima->rect == NULL)
- IMB_rect_from_float(ima);
+ /* if needed, convert to 32 bits */
+ if (ima->rect == NULL)
+ IMB_rect_from_float(ima);
- srect = ima->rect;
- drect = rect;
+ srect = ima->rect;
+ drect = rect;
- drect += dy * w + dx;
- for (; ey > 0; ey--) {
- memcpy(drect, srect, ex * sizeof(int));
- drect += w;
- srect += ima->x;
- }
+ drect += dy * w + dx;
+ for (; ey > 0; ey--) {
+ memcpy(drect, srect, ex * sizeof(int));
+ drect += w;
+ srect += ima->x;
+ }
- IMB_freeImBuf(ima);
+ IMB_freeImBuf(ima);
}
static void set_alpha(char *cp, int sizex, int sizey, char alpha)
{
- int a, size = sizex * sizey;
+ int a, size = sizex * sizey;
- for (a = 0; a < size; a++, cp += 4)
- cp[3] = alpha;
+ for (a = 0; a < size; a++, cp += 4)
+ cp[3] = alpha;
}
static void icon_preview_startjob(void *customdata, short *stop, short *do_update)
{
- ShaderPreview *sp = customdata;
-
- if (sp->pr_method == PR_ICON_DEFERRED) {
- PreviewImage *prv = sp->owner;
- ImBuf *thumb;
- char *deferred_data = PRV_DEFERRED_DATA(prv);
- int source = deferred_data[0];
- char *path = &deferred_data[1];
-
-// printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path);
-
- thumb = IMB_thumb_manage(path, THB_LARGE, source);
-
- if (thumb) {
- /* PreviewImage assumes premultiplied alhpa... */
- IMB_premultiply_alpha(thumb);
-
- icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect);
- IMB_freeImBuf(thumb);
- }
- }
- else {
- ID *id = sp->id;
- short idtype = GS(id->name);
-
- if (idtype == ID_IM) {
- Image *ima = (Image *)id;
- ImBuf *ibuf = NULL;
- ImageUser iuser = {NULL};
-
- /* ima->ok is zero when Image cannot load */
- if (ima == NULL || ima->ok == 0)
- return;
-
- /* setup dummy image user */
- iuser.ok = iuser.framenr = 1;
- iuser.scene = sp->scene;
-
- /* elubie: this needs to be changed: here image is always loaded if not
- * already there. Very expensive for large images. Need to find a way to
- * only get existing ibuf */
- ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
- if (ibuf == NULL || ibuf->rect == NULL) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- return;
- }
-
- icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
-
- *do_update = true;
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
- else if (idtype == ID_BR) {
- Brush *br = (Brush *)id;
-
- br->icon_imbuf = get_brush_icon(br);
-
- memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));
-
- if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
- return;
-
- icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
-
- *do_update = true;
- }
- else if (idtype == ID_SCR) {
- bScreen *screen = (bScreen *)id;
-
- ED_screen_preview_render(screen, sp->sizex, sp->sizey, sp->pr_rect);
- *do_update = true;
- }
- else {
- /* re-use shader job */
- shader_preview_startjob(customdata, stop, do_update);
-
- /* world is rendered with alpha=0, so it wasn't displayed
- * this could be render option for sky to, for later */
- if (idtype == ID_WO) {
- set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
- }
- }
- }
+ ShaderPreview *sp = customdata;
+
+ if (sp->pr_method == PR_ICON_DEFERRED) {
+ PreviewImage *prv = sp->owner;
+ ImBuf *thumb;
+ char *deferred_data = PRV_DEFERRED_DATA(prv);
+ int source = deferred_data[0];
+ char *path = &deferred_data[1];
+
+ // printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path);
+
+ thumb = IMB_thumb_manage(path, THB_LARGE, source);
+
+ if (thumb) {
+ /* PreviewImage assumes premultiplied alhpa... */
+ IMB_premultiply_alpha(thumb);
+
+ icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect);
+ IMB_freeImBuf(thumb);
+ }
+ }
+ else {
+ ID *id = sp->id;
+ short idtype = GS(id->name);
+
+ if (idtype == ID_IM) {
+ Image *ima = (Image *)id;
+ ImBuf *ibuf = NULL;
+ ImageUser iuser = {NULL};
+
+ /* ima->ok is zero when Image cannot load */
+ if (ima == NULL || ima->ok == 0)
+ return;
+
+ /* setup dummy image user */
+ iuser.ok = iuser.framenr = 1;
+ iuser.scene = sp->scene;
+
+ /* elubie: this needs to be changed: here image is always loaded if not
+ * already there. Very expensive for large images. Need to find a way to
+ * only get existing ibuf */
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return;
+ }
+
+ icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
+
+ *do_update = true;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ else if (idtype == ID_BR) {
+ Brush *br = (Brush *)id;
+
+ br->icon_imbuf = get_brush_icon(br);
+
+ memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));
+
+ if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
+ return;
+
+ icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
+
+ *do_update = true;
+ }
+ else if (idtype == ID_SCR) {
+ bScreen *screen = (bScreen *)id;
+
+ ED_screen_preview_render(screen, sp->sizex, sp->sizey, sp->pr_rect);
+ *do_update = true;
+ }
+ else {
+ /* re-use shader job */
+ shader_preview_startjob(customdata, stop, do_update);
+
+ /* world is rendered with alpha=0, so it wasn't displayed
+ * this could be render option for sky to, for later */
+ if (idtype == ID_WO) {
+ set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ }
+ }
+ }
}
/* use same function for icon & shader, so the job manager
* does not run two of them at the same time. */
-static void common_preview_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress))
+static void common_preview_startjob(void *customdata,
+ short *stop,
+ short *do_update,
+ float *UNUSED(progress))
{
- ShaderPreview *sp = customdata;
+ ShaderPreview *sp = customdata;
- if (ELEM(sp->pr_method, PR_ICON_RENDER, PR_ICON_DEFERRED))
- icon_preview_startjob(customdata, stop, do_update);
- else
- shader_preview_startjob(customdata, stop, do_update);
+ if (ELEM(sp->pr_method, PR_ICON_RENDER, PR_ICON_DEFERRED))
+ icon_preview_startjob(customdata, stop, do_update);
+ else
+ shader_preview_startjob(customdata, stop, do_update);
}
/* exported functions */
static void icon_preview_add_size(IconPreview *ip, unsigned int *rect, int sizex, int sizey)
{
- IconPreviewSize *cur_size = ip->sizes.first, *new_size;
+ IconPreviewSize *cur_size = ip->sizes.first, *new_size;
- while (cur_size) {
- if (cur_size->sizex == sizex && cur_size->sizey == sizey) {
- /* requested size is already in list, no need to add it again */
- return;
- }
+ while (cur_size) {
+ if (cur_size->sizex == sizex && cur_size->sizey == sizey) {
+ /* requested size is already in list, no need to add it again */
+ return;
+ }
- cur_size = cur_size->next;
- }
+ cur_size = cur_size->next;
+ }
- new_size = MEM_callocN(sizeof(IconPreviewSize), "IconPreviewSize");
- new_size->sizex = sizex;
- new_size->sizey = sizey;
- new_size->rect = rect;
+ new_size = MEM_callocN(sizeof(IconPreviewSize), "IconPreviewSize");
+ new_size->sizex = sizex;
+ new_size->sizey = sizey;
+ new_size->rect = rect;
- BLI_addtail(&ip->sizes, new_size);
+ BLI_addtail(&ip->sizes, new_size);
}
-static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, float *progress)
+static void icon_preview_startjob_all_sizes(void *customdata,
+ short *stop,
+ short *do_update,
+ float *progress)
{
- IconPreview *ip = (IconPreview *)customdata;
- IconPreviewSize *cur_size;
-
- for (cur_size = ip->sizes.first; cur_size; cur_size = cur_size->next) {
- PreviewImage *prv = ip->owner;
-
- if (prv->tag & PRV_TAG_DEFFERED_DELETE) {
- /* Non-thread-protected reading is not an issue here. */
- continue;
- }
-
- if (!check_engine_supports_preview(ip->scene)) {
- continue;
- }
-
- ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
- const bool is_render = !(prv->tag & PRV_TAG_DEFFERED);
-
- /* construct shader preview from image size and previewcustomdata */
- sp->scene = ip->scene;
- sp->depsgraph = ip->depsgraph;
- sp->owner = ip->owner;
- sp->sizex = cur_size->sizex;
- sp->sizey = cur_size->sizey;
- sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
- sp->pr_rect = cur_size->rect;
- sp->id = ip->id;
- sp->id_copy = ip->id_copy;
- sp->bmain = ip->bmain;
- sp->own_id_copy = false;
- Material *ma = NULL;
-
- if (is_render) {
- BLI_assert(ip->id);
-
- /* grease pencil use its own preview file */
- if (GS(ip->id->name) == ID_MA) {
- ma = (Material *)ip->id;
- }
-
- if ((ma == NULL) || (ma->gp_style == NULL)) {
- sp->pr_main = G_pr_main;
- }
- else {
- sp->pr_main = G_pr_main_grease_pencil;
- }
- }
-
- common_preview_startjob(sp, stop, do_update, progress);
- shader_preview_free(sp);
- }
+ IconPreview *ip = (IconPreview *)customdata;
+ IconPreviewSize *cur_size;
+
+ for (cur_size = ip->sizes.first; cur_size; cur_size = cur_size->next) {
+ PreviewImage *prv = ip->owner;
+
+ if (prv->tag & PRV_TAG_DEFFERED_DELETE) {
+ /* Non-thread-protected reading is not an issue here. */
+ continue;
+ }
+
+ if (!check_engine_supports_preview(ip->scene)) {
+ continue;
+ }
+
+ ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
+ const bool is_render = !(prv->tag & PRV_TAG_DEFFERED);
+
+ /* construct shader preview from image size and previewcustomdata */
+ sp->scene = ip->scene;
+ sp->depsgraph = ip->depsgraph;
+ sp->owner = ip->owner;
+ sp->sizex = cur_size->sizex;
+ sp->sizey = cur_size->sizey;
+ sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
+ sp->pr_rect = cur_size->rect;
+ sp->id = ip->id;
+ sp->id_copy = ip->id_copy;
+ sp->bmain = ip->bmain;
+ sp->own_id_copy = false;
+ Material *ma = NULL;
+
+ if (is_render) {
+ BLI_assert(ip->id);
+
+ /* grease pencil use its own preview file */
+ if (GS(ip->id->name) == ID_MA) {
+ ma = (Material *)ip->id;
+ }
+
+ if ((ma == NULL) || (ma->gp_style == NULL)) {
+ sp->pr_main = G_pr_main;
+ }
+ else {
+ sp->pr_main = G_pr_main_grease_pencil;
+ }
+ }
+
+ common_preview_startjob(sp, stop, do_update, progress);
+ shader_preview_free(sp);
+ }
}
static void icon_preview_endjob(void *customdata)
{
- IconPreview *ip = customdata;
+ IconPreview *ip = customdata;
- if (ip->id) {
+ if (ip->id) {
- if (GS(ip->id->name) == ID_BR)
- WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
+ if (GS(ip->id->name) == ID_BR)
+ WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id);
#if 0
- if (GS(ip->id->name) == ID_MA) {
- Material *ma = (Material *)ip->id;
- PreviewImage *prv_img = ma->preview;
- int i;
-
- /* signal to gpu texture */
- for (i = 0; i < NUM_ICON_SIZES; ++i) {
- if (prv_img->gputexture[i]) {
- GPU_texture_free(prv_img->gputexture[i]);
- prv_img->gputexture[i] = NULL;
- WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ip->id);
- }
- }
- }
+ if (GS(ip->id->name) == ID_MA) {
+ Material *ma = (Material *)ip->id;
+ PreviewImage *prv_img = ma->preview;
+ int i;
+
+ /* signal to gpu texture */
+ for (i = 0; i < NUM_ICON_SIZES; ++i) {
+ if (prv_img->gputexture[i]) {
+ GPU_texture_free(prv_img->gputexture[i]);
+ prv_img->gputexture[i] = NULL;
+ WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ip->id);
+ }
+ }
+ }
#endif
- }
-
- if (ip->owner) {
- PreviewImage *prv_img = ip->owner;
- prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING;
- if (prv_img->tag & PRV_TAG_DEFFERED_DELETE) {
- BLI_assert(prv_img->tag & PRV_TAG_DEFFERED);
- BKE_previewimg_cached_release_pointer(prv_img);
- }
- }
+ }
+
+ if (ip->owner) {
+ PreviewImage *prv_img = ip->owner;
+ prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING;
+ if (prv_img->tag & PRV_TAG_DEFFERED_DELETE) {
+ BLI_assert(prv_img->tag & PRV_TAG_DEFFERED);
+ BKE_previewimg_cached_release_pointer(prv_img);
+ }
+ }
}
static void icon_preview_free(void *customdata)
{
- IconPreview *ip = (IconPreview *)customdata;
-
- if (ip->id_copy) {
- /* Feels a bit hacky just to reuse shader_preview_free() */
- ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
- sp->id_copy = ip->id_copy;
- sp->own_id_copy = true;
- shader_preview_free(sp);
- ip->id_copy = NULL;
- }
-
- BLI_freelistN(&ip->sizes);
- MEM_freeN(ip);
+ IconPreview *ip = (IconPreview *)customdata;
+
+ if (ip->id_copy) {
+ /* Feels a bit hacky just to reuse shader_preview_free() */
+ ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
+ sp->id_copy = ip->id_copy;
+ sp->own_id_copy = true;
+ shader_preview_free(sp);
+ ip->id_copy = NULL;
+ }
+
+ BLI_freelistN(&ip->sizes);
+ MEM_freeN(ip);
}
-void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rect, int sizex, int sizey)
+void ED_preview_icon_render(
+ Main *bmain, Scene *scene, ID *id, unsigned int *rect, int sizex, int sizey)
{
- IconPreview ip = {NULL};
- short stop = false, update = false;
- float progress = 0.0f;
+ IconPreview ip = {NULL};
+ short stop = false, update = false;
+ float progress = 0.0f;
- ED_preview_ensure_dbase();
+ ED_preview_ensure_dbase();
- ip.bmain = bmain;
- ip.scene = scene;
- ip.owner = BKE_previewimg_id_ensure(id);
- ip.id = id;
- ip.id_copy = duplicate_ids(id, NULL);
+ ip.bmain = bmain;
+ ip.scene = scene;
+ ip.owner = BKE_previewimg_id_ensure(id);
+ ip.id = id;
+ ip.id_copy = duplicate_ids(id, NULL);
- icon_preview_add_size(&ip, rect, sizex, sizey);
+ icon_preview_add_size(&ip, rect, sizex, sizey);
- icon_preview_startjob_all_sizes(&ip, &stop, &update, &progress);
+ icon_preview_startjob_all_sizes(&ip, &stop, &update, &progress);
- icon_preview_endjob(&ip);
+ icon_preview_endjob(&ip);
- BLI_freelistN(&ip.sizes);
+ BLI_freelistN(&ip.sizes);
}
-void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey)
+void ED_preview_icon_job(
+ const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey)
{
- wmJob *wm_job;
- IconPreview *ip, *old_ip;
-
- ED_preview_ensure_dbase();
-
- /* suspended start means it starts after 1 timer step, see WM_jobs_timer below */
- wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Icon Preview",
- WM_JOB_EXCL_RENDER | WM_JOB_SUSPEND, WM_JOB_TYPE_RENDER_PREVIEW);
-
- ip = MEM_callocN(sizeof(IconPreview), "icon preview");
-
- /* render all resolutions from suspended job too */
- old_ip = WM_jobs_customdata_get(wm_job);
- if (old_ip)
- BLI_movelisttolist(&ip->sizes, &old_ip->sizes);
-
- /* customdata for preview thread */
- ip->bmain = CTX_data_main(C);
- ip->scene = CTX_data_scene(C);
- ip->depsgraph = CTX_data_depsgraph(C);
- ip->owner = owner;
- ip->id = id;
- ip->id_copy = duplicate_ids(id, ip->depsgraph);
-
- icon_preview_add_size(ip, rect, sizex, sizey);
-
- /* Special threading hack: warn main code that this preview is being rendered and cannot be freed... */
- {
- PreviewImage *prv_img = owner;
- if (prv_img->tag & PRV_TAG_DEFFERED) {
- prv_img->tag |= PRV_TAG_DEFFERED_RENDERING;
- }
- }
-
- /* setup job */
- WM_jobs_customdata_set(wm_job, ip, icon_preview_free);
- WM_jobs_timer(wm_job, 0.1, NC_WINDOW, NC_WINDOW);
- WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob);
-
- WM_jobs_start(CTX_wm_manager(C), wm_job);
+ wmJob *wm_job;
+ IconPreview *ip, *old_ip;
+
+ ED_preview_ensure_dbase();
+
+ /* suspended start means it starts after 1 timer step, see WM_jobs_timer below */
+ wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ owner,
+ "Icon Preview",
+ WM_JOB_EXCL_RENDER | WM_JOB_SUSPEND,
+ WM_JOB_TYPE_RENDER_PREVIEW);
+
+ ip = MEM_callocN(sizeof(IconPreview), "icon preview");
+
+ /* render all resolutions from suspended job too */
+ old_ip = WM_jobs_customdata_get(wm_job);
+ if (old_ip)
+ BLI_movelisttolist(&ip->sizes, &old_ip->sizes);
+
+ /* customdata for preview thread */
+ ip->bmain = CTX_data_main(C);
+ ip->scene = CTX_data_scene(C);
+ ip->depsgraph = CTX_data_depsgraph(C);
+ ip->owner = owner;
+ ip->id = id;
+ ip->id_copy = duplicate_ids(id, ip->depsgraph);
+
+ icon_preview_add_size(ip, rect, sizex, sizey);
+
+ /* Special threading hack: warn main code that this preview is being rendered and cannot be freed... */
+ {
+ PreviewImage *prv_img = owner;
+ if (prv_img->tag & PRV_TAG_DEFFERED) {
+ prv_img->tag |= PRV_TAG_DEFFERED_RENDERING;
+ }
+ }
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, ip, icon_preview_free);
+ WM_jobs_timer(wm_job, 0.1, NC_WINDOW, NC_WINDOW);
+ WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
}
-void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, MTex *slot, int sizex, int sizey, int method)
+void ED_preview_shader_job(const bContext *C,
+ void *owner,
+ ID *id,
+ ID *parent,
+ MTex *slot,
+ int sizex,
+ int sizey,
+ int method)
{
- Object *ob = CTX_data_active_object(C);
- wmJob *wm_job;
- ShaderPreview *sp;
- Scene *scene = CTX_data_scene(C);
- short id_type = GS(id->name);
-
- /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */
-
- if (!check_engine_supports_preview(scene)) {
- return;
- }
-
- /* Only texture node preview is supported with Cycles. */
- if (method == PR_NODE_RENDER && id_type != ID_TE) {
- return;
- }
-
- ED_preview_ensure_dbase();
-
- wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Shader Preview",
- WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
- sp = MEM_callocN(sizeof(ShaderPreview), "shader preview");
-
- /* customdata for preview thread */
- sp->scene = scene;
- sp->depsgraph = CTX_data_depsgraph(C);
- sp->owner = owner;
- sp->sizex = sizex;
- sp->sizey = sizey;
- sp->pr_method = method;
- sp->id = id;
- sp->id_copy = duplicate_ids(id, sp->depsgraph);
- sp->own_id_copy = true;
- sp->parent = parent;
- sp->slot = slot;
- sp->bmain = CTX_data_main(C);
- Material *ma = NULL;
-
- /* hardcoded preview .blend for Eevee + Cycles, this should be solved
- * once with custom preview .blend path for external engines */
-
- /* grease pencil use its own preview file */
- if (GS(id->name) == ID_MA) {
- ma = (Material *)id;
- }
-
- if ((ma == NULL) || (ma->gp_style == NULL)) {
- sp->pr_main = G_pr_main;
- }
- else {
- sp->pr_main = G_pr_main_grease_pencil;
- }
-
- if (ob && ob->totcol) {
- copy_v4_v4(sp->color, ob->color);
- }
- else {
- ARRAY_SET_ITEMS(sp->color, 0.0f, 0.0f, 0.0f, 1.0f);
- }
-
- /* setup job */
- WM_jobs_customdata_set(wm_job, sp, shader_preview_free);
- WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
- WM_jobs_callbacks(wm_job, common_preview_startjob, NULL, shader_preview_updatejob, NULL);
-
- WM_jobs_start(CTX_wm_manager(C), wm_job);
+ Object *ob = CTX_data_active_object(C);
+ wmJob *wm_job;
+ ShaderPreview *sp;
+ Scene *scene = CTX_data_scene(C);
+ short id_type = GS(id->name);
+
+ /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */
+
+ if (!check_engine_supports_preview(scene)) {
+ return;
+ }
+
+ /* Only texture node preview is supported with Cycles. */
+ if (method == PR_NODE_RENDER && id_type != ID_TE) {
+ return;
+ }
+
+ ED_preview_ensure_dbase();
+
+ wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ owner,
+ "Shader Preview",
+ WM_JOB_EXCL_RENDER,
+ WM_JOB_TYPE_RENDER_PREVIEW);
+ sp = MEM_callocN(sizeof(ShaderPreview), "shader preview");
+
+ /* customdata for preview thread */
+ sp->scene = scene;
+ sp->depsgraph = CTX_data_depsgraph(C);
+ sp->owner = owner;
+ sp->sizex = sizex;
+ sp->sizey = sizey;
+ sp->pr_method = method;
+ sp->id = id;
+ sp->id_copy = duplicate_ids(id, sp->depsgraph);
+ sp->own_id_copy = true;
+ sp->parent = parent;
+ sp->slot = slot;
+ sp->bmain = CTX_data_main(C);
+ Material *ma = NULL;
+
+ /* hardcoded preview .blend for Eevee + Cycles, this should be solved
+ * once with custom preview .blend path for external engines */
+
+ /* grease pencil use its own preview file */
+ if (GS(id->name) == ID_MA) {
+ ma = (Material *)id;
+ }
+
+ if ((ma == NULL) || (ma->gp_style == NULL)) {
+ sp->pr_main = G_pr_main;
+ }
+ else {
+ sp->pr_main = G_pr_main_grease_pencil;
+ }
+
+ if (ob && ob->totcol) {
+ copy_v4_v4(sp->color, ob->color);
+ }
+ else {
+ ARRAY_SET_ITEMS(sp->color, 0.0f, 0.0f, 0.0f, 1.0f);
+ }
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, sp, shader_preview_free);
+ WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
+ WM_jobs_callbacks(wm_job, common_preview_startjob, NULL, shader_preview_updatejob, NULL);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
}
void ED_preview_kill_jobs(wmWindowManager *wm, Main *UNUSED(bmain))
{
- if (wm)
- WM_jobs_kill(wm, NULL, common_preview_startjob);
+ if (wm)
+ WM_jobs_kill(wm, NULL, common_preview_startjob);
}
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 9bf9b15cd07..70157abf2ef 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -100,1890 +100,1937 @@
*/
static Object **object_array_for_shading(bContext *C, uint *r_objects_len)
{
- ScrArea *sa = CTX_wm_area(C);
- SpaceProperties *sbuts = NULL;
- View3D *v3d = NULL;
- if (sa->spacetype == SPACE_PROPERTIES) {
- sbuts = sa->spacedata.first;
- }
- else if (sa->spacetype == SPACE_VIEW3D) {
- v3d = sa->spacedata.first;
- }
-
- Object **objects;
- if (sbuts && sbuts->pinid && GS(sbuts->pinid->name) == ID_OB) {
- objects = MEM_mallocN(sizeof(*objects), __func__);
- objects[0] = (Object *)sbuts->pinid;
- *r_objects_len = 1;
- }
- else {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_objects_len);
- }
- return objects;
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceProperties *sbuts = NULL;
+ View3D *v3d = NULL;
+ if (sa->spacetype == SPACE_PROPERTIES) {
+ sbuts = sa->spacedata.first;
+ }
+ else if (sa->spacetype == SPACE_VIEW3D) {
+ v3d = sa->spacedata.first;
+ }
+
+ Object **objects;
+ if (sbuts && sbuts->pinid && GS(sbuts->pinid->name) == ID_OB) {
+ objects = MEM_mallocN(sizeof(*objects), __func__);
+ objects[0] = (Object *)sbuts->pinid;
+ *r_objects_len = 1;
+ }
+ else {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, v3d, r_objects_len);
+ }
+ return objects;
}
/********************** material slot operators *********************/
static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- Object *ob = ED_object_context(C);
+ Main *bmain = CTX_data_main(C);
+ Object *ob = ED_object_context(C);
- if (!ob)
- return OPERATOR_CANCELLED;
+ if (!ob)
+ return OPERATOR_CANCELLED;
- BKE_object_material_slot_add(bmain, ob);
+ BKE_object_material_slot_add(bmain, ob);
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- Scene *scene = CTX_data_scene(C);
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
- }
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ Scene *scene = CTX_data_scene(C);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OBJECT_OT_material_slot_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Material Slot";
- ot->idname = "OBJECT_OT_material_slot_add";
- ot->description = "Add a new material slot";
+ /* identifiers */
+ ot->name = "Add Material Slot";
+ ot->idname = "OBJECT_OT_material_slot_add";
+ ot->description = "Add a new material slot";
- /* api callbacks */
- ot->exec = material_slot_add_exec;
- ot->poll = ED_operator_object_active_editable;
+ /* api callbacks */
+ ot->exec = material_slot_add_exec;
+ ot->poll = ED_operator_object_active_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int material_slot_remove_exec(bContext *C, wmOperator *op)
{
- Object *ob = ED_object_context(C);
+ Object *ob = ED_object_context(C);
- if (!ob)
- return OPERATOR_CANCELLED;
+ if (!ob)
+ return OPERATOR_CANCELLED;
- /* Removing material slots in edit mode screws things up, see bug #21822.*/
- if (ob == CTX_data_edit_object(C)) {
- BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
- return OPERATOR_CANCELLED;
- }
+ /* Removing material slots in edit mode screws things up, see bug #21822.*/
+ if (ob == CTX_data_edit_object(C)) {
+ BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
+ return OPERATOR_CANCELLED;
+ }
- BKE_object_material_slot_remove(CTX_data_main(C), ob);
+ BKE_object_material_slot_remove(CTX_data_main(C), ob);
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- Scene *scene = CTX_data_scene(C);
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
- }
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ Scene *scene = CTX_data_scene(C);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Material Slot";
- ot->idname = "OBJECT_OT_material_slot_remove";
- ot->description = "Remove the selected material slot";
+ /* identifiers */
+ ot->name = "Remove Material Slot";
+ ot->idname = "OBJECT_OT_material_slot_remove";
+ ot->description = "Remove the selected material slot";
- /* api callbacks */
- ot->exec = material_slot_remove_exec;
- ot->poll = ED_operator_object_active_editable;
+ /* api callbacks */
+ ot->exec = material_slot_remove_exec;
+ ot->poll = ED_operator_object_active_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
{
- View3D *v3d = CTX_wm_view3d(C);
- bool changed_multi = false;
-
- uint objects_len = 0;
- Object **objects = object_array_for_shading(C, &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob = objects[ob_index];
- if (ob->actcol <= 0) {
- continue;
- }
- bool changed = false;
- if (ob->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(ob);
- BMFace *efa;
- BMIter iter;
-
- if (em) {
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
- changed = true;
- efa->mat_nr = ob->actcol - 1;
- }
- }
- }
- }
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- Nurb *nu;
- ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
-
- if (nurbs) {
- for (nu = nurbs->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- changed = true;
- nu->mat_nr = ob->actcol - 1;
- }
- }
- }
- }
- else if (ob->type == OB_FONT) {
- EditFont *ef = ((Curve *)ob->data)->editfont;
- int i, selstart, selend;
-
- if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
- for (i = selstart; i <= selend; i++) {
- changed = true;
- ef->textbufinfo[i].mat_nr = ob->actcol;
- }
- }
- }
-
- if (changed) {
- changed_multi = true;
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
- }
- }
- MEM_freeN(objects);
-
- return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ View3D *v3d = CTX_wm_view3d(C);
+ bool changed_multi = false;
+
+ uint objects_len = 0;
+ Object **objects = object_array_for_shading(C, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ if (ob->actcol <= 0) {
+ continue;
+ }
+ bool changed = false;
+ if (ob->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMFace *efa;
+ BMIter iter;
+
+ if (em) {
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
+ changed = true;
+ efa->mat_nr = ob->actcol - 1;
+ }
+ }
+ }
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Nurb *nu;
+ ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
+
+ if (nurbs) {
+ for (nu = nurbs->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ changed = true;
+ nu->mat_nr = ob->actcol - 1;
+ }
+ }
+ }
+ }
+ else if (ob->type == OB_FONT) {
+ EditFont *ef = ((Curve *)ob->data)->editfont;
+ int i, selstart, selend;
+
+ if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
+ for (i = selstart; i <= selend; i++) {
+ changed = true;
+ ef->textbufinfo[i].mat_nr = ob->actcol;
+ }
+ }
+ }
+
+ if (changed) {
+ changed_multi = true;
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ }
+ }
+ MEM_freeN(objects);
+
+ return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Assign Material Slot";
- ot->idname = "OBJECT_OT_material_slot_assign";
- ot->description = "Assign active material slot to selection";
+ /* identifiers */
+ ot->name = "Assign Material Slot";
+ ot->idname = "OBJECT_OT_material_slot_assign";
+ ot->description = "Assign active material slot to selection";
- /* api callbacks */
- ot->exec = material_slot_assign_exec;
- ot->poll = ED_operator_object_active_editable;
+ /* api callbacks */
+ ot->exec = material_slot_assign_exec;
+ ot->poll = ED_operator_object_active_editable;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int material_slot_de_select(bContext *C, bool select)
{
- bool changed_multi = false;
- Object *obact = CTX_data_active_object(C);
- const Material *mat_active = obact ? give_current_material(obact, obact->actcol) : NULL;
-
- uint objects_len = 0;
- Object **objects = object_array_for_shading(C, &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *ob = objects[ob_index];
- short mat_nr_active = -1;
-
- if (ob->totcol == 0) {
- continue;
- }
- if (obact && (mat_active == give_current_material(ob, obact->actcol))) {
- /* Avoid searching since there may be multiple slots with the same material.
- * For the active object or duplicates: match the material slot index first. */
- mat_nr_active = obact->actcol - 1;
- }
- else {
- /* Find the first matching material.
- * Note: there may be multiple but thats not a common use case. */
- for (short i = 0; i < ob->totcol; i++) {
- const Material *mat = give_current_material(ob, i + 1);
- if (mat_active == mat) {
- mat_nr_active = i;
- break;
- }
- }
- if (mat_nr_active == -1) {
- continue;
- }
- }
-
-
- bool changed = false;
-
- if (ob->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(ob);
-
- if (em) {
- changed = EDBM_deselect_by_material(em, mat_nr_active, select);
- }
- }
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
- Nurb *nu;
- BPoint *bp;
- BezTriple *bezt;
- int a;
-
- if (nurbs) {
- for (nu = nurbs->first; nu; nu = nu->next) {
- if (nu->mat_nr == mat_nr_active) {
- if (nu->bezt) {
- a = nu->pntsu;
- bezt = nu->bezt;
- while (a--) {
- if (bezt->hide == 0) {
- changed = true;
- if (select) {
- bezt->f1 |= SELECT;
- bezt->f2 |= SELECT;
- bezt->f3 |= SELECT;
- }
- else {
- bezt->f1 &= ~SELECT;
- bezt->f2 &= ~SELECT;
- bezt->f3 &= ~SELECT;
- }
- }
- bezt++;
- }
- }
- else if (nu->bp) {
- a = nu->pntsu * nu->pntsv;
- bp = nu->bp;
- while (a--) {
- if (bp->hide == 0) {
- changed = true;
- if (select) bp->f1 |= SELECT;
- else bp->f1 &= ~SELECT;
- }
- bp++;
- }
- }
- }
- }
- }
- }
-
- if (changed) {
- changed_multi = true;
- DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
- }
- }
-
- MEM_freeN(objects);
-
- return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ bool changed_multi = false;
+ Object *obact = CTX_data_active_object(C);
+ const Material *mat_active = obact ? give_current_material(obact, obact->actcol) : NULL;
+
+ uint objects_len = 0;
+ Object **objects = object_array_for_shading(C, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ short mat_nr_active = -1;
+
+ if (ob->totcol == 0) {
+ continue;
+ }
+ if (obact && (mat_active == give_current_material(ob, obact->actcol))) {
+ /* Avoid searching since there may be multiple slots with the same material.
+ * For the active object or duplicates: match the material slot index first. */
+ mat_nr_active = obact->actcol - 1;
+ }
+ else {
+ /* Find the first matching material.
+ * Note: there may be multiple but thats not a common use case. */
+ for (short i = 0; i < ob->totcol; i++) {
+ const Material *mat = give_current_material(ob, i + 1);
+ if (mat_active == mat) {
+ mat_nr_active = i;
+ break;
+ }
+ }
+ if (mat_nr_active == -1) {
+ continue;
+ }
+ }
+
+ bool changed = false;
+
+ if (ob->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+
+ if (em) {
+ changed = EDBM_deselect_by_material(em, mat_nr_active, select);
+ }
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int a;
+
+ if (nurbs) {
+ for (nu = nurbs->first; nu; nu = nu->next) {
+ if (nu->mat_nr == mat_nr_active) {
+ if (nu->bezt) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ while (a--) {
+ if (bezt->hide == 0) {
+ changed = true;
+ if (select) {
+ bezt->f1 |= SELECT;
+ bezt->f2 |= SELECT;
+ bezt->f3 |= SELECT;
+ }
+ else {
+ bezt->f1 &= ~SELECT;
+ bezt->f2 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
+ }
+ }
+ bezt++;
+ }
+ }
+ else if (nu->bp) {
+ a = nu->pntsu * nu->pntsv;
+ bp = nu->bp;
+ while (a--) {
+ if (bp->hide == 0) {
+ changed = true;
+ if (select)
+ bp->f1 |= SELECT;
+ else
+ bp->f1 &= ~SELECT;
+ }
+ bp++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (changed) {
+ changed_multi = true;
+ DEG_id_tag_update(ob->data, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
+ }
+ }
+
+ MEM_freeN(objects);
+
+ return (changed_multi) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static int material_slot_select_exec(bContext *C, wmOperator *UNUSED(op))
{
- return material_slot_de_select(C, true);
+ return material_slot_de_select(C, true);
}
void OBJECT_OT_material_slot_select(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Material Slot";
- ot->idname = "OBJECT_OT_material_slot_select";
- ot->description = "Select by active material slot";
+ /* identifiers */
+ ot->name = "Select Material Slot";
+ ot->idname = "OBJECT_OT_material_slot_select";
+ ot->description = "Select by active material slot";
- /* api callbacks */
- ot->exec = material_slot_select_exec;
+ /* api callbacks */
+ ot->exec = material_slot_select_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int material_slot_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
- return material_slot_de_select(C, false);
+ return material_slot_de_select(C, false);
}
void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Deselect Material Slot";
- ot->idname = "OBJECT_OT_material_slot_deselect";
- ot->description = "Deselect by active material slot";
+ /* identifiers */
+ ot->name = "Deselect Material Slot";
+ ot->idname = "OBJECT_OT_material_slot_deselect";
+ ot->description = "Deselect by active material slot";
- /* api callbacks */
- ot->exec = material_slot_deselect_exec;
+ /* api callbacks */
+ ot->exec = material_slot_deselect_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
-
static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- Object *ob = ED_object_context(C);
- Material ***matar;
+ Main *bmain = CTX_data_main(C);
+ Object *ob = ED_object_context(C);
+ Material ***matar;
- if (!ob || !(matar = give_matarar(ob)))
- return OPERATOR_CANCELLED;
+ if (!ob || !(matar = give_matarar(ob)))
+ return OPERATOR_CANCELLED;
- CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects)
- {
- if (ob != ob_iter && give_matarar(ob_iter)) {
- if (ob->data != ob_iter->data)
- assign_matarar(bmain, ob_iter, matar, ob->totcol);
+ CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
+ if (ob != ob_iter && give_matarar(ob_iter)) {
+ if (ob->data != ob_iter->data)
+ assign_matarar(bmain, ob_iter, matar, ob->totcol);
- if (ob_iter->totcol == ob->totcol) {
- ob_iter->actcol = ob->actcol;
- DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
- }
- }
- }
- CTX_DATA_END;
+ if (ob_iter->totcol == ob->totcol) {
+ ob_iter->actcol = ob->actcol;
+ DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
+ }
+ }
+ }
+ CTX_DATA_END;
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
-
void OBJECT_OT_material_slot_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Material to Selected";
- ot->idname = "OBJECT_OT_material_slot_copy";
- ot->description = "Copy material to selected objects";
+ /* identifiers */
+ ot->name = "Copy Material to Selected";
+ ot->idname = "OBJECT_OT_material_slot_copy";
+ ot->description = "Copy material to selected objects";
- /* api callbacks */
- ot->exec = material_slot_copy_exec;
+ /* api callbacks */
+ ot->exec = material_slot_copy_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int material_slot_move_exec(bContext *C, wmOperator *op)
{
- Object *ob = ED_object_context(C);
+ Object *ob = ED_object_context(C);
- unsigned int *slot_remap;
- int index_pair[2];
+ unsigned int *slot_remap;
+ int index_pair[2];
- int dir = RNA_enum_get(op->ptr, "direction");
+ int dir = RNA_enum_get(op->ptr, "direction");
- if (!ob || ob->totcol < 2) {
- return OPERATOR_CANCELLED;
- }
+ if (!ob || ob->totcol < 2) {
+ return OPERATOR_CANCELLED;
+ }
- /* up */
- if (dir == 1 && ob->actcol > 1) {
- index_pair[0] = ob->actcol - 2;
- index_pair[1] = ob->actcol - 1;
- ob->actcol--;
- }
- /* down */
- else if (dir == -1 && ob->actcol < ob->totcol) {
- index_pair[0] = ob->actcol - 1;
- index_pair[1] = ob->actcol - 0;
- ob->actcol++;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* up */
+ if (dir == 1 && ob->actcol > 1) {
+ index_pair[0] = ob->actcol - 2;
+ index_pair[1] = ob->actcol - 1;
+ ob->actcol--;
+ }
+ /* down */
+ else if (dir == -1 && ob->actcol < ob->totcol) {
+ index_pair[0] = ob->actcol - 1;
+ index_pair[1] = ob->actcol - 0;
+ ob->actcol++;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
- slot_remap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, __func__);
+ slot_remap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, __func__);
- range_vn_u(slot_remap, ob->totcol, 0);
+ range_vn_u(slot_remap, ob->totcol, 0);
- slot_remap[index_pair[0]] = index_pair[1];
- slot_remap[index_pair[1]] = index_pair[0];
+ slot_remap[index_pair[0]] = index_pair[1];
+ slot_remap[index_pair[1]] = index_pair[0];
- BKE_material_remap_object(ob, slot_remap);
+ BKE_material_remap_object(ob, slot_remap);
- MEM_freeN(slot_remap);
+ MEM_freeN(slot_remap);
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void OBJECT_OT_material_slot_move(wmOperatorType *ot)
{
- static const EnumPropertyItem material_slot_move[] = {
- {1, "UP", 0, "Up", ""},
- {-1, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ static const EnumPropertyItem material_slot_move[] = {
+ {1, "UP", 0, "Up", ""},
+ {-1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
- /* identifiers */
- ot->name = "Move Material";
- ot->idname = "OBJECT_OT_material_slot_move";
- ot->description = "Move the active material up/down in the list";
+ /* identifiers */
+ ot->name = "Move Material";
+ ot->idname = "OBJECT_OT_material_slot_move";
+ ot->description = "Move the active material up/down in the list";
- /* api callbacks */
- ot->exec = material_slot_move_exec;
+ /* api callbacks */
+ ot->exec = material_slot_move_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_enum(ot->srna, "direction", material_slot_move, 0, "Direction",
- "Direction to move the active material towards");
+ RNA_def_enum(ot->srna,
+ "direction",
+ material_slot_move,
+ 0,
+ "Direction",
+ "Direction to move the active material towards");
}
/********************** new material operator *********************/
static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
{
- Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
- Main *bmain = CTX_data_main(C);
- PointerRNA ptr, idptr;
- PropertyRNA *prop;
-
- /* hook into UI */
- UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
-
- Object *ob = (prop && RNA_struct_is_a(ptr.type, &RNA_Object)) ? ptr.data : NULL;
-
- /* add or copy material */
- if (ma) {
- Material *new_ma = NULL;
- BKE_id_copy_ex(bmain, &ma->id, (ID **)&new_ma, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
- ma = new_ma;
- }
- else {
- const char *name = DATA_("Material");
- if (!(ob != NULL && ob->type == OB_GPENCIL)) {
- ma = BKE_material_add(bmain, name);
- }
- else {
- ma = BKE_material_add_gpencil(bmain, name);
- }
- ED_node_shader_default(C, &ma->id);
- ma->use_nodes = true;
- }
-
-
- if (prop) {
- if (ob != NULL) {
- /* Add slot follows user-preferences for creating new slots,
- * RNA pointer assignment doesn't, see: T60014. */
- if (give_current_material_p(ob, ob->actcol) == NULL) {
- BKE_object_material_slot_add(bmain, ob);
- }
- }
-
- /* when creating new ID blocks, use is already 1, but RNA
- * pointer use also increases user, so this compensates it */
- id_us_min(&ma->id);
-
- RNA_id_pointer_create(&ma->id, &idptr);
- RNA_property_pointer_set(&ptr, prop, idptr);
- RNA_property_update(C, &ptr, prop);
- }
-
- WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma);
-
- return OPERATOR_FINISHED;
+ Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
+ Main *bmain = CTX_data_main(C);
+ PointerRNA ptr, idptr;
+ PropertyRNA *prop;
+
+ /* hook into UI */
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
+
+ Object *ob = (prop && RNA_struct_is_a(ptr.type, &RNA_Object)) ? ptr.data : NULL;
+
+ /* add or copy material */
+ if (ma) {
+ Material *new_ma = NULL;
+ BKE_id_copy_ex(bmain, &ma->id, (ID **)&new_ma, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
+ ma = new_ma;
+ }
+ else {
+ const char *name = DATA_("Material");
+ if (!(ob != NULL && ob->type == OB_GPENCIL)) {
+ ma = BKE_material_add(bmain, name);
+ }
+ else {
+ ma = BKE_material_add_gpencil(bmain, name);
+ }
+ ED_node_shader_default(C, &ma->id);
+ ma->use_nodes = true;
+ }
+
+ if (prop) {
+ if (ob != NULL) {
+ /* Add slot follows user-preferences for creating new slots,
+ * RNA pointer assignment doesn't, see: T60014. */
+ if (give_current_material_p(ob, ob->actcol) == NULL) {
+ BKE_object_material_slot_add(bmain, ob);
+ }
+ }
+
+ /* when creating new ID blocks, use is already 1, but RNA
+ * pointer use also increases user, so this compensates it */
+ id_us_min(&ma->id);
+
+ RNA_id_pointer_create(&ma->id, &idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr);
+ RNA_property_update(C, &ptr, prop);
+ }
+
+ WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma);
+
+ return OPERATOR_FINISHED;
}
void MATERIAL_OT_new(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "New Material";
- ot->idname = "MATERIAL_OT_new";
- ot->description = "Add a new material";
+ /* identifiers */
+ ot->name = "New Material";
+ ot->idname = "MATERIAL_OT_new";
+ ot->description = "Add a new material";
- /* api callbacks */
- ot->exec = new_material_exec;
+ /* api callbacks */
+ ot->exec = new_material_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/********************** new texture operator *********************/
static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
{
- Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
- Main *bmain = CTX_data_main(C);
- PointerRNA ptr, idptr;
- PropertyRNA *prop;
+ Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
+ Main *bmain = CTX_data_main(C);
+ PointerRNA ptr, idptr;
+ PropertyRNA *prop;
- /* add or copy texture */
- if (tex) {
- tex = BKE_texture_copy(bmain, tex);
- }
- else {
- tex = BKE_texture_add(bmain, DATA_("Texture"));
- }
+ /* add or copy texture */
+ if (tex) {
+ tex = BKE_texture_copy(bmain, tex);
+ }
+ else {
+ tex = BKE_texture_add(bmain, DATA_("Texture"));
+ }
- /* hook into UI */
- UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
+ /* hook into UI */
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
- if (prop) {
- /* when creating new ID blocks, use is already 1, but RNA
- * pointer use also increases user, so this compensates it */
- id_us_min(&tex->id);
+ if (prop) {
+ /* when creating new ID blocks, use is already 1, but RNA
+ * pointer use also increases user, so this compensates it */
+ id_us_min(&tex->id);
- RNA_id_pointer_create(&tex->id, &idptr);
- RNA_property_pointer_set(&ptr, prop, idptr);
- RNA_property_update(C, &ptr, prop);
- }
+ RNA_id_pointer_create(&tex->id, &idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr);
+ RNA_property_update(C, &ptr, prop);
+ }
- WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex);
+ WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void TEXTURE_OT_new(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "New Texture";
- ot->idname = "TEXTURE_OT_new";
- ot->description = "Add a new texture";
+ /* identifiers */
+ ot->name = "New Texture";
+ ot->idname = "TEXTURE_OT_new";
+ ot->description = "Add a new texture";
- /* api callbacks */
- ot->exec = new_texture_exec;
+ /* api callbacks */
+ ot->exec = new_texture_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/********************** new world operator *********************/
static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
{
- World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
- Main *bmain = CTX_data_main(C);
- PointerRNA ptr, idptr;
- PropertyRNA *prop;
+ World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
+ Main *bmain = CTX_data_main(C);
+ PointerRNA ptr, idptr;
+ PropertyRNA *prop;
- /* add or copy world */
- if (wo) {
- wo = BKE_world_copy(bmain, wo);
- }
- else {
- wo = BKE_world_add(bmain, DATA_("World"));
- ED_node_shader_default(C, &wo->id);
- wo->use_nodes = true;
- }
+ /* add or copy world */
+ if (wo) {
+ wo = BKE_world_copy(bmain, wo);
+ }
+ else {
+ wo = BKE_world_add(bmain, DATA_("World"));
+ ED_node_shader_default(C, &wo->id);
+ wo->use_nodes = true;
+ }
- /* hook into UI */
- UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
+ /* hook into UI */
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
- if (prop) {
- /* when creating new ID blocks, use is already 1, but RNA
- * pointer use also increases user, so this compensates it */
- id_us_min(&wo->id);
+ if (prop) {
+ /* when creating new ID blocks, use is already 1, but RNA
+ * pointer use also increases user, so this compensates it */
+ id_us_min(&wo->id);
- RNA_id_pointer_create(&wo->id, &idptr);
- RNA_property_pointer_set(&ptr, prop, idptr);
- RNA_property_update(C, &ptr, prop);
- }
+ RNA_id_pointer_create(&wo->id, &idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr);
+ RNA_property_update(C, &ptr, prop);
+ }
- WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
+ WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void WORLD_OT_new(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "New World";
- ot->idname = "WORLD_OT_new";
- ot->description = "Create a new world Data-Block";
+ /* identifiers */
+ ot->name = "New World";
+ ot->idname = "WORLD_OT_new";
+ ot->description = "Create a new world Data-Block";
- /* api callbacks */
- ot->exec = new_world_exec;
+ /* api callbacks */
+ ot->exec = new_world_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/********************** render layer operators *********************/
static int view_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- wmWindow *win = CTX_wm_window(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = BKE_view_layer_add(scene, NULL);
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = BKE_view_layer_add(scene, NULL);
- if (win) {
- WM_window_set_active_view_layer(win, view_layer);
- }
+ if (win) {
+ WM_window_set_active_view_layer(win, view_layer);
+ }
- DEG_id_tag_update(&scene->id, 0);
- DEG_relations_tag_update(CTX_data_main(C));
- WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+ DEG_id_tag_update(&scene->id, 0);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_view_layer_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add View Layer";
- ot->idname = "SCENE_OT_view_layer_add";
- ot->description = "Add a view layer";
+ /* identifiers */
+ ot->name = "Add View Layer";
+ ot->idname = "SCENE_OT_view_layer_add";
+ ot->description = "Add a view layer";
- /* api callbacks */
- ot->exec = view_layer_add_exec;
+ /* api callbacks */
+ ot->exec = view_layer_add_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static bool view_layer_remove_poll(bContext *C)
{
- Scene *scene = CTX_data_scene(C);
- return (scene->view_layers.first != scene->view_layers.last);
+ Scene *scene = CTX_data_scene(C);
+ return (scene->view_layers.first != scene->view_layers.last);
}
static int view_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- if (!ED_scene_view_layer_delete(bmain, scene, view_layer, NULL)) {
- return OPERATOR_CANCELLED;
- }
+ if (!ED_scene_view_layer_delete(bmain, scene, view_layer, NULL)) {
+ return OPERATOR_CANCELLED;
+ }
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_view_layer_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove View Layer";
- ot->idname = "SCENE_OT_view_layer_remove";
- ot->description = "Remove the selected view layer";
+ /* identifiers */
+ ot->name = "Remove View Layer";
+ ot->idname = "SCENE_OT_view_layer_remove";
+ ot->description = "Remove the selected view layer";
- /* api callbacks */
- ot->exec = view_layer_remove_exec;
- ot->poll = view_layer_remove_poll;
+ /* api callbacks */
+ ot->exec = view_layer_remove_exec;
+ ot->poll = view_layer_remove_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/********************** light cache operators *********************/
enum {
- LIGHTCACHE_SUBSET_ALL = 0,
- LIGHTCACHE_SUBSET_DIRTY,
- LIGHTCACHE_SUBSET_CUBE,
+ LIGHTCACHE_SUBSET_ALL = 0,
+ LIGHTCACHE_SUBSET_DIRTY,
+ LIGHTCACHE_SUBSET_CUBE,
};
static void light_cache_bake_tag_cache(Scene *scene, wmOperator *op)
{
- if (scene->eevee.light_cache != NULL) {
- int subset = RNA_enum_get(op->ptr, "subset");
- switch (subset) {
- case LIGHTCACHE_SUBSET_ALL:
- scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_UPDATE_CUBE;
- break;
- case LIGHTCACHE_SUBSET_CUBE:
- scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
- break;
- case LIGHTCACHE_SUBSET_DIRTY:
- /* Leave tag untouched. */
- break;
- }
- }
+ if (scene->eevee.light_cache != NULL) {
+ int subset = RNA_enum_get(op->ptr, "subset");
+ switch (subset) {
+ case LIGHTCACHE_SUBSET_ALL:
+ scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID | LIGHTCACHE_UPDATE_CUBE;
+ break;
+ case LIGHTCACHE_SUBSET_CUBE:
+ scene->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
+ break;
+ case LIGHTCACHE_SUBSET_DIRTY:
+ /* Leave tag untouched. */
+ break;
+ }
+ }
}
/* catch esc */
static int light_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- Scene *scene = (Scene *) op->customdata;
+ Scene *scene = (Scene *)op->customdata;
- /* no running blender, remove handler and pass through */
- if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
- }
+ /* no running blender, remove handler and pass through */
+ if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ }
- /* running render */
- switch (event->type) {
- case ESCKEY:
- return OPERATOR_RUNNING_MODAL;
- }
- return OPERATOR_PASS_THROUGH;
+ /* running render */
+ switch (event->type) {
+ case ESCKEY:
+ return OPERATOR_RUNNING_MODAL;
+ }
+ return OPERATOR_PASS_THROUGH;
}
static void light_cache_bake_cancel(bContext *C, wmOperator *op)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- Scene *scene = (Scene *) op->customdata;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ Scene *scene = (Scene *)op->customdata;
- /* kill on cancel, because job is using op->reports */
- WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
+ /* kill on cancel, because job is using op->reports */
+ WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
}
/* executes blocking render */
static int light_cache_bake_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
- G.is_break = false;
+ G.is_break = false;
- /* TODO abort if selected engine is not eevee. */
- void *rj = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, false, scene->r.cfra);
+ /* TODO abort if selected engine is not eevee. */
+ void *rj = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, false, scene->r.cfra);
- light_cache_bake_tag_cache(scene, op);
+ light_cache_bake_tag_cache(scene, op);
- short stop = 0, do_update; float progress; /* Not actually used. */
- EEVEE_lightbake_job(rj, &stop, &do_update, &progress);
- EEVEE_lightbake_job_data_free(rj);
+ short stop = 0, do_update;
+ float progress; /* Not actually used. */
+ EEVEE_lightbake_job(rj, &stop, &do_update, &progress);
+ EEVEE_lightbake_job_data_free(rj);
- // no redraw needed, we leave state as we entered it
- ED_update_for_newframe(bmain, CTX_data_depsgraph(C));
+ // no redraw needed, we leave state as we entered it
+ ED_update_for_newframe(bmain, CTX_data_depsgraph(C));
- WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
+ WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int light_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- int delay = RNA_int_get(op->ptr, "delay");
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ int delay = RNA_int_get(op->ptr, "delay");
- wmJob *wm_job = EEVEE_lightbake_job_create(wm, win, bmain, view_layer, scene, delay, scene->r.cfra);
+ wmJob *wm_job = EEVEE_lightbake_job_create(
+ wm, win, bmain, view_layer, scene, delay, scene->r.cfra);
- if (!wm_job) {
- return OPERATOR_CANCELLED;
- }
+ if (!wm_job) {
+ return OPERATOR_CANCELLED;
+ }
- /* add modal handler for ESC */
- WM_event_add_modal_handler(C, op);
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
- light_cache_bake_tag_cache(scene, op);
+ light_cache_bake_tag_cache(scene, op);
- /* store actual owner of job, so modal operator could check for it,
- * the reason of this is that active scene could change when rendering
- * several layers from compositor [#31800]
- */
- op->customdata = scene;
+ /* store actual owner of job, so modal operator could check for it,
+ * the reason of this is that active scene could change when rendering
+ * several layers from compositor [#31800]
+ */
+ op->customdata = scene;
- WM_jobs_start(wm, wm_job);
+ WM_jobs_start(wm, wm_job);
- WM_cursor_wait(0);
+ WM_cursor_wait(0);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
void SCENE_OT_light_cache_bake(wmOperatorType *ot)
{
- static const EnumPropertyItem light_cache_subset_items[] = {
- {LIGHTCACHE_SUBSET_ALL, "ALL", 0, "All LightProbes",
- "Bake both irradiance grids and reflection cubemaps"},
- {LIGHTCACHE_SUBSET_DIRTY, "DIRTY", 0, "Dirty Only",
- "Only bake lightprobes that are marked as dirty"},
- {LIGHTCACHE_SUBSET_CUBE, "CUBEMAPS", 0, "Cubemaps Only",
- "Try to only bake reflection cubemaps if irradiance grids are up to date"},
- {0, NULL, 0, NULL, NULL},
- };
-
- /* identifiers */
- ot->name = "Bake Light Cache";
- ot->idname = "SCENE_OT_light_cache_bake";
- ot->description = "Bake the active view layer lighting";
-
- /* api callbacks */
- ot->invoke = light_cache_bake_invoke;
- ot->modal = light_cache_bake_modal;
- ot->cancel = light_cache_bake_cancel;
- ot->exec = light_cache_bake_exec;
-
- ot->prop = RNA_def_int(ot->srna, "delay", 0, 0, 2000, "Delay", "Delay in millisecond before baking starts", 0, 2000);
- RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
-
- ot->prop = RNA_def_enum(ot->srna, "subset", light_cache_subset_items, 0, "Subset", "Subset of probes to update");
- RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+ static const EnumPropertyItem light_cache_subset_items[] = {
+ {LIGHTCACHE_SUBSET_ALL,
+ "ALL",
+ 0,
+ "All LightProbes",
+ "Bake both irradiance grids and reflection cubemaps"},
+ {LIGHTCACHE_SUBSET_DIRTY,
+ "DIRTY",
+ 0,
+ "Dirty Only",
+ "Only bake lightprobes that are marked as dirty"},
+ {LIGHTCACHE_SUBSET_CUBE,
+ "CUBEMAPS",
+ 0,
+ "Cubemaps Only",
+ "Try to only bake reflection cubemaps if irradiance grids are up to date"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Bake Light Cache";
+ ot->idname = "SCENE_OT_light_cache_bake";
+ ot->description = "Bake the active view layer lighting";
+
+ /* api callbacks */
+ ot->invoke = light_cache_bake_invoke;
+ ot->modal = light_cache_bake_modal;
+ ot->cancel = light_cache_bake_cancel;
+ ot->exec = light_cache_bake_exec;
+
+ ot->prop = RNA_def_int(ot->srna,
+ "delay",
+ 0,
+ 0,
+ 2000,
+ "Delay",
+ "Delay in millisecond before baking starts",
+ 0,
+ 2000);
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+
+ ot->prop = RNA_def_enum(
+ ot->srna, "subset", light_cache_subset_items, 0, "Subset", "Subset of probes to update");
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
}
static bool light_cache_free_poll(bContext *C)
{
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- return scene->eevee.light_cache;
+ return scene->eevee.light_cache;
}
static int light_cache_free_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- /* kill potential bake job first (see T57011) */
- wmWindowManager *wm = CTX_wm_manager(C);
- WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_LIGHT_BAKE);
+ /* kill potential bake job first (see T57011) */
+ wmWindowManager *wm = CTX_wm_manager(C);
+ WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_LIGHT_BAKE);
- if (!scene->eevee.light_cache) {
- return OPERATOR_CANCELLED;
- }
+ if (!scene->eevee.light_cache) {
+ return OPERATOR_CANCELLED;
+ }
- EEVEE_lightcache_free(scene->eevee.light_cache);
- scene->eevee.light_cache = NULL;
+ EEVEE_lightcache_free(scene->eevee.light_cache);
+ scene->eevee.light_cache = NULL;
- EEVEE_lightcache_info_update(&scene->eevee);
+ EEVEE_lightcache_info_update(&scene->eevee);
- DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_light_cache_free(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Light Cache";
- ot->idname = "SCENE_OT_light_cache_free";
- ot->description = "Delete cached indirect lighting";
+ /* identifiers */
+ ot->name = "Delete Light Cache";
+ ot->idname = "SCENE_OT_light_cache_free";
+ ot->description = "Delete cached indirect lighting";
- /* api callbacks */
- ot->exec = light_cache_free_exec;
- ot->poll = light_cache_free_poll;
+ /* api callbacks */
+ ot->exec = light_cache_free_exec;
+ ot->poll = light_cache_free_poll;
}
/********************** render view operators *********************/
static bool render_view_remove_poll(bContext *C)
{
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- /* don't allow user to remove "left" and "right" views */
- return scene->r.actview > 1;
+ /* don't allow user to remove "left" and "right" views */
+ return scene->r.actview > 1;
}
static int render_view_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- BKE_scene_add_render_view(scene, NULL);
- scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
+ BKE_scene_add_render_view(scene, NULL);
+ scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_render_view_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Render View";
- ot->idname = "SCENE_OT_render_view_add";
- ot->description = "Add a render view";
+ /* identifiers */
+ ot->name = "Add Render View";
+ ot->idname = "SCENE_OT_render_view_add";
+ ot->description = "Add a render view";
- /* api callbacks */
- ot->exec = render_view_add_exec;
+ /* api callbacks */
+ ot->exec = render_view_add_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- SceneRenderView *rv = BLI_findlink(&scene->r.views, scene->r.actview);
+ Scene *scene = CTX_data_scene(C);
+ SceneRenderView *rv = BLI_findlink(&scene->r.views, scene->r.actview);
- if (!BKE_scene_remove_render_view(scene, rv))
- return OPERATOR_CANCELLED;
+ if (!BKE_scene_remove_render_view(scene, rv))
+ return OPERATOR_CANCELLED;
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_render_view_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Render View";
- ot->idname = "SCENE_OT_render_view_remove";
- ot->description = "Remove the selected render view";
+ /* identifiers */
+ ot->name = "Remove Render View";
+ ot->idname = "SCENE_OT_render_view_remove";
+ ot->description = "Remove the selected render view";
- /* api callbacks */
- ot->exec = render_view_remove_exec;
- ot->poll = render_view_remove_poll;
+ /* api callbacks */
+ ot->exec = render_view_remove_exec;
+ ot->poll = render_view_remove_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
#ifdef WITH_FREESTYLE
static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
{
- if (!lineset) {
- BKE_report(reports, RPT_ERROR, "No active lineset and associated line style to manipulate the modifier");
- return false;
- }
- if (!lineset->linestyle) {
- BKE_report(reports, RPT_ERROR, "The active lineset does not have a line style (indicating data corruption)");
- return false;
- }
+ if (!lineset) {
+ BKE_report(reports,
+ RPT_ERROR,
+ "No active lineset and associated line style to manipulate the modifier");
+ return false;
+ }
+ if (!lineset->linestyle) {
+ BKE_report(reports,
+ RPT_ERROR,
+ "The active lineset does not have a line style (indicating data corruption)");
+ return false;
+ }
- return true;
+ return true;
}
static bool freestyle_active_module_poll(bContext *C)
{
- PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
- FreestyleModuleConfig *module = ptr.data;
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
+ FreestyleModuleConfig *module = ptr.data;
- return module != NULL;
+ return module != NULL;
}
static int freestyle_module_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- BKE_freestyle_module_add(&view_layer->freestyle_config);
+ BKE_freestyle_module_add(&view_layer->freestyle_config);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Freestyle Module";
- ot->idname = "SCENE_OT_freestyle_module_add";
- ot->description = "Add a style module into the list of modules";
+ /* identifiers */
+ ot->name = "Add Freestyle Module";
+ ot->idname = "SCENE_OT_freestyle_module_add";
+ ot->description = "Add a style module into the list of modules";
- /* api callbacks */
- ot->exec = freestyle_module_add_exec;
+ /* api callbacks */
+ ot->exec = freestyle_module_add_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
- FreestyleModuleConfig *module = ptr.data;
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
+ FreestyleModuleConfig *module = ptr.data;
- BKE_freestyle_module_delete(&view_layer->freestyle_config, module);
+ BKE_freestyle_module_delete(&view_layer->freestyle_config, module);
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ DEG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_module_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Freestyle Module";
- ot->idname = "SCENE_OT_freestyle_module_remove";
- ot->description = "Remove the style module from the stack";
+ /* identifiers */
+ ot->name = "Remove Freestyle Module";
+ ot->idname = "SCENE_OT_freestyle_module_remove";
+ ot->description = "Remove the style module from the stack";
- /* api callbacks */
- ot->poll = freestyle_active_module_poll;
- ot->exec = freestyle_module_remove_exec;
+ /* api callbacks */
+ ot->poll = freestyle_active_module_poll;
+ ot->exec = freestyle_module_remove_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_module_move_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
- FreestyleModuleConfig *module = ptr.data;
- int dir = RNA_enum_get(op->ptr, "direction");
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
+ FreestyleModuleConfig *module = ptr.data;
+ int dir = RNA_enum_get(op->ptr, "direction");
- if (BKE_freestyle_module_move(&view_layer->freestyle_config, module, dir)) {
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- }
+ if (BKE_freestyle_module_move(&view_layer->freestyle_config, module, dir)) {
+ DEG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
{
- static const EnumPropertyItem direction_items[] = {
- {-1, "UP", 0, "Up", ""},
- {1, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ static const EnumPropertyItem direction_items[] = {
+ {-1, "UP", 0, "Up", ""},
+ {1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
- /* identifiers */
- ot->name = "Move Freestyle Module";
- ot->idname = "SCENE_OT_freestyle_module_move";
- ot->description = "Change the position of the style module within in the list of style modules";
+ /* identifiers */
+ ot->name = "Move Freestyle Module";
+ ot->idname = "SCENE_OT_freestyle_module_move";
+ ot->description = "Change the position of the style module within in the list of style modules";
- /* api callbacks */
- ot->poll = freestyle_active_module_poll;
- ot->exec = freestyle_module_move_exec;
+ /* api callbacks */
+ ot->poll = freestyle_active_module_poll;
+ ot->exec = freestyle_module_move_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* props */
- RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
- "Direction to move the chosen style module towards");
+ /* props */
+ RNA_def_enum(ot->srna,
+ "direction",
+ direction_items,
+ 0,
+ "Direction",
+ "Direction to move the chosen style module towards");
}
static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- BKE_freestyle_lineset_add(bmain, &view_layer->freestyle_config, NULL);
+ BKE_freestyle_lineset_add(bmain, &view_layer->freestyle_config, NULL);
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ DEG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Line Set";
- ot->idname = "SCENE_OT_freestyle_lineset_add";
- ot->description = "Add a line set into the list of line sets";
+ /* identifiers */
+ ot->name = "Add Line Set";
+ ot->idname = "SCENE_OT_freestyle_lineset_add";
+ ot->description = "Add a line set into the list of line sets";
- /* api callbacks */
- ot->exec = freestyle_lineset_add_exec;
+ /* api callbacks */
+ ot->exec = freestyle_lineset_add_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static bool freestyle_active_lineset_poll(bContext *C)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- if (!view_layer) {
- return false;
- }
+ if (!view_layer) {
+ return false;
+ }
- return BKE_freestyle_lineset_get_active(&view_layer->freestyle_config) != NULL;
+ return BKE_freestyle_lineset_get_active(&view_layer->freestyle_config) != NULL;
}
static int freestyle_lineset_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- FRS_copy_active_lineset(&view_layer->freestyle_config);
+ FRS_copy_active_lineset(&view_layer->freestyle_config);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Line Set";
- ot->idname = "SCENE_OT_freestyle_lineset_copy";
- ot->description = "Copy the active line set to a buffer";
+ /* identifiers */
+ ot->name = "Copy Line Set";
+ ot->idname = "SCENE_OT_freestyle_lineset_copy";
+ ot->description = "Copy the active line set to a buffer";
- /* api callbacks */
- ot->exec = freestyle_lineset_copy_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_lineset_copy_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- FRS_paste_active_lineset(&view_layer->freestyle_config);
+ FRS_paste_active_lineset(&view_layer->freestyle_config);
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ DEG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste Line Set";
- ot->idname = "SCENE_OT_freestyle_lineset_paste";
- ot->description = "Paste the buffer content to the active line set";
+ /* identifiers */
+ ot->name = "Paste Line Set";
+ ot->idname = "SCENE_OT_freestyle_lineset_paste";
+ ot->description = "Paste the buffer content to the active line set";
- /* api callbacks */
- ot->exec = freestyle_lineset_paste_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_lineset_paste_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
- FRS_delete_active_lineset(&view_layer->freestyle_config);
+ FRS_delete_active_lineset(&view_layer->freestyle_config);
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ DEG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Line Set";
- ot->idname = "SCENE_OT_freestyle_lineset_remove";
- ot->description = "Remove the active line set from the list of line sets";
+ /* identifiers */
+ ot->name = "Remove Line Set";
+ ot->idname = "SCENE_OT_freestyle_lineset_remove";
+ ot->description = "Remove the active line set from the list of line sets";
- /* api callbacks */
- ot->exec = freestyle_lineset_remove_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_lineset_remove_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_lineset_move_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- int dir = RNA_enum_get(op->ptr, "direction");
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ int dir = RNA_enum_get(op->ptr, "direction");
- if (FRS_move_active_lineset(&view_layer->freestyle_config, dir)) {
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
- }
+ if (FRS_move_active_lineset(&view_layer->freestyle_config, dir)) {
+ DEG_id_tag_update(&scene->id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
{
- static const EnumPropertyItem direction_items[] = {
- {-1, "UP", 0, "Up", ""},
- {1, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ static const EnumPropertyItem direction_items[] = {
+ {-1, "UP", 0, "Up", ""},
+ {1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
- /* identifiers */
- ot->name = "Move Line Set";
- ot->idname = "SCENE_OT_freestyle_lineset_move";
- ot->description = "Change the position of the active line set within the list of line sets";
+ /* identifiers */
+ ot->name = "Move Line Set";
+ ot->idname = "SCENE_OT_freestyle_lineset_move";
+ ot->description = "Change the position of the active line set within the list of line sets";
- /* api callbacks */
- ot->exec = freestyle_lineset_move_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_lineset_move_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* props */
- RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
- "Direction to move the active line set towards");
+ /* props */
+ RNA_def_enum(ot->srna,
+ "direction",
+ direction_items,
+ 0,
+ "Direction",
+ "Direction to move the active line set towards");
}
static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- if (!lineset) {
- BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
- return OPERATOR_CANCELLED;
- }
- if (lineset->linestyle) {
- id_us_min(&lineset->linestyle->id);
- lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
- }
- else {
- lineset->linestyle = BKE_linestyle_new(bmain, "LineStyle");
- }
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+ if (!lineset) {
+ BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
+ return OPERATOR_CANCELLED;
+ }
+ if (lineset->linestyle) {
+ id_us_min(&lineset->linestyle->id);
+ lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
+ }
+ else {
+ lineset->linestyle = BKE_linestyle_new(bmain, "LineStyle");
+ }
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "New Line Style";
- ot->idname = "SCENE_OT_freestyle_linestyle_new";
- ot->description = "Create a new line style, reusable by multiple line sets";
+ /* identifiers */
+ ot->name = "New Line Style";
+ ot->idname = "SCENE_OT_freestyle_linestyle_new";
+ ot->description = "Create a new line style, reusable by multiple line sets";
- /* api callbacks */
- ot->exec = freestyle_linestyle_new_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_linestyle_new_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- int type = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ int type = RNA_enum_get(op->ptr, "type");
- if (!freestyle_linestyle_check_report(lineset, op->reports)) {
- return OPERATOR_CANCELLED;
- }
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
- if (BKE_linestyle_color_modifier_add(lineset->linestyle, NULL, type) == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
- return OPERATOR_CANCELLED;
- }
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+ if (BKE_linestyle_color_modifier_add(lineset->linestyle, NULL, type) == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
+ return OPERATOR_CANCELLED;
+ }
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Line Color Modifier";
- ot->idname = "SCENE_OT_freestyle_color_modifier_add";
- ot->description = "Add a line color modifier to the line style associated with the active lineset";
+ /* identifiers */
+ ot->name = "Add Line Color Modifier";
+ ot->idname = "SCENE_OT_freestyle_color_modifier_add";
+ ot->description =
+ "Add a line color modifier to the line style associated with the active lineset";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = freestyle_color_modifier_add_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = freestyle_color_modifier_add_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", "");
+ /* properties */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", "");
}
static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- int type = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ int type = RNA_enum_get(op->ptr, "type");
- if (!freestyle_linestyle_check_report(lineset, op->reports)) {
- return OPERATOR_CANCELLED;
- }
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
- if (BKE_linestyle_alpha_modifier_add(lineset->linestyle, NULL, type) == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
- return OPERATOR_CANCELLED;
- }
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+ if (BKE_linestyle_alpha_modifier_add(lineset->linestyle, NULL, type) == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
+ return OPERATOR_CANCELLED;
+ }
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Alpha Transparency Modifier";
- ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
- ot->description = "Add an alpha transparency modifier to the line style associated with the active lineset";
+ /* identifiers */
+ ot->name = "Add Alpha Transparency Modifier";
+ ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
+ ot->description =
+ "Add an alpha transparency modifier to the line style associated with the active lineset";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = freestyle_alpha_modifier_add_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = freestyle_alpha_modifier_add_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", "");
+ /* properties */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", "");
}
static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- int type = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ int type = RNA_enum_get(op->ptr, "type");
- if (!freestyle_linestyle_check_report(lineset, op->reports)) {
- return OPERATOR_CANCELLED;
- }
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
- if (BKE_linestyle_thickness_modifier_add(lineset->linestyle, NULL, type) == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
- return OPERATOR_CANCELLED;
- }
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+ if (BKE_linestyle_thickness_modifier_add(lineset->linestyle, NULL, type) == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
+ return OPERATOR_CANCELLED;
+ }
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Line Thickness Modifier";
- ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
- ot->description = "Add a line thickness modifier to the line style associated with the active lineset";
+ /* identifiers */
+ ot->name = "Add Line Thickness Modifier";
+ ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
+ ot->description =
+ "Add a line thickness modifier to the line style associated with the active lineset";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = freestyle_thickness_modifier_add_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = freestyle_thickness_modifier_add_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", "");
+ /* properties */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", "");
}
static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- int type = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ int type = RNA_enum_get(op->ptr, "type");
- if (!freestyle_linestyle_check_report(lineset, op->reports)) {
- return OPERATOR_CANCELLED;
- }
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
- if (BKE_linestyle_geometry_modifier_add(lineset->linestyle, NULL, type) == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
- return OPERATOR_CANCELLED;
- }
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+ if (BKE_linestyle_geometry_modifier_add(lineset->linestyle, NULL, type) == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
+ return OPERATOR_CANCELLED;
+ }
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Stroke Geometry Modifier";
- ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
- ot->description = "Add a stroke geometry modifier to the line style associated with the active lineset";
+ /* identifiers */
+ ot->name = "Add Stroke Geometry Modifier";
+ ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
+ ot->description =
+ "Add a stroke geometry modifier to the line style associated with the active lineset";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = freestyle_geometry_modifier_add_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = freestyle_geometry_modifier_add_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", "");
+ /* properties */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", "");
}
static int freestyle_get_modifier_type(PointerRNA *ptr)
{
- if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier))
- return LS_MODIFIER_TYPE_COLOR;
- else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier))
- return LS_MODIFIER_TYPE_ALPHA;
- else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier))
- return LS_MODIFIER_TYPE_THICKNESS;
- else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier))
- return LS_MODIFIER_TYPE_GEOMETRY;
- return -1;
+ if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier))
+ return LS_MODIFIER_TYPE_COLOR;
+ else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier))
+ return LS_MODIFIER_TYPE_ALPHA;
+ else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier))
+ return LS_MODIFIER_TYPE_THICKNESS;
+ else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier))
+ return LS_MODIFIER_TYPE_GEOMETRY;
+ return -1;
}
static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
- LineStyleModifier *modifier = ptr.data;
-
- if (!freestyle_linestyle_check_report(lineset, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- switch (freestyle_get_modifier_type(&ptr)) {
- case LS_MODIFIER_TYPE_COLOR:
- BKE_linestyle_color_modifier_remove(lineset->linestyle, modifier);
- break;
- case LS_MODIFIER_TYPE_ALPHA:
- BKE_linestyle_alpha_modifier_remove(lineset->linestyle, modifier);
- break;
- case LS_MODIFIER_TYPE_THICKNESS:
- BKE_linestyle_thickness_modifier_remove(lineset->linestyle, modifier);
- break;
- case LS_MODIFIER_TYPE_GEOMETRY:
- BKE_linestyle_geometry_modifier_remove(lineset->linestyle, modifier);
- break;
- default:
- BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
- return OPERATOR_CANCELLED;
- }
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
-
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
+ LineStyleModifier *modifier = ptr.data;
+
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ switch (freestyle_get_modifier_type(&ptr)) {
+ case LS_MODIFIER_TYPE_COLOR:
+ BKE_linestyle_color_modifier_remove(lineset->linestyle, modifier);
+ break;
+ case LS_MODIFIER_TYPE_ALPHA:
+ BKE_linestyle_alpha_modifier_remove(lineset->linestyle, modifier);
+ break;
+ case LS_MODIFIER_TYPE_THICKNESS:
+ BKE_linestyle_thickness_modifier_remove(lineset->linestyle, modifier);
+ break;
+ case LS_MODIFIER_TYPE_GEOMETRY:
+ BKE_linestyle_geometry_modifier_remove(lineset->linestyle, modifier);
+ break;
+ default:
+ BKE_report(
+ op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
+ return OPERATOR_CANCELLED;
+ }
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Modifier";
- ot->idname = "SCENE_OT_freestyle_modifier_remove";
- ot->description = "Remove the modifier from the list of modifiers";
+ /* identifiers */
+ ot->name = "Remove Modifier";
+ ot->idname = "SCENE_OT_freestyle_modifier_remove";
+ ot->description = "Remove the modifier from the list of modifiers";
- /* api callbacks */
- ot->exec = freestyle_modifier_remove_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_modifier_remove_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
- LineStyleModifier *modifier = ptr.data;
-
- if (!freestyle_linestyle_check_report(lineset, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- switch (freestyle_get_modifier_type(&ptr)) {
- case LS_MODIFIER_TYPE_COLOR:
- BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
- break;
- case LS_MODIFIER_TYPE_ALPHA:
- BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
- break;
- case LS_MODIFIER_TYPE_THICKNESS:
- BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
- break;
- case LS_MODIFIER_TYPE_GEOMETRY:
- BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
- break;
- default:
- BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
- return OPERATOR_CANCELLED;
- }
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
-
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
+ LineStyleModifier *modifier = ptr.data;
+
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ switch (freestyle_get_modifier_type(&ptr)) {
+ case LS_MODIFIER_TYPE_COLOR:
+ BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
+ break;
+ case LS_MODIFIER_TYPE_ALPHA:
+ BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
+ break;
+ case LS_MODIFIER_TYPE_THICKNESS:
+ BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
+ break;
+ case LS_MODIFIER_TYPE_GEOMETRY:
+ BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
+ break;
+ default:
+ BKE_report(
+ op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
+ return OPERATOR_CANCELLED;
+ }
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Modifier";
- ot->idname = "SCENE_OT_freestyle_modifier_copy";
- ot->description = "Duplicate the modifier within the list of modifiers";
+ /* identifiers */
+ ot->name = "Copy Modifier";
+ ot->idname = "SCENE_OT_freestyle_modifier_copy";
+ ot->description = "Duplicate the modifier within the list of modifiers";
- /* api callbacks */
- ot->exec = freestyle_modifier_copy_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_modifier_copy_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
static int freestyle_modifier_move_exec(bContext *C, wmOperator *op)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
- LineStyleModifier *modifier = ptr.data;
- int dir = RNA_enum_get(op->ptr, "direction");
- bool changed = false;
-
- if (!freestyle_linestyle_check_report(lineset, op->reports)) {
- return OPERATOR_CANCELLED;
- }
-
- switch (freestyle_get_modifier_type(&ptr)) {
- case LS_MODIFIER_TYPE_COLOR:
- changed = BKE_linestyle_color_modifier_move(lineset->linestyle, modifier, dir);
- break;
- case LS_MODIFIER_TYPE_ALPHA:
- changed = BKE_linestyle_alpha_modifier_move(lineset->linestyle, modifier, dir);
- break;
- case LS_MODIFIER_TYPE_THICKNESS:
- changed = BKE_linestyle_thickness_modifier_move(lineset->linestyle, modifier, dir);
- break;
- case LS_MODIFIER_TYPE_GEOMETRY:
- changed = BKE_linestyle_geometry_modifier_move(lineset->linestyle, modifier, dir);
- break;
- default:
- BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
- return OPERATOR_CANCELLED;
- }
-
- if (changed) {
- DEG_id_tag_update(&lineset->linestyle->id, 0);
- WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
- }
-
- return OPERATOR_FINISHED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&view_layer->freestyle_config);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
+ LineStyleModifier *modifier = ptr.data;
+ int dir = RNA_enum_get(op->ptr, "direction");
+ bool changed = false;
+
+ if (!freestyle_linestyle_check_report(lineset, op->reports)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ switch (freestyle_get_modifier_type(&ptr)) {
+ case LS_MODIFIER_TYPE_COLOR:
+ changed = BKE_linestyle_color_modifier_move(lineset->linestyle, modifier, dir);
+ break;
+ case LS_MODIFIER_TYPE_ALPHA:
+ changed = BKE_linestyle_alpha_modifier_move(lineset->linestyle, modifier, dir);
+ break;
+ case LS_MODIFIER_TYPE_THICKNESS:
+ changed = BKE_linestyle_thickness_modifier_move(lineset->linestyle, modifier, dir);
+ break;
+ case LS_MODIFIER_TYPE_GEOMETRY:
+ changed = BKE_linestyle_geometry_modifier_move(lineset->linestyle, modifier, dir);
+ break;
+ default:
+ BKE_report(
+ op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (changed) {
+ DEG_id_tag_update(&lineset->linestyle->id, 0);
+ WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
+ }
+
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
{
- static const EnumPropertyItem direction_items[] = {
- {-1, "UP", 0, "Up", ""},
- {1, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ static const EnumPropertyItem direction_items[] = {
+ {-1, "UP", 0, "Up", ""},
+ {1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
- /* identifiers */
- ot->name = "Move Modifier";
- ot->idname = "SCENE_OT_freestyle_modifier_move";
- ot->description = "Move the modifier within the list of modifiers";
+ /* identifiers */
+ ot->name = "Move Modifier";
+ ot->idname = "SCENE_OT_freestyle_modifier_move";
+ ot->description = "Move the modifier within the list of modifiers";
- /* api callbacks */
- ot->exec = freestyle_modifier_move_exec;
- ot->poll = freestyle_active_lineset_poll;
+ /* api callbacks */
+ ot->exec = freestyle_modifier_move_exec;
+ ot->poll = freestyle_active_lineset_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* props */
- RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
- "Direction to move the chosen modifier towards");
+ /* props */
+ RNA_def_enum(ot->srna,
+ "direction",
+ direction_items,
+ 0,
+ "Direction",
+ "Direction to move the chosen modifier towards");
}
static int freestyle_stroke_material_create_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- FreestyleLineStyle *linestyle = BKE_linestyle_active_from_view_layer(view_layer);
+ Main *bmain = CTX_data_main(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ FreestyleLineStyle *linestyle = BKE_linestyle_active_from_view_layer(view_layer);
- if (!linestyle) {
- BKE_report(op->reports, RPT_ERROR, "No active line style in the current scene");
- return OPERATOR_CANCELLED;
- }
+ if (!linestyle) {
+ BKE_report(op->reports, RPT_ERROR, "No active line style in the current scene");
+ return OPERATOR_CANCELLED;
+ }
- FRS_create_stroke_material(bmain, linestyle);
+ FRS_create_stroke_material(bmain, linestyle);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void SCENE_OT_freestyle_stroke_material_create(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Create Freestyle Stroke Material";
- ot->idname = "SCENE_OT_freestyle_stroke_material_create";
- ot->description = "Create Freestyle stroke material for testing";
+ /* identifiers */
+ ot->name = "Create Freestyle Stroke Material";
+ ot->idname = "SCENE_OT_freestyle_stroke_material_create";
+ ot->description = "Create Freestyle stroke material for testing";
- /* api callbacks */
- ot->exec = freestyle_stroke_material_create_exec;
+ /* api callbacks */
+ ot->exec = freestyle_stroke_material_create_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
#endif /* WITH_FREESTYLE */
static int texture_slot_move_exec(bContext *C, wmOperator *op)
{
- ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
+ ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
- if (id) {
- MTex **mtex_ar, *mtexswap;
- short act;
- int type = RNA_enum_get(op->ptr, "type");
- struct AnimData *adt = BKE_animdata_from_id(id);
+ if (id) {
+ MTex **mtex_ar, *mtexswap;
+ short act;
+ int type = RNA_enum_get(op->ptr, "type");
+ struct AnimData *adt = BKE_animdata_from_id(id);
- give_active_mtex(id, &mtex_ar, &act);
+ give_active_mtex(id, &mtex_ar, &act);
- if (type == -1) { /* Up */
- if (act > 0) {
- mtexswap = mtex_ar[act];
- mtex_ar[act] = mtex_ar[act - 1];
- mtex_ar[act - 1] = mtexswap;
+ if (type == -1) { /* Up */
+ if (act > 0) {
+ mtexswap = mtex_ar[act];
+ mtex_ar[act] = mtex_ar[act - 1];
+ mtex_ar[act - 1] = mtexswap;
- BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0);
- BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0);
- BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
+ BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0);
+ BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0);
+ BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
- set_active_mtex(id, act - 1);
- }
- }
- else { /* Down */
- if (act < MAX_MTEX - 1) {
- mtexswap = mtex_ar[act];
- mtex_ar[act] = mtex_ar[act + 1];
- mtex_ar[act + 1] = mtexswap;
+ set_active_mtex(id, act - 1);
+ }
+ }
+ else { /* Down */
+ if (act < MAX_MTEX - 1) {
+ mtexswap = mtex_ar[act];
+ mtex_ar[act] = mtex_ar[act + 1];
+ mtex_ar[act + 1] = mtexswap;
- BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0);
- BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0);
- BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
+ BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0);
+ BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0);
+ BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
- set_active_mtex(id, act + 1);
- }
- }
+ set_active_mtex(id, act + 1);
+ }
+ }
- DEG_id_tag_update(id, 0);
- WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C));
- }
+ DEG_id_tag_update(id, 0);
+ WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C));
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void TEXTURE_OT_slot_move(wmOperatorType *ot)
{
- static const EnumPropertyItem slot_move[] = {
- {-1, "UP", 0, "Up", ""},
- {1, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL},
- };
+ static const EnumPropertyItem slot_move[] = {
+ {-1, "UP", 0, "Up", ""},
+ {1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
- /* identifiers */
- ot->name = "Move Texture Slot";
- ot->idname = "TEXTURE_OT_slot_move";
- ot->description = "Move texture slots up and down";
+ /* identifiers */
+ ot->name = "Move Texture Slot";
+ ot->idname = "TEXTURE_OT_slot_move";
+ ot->description = "Move texture slots up and down";
- /* api callbacks */
- ot->exec = texture_slot_move_exec;
+ /* api callbacks */
+ ot->exec = texture_slot_move_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
+ RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
}
-
-
/********************** material operators *********************/
/* material copy/paste */
static int copy_material_exec(bContext *C, wmOperator *UNUSED(op))
{
- Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
+ Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
- if (ma == NULL)
- return OPERATOR_CANCELLED;
+ if (ma == NULL)
+ return OPERATOR_CANCELLED;
- copy_matcopybuf(CTX_data_main(C), ma);
+ copy_matcopybuf(CTX_data_main(C), ma);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void MATERIAL_OT_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Material";
- ot->idname = "MATERIAL_OT_copy";
- ot->description = "Copy the material settings and nodes";
+ /* identifiers */
+ ot->name = "Copy Material";
+ ot->idname = "MATERIAL_OT_copy";
+ ot->description = "Copy the material settings and nodes";
- /* api callbacks */
- ot->exec = copy_material_exec;
+ /* api callbacks */
+ ot->exec = copy_material_exec;
- /* flags */
- /* no undo needed since no changes are made to the material */
- ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
+ /* flags */
+ /* no undo needed since no changes are made to the material */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
}
static int paste_material_exec(bContext *C, wmOperator *UNUSED(op))
{
- Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
+ Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
- if (ma == NULL)
- return OPERATOR_CANCELLED;
+ if (ma == NULL)
+ return OPERATOR_CANCELLED;
- paste_matcopybuf(CTX_data_main(C), ma);
+ paste_matcopybuf(CTX_data_main(C), ma);
- DEG_id_tag_update(&ma->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
+ DEG_id_tag_update(&ma->id, ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void MATERIAL_OT_paste(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste Material";
- ot->idname = "MATERIAL_OT_paste";
- ot->description = "Paste the material settings and nodes";
+ /* identifiers */
+ ot->name = "Paste Material";
+ ot->idname = "MATERIAL_OT_paste";
+ ot->description = "Paste the material settings and nodes";
- /* api callbacks */
- ot->exec = paste_material_exec;
+ /* api callbacks */
+ ot->exec = paste_material_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
-
static short mtexcopied = 0; /* must be reset on file load */
static MTex mtexcopybuf;
void ED_render_clear_mtex_copybuf(void)
-{ /* use for file reload */
- mtexcopied = 0;
+{ /* use for file reload */
+ mtexcopied = 0;
}
static void copy_mtex_copybuf(ID *id)
{
- MTex **mtex = NULL;
+ MTex **mtex = NULL;
- switch (GS(id->name)) {
- case ID_PA:
- mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
- break;
- case ID_LS:
- mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
- break;
- default:
- break;
- }
+ switch (GS(id->name)) {
+ case ID_PA:
+ mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
+ break;
+ case ID_LS:
+ mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
+ break;
+ default:
+ break;
+ }
- if (mtex && *mtex) {
- memcpy(&mtexcopybuf, *mtex, sizeof(MTex));
- mtexcopied = 1;
- }
- else {
- mtexcopied = 0;
- }
+ if (mtex && *mtex) {
+ memcpy(&mtexcopybuf, *mtex, sizeof(MTex));
+ mtexcopied = 1;
+ }
+ else {
+ mtexcopied = 0;
+ }
}
static void paste_mtex_copybuf(ID *id)
{
- MTex **mtex = NULL;
+ MTex **mtex = NULL;
- if (mtexcopied == 0 || mtexcopybuf.tex == NULL)
- return;
+ if (mtexcopied == 0 || mtexcopybuf.tex == NULL)
+ return;
- switch (GS(id->name)) {
- case ID_PA:
- mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
- break;
- case ID_LS:
- mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
- break;
- default:
- BLI_assert(!"invalid id type");
- return;
- }
+ switch (GS(id->name)) {
+ case ID_PA:
+ mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
+ break;
+ case ID_LS:
+ mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
+ break;
+ default:
+ BLI_assert(!"invalid id type");
+ return;
+ }
- if (mtex) {
- if (*mtex == NULL) {
- *mtex = MEM_mallocN(sizeof(MTex), "mtex copy");
- }
- else if ((*mtex)->tex) {
- id_us_min(&(*mtex)->tex->id);
- }
+ if (mtex) {
+ if (*mtex == NULL) {
+ *mtex = MEM_mallocN(sizeof(MTex), "mtex copy");
+ }
+ else if ((*mtex)->tex) {
+ id_us_min(&(*mtex)->tex->id);
+ }
- memcpy(*mtex, &mtexcopybuf, sizeof(MTex));
+ memcpy(*mtex, &mtexcopybuf, sizeof(MTex));
- id_us_plus((ID *)mtexcopybuf.tex);
- }
+ id_us_plus((ID *)mtexcopybuf.tex);
+ }
}
-
static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op))
{
- ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
+ ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
- if (id == NULL) {
- /* copying empty slot */
- ED_render_clear_mtex_copybuf();
- return OPERATOR_CANCELLED;
- }
+ if (id == NULL) {
+ /* copying empty slot */
+ ED_render_clear_mtex_copybuf();
+ return OPERATOR_CANCELLED;
+ }
- copy_mtex_copybuf(id);
+ copy_mtex_copybuf(id);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static bool copy_mtex_poll(bContext *C)
{
- ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
+ ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
- return (id != NULL);
+ return (id != NULL);
}
void TEXTURE_OT_slot_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Texture Slot Settings";
- ot->idname = "TEXTURE_OT_slot_copy";
- ot->description = "Copy the material texture settings and nodes";
+ /* identifiers */
+ ot->name = "Copy Texture Slot Settings";
+ ot->idname = "TEXTURE_OT_slot_copy";
+ ot->description = "Copy the material texture settings and nodes";
- /* api callbacks */
- ot->exec = copy_mtex_exec;
- ot->poll = copy_mtex_poll;
+ /* api callbacks */
+ ot->exec = copy_mtex_exec;
+ ot->poll = copy_mtex_poll;
- /* flags */
- /* no undo needed since no changes are made to the mtex */
- ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
+ /* flags */
+ /* no undo needed since no changes are made to the mtex */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
}
static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
{
- ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
+ ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
- if (id == NULL) {
- Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
- Light *la = CTX_data_pointer_get_type(C, "light", &RNA_Light).data;
- World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
- ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
- FreestyleLineStyle *linestyle = CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
+ if (id == NULL) {
+ Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
+ Light *la = CTX_data_pointer_get_type(C, "light", &RNA_Light).data;
+ World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
+ ParticleSystem *psys =
+ CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
+ FreestyleLineStyle *linestyle =
+ CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
- if (ma)
- id = &ma->id;
- else if (la)
- id = &la->id;
- else if (wo)
- id = &wo->id;
- else if (psys)
- id = &psys->part->id;
- else if (linestyle)
- id = &linestyle->id;
+ if (ma)
+ id = &ma->id;
+ else if (la)
+ id = &la->id;
+ else if (wo)
+ id = &wo->id;
+ else if (psys)
+ id = &psys->part->id;
+ else if (linestyle)
+ id = &linestyle->id;
- if (id == NULL)
- return OPERATOR_CANCELLED;
- }
+ if (id == NULL)
+ return OPERATOR_CANCELLED;
+ }
- paste_mtex_copybuf(id);
+ paste_mtex_copybuf(id);
- WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL);
+ WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void TEXTURE_OT_slot_paste(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste Texture Slot Settings";
- ot->idname = "TEXTURE_OT_slot_paste";
- ot->description = "Copy the texture settings and nodes";
+ /* identifiers */
+ ot->name = "Paste Texture Slot Settings";
+ ot->idname = "TEXTURE_OT_slot_paste";
+ ot->description = "Copy the texture settings and nodes";
- /* api callbacks */
- ot->exec = paste_mtex_exec;
+ /* api callbacks */
+ ot->exec = paste_mtex_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index bbd73b581f4..dfc7610946a 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -69,141 +69,138 @@
void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int updated)
{
- /* viewport rendering update on data changes, happens after depsgraph
- * updates if there was any change. context is set to the 3d view */
- Main *bmain = update_ctx->bmain;
- Scene *scene = update_ctx->scene;
- ViewLayer *view_layer = update_ctx->view_layer;
- bContext *C;
- wmWindowManager *wm;
- wmWindow *win;
- static bool recursive_check = false;
-
- /* don't do this render engine update if we're updating the scene from
- * other threads doing e.g. rendering or baking jobs */
- if (!BLI_thread_is_main())
- return;
-
- /* don't call this recursively for frame updates */
- if (recursive_check)
- return;
-
- /* Do not call if no WM available, see T42688. */
- if (BLI_listbase_is_empty(&bmain->wm))
- return;
-
- recursive_check = true;
-
- C = CTX_create();
- CTX_data_main_set(C, bmain);
- CTX_data_scene_set(C, scene);
-
- CTX_wm_manager_set(C, bmain->wm.first);
- wm = bmain->wm.first;
-
- for (win = wm->windows.first; win; win = win->next) {
- bScreen *sc = WM_window_get_active_screen(win);
- ScrArea *sa;
- ARegion *ar;
-
- CTX_wm_window_set(C, win);
-
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- if (sa->spacetype != SPACE_VIEW3D) {
- continue;
- }
- View3D *v3d = sa->spacedata.first;
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype != RGN_TYPE_WINDOW) {
- continue;
- }
- RegionView3D *rv3d = ar->regiondata;
- RenderEngine *engine = rv3d->render_engine;
- /* call update if the scene changed, or if the render engine
- * tagged itself for update (e.g. because it was busy at the
- * time of the last update) */
- if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
-
- CTX_wm_screen_set(C, sc);
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
-
- engine->flag &= ~RE_ENGINE_DO_UPDATE;
- engine->type->view_update(engine, C);
-
- }
- else {
- RenderEngineType *engine_type =
- ED_view3d_engine_type(scene, v3d->shading.type);
- if (updated) {
- DRW_notify_view_update(
- (&(DRWUpdateContext){
- .bmain = bmain,
- .depsgraph = update_ctx->depsgraph,
- .scene = scene,
- .view_layer = view_layer,
- .ar = ar,
- .v3d = (View3D *)sa->spacedata.first,
- .engine_type = engine_type,
- }));
- }
- }
- }
- }
- }
-
- CTX_free(C);
-
- recursive_check = false;
+ /* viewport rendering update on data changes, happens after depsgraph
+ * updates if there was any change. context is set to the 3d view */
+ Main *bmain = update_ctx->bmain;
+ Scene *scene = update_ctx->scene;
+ ViewLayer *view_layer = update_ctx->view_layer;
+ bContext *C;
+ wmWindowManager *wm;
+ wmWindow *win;
+ static bool recursive_check = false;
+
+ /* don't do this render engine update if we're updating the scene from
+ * other threads doing e.g. rendering or baking jobs */
+ if (!BLI_thread_is_main())
+ return;
+
+ /* don't call this recursively for frame updates */
+ if (recursive_check)
+ return;
+
+ /* Do not call if no WM available, see T42688. */
+ if (BLI_listbase_is_empty(&bmain->wm))
+ return;
+
+ recursive_check = true;
+
+ C = CTX_create();
+ CTX_data_main_set(C, bmain);
+ CTX_data_scene_set(C, scene);
+
+ CTX_wm_manager_set(C, bmain->wm.first);
+ wm = bmain->wm.first;
+
+ for (win = wm->windows.first; win; win = win->next) {
+ bScreen *sc = WM_window_get_active_screen(win);
+ ScrArea *sa;
+ ARegion *ar;
+
+ CTX_wm_window_set(C, win);
+
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype != SPACE_VIEW3D) {
+ continue;
+ }
+ View3D *v3d = sa->spacedata.first;
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype != RGN_TYPE_WINDOW) {
+ continue;
+ }
+ RegionView3D *rv3d = ar->regiondata;
+ RenderEngine *engine = rv3d->render_engine;
+ /* call update if the scene changed, or if the render engine
+ * tagged itself for update (e.g. because it was busy at the
+ * time of the last update) */
+ if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
+
+ CTX_wm_screen_set(C, sc);
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ engine->flag &= ~RE_ENGINE_DO_UPDATE;
+ engine->type->view_update(engine, C);
+ }
+ else {
+ RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
+ if (updated) {
+ DRW_notify_view_update((&(DRWUpdateContext){
+ .bmain = bmain,
+ .depsgraph = update_ctx->depsgraph,
+ .scene = scene,
+ .view_layer = view_layer,
+ .ar = ar,
+ .v3d = (View3D *)sa->spacedata.first,
+ .engine_type = engine_type,
+ }));
+ }
+ }
+ }
+ }
+ }
+
+ CTX_free(C);
+
+ recursive_check = false;
}
void ED_render_engine_area_exit(Main *bmain, ScrArea *sa)
{
- /* clear all render engines in this area */
- ARegion *ar;
- wmWindowManager *wm = bmain->wm.first;
-
- if (sa->spacetype != SPACE_VIEW3D)
- return;
-
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype != RGN_TYPE_WINDOW || !(ar->regiondata))
- continue;
- ED_view3d_stop_render_preview(wm, ar);
- }
+ /* clear all render engines in this area */
+ ARegion *ar;
+ wmWindowManager *wm = bmain->wm.first;
+
+ if (sa->spacetype != SPACE_VIEW3D)
+ return;
+
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype != RGN_TYPE_WINDOW || !(ar->regiondata))
+ continue;
+ ED_view3d_stop_render_preview(wm, ar);
+ }
}
void ED_render_engine_changed(Main *bmain)
{
- /* on changing the render engine type, clear all running render engines */
- for (bScreen *sc = bmain->screens.first; sc; sc = sc->id.next) {
- for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
- ED_render_engine_area_exit(bmain, sa);
- }
- }
- RE_FreePersistentData();
- /* Inform all render engines and draw managers. */
- DEGEditorUpdateContext update_ctx = {NULL};
- update_ctx.bmain = bmain;
- for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
- update_ctx.scene = scene;
- LISTBASE_FOREACH(ViewLayer *, view_layer, &scene->view_layers) {
- /* TDODO(sergey): Iterate over depsgraphs instead? */
- update_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
- update_ctx.view_layer = view_layer;
- ED_render_id_flush_update(&update_ctx, &scene->id);
- }
- if (scene->nodetree) {
- ntreeCompositUpdateRLayers(scene->nodetree);
- }
- }
+ /* on changing the render engine type, clear all running render engines */
+ for (bScreen *sc = bmain->screens.first; sc; sc = sc->id.next) {
+ for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
+ ED_render_engine_area_exit(bmain, sa);
+ }
+ }
+ RE_FreePersistentData();
+ /* Inform all render engines and draw managers. */
+ DEGEditorUpdateContext update_ctx = {NULL};
+ update_ctx.bmain = bmain;
+ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ update_ctx.scene = scene;
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ /* TDODO(sergey): Iterate over depsgraphs instead? */
+ update_ctx.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
+ update_ctx.view_layer = view_layer;
+ ED_render_id_flush_update(&update_ctx, &scene->id);
+ }
+ if (scene->nodetree) {
+ ntreeCompositUpdateRLayers(scene->nodetree);
+ }
+ }
}
void ED_render_view_layer_changed(Main *bmain, bScreen *sc)
{
- for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
- ED_render_engine_area_exit(bmain, sa);
- }
+ for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) {
+ ED_render_engine_area_exit(bmain, sa);
+ }
}
/***************************** Updates ***********************************
@@ -213,102 +210,102 @@ void ED_render_view_layer_changed(Main *bmain, bScreen *sc)
static void material_changed(Main *UNUSED(bmain), Material *ma)
{
- /* icons */
- BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
+ /* icons */
+ BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
}
static void lamp_changed(Main *UNUSED(bmain), Light *la)
{
- /* icons */
- BKE_icon_changed(BKE_icon_id_ensure(&la->id));
+ /* icons */
+ BKE_icon_changed(BKE_icon_id_ensure(&la->id));
}
static void texture_changed(Main *bmain, Tex *tex)
{
- Scene *scene;
- ViewLayer *view_layer;
- bNode *node;
-
- /* icons */
- BKE_icon_changed(BKE_icon_id_ensure(&tex->id));
-
- for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
- /* paint overlays */
- for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
- BKE_paint_invalidate_overlay_tex(scene, view_layer, tex);
- }
- /* find compositing nodes */
- if (scene->use_nodes && scene->nodetree) {
- for (node = scene->nodetree->nodes.first; node; node = node->next) {
- if (node->id == &tex->id)
- ED_node_tag_update_id(&scene->id);
- }
- }
- }
+ Scene *scene;
+ ViewLayer *view_layer;
+ bNode *node;
+
+ /* icons */
+ BKE_icon_changed(BKE_icon_id_ensure(&tex->id));
+
+ for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ /* paint overlays */
+ for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ BKE_paint_invalidate_overlay_tex(scene, view_layer, tex);
+ }
+ /* find compositing nodes */
+ if (scene->use_nodes && scene->nodetree) {
+ for (node = scene->nodetree->nodes.first; node; node = node->next) {
+ if (node->id == &tex->id)
+ ED_node_tag_update_id(&scene->id);
+ }
+ }
+ }
}
static void world_changed(Main *UNUSED(bmain), World *wo)
{
- /* icons */
- BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
+ /* icons */
+ BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
}
static void image_changed(Main *bmain, Image *ima)
{
- Tex *tex;
+ Tex *tex;
- /* icons */
- BKE_icon_changed(BKE_icon_id_ensure(&ima->id));
+ /* icons */
+ BKE_icon_changed(BKE_icon_id_ensure(&ima->id));
- /* textures */
- for (tex = bmain->textures.first; tex; tex = tex->id.next)
- if (tex->ima == ima)
- texture_changed(bmain, tex);
+ /* textures */
+ for (tex = bmain->textures.first; tex; tex = tex->id.next)
+ if (tex->ima == ima)
+ texture_changed(bmain, tex);
}
static void scene_changed(Main *bmain, Scene *scene)
{
- Object *ob;
-
- /* glsl */
- for (ob = bmain->objects.first; ob; ob = ob->id.next) {
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- BKE_texpaint_slots_refresh_object(scene, ob);
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- }
- }
+ Object *ob;
+
+ /* glsl */
+ for (ob = bmain->objects.first; ob; ob = ob->id.next) {
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ BKE_texpaint_slots_refresh_object(scene, ob);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ }
+ }
}
void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id)
{
- /* this can be called from render or baking thread when a python script makes
- * changes, in that case we don't want to do any editor updates, and making
- * GPU changes is not possible because OpenGL only works in the main thread */
- if (!BLI_thread_is_main()) {
- return;
- }
- Main *bmain = update_ctx->bmain;
- /* Internal ID update handlers. */
- switch (GS(id->name)) {
- case ID_MA:
- material_changed(bmain, (Material *)id);
- break;
- case ID_TE:
- texture_changed(bmain, (Tex *)id);
- break;
- case ID_WO:
- world_changed(bmain, (World *)id);
- break;
- case ID_LA:
- lamp_changed(bmain, (Light *)id);
- break;
- case ID_IM:
- image_changed(bmain, (Image *)id);
- break;
- case ID_SCE:
- scene_changed(bmain, (Scene *)id);
- break;
- default:
- break;
- }
+ /* this can be called from render or baking thread when a python script makes
+ * changes, in that case we don't want to do any editor updates, and making
+ * GPU changes is not possible because OpenGL only works in the main thread */
+ if (!BLI_thread_is_main()) {
+ return;
+ }
+ Main *bmain = update_ctx->bmain;
+ /* Internal ID update handlers. */
+ switch (GS(id->name)) {
+ case ID_MA:
+ material_changed(bmain, (Material *)id);
+ break;
+ case ID_TE:
+ texture_changed(bmain, (Tex *)id);
+ break;
+ case ID_WO:
+ world_changed(bmain, (World *)id);
+ break;
+ case ID_LA:
+ lamp_changed(bmain, (Light *)id);
+ break;
+ case ID_IM:
+ image_changed(bmain, (Image *)id);
+ break;
+ case ID_SCE:
+ scene_changed(bmain, (Scene *)id);
+ break;
+ default:
+ break;
+ }
}
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 1d7022c5263..258e98977c7 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -49,77 +49,77 @@
/*********************** utilities for finding areas *************************/
/* returns biggest area that is not uv/image editor. Note that it uses buttons */
-/* window as the last possible alternative. */
+/* window as the last possible alternative. */
/* would use BKE_screen_find_big_area(...) but this is too specific */
static ScrArea *biggest_non_image_area(bContext *C)
{
- bScreen *sc = CTX_wm_screen(C);
- ScrArea *sa, *big = NULL;
- int size, maxsize = 0, bwmaxsize = 0;
- short foundwin = 0;
-
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- if (sa->winx > 30 && sa->winy > 30) {
- size = sa->winx * sa->winy;
- if (!sa->full && sa->spacetype == SPACE_PROPERTIES) {
- if (foundwin == 0 && size > bwmaxsize) {
- bwmaxsize = size;
- big = sa;
- }
- }
- else if (sa->spacetype != SPACE_IMAGE && size > maxsize) {
- maxsize = size;
- big = sa;
- foundwin = 1;
- }
- }
- }
-
- return big;
+ bScreen *sc = CTX_wm_screen(C);
+ ScrArea *sa, *big = NULL;
+ int size, maxsize = 0, bwmaxsize = 0;
+ short foundwin = 0;
+
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ if (sa->winx > 30 && sa->winy > 30) {
+ size = sa->winx * sa->winy;
+ if (!sa->full && sa->spacetype == SPACE_PROPERTIES) {
+ if (foundwin == 0 && size > bwmaxsize) {
+ bwmaxsize = size;
+ big = sa;
+ }
+ }
+ else if (sa->spacetype != SPACE_IMAGE && size > maxsize) {
+ maxsize = size;
+ big = sa;
+ foundwin = 1;
+ }
+ }
+ }
+
+ return big;
}
static ScrArea *find_area_showing_r_result(bContext *C, Scene *scene, wmWindow **win)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- ScrArea *sa = NULL;
- SpaceImage *sima;
-
- /* find an imagewindow showing render result */
- for (*win = wm->windows.first; *win; *win = (*win)->next) {
- if (WM_window_get_active_scene(*win) == scene) {
- const bScreen *screen = WM_window_get_active_screen(*win);
-
- for (sa = screen->areabase.first; sa; sa = sa->next) {
- if (sa->spacetype == SPACE_IMAGE) {
- sima = sa->spacedata.first;
- if (sima->image && sima->image->type == IMA_TYPE_R_RESULT)
- break;
- }
- }
- if (sa)
- break;
- }
- }
-
- return sa;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ScrArea *sa = NULL;
+ SpaceImage *sima;
+
+ /* find an imagewindow showing render result */
+ for (*win = wm->windows.first; *win; *win = (*win)->next) {
+ if (WM_window_get_active_scene(*win) == scene) {
+ const bScreen *screen = WM_window_get_active_screen(*win);
+
+ for (sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ sima = sa->spacedata.first;
+ if (sima->image && sima->image->type == IMA_TYPE_R_RESULT)
+ break;
+ }
+ }
+ if (sa)
+ break;
+ }
+ }
+
+ return sa;
}
static ScrArea *find_area_image_empty(bContext *C)
{
- bScreen *sc = CTX_wm_screen(C);
- ScrArea *sa;
- SpaceImage *sima;
-
- /* find an imagewindow showing render result */
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- if (sa->spacetype == SPACE_IMAGE) {
- sima = sa->spacedata.first;
- if (!sima->image)
- break;
- }
- }
-
- return sa;
+ bScreen *sc = CTX_wm_screen(C);
+ ScrArea *sa;
+ SpaceImage *sima;
+
+ /* find an imagewindow showing render result */
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ sima = sa->spacedata.first;
+ if (!sima->image)
+ break;
+ }
+ }
+
+ return sa;
}
/********************** open image editor for render *************************/
@@ -127,224 +127,225 @@ static ScrArea *find_area_image_empty(bContext *C)
/* new window uses x,y to set position */
ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- wmWindow *win = NULL;
- ScrArea *sa = NULL;
- SpaceImage *sima;
- bool area_was_image = false;
-
- if (scene->r.displaymode == R_OUTPUT_NONE)
- return NULL;
-
- if (scene->r.displaymode == R_OUTPUT_WINDOW) {
- int sizex = 30 * UI_DPI_FAC + (scene->r.xsch * scene->r.size) / 100;
- int sizey = 60 * UI_DPI_FAC + (scene->r.ysch * scene->r.size) / 100;
-
- /* arbitrary... miniature image window views don't make much sense */
- if (sizex < 320) sizex = 320;
- if (sizey < 256) sizey = 256;
-
- /* changes context! */
- if (WM_window_open_temp(C, mx, my, sizex, sizey, WM_WINDOW_RENDER) == NULL) {
- BKE_report(reports, RPT_ERROR, "Failed to open window!");
- return NULL;
- }
-
- sa = CTX_wm_area(C);
- }
- else if (scene->r.displaymode == R_OUTPUT_SCREEN) {
- sa = CTX_wm_area(C);
-
- /* if the active screen is already in fullscreen mode, skip this and
- * unset the area, so that the fullscreen area is just changed later */
- if (sa && sa->full) {
- sa = NULL;
- }
- else {
- if (sa && sa->spacetype == SPACE_IMAGE)
- area_was_image = true;
-
- /* this function returns with changed context */
- sa = ED_screen_full_newspace(C, sa, SPACE_IMAGE);
- }
- }
-
- if (!sa) {
- sa = find_area_showing_r_result(C, scene, &win);
- if (sa == NULL)
- sa = find_area_image_empty(C);
-
- /* if area found in other window, we make that one show in front */
- if (win && win != CTX_wm_window(C))
- wm_window_raise(win);
-
- if (sa == NULL) {
- /* find largest open non-image area */
- sa = biggest_non_image_area(C);
- if (sa) {
- ED_area_newspace(C, sa, SPACE_IMAGE, true);
- sima = sa->spacedata.first;
-
- /* makes ESC go back to prev space */
- sima->flag |= SI_PREVSPACE;
-
- /* we already had a fullscreen here -> mark new space as a stacked fullscreen */
- if (sa->full) {
- sa->flag |= (AREA_FLAG_STACKED_FULLSCREEN | AREA_FLAG_TEMP_TYPE);
- }
- }
- else {
- /* use any area of decent size */
- sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TYPE_ANY, 0);
- if (sa->spacetype != SPACE_IMAGE) {
- // XXX newspace(sa, SPACE_IMAGE);
- sima = sa->spacedata.first;
-
- /* makes ESC go back to prev space */
- sima->flag |= SI_PREVSPACE;
- }
- }
- }
- }
- sima = sa->spacedata.first;
-
- /* get the correct image, and scale it */
- sima->image = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
-
-
- /* if we're rendering to full screen, set appropriate hints on image editor
- * so it can restore properly on pressing esc */
- if (sa->full) {
- sima->flag |= SI_FULLWINDOW;
-
- /* Tell the image editor to revert to previous space in space list on close
- * _only_ if it wasn't already an image editor when the render was invoked */
- if (area_was_image == 0)
- sima->flag |= SI_PREVSPACE;
- else {
- /* Leave it alone so the image editor will just go back from
- * full screen to the original tiled setup */
- }
- }
-
- return sa;
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ wmWindow *win = NULL;
+ ScrArea *sa = NULL;
+ SpaceImage *sima;
+ bool area_was_image = false;
+
+ if (scene->r.displaymode == R_OUTPUT_NONE)
+ return NULL;
+
+ if (scene->r.displaymode == R_OUTPUT_WINDOW) {
+ int sizex = 30 * UI_DPI_FAC + (scene->r.xsch * scene->r.size) / 100;
+ int sizey = 60 * UI_DPI_FAC + (scene->r.ysch * scene->r.size) / 100;
+
+ /* arbitrary... miniature image window views don't make much sense */
+ if (sizex < 320)
+ sizex = 320;
+ if (sizey < 256)
+ sizey = 256;
+
+ /* changes context! */
+ if (WM_window_open_temp(C, mx, my, sizex, sizey, WM_WINDOW_RENDER) == NULL) {
+ BKE_report(reports, RPT_ERROR, "Failed to open window!");
+ return NULL;
+ }
+
+ sa = CTX_wm_area(C);
+ }
+ else if (scene->r.displaymode == R_OUTPUT_SCREEN) {
+ sa = CTX_wm_area(C);
+
+ /* if the active screen is already in fullscreen mode, skip this and
+ * unset the area, so that the fullscreen area is just changed later */
+ if (sa && sa->full) {
+ sa = NULL;
+ }
+ else {
+ if (sa && sa->spacetype == SPACE_IMAGE)
+ area_was_image = true;
+
+ /* this function returns with changed context */
+ sa = ED_screen_full_newspace(C, sa, SPACE_IMAGE);
+ }
+ }
+
+ if (!sa) {
+ sa = find_area_showing_r_result(C, scene, &win);
+ if (sa == NULL)
+ sa = find_area_image_empty(C);
+
+ /* if area found in other window, we make that one show in front */
+ if (win && win != CTX_wm_window(C))
+ wm_window_raise(win);
+
+ if (sa == NULL) {
+ /* find largest open non-image area */
+ sa = biggest_non_image_area(C);
+ if (sa) {
+ ED_area_newspace(C, sa, SPACE_IMAGE, true);
+ sima = sa->spacedata.first;
+
+ /* makes ESC go back to prev space */
+ sima->flag |= SI_PREVSPACE;
+
+ /* we already had a fullscreen here -> mark new space as a stacked fullscreen */
+ if (sa->full) {
+ sa->flag |= (AREA_FLAG_STACKED_FULLSCREEN | AREA_FLAG_TEMP_TYPE);
+ }
+ }
+ else {
+ /* use any area of decent size */
+ sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TYPE_ANY, 0);
+ if (sa->spacetype != SPACE_IMAGE) {
+ // XXX newspace(sa, SPACE_IMAGE);
+ sima = sa->spacedata.first;
+
+ /* makes ESC go back to prev space */
+ sima->flag |= SI_PREVSPACE;
+ }
+ }
+ }
+ }
+ sima = sa->spacedata.first;
+
+ /* get the correct image, and scale it */
+ sima->image = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
+
+ /* if we're rendering to full screen, set appropriate hints on image editor
+ * so it can restore properly on pressing esc */
+ if (sa->full) {
+ sima->flag |= SI_FULLWINDOW;
+
+ /* Tell the image editor to revert to previous space in space list on close
+ * _only_ if it wasn't already an image editor when the render was invoked */
+ if (area_was_image == 0)
+ sima->flag |= SI_PREVSPACE;
+ else {
+ /* Leave it alone so the image editor will just go back from
+ * full screen to the original tiled setup */
+ }
+ }
+
+ return sa;
}
/*************************** cancel render viewer **********************/
static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op))
{
- wmWindow *win = CTX_wm_window(C);
- ScrArea *sa = CTX_wm_area(C);
- SpaceImage *sima = sa->spacedata.first;
-
- /* ensure image editor fullscreen and area fullscreen states are in sync */
- if ((sima->flag & SI_FULLWINDOW) && !sa->full) {
- sima->flag &= ~SI_FULLWINDOW;
- }
-
- /* test if we have a temp screen in front */
- if (WM_window_is_temp_screen(win)) {
- wm_window_lower(win);
- return OPERATOR_FINISHED;
- }
- /* determine if render already shows */
- else 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 {
- ED_area_prevspace(C, sa);
- }
-
- return OPERATOR_FINISHED;
- }
- else if (sima->flag & SI_FULLWINDOW) {
- sima->flag &= ~SI_FULLWINDOW;
- ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED);
- return OPERATOR_FINISHED;
- }
-
- return OPERATOR_PASS_THROUGH;
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceImage *sima = sa->spacedata.first;
+
+ /* ensure image editor fullscreen and area fullscreen states are in sync */
+ if ((sima->flag & SI_FULLWINDOW) && !sa->full) {
+ sima->flag &= ~SI_FULLWINDOW;
+ }
+
+ /* test if we have a temp screen in front */
+ if (WM_window_is_temp_screen(win)) {
+ wm_window_lower(win);
+ return OPERATOR_FINISHED;
+ }
+ /* determine if render already shows */
+ else 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 {
+ ED_area_prevspace(C, sa);
+ }
+
+ return OPERATOR_FINISHED;
+ }
+ else if (sima->flag & SI_FULLWINDOW) {
+ sima->flag &= ~SI_FULLWINDOW;
+ ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED);
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_PASS_THROUGH;
}
void RENDER_OT_view_cancel(struct wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Cancel Render View";
- ot->description = "Cancel show render view";
- ot->idname = "RENDER_OT_view_cancel";
-
- /* api callbacks */
- ot->exec = render_view_cancel_exec;
- ot->poll = ED_operator_image_active;
+ /* identifiers */
+ ot->name = "Cancel Render View";
+ ot->description = "Cancel show render view";
+ ot->idname = "RENDER_OT_view_cancel";
+
+ /* api callbacks */
+ ot->exec = render_view_cancel_exec;
+ ot->poll = ED_operator_image_active;
}
/************************* show render viewer *****************/
static int render_view_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- wmWindow *wincur = CTX_wm_window(C);
-
- /* test if we have currently a temp screen active */
- if (WM_window_is_temp_screen(wincur)) {
- wm_window_lower(wincur);
- }
- else {
- wmWindow *win, *winshow;
- ScrArea *sa = find_area_showing_r_result(C, CTX_data_scene(C), &winshow);
-
- /* is there another window on current scene showing result? */
- for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) {
- const bScreen *sc = WM_window_get_active_screen(win);
-
- if ((WM_window_is_temp_screen(win) && ((ScrArea *)sc->areabase.first)->spacetype == SPACE_IMAGE) ||
- (win == winshow && winshow != wincur))
- {
- wm_window_raise(win);
- return OPERATOR_FINISHED;
- }
- }
-
- /* determine if render already shows */
- if (sa) {
- /* but don't close it when rendering */
- if (G.is_rendering == false) {
- 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 {
- ED_area_prevspace(C, sa);
- }
- }
- }
- }
- else {
- render_view_open(C, event->x, event->y, op->reports);
- }
- }
-
- return OPERATOR_FINISHED;
+ wmWindow *wincur = CTX_wm_window(C);
+
+ /* test if we have currently a temp screen active */
+ if (WM_window_is_temp_screen(wincur)) {
+ wm_window_lower(wincur);
+ }
+ else {
+ wmWindow *win, *winshow;
+ ScrArea *sa = find_area_showing_r_result(C, CTX_data_scene(C), &winshow);
+
+ /* is there another window on current scene showing result? */
+ for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) {
+ const bScreen *sc = WM_window_get_active_screen(win);
+
+ if ((WM_window_is_temp_screen(win) &&
+ ((ScrArea *)sc->areabase.first)->spacetype == SPACE_IMAGE) ||
+ (win == winshow && winshow != wincur)) {
+ wm_window_raise(win);
+ return OPERATOR_FINISHED;
+ }
+ }
+
+ /* determine if render already shows */
+ if (sa) {
+ /* but don't close it when rendering */
+ if (G.is_rendering == false) {
+ 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 {
+ ED_area_prevspace(C, sa);
+ }
+ }
+ }
+ }
+ else {
+ render_view_open(C, event->x, event->y, op->reports);
+ }
+ }
+
+ return OPERATOR_FINISHED;
}
void RENDER_OT_view_show(struct wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Show/Hide Render View";
- ot->description = "Toggle show render view";
- ot->idname = "RENDER_OT_view_show";
-
- /* api callbacks */
- ot->invoke = render_view_show_invoke;
- ot->poll = ED_operator_screenactive;
+ /* identifiers */
+ ot->name = "Show/Hide Render View";
+ ot->description = "Toggle show render view";
+ ot->idname = "RENDER_OT_view_show";
+
+ /* api callbacks */
+ ot->invoke = render_view_show_invoke;
+ ot->poll = ED_operator_screenactive;
}