Compositor: UI: Visualize render size and domain size in image editor
Show render region as a bounding box with a passepartout option. Additionally, a text info is shown at the upper left corner, similar to the info text in 3d view, showing the render size and current image size. Devtalk thread: https://devtalk.blender.org/t/compositor-ui-improvements/34186?u=izo Pull Request: https://projects.blender.org/blender/blender/pulls/120471
This commit is contained in:
@@ -1588,7 +1588,7 @@ class IMAGE_PT_overlay(Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Overlays"
|
||||
bl_ui_units_x = 13
|
||||
bl_ui_units_x = 14
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
@@ -1735,6 +1735,37 @@ class IMAGE_PT_overlay_image(Panel):
|
||||
layout.prop(uvedit, "show_metadata")
|
||||
|
||||
|
||||
class IMAGE_PT_overlay_render_guides(Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Guides"
|
||||
bl_parent_id = "IMAGE_PT_overlay"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sima = context.space_data
|
||||
return ((sima.mode == 'MASK' or sima.mode == 'VIEW') and
|
||||
(sima.image and sima.image.source == 'VIEWER' and
|
||||
sima.image.type == 'COMPOSITING'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sima = context.space_data
|
||||
overlay = sima.overlay
|
||||
|
||||
layout.active = overlay.show_overlays
|
||||
|
||||
row = layout.row(align=True)
|
||||
layout.prop(overlay, "show_text_info")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(overlay, "show_render_size")
|
||||
subrow = row.row()
|
||||
subrow.active = overlay.show_render_size
|
||||
subrow.prop(overlay, "passepartout_alpha", text="Passepartout")
|
||||
|
||||
|
||||
# Grease Pencil properties
|
||||
class IMAGE_PT_annotation(AnnotationDataPanel, Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
@@ -1830,6 +1861,7 @@ classes = (
|
||||
IMAGE_PT_overlay_uv_edit_geometry,
|
||||
IMAGE_PT_overlay_uv_display,
|
||||
IMAGE_PT_overlay_image,
|
||||
IMAGE_PT_overlay_render_guides,
|
||||
IMAGE_AST_brush_paint,
|
||||
)
|
||||
|
||||
|
||||
@@ -77,6 +77,18 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *region, void *arg_
|
||||
void ED_region_image_metadata_draw(
|
||||
int x, int y, const ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy);
|
||||
|
||||
void ED_region_image_overlay_info_text_draw(const int render_size_x,
|
||||
const int render_size_y,
|
||||
|
||||
const int viewer_size_x,
|
||||
const int viewer_size_y,
|
||||
|
||||
const int draw_offset_x,
|
||||
const int draw_offset_y);
|
||||
|
||||
void ED_region_image_render_region_draw(
|
||||
int x, int y, const rcti *frame, float zoomx, float zoomy, float passepartout_alpha);
|
||||
|
||||
/* Slider */
|
||||
|
||||
struct tSlider;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_scene.hh"
|
||||
#include "BKE_screen.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
@@ -105,6 +106,7 @@ static SpaceLink *image_create(const ScrArea * /*area*/, const Scene * /*scene*/
|
||||
simage->uv_face_opacity = 1.0f;
|
||||
simage->stretch_opacity = 1.0f;
|
||||
simage->overlay.flag = SI_OVERLAY_SHOW_OVERLAYS | SI_OVERLAY_SHOW_GRID_BACKGROUND;
|
||||
simage->overlay.passepartout_alpha = 0.5f;
|
||||
|
||||
BKE_imageuser_default(&simage->iuser);
|
||||
simage->iuser.flag = IMA_SHOW_STEREO | IMA_ANIM_ALWAYS;
|
||||
@@ -634,7 +636,19 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View2D *v2d = ®ion->v2d;
|
||||
Image *image = ED_space_image(sima);
|
||||
/* Typically a render result or viewer image from the compositor. */
|
||||
const bool show_viewer = (image && image->source == IMA_SRC_VIEWER);
|
||||
const bool show_compositor_viewer = show_viewer && image->type == IMA_TYPE_COMPOSITE;
|
||||
|
||||
/* Text info and render region are only relevant for the compositor. */
|
||||
const bool show_text_info = (sima->overlay.flag & SI_OVERLAY_SHOW_OVERLAYS &&
|
||||
sima->overlay.flag & SI_OVERLAY_DRAW_TEXT_INFO &&
|
||||
(sima->mode == SI_MODE_MASK || sima->mode == SI_MODE_VIEW)) &&
|
||||
show_compositor_viewer;
|
||||
const bool show_render_region = (sima->overlay.flag & SI_OVERLAY_SHOW_OVERLAYS &&
|
||||
sima->overlay.flag & SI_OVERLAY_DRAW_RENDER_REGION &&
|
||||
(sima->mode == SI_MODE_MASK || sima->mode == SI_MODE_VIEW)) &&
|
||||
show_compositor_viewer;
|
||||
|
||||
/* XXX not supported yet, disabling for now */
|
||||
scene->r.scemode &= ~R_COMP_CROP;
|
||||
@@ -657,6 +671,28 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
|
||||
BLI_thread_unlock(LOCK_DRAW_IMAGE);
|
||||
}
|
||||
|
||||
if (show_render_region) {
|
||||
int render_size_x, render_size_y;
|
||||
|
||||
BKE_render_resolution(&scene->r, true, &render_size_x, &render_size_y);
|
||||
|
||||
float zoomx, zoomy;
|
||||
ED_space_image_get_zoom(sima, region, &zoomx, &zoomy);
|
||||
int width, height;
|
||||
ED_space_image_get_size(sima, &width, &height);
|
||||
int center_x = width / 2;
|
||||
int center_y = height / 2;
|
||||
|
||||
int x, y;
|
||||
rcti render_region;
|
||||
BLI_rcti_init(
|
||||
&render_region, center_x, render_size_x + center_x, center_y, render_size_y + center_y);
|
||||
UI_view2d_view_to_region(®ion->v2d, 0.0f, 0.0f, &x, &y);
|
||||
|
||||
ED_region_image_render_region_draw(
|
||||
x, y, &render_region, zoomx, zoomy, sima->overlay.passepartout_alpha);
|
||||
}
|
||||
|
||||
draw_image_main_helpers(C, region);
|
||||
|
||||
/* Draw Meta data of the image isn't added to the DrawManager as it is
|
||||
@@ -678,6 +714,23 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
|
||||
ED_space_image_release_buffer(sima, ibuf, lock);
|
||||
}
|
||||
|
||||
if (show_text_info) {
|
||||
|
||||
int render_size_x, render_size_y;
|
||||
BKE_render_resolution(&scene->r, true, &render_size_x, &render_size_y);
|
||||
|
||||
/* Use same positioning convention as in 3D View. */
|
||||
const rcti *rect = ED_region_visible_rect(region);
|
||||
int xoffset = rect->xmin + (0.5f * U.widget_unit);
|
||||
int yoffset = rect->ymax - (0.1f * U.widget_unit);
|
||||
|
||||
int viewer_size_x, viewer_size_y;
|
||||
ED_space_image_get_size(sima, &viewer_size_x, &viewer_size_y);
|
||||
|
||||
ED_region_image_overlay_info_text_draw(
|
||||
render_size_x, render_size_y, viewer_size_x, viewer_size_y, xoffset, yoffset);
|
||||
}
|
||||
|
||||
/* sample line */
|
||||
UI_view2d_view_ortho(v2d);
|
||||
draw_image_sample_line(sima);
|
||||
|
||||
@@ -909,6 +909,124 @@ static float metadata_box_height_get(const ImBuf *ibuf, int fontid, const bool i
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void text_info_row(const char *text,
|
||||
const int text_len,
|
||||
int col1,
|
||||
int col2,
|
||||
int row,
|
||||
const int size_x,
|
||||
const int size_y)
|
||||
{
|
||||
const int font_id = BLF_default();
|
||||
float text_color[4];
|
||||
|
||||
UI_GetThemeColor4fv(TH_TEXT_HI, text_color);
|
||||
BLF_color4fv(font_id, text_color);
|
||||
|
||||
/* Ensure text is visible against bright background. */
|
||||
const float shadow_color[4] = {0.0f, 0.0f, 0.0f, 0.8f};
|
||||
BLF_enable(font_id, BLF_SHADOW);
|
||||
BLF_shadow_offset(font_id, 0, 0);
|
||||
BLF_shadow(font_id, FontShadowType::Outline, shadow_color);
|
||||
|
||||
BLF_position(font_id, col1, row, 0.0f);
|
||||
BLF_draw(font_id, IFACE_(text), text_len);
|
||||
BLF_position(font_id, col2, row, 0.0f);
|
||||
char draw_text[MAX_NAME];
|
||||
SNPRINTF(draw_text, "%d x %d", size_x, size_y);
|
||||
BLF_draw(font_id, draw_text, sizeof(draw_text));
|
||||
|
||||
BLF_disable(font_id, BLF_SHADOW);
|
||||
}
|
||||
|
||||
void ED_region_image_overlay_info_text_draw(const int render_size_x,
|
||||
const int render_size_y,
|
||||
|
||||
const int viewer_size_x,
|
||||
const int viewer_size_y,
|
||||
|
||||
const int draw_offset_x,
|
||||
const int draw_offset_y)
|
||||
{
|
||||
BLF_set_default();
|
||||
const int font_id = BLF_default();
|
||||
int overlay_lineheight = (UI_style_get()->widget.points * UI_SCALE_FAC * 1.6f);
|
||||
|
||||
const char render_size_name[MAX_NAME] = "Render Size";
|
||||
const char viewer_size_name[MAX_NAME] = "Image Size";
|
||||
|
||||
const int render_size_width = BLF_width(font_id, render_size_name, sizeof(render_size_name));
|
||||
const int viewer_size_width = BLF_width(font_id, viewer_size_name, sizeof(viewer_size_name));
|
||||
int longest_label = max_ii(render_size_width, viewer_size_width);
|
||||
|
||||
int col1 = draw_offset_x;
|
||||
int col2 = draw_offset_x + longest_label + (0.5 * U.widget_unit);
|
||||
|
||||
text_info_row(render_size_name,
|
||||
sizeof(render_size_name),
|
||||
col1,
|
||||
col2,
|
||||
draw_offset_y - overlay_lineheight,
|
||||
render_size_x,
|
||||
render_size_y);
|
||||
|
||||
text_info_row(viewer_size_name,
|
||||
sizeof(viewer_size_name),
|
||||
col1,
|
||||
col2,
|
||||
draw_offset_y - overlay_lineheight * 2,
|
||||
viewer_size_x,
|
||||
viewer_size_y);
|
||||
}
|
||||
|
||||
void ED_region_image_render_region_draw(
|
||||
int x, int y, const rcti *frame, float zoomx, float zoomy, float passepartout_alpha)
|
||||
{
|
||||
GPU_matrix_push();
|
||||
|
||||
/* Offset and zoom using GPU viewport. */
|
||||
const auto frame_width = BLI_rcti_size_x(frame);
|
||||
const auto frame_height = BLI_rcti_size_y(frame);
|
||||
GPU_matrix_translate_2f(x, y);
|
||||
GPU_matrix_scale_2f(zoomx, zoomy);
|
||||
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
const float x1 = frame->xmin - frame_width / 2;
|
||||
const float x2 = frame->xmax - frame_width / 2;
|
||||
const float y1 = frame->ymin - frame_height / 2;
|
||||
const float y2 = frame->ymax - frame_height / 2;
|
||||
|
||||
/* Darken the area outside the frame. */
|
||||
if (passepartout_alpha > 0) {
|
||||
/* Using a sufficiently large number instead of numeric_limits::infinity(), to avoid comparison
|
||||
* issues and different behavior around large numbers on different platforms. */
|
||||
constexpr float inf = 10e5;
|
||||
immUniformColor4f(0.0f, 0.0f, 0.0f, passepartout_alpha);
|
||||
immRectf(pos, -inf, y2, inf, inf);
|
||||
immRectf(pos, -inf, y1, inf, -inf);
|
||||
immRectf(pos, -inf, y1, x1, y2);
|
||||
immRectf(pos, x2, y1, inf, y2);
|
||||
}
|
||||
|
||||
float wire_color[3];
|
||||
UI_GetThemeColor3fv(TH_WIRE_EDIT, wire_color);
|
||||
immUniformColor4f(wire_color[0], wire_color[1], wire_color[2], 1);
|
||||
|
||||
/* The bounding box must be drawn last to ensure it remains visible
|
||||
* when passepartout_alpha > 0. */
|
||||
imm_draw_box_wire_2d(pos, x1, y1, x2, y2);
|
||||
|
||||
immUnbindProgram();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
|
||||
void ED_region_image_metadata_draw(
|
||||
int x, int y, const ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
|
||||
{
|
||||
|
||||
@@ -770,6 +770,8 @@ typedef enum eSpaceImage_Flag {
|
||||
typedef enum eSpaceImageOverlay_Flag {
|
||||
SI_OVERLAY_SHOW_OVERLAYS = (1 << 0),
|
||||
SI_OVERLAY_SHOW_GRID_BACKGROUND = (1 << 1),
|
||||
SI_OVERLAY_DRAW_RENDER_REGION = (1 << 2),
|
||||
SI_OVERLAY_DRAW_TEXT_INFO = (1 << 3),
|
||||
} eSpaceImageOverlay_Flag;
|
||||
|
||||
/** #SpaceImage.gizmo_flag */
|
||||
|
||||
@@ -622,7 +622,7 @@ typedef struct FileDirEntryArr {
|
||||
|
||||
typedef struct SpaceImageOverlay {
|
||||
int flag;
|
||||
char _pad[4];
|
||||
float passepartout_alpha;
|
||||
} SpaceImageOverlay;
|
||||
|
||||
typedef struct SpaceImage {
|
||||
|
||||
@@ -5854,6 +5854,23 @@ static void rna_def_space_image_overlay(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "overlay.flag", SI_OVERLAY_SHOW_GRID_BACKGROUND);
|
||||
RNA_def_property_ui_text(prop, "Display Background", "Show the grid background and borders");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "show_render_size", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "overlay.flag", SI_OVERLAY_DRAW_RENDER_REGION);
|
||||
RNA_def_property_ui_text(prop, "Render Region", "Display the region of the final render");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "show_text_info", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "overlay.flag", SI_OVERLAY_DRAW_TEXT_INFO);
|
||||
RNA_def_property_ui_text(prop, "Text Info", "Display overlay text");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, nullptr, "overlay.passepartout_alpha");
|
||||
RNA_def_property_float_default(prop, 0.5f);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Passepartout Alpha", "Opacity of the darkened overlay outside the render region");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, nullptr);
|
||||
}
|
||||
|
||||
static void rna_def_space_image(BlenderRNA *brna)
|
||||
|
||||
Reference in New Issue
Block a user