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:
authorJulian Eisel <julian@blender.org>2020-03-26 23:03:42 +0300
committerJulian Eisel <julian@blender.org>2020-03-26 23:18:45 +0300
commitc94b6209861ca7cc3985b53474feed7d94c0221a (patch)
tree752054f0dca1338cda5cf8ad4f6d18573fcca3b9 /source/blender/editors/space_image
parent357ed79cb93f9d655501a828c6cddd68282de62d (diff)
parentafb1a64ccb81b7ed792f64151986f40f53af8da5 (diff)
Merge branch 'master' into wm-drag-drop-rewrite
Diffstat (limited to 'source/blender/editors/space_image')
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_image/image_buttons.c16
-rw-r--r--source/blender/editors/space_image/image_draw.c152
-rw-r--r--source/blender/editors/space_image/image_edit.c126
-rw-r--r--source/blender/editors/space_image/image_intern.h4
-rw-r--r--source/blender/editors/space_image/image_ops.c687
-rw-r--r--source/blender/editors/space_image/image_sequence.c248
-rw-r--r--source/blender/editors/space_image/image_undo.c63
-rw-r--r--source/blender/editors/space_image/space_image.c254
9 files changed, 849 insertions, 702 deletions
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index 5abcff436f1..12de74c6ae7 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
image_draw.c
image_edit.c
image_ops.c
+ image_sequence.c
image_undo.c
space_image.c
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 270fe0c59dc..873091bd68d 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -21,8 +21,8 @@
* \ingroup spimage
*/
-#include <string.h>
#include <stdio.h>
+#include <string.h>
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
@@ -37,8 +37,8 @@
#include "BKE_context.h"
#include "BKE_image.h"
#include "BKE_node.h"
-#include "BKE_screen.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "RE_pipeline.h"
@@ -47,8 +47,8 @@
#include "IMB_imbuf_types.h"
#include "ED_gpencil.h"
-#include "ED_screen.h"
#include "ED_image.h"
+#include "ED_screen.h"
#include "RNA_access.h"
@@ -980,6 +980,16 @@ void uiTemplateImage(uiLayout *layout,
bool is_data = IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name);
uiLayoutSetActive(sub, !is_data);
}
+
+ if (ima && iuser) {
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+
+ if (ibuf && ibuf->rect_float && (ibuf->flags & IB_halffloat) == 0) {
+ uiItemR(col, &imaptr, "use_half_precision", 0, NULL, ICON_NONE);
+ }
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
}
uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE);
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 3f563fe9033..85f7f744abc 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -27,26 +27,26 @@
#include "MEM_guardedalloc.h"
+#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
+#include "DNA_mask_types.h"
#include "DNA_object_types.h"
-#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_brush_types.h"
-#include "DNA_mask_types.h"
+#include "DNA_space_types.h"
#include "PIL_time.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_rect.h"
-#include "BLI_threads.h"
#include "BLI_string.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "IMB_colormanagement.h"
#include "IMB_moviecache.h"
#include "BKE_context.h"
@@ -72,13 +72,13 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "RE_pipeline.h"
#include "RE_engine.h"
+#include "RE_pipeline.h"
#include "image_intern.h"
static void draw_render_info(
- const bContext *C, Scene *scene, Image *ima, ARegion *ar, float zoomx, float zoomy)
+ const bContext *C, Scene *scene, Image *ima, ARegion *region, float zoomx, float zoomy)
{
Render *re = RE_GetSceneRender(scene);
RenderData *rd = RE_engine_get_render_data(re);
@@ -91,7 +91,7 @@ static void draw_render_info(
if (rr && rr->text) {
float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
- ED_region_info_draw(ar, rr->text, fill_color, true);
+ ED_region_info_draw(region, rr->text, fill_color, true);
}
BKE_image_release_renderresult(stats_scene, ima);
@@ -104,7 +104,7 @@ static void draw_render_info(
if (total_tiles) {
/* find window pixel coordinates of origin */
int x, y;
- UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region(&region->v2d, 0.0f, 0.0f, &x, &y);
GPU_matrix_push();
GPU_matrix_translate_2f(x, y);
@@ -141,13 +141,13 @@ static void draw_render_info(
/* used by node view too */
void ED_image_draw_info(Scene *scene,
- ARegion *ar,
+ ARegion *region,
bool color_manage,
bool use_default_view,
int channels,
int x,
int y,
- const unsigned char cp[4],
+ const uchar cp[4],
const float fp[4],
const float linearcol[4],
int *zp,
@@ -157,20 +157,20 @@ void ED_image_draw_info(Scene *scene,
char str[256];
int dx = 6;
/* local coordinate visible rect inside region, to accommodate overlapping ui */
- const rcti *rect = ED_region_visible_rect(ar);
+ const rcti *rect = ED_region_visible_rect(region);
const int ymin = rect->ymin;
const int dy = ymin + 0.3f * UI_UNIT_Y;
/* text colors */
/* XXX colored text not allowed in Blender UI */
#if 0
- unsigned char red[3] = {255, 50, 50};
- unsigned char green[3] = {0, 255, 0};
- unsigned char blue[3] = {100, 100, 255};
+ uchar red[3] = {255, 50, 50};
+ uchar green[3] = {0, 255, 0};
+ uchar blue[3] = {100, 100, 255};
#else
- unsigned char red[3] = {255, 255, 255};
- unsigned char green[3] = {255, 255, 255};
- unsigned char blue[3] = {255, 255, 255};
+ uchar red[3] = {255, 255, 255};
+ uchar green[3] = {255, 255, 255};
+ uchar blue[3] = {255, 255, 255};
#endif
float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
float col[4], finalcol[4];
@@ -185,7 +185,7 @@ void ED_image_draw_info(Scene *scene,
/* noisy, high contrast make impossible to read if lower alpha is used. */
immUniformColor4ub(0, 0, 0, 190);
- immRecti(pos, 0, ymin, BLI_rcti_size_x(&ar->winrct) + 1, ymin + UI_UNIT_Y);
+ immRecti(pos, 0, ymin, BLI_rcti_size_x(&region->winrct) + 1, ymin + UI_UNIT_Y);
immUnbindProgram();
@@ -532,7 +532,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene,
MEM_freeN(rectf);
}
-static void draw_udim_label(ARegion *ar, float fx, float fy, const char *label)
+static void draw_udim_label(ARegion *region, float fx, float fy, const char *label)
{
if (label == NULL || !label[0]) {
return;
@@ -540,14 +540,14 @@ static void draw_udim_label(ARegion *ar, float fx, float fy, const char *label)
/* find window pixel coordinates of origin */
int x, y;
- UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y);
+ UI_view2d_view_to_region(&region->v2d, fx, fy, &x, &y);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
int textwidth = BLF_width(blf_mono_font, label, strlen(label)) + 10;
- float stepx = BLI_rcti_size_x(&ar->v2d.mask) / BLI_rctf_size_x(&ar->v2d.cur);
+ float stepx = BLI_rcti_size_x(&region->v2d.mask) / BLI_rctf_size_x(&region->v2d.cur);
float opacity;
if (textwidth < 0.5f * (stepx - 10)) {
opacity = 1.0f;
@@ -567,7 +567,7 @@ static void draw_udim_label(ARegion *ar, float fx, float fy, const char *label)
static void draw_image_buffer(const bContext *C,
SpaceImage *sima,
- ARegion *ar,
+ ARegion *region,
Scene *scene,
ImBuf *ibuf,
float fx,
@@ -576,12 +576,13 @@ static void draw_image_buffer(const bContext *C,
float zoomy)
{
int x, y;
+ int sima_flag = sima->flag & ED_space_image_get_display_channel_mask(ibuf);
/* find window pixel coordinates of origin */
- UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y);
+ UI_view2d_view_to_region(&region->v2d, fx, fy, &x, &y);
/* this part is generic image display */
- if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
+ if (sima_flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
if (ibuf->zbuf) {
sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf, zoomx, zoomy);
}
@@ -595,9 +596,9 @@ static void draw_image_buffer(const bContext *C,
else {
int clip_max_x, clip_max_y;
UI_view2d_view_to_region(
- &ar->v2d, ar->v2d.cur.xmax, ar->v2d.cur.ymax, &clip_max_x, &clip_max_y);
+ &region->v2d, region->v2d.cur.xmax, region->v2d.cur.ymax, &clip_max_x, &clip_max_y);
- if (sima->flag & SI_USE_ALPHA) {
+ if (sima_flag & SI_USE_ALPHA) {
imm_draw_box_checker_2d(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
GPU_blend(true);
@@ -606,28 +607,28 @@ static void draw_image_buffer(const bContext *C,
}
/* If RGBA display with color management */
- if ((sima->flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) {
+ if ((sima_flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) {
ED_draw_imbuf_ctx_clipping(
C, ibuf, x, y, GL_NEAREST, 0, 0, clip_max_x, clip_max_y, zoomx, zoomy);
}
else {
float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- unsigned char *display_buffer;
+ uchar *display_buffer;
void *cache_handle;
ColorManagedViewSettings *view_settings;
ColorManagedDisplaySettings *display_settings;
- if (sima->flag & SI_SHOW_R) {
+ if (sima_flag & SI_SHOW_R) {
shuffle[0] = 1.0f;
}
- else if (sima->flag & SI_SHOW_G) {
+ else if (sima_flag & SI_SHOW_G) {
shuffle[1] = 1.0f;
}
- else if (sima->flag & SI_SHOW_B) {
+ else if (sima_flag & SI_SHOW_B) {
shuffle[2] = 1.0f;
}
- else if (sima->flag & SI_SHOW_ALPHA) {
+ else if (sima_flag & SI_SHOW_ALPHA) {
shuffle[3] = 1.0f;
}
@@ -661,7 +662,7 @@ static void draw_image_buffer(const bContext *C,
IMB_display_buffer_release(cache_handle);
}
- if (sima->flag & SI_USE_ALPHA) {
+ if (sima_flag & SI_USE_ALPHA) {
GPU_blend(false);
}
}
@@ -669,7 +670,7 @@ static void draw_image_buffer(const bContext *C,
static void draw_image_buffer_repeated(const bContext *C,
SpaceImage *sima,
- ARegion *ar,
+ ARegion *region,
Scene *scene,
ImBuf *ibuf,
float zoomx,
@@ -677,14 +678,14 @@ static void draw_image_buffer_repeated(const bContext *C,
{
const double time_current = PIL_check_seconds_timer();
- const int xmax = ceil(ar->v2d.cur.xmax);
- const int ymax = ceil(ar->v2d.cur.ymax);
- const int xmin = floor(ar->v2d.cur.xmin);
- const int ymin = floor(ar->v2d.cur.ymin);
+ const int xmax = ceil(region->v2d.cur.xmax);
+ const int ymax = ceil(region->v2d.cur.ymax);
+ const int xmin = floor(region->v2d.cur.xmin);
+ const int ymin = floor(region->v2d.cur.ymin);
for (int x = xmin; x < xmax; x++) {
for (int y = ymin; y < ymax; y++) {
- draw_image_buffer(C, sima, ar, scene, ibuf, x, y, zoomx, zoomy);
+ draw_image_buffer(C, sima, region, scene, ibuf, x, y, zoomx, zoomy);
/* only draw until running out of time */
if ((PIL_check_seconds_timer() - time_current) > 0.25) {
@@ -744,7 +745,7 @@ void draw_image_sample_line(SpaceImage *sima)
}
static void draw_image_paint_helpers(
- const bContext *C, ARegion *ar, Scene *scene, float zoomx, float zoomy)
+ const bContext *C, ARegion *region, Scene *scene, float zoomx, float zoomy)
{
Brush *brush;
int x, y;
@@ -758,9 +759,10 @@ static void draw_image_paint_helpers(
if (ibuf) {
void *cache_handle = NULL;
float col[4] = {1.0f, 1.0f, 1.0f, brush->clone.alpha};
- UI_view2d_view_to_region(&ar->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
+ UI_view2d_view_to_region(
+ &region->v2d, brush->clone.offset[0], brush->clone.offset[1], &x, &y);
- unsigned char *display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+ uchar *display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
if (!display_buffer) {
BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
@@ -794,9 +796,9 @@ static void draw_image_paint_helpers(
}
}
-static void draw_udim_tile_grid(unsigned int pos_attr,
- unsigned int color_attr,
- ARegion *ar,
+static void draw_udim_tile_grid(uint pos_attr,
+ uint color_attr,
+ ARegion *region,
int x,
int y,
float stepx,
@@ -804,7 +806,7 @@ static void draw_udim_tile_grid(unsigned int pos_attr,
const float color[3])
{
float x1, y1;
- UI_view2d_view_to_region_fl(&ar->v2d, x, y, &x1, &y1);
+ UI_view2d_view_to_region_fl(&region->v2d, x, y, &x1, &y1);
int gridpos[5][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
for (int i = 0; i < 4; i++) {
immAttr3fv(color_attr, color);
@@ -814,7 +816,7 @@ static void draw_udim_tile_grid(unsigned int pos_attr,
}
}
-static void draw_udim_tile_grids(ARegion *ar, SpaceImage *sima, Image *ima)
+static void draw_udim_tile_grids(ARegion *region, SpaceImage *sima, Image *ima)
{
int num_tiles;
if (ima != NULL) {
@@ -828,12 +830,12 @@ static void draw_udim_tile_grids(ARegion *ar, SpaceImage *sima, Image *ima)
num_tiles = sima->tile_grid_shape[0] * sima->tile_grid_shape[1];
}
- float stepx = BLI_rcti_size_x(&ar->v2d.mask) / BLI_rctf_size_x(&ar->v2d.cur);
- float stepy = BLI_rcti_size_y(&ar->v2d.mask) / BLI_rctf_size_y(&ar->v2d.cur);
+ float stepx = BLI_rcti_size_x(&region->v2d.mask) / BLI_rctf_size_x(&region->v2d.cur);
+ float stepy = BLI_rcti_size_y(&region->v2d.mask) / BLI_rctf_size_y(&region->v2d.cur);
GPUVertFormat *format = immVertexFormat();
- unsigned int pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- unsigned color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
immBegin(GPU_PRIM_LINES, 8 * num_tiles);
@@ -849,20 +851,20 @@ static void draw_udim_tile_grids(ARegion *ar, SpaceImage *sima, Image *ima)
if (tile != cur_tile) {
int x = (tile->tile_number - 1001) % 10;
int y = (tile->tile_number - 1001) / 10;
- draw_udim_tile_grid(pos, color, ar, x, y, stepx, stepy, theme_color);
+ draw_udim_tile_grid(pos, color, region, x, y, stepx, stepy, theme_color);
}
}
if (cur_tile != NULL) {
int cur_x = (cur_tile->tile_number - 1001) % 10;
int cur_y = (cur_tile->tile_number - 1001) / 10;
- draw_udim_tile_grid(pos, color, ar, cur_x, cur_y, stepx, stepy, selected_color);
+ draw_udim_tile_grid(pos, color, region, cur_x, cur_y, stepx, stepy, selected_color);
}
}
else {
for (int y = 0; y < sima->tile_grid_shape[1]; y++) {
for (int x = 0; x < sima->tile_grid_shape[0]; x++) {
- draw_udim_tile_grid(pos, color, ar, x, y, stepx, stepy, theme_color);
+ draw_udim_tile_grid(pos, color, region, x, y, stepx, stepy, theme_color);
}
}
}
@@ -873,7 +875,7 @@ static void draw_udim_tile_grids(ARegion *ar, SpaceImage *sima, Image *ima)
/* draw main image region */
-void draw_image_main(const bContext *C, ARegion *ar)
+void draw_image_main(const bContext *C, ARegion *region)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
@@ -905,7 +907,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
/* retrieve the image and information about it */
ima = ED_space_image(sima);
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ ED_space_image_get_zoom(sima, region, &zoomx, &zoomy);
/* Tag image as in active use for garbage collector. */
if (ima) {
@@ -949,31 +951,31 @@ void draw_image_main(const bContext *C, ARegion *ar)
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
int x = (tile->tile_number - 1001) % 10;
int y = (tile->tile_number - 1001) / 10;
- ED_region_grid_draw(ar, zoomx, zoomy, x, y);
+ ED_region_grid_draw(region, zoomx, zoomy, x, y);
}
}
else {
for (int y = 0; y < sima->tile_grid_shape[1]; y++) {
for (int x = 0; x < sima->tile_grid_shape[0]; x++) {
- ED_region_grid_draw(ar, zoomx, zoomy, x, y);
+ ED_region_grid_draw(region, zoomx, zoomy, x, y);
}
}
}
}
else {
if (sima->flag & SI_DRAW_TILE) {
- draw_image_buffer_repeated(C, sima, ar, scene, ibuf, zoomx, zoomy);
+ draw_image_buffer_repeated(C, sima, region, scene, ibuf, zoomx, zoomy);
}
else {
main_w = ibuf->x;
main_h = ibuf->y;
- draw_image_buffer(C, sima, ar, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy);
+ draw_image_buffer(C, sima, region, scene, ibuf, 0.0f, 0.0f, zoomx, zoomy);
if (ima->source == IMA_SRC_TILED) {
ImageTile *tile = BKE_image_get_tile(ima, 0);
char label[sizeof(tile->label)];
BKE_image_get_tile_label(ima, tile, label, sizeof(label));
- draw_udim_label(ar, 0.0f, 0.0f, label);
+ draw_udim_label(region, 0.0f, 0.0f, label);
}
}
@@ -982,7 +984,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
rctf frame;
BLI_rctf_init(&frame, 0.0f, ibuf->x, 0.0f, ibuf->y);
- UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
+ UI_view2d_view_to_region(&region->v2d, 0.0f, 0.0f, &x, &y);
ED_region_image_metadata_draw(x, y, ibuf, &frame, zoomx, zoomy);
}
@@ -1005,18 +1007,18 @@ void draw_image_main(const bContext *C, ARegion *ar)
float tile_zoomx = (zoomx * main_w) / ibuf->x;
float tile_zoomy = (zoomy * main_h) / ibuf->y;
- draw_image_buffer(C, sima, ar, scene, ibuf, x_pos, y_pos, tile_zoomx, tile_zoomy);
- draw_udim_label(ar, x_pos, y_pos, label);
+ draw_image_buffer(C, sima, region, scene, ibuf, x_pos, y_pos, tile_zoomx, tile_zoomy);
+ draw_udim_label(region, x_pos, y_pos, label);
}
ED_space_image_release_buffer(sima, ibuf, lock);
}
}
- draw_udim_tile_grids(ar, sima, ima);
+ draw_udim_tile_grids(region, sima, ima);
/* paint helpers */
if (show_paint) {
- draw_image_paint_helpers(C, ar, scene, zoomx, zoomy);
+ draw_image_paint_helpers(C, region, scene, zoomx, zoomy);
}
if (show_viewer) {
@@ -1025,7 +1027,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
/* render info */
if (ima && show_render) {
- draw_render_info(C, sima->iuser.scene, ima, ar, zoomx, zoomy);
+ draw_render_info(C, sima->iuser.scene, ima, region, zoomx, zoomy);
}
}
@@ -1045,12 +1047,12 @@ bool ED_space_image_show_cache(SpaceImage *sima)
return true;
}
-void draw_image_cache(const bContext *C, ARegion *ar)
+void draw_image_cache(const bContext *C, ARegion *region)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
Image *image = ED_space_image(sima);
- float x, cfra = CFRA, sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
+ float x, cfra = CFRA, sfra = SFRA, efra = EFRA, framelen = region->winx / (efra - sfra + 1);
Mask *mask = NULL;
if (!ED_space_image_show_cache(sima)) {
@@ -1062,7 +1064,7 @@ void draw_image_cache(const bContext *C, ARegion *ar)
}
/* Local coordinate visible rect inside region, to accommodate overlapping ui. */
- const rcti *rect_visible = ED_region_visible_rect(ar);
+ const rcti *rect_visible = ED_region_visible_rect(region);
const int region_bottom = rect_visible->ymin;
GPU_blend(true);
@@ -1070,7 +1072,7 @@ void draw_image_cache(const bContext *C, ARegion *ar)
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
/* Draw cache background. */
- ED_region_cache_draw_background(ar);
+ ED_region_cache_draw_background(region);
/* Draw cached segments. */
if (image != NULL && image->cache != NULL &&
@@ -1080,13 +1082,13 @@ void draw_image_cache(const bContext *C, ARegion *ar)
IMB_moviecache_get_cache_segments(image->cache, IMB_PROXY_NONE, 0, &num_segments, &points);
ED_region_cache_draw_cached_segments(
- ar, num_segments, points, sfra + sima->iuser.offset, efra + sima->iuser.offset);
+ region, num_segments, points, sfra + sima->iuser.offset, efra + sima->iuser.offset);
}
GPU_blend(false);
/* Draw current frame. */
- x = (cfra - sfra) / (efra - sfra + 1) * ar->winx;
+ x = (cfra - sfra) / (efra - sfra + 1) * region->winx;
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
@@ -1098,6 +1100,6 @@ void draw_image_cache(const bContext *C, ARegion *ar)
ED_region_cache_draw_curfra_label(cfra, x, region_bottom + 8.0f * UI_DPI_FAC);
if (mask != NULL) {
- ED_mask_draw_frames(mask, ar, cfra, sfra, efra);
+ ED_mask_draw_frames(mask, region, cfra, sfra, efra);
}
}
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index c1ed049130e..7f911113b7c 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -26,15 +26,15 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BLI_rect.h"
#include "BLI_listbase.h"
+#include "BLI_rect.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_image.h"
-#include "BKE_library.h"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "IMB_imbuf_types.h"
@@ -175,6 +175,30 @@ void ED_space_image_release_buffer(SpaceImage *sima, ImBuf *ibuf, void *lock)
}
}
+/* Get the SpaceImage flag that is valid for the given ibuf. */
+int ED_space_image_get_display_channel_mask(ImBuf *ibuf)
+{
+ int result = (SI_USE_ALPHA | SI_SHOW_ALPHA | SI_SHOW_ZBUF | SI_SHOW_R | SI_SHOW_G | SI_SHOW_B);
+ if (!ibuf) {
+ return result;
+ }
+
+ const bool color = ibuf->channels >= 3;
+ const bool alpha = ibuf->channels == 4;
+ const bool zbuf = ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1);
+
+ if (!alpha) {
+ result &= ~(SI_USE_ALPHA | SI_SHOW_ALPHA);
+ }
+ if (!zbuf) {
+ result &= ~(SI_SHOW_ZBUF);
+ }
+ if (!color) {
+ result &= ~(SI_SHOW_R | SI_SHOW_G | SI_SHOW_B);
+ }
+ return result;
+}
+
bool ED_space_image_has_buffer(SpaceImage *sima)
{
ImBuf *ibuf;
@@ -188,7 +212,7 @@ bool ED_space_image_has_buffer(SpaceImage *sima)
return has_buffer;
}
-void ED_space_image_get_size(SpaceImage *sima, int *width, int *height)
+void ED_space_image_get_size(SpaceImage *sima, int *r_width, int *r_height)
{
Scene *scene = sima->iuser.scene;
ImBuf *ibuf;
@@ -198,107 +222,107 @@ void ED_space_image_get_size(SpaceImage *sima, int *width, int *height)
ibuf = ED_space_image_acquire_buffer(sima, &lock, 0);
if (ibuf && ibuf->x > 0 && ibuf->y > 0) {
- *width = ibuf->x;
- *height = ibuf->y;
+ *r_width = ibuf->x;
+ *r_height = ibuf->y;
}
else if (sima->image && sima->image->type == IMA_TYPE_R_RESULT && scene) {
/* not very important, just nice */
- *width = (scene->r.xsch * scene->r.size) / 100;
- *height = (scene->r.ysch * scene->r.size) / 100;
+ *r_width = (scene->r.xsch * scene->r.size) / 100;
+ *r_height = (scene->r.ysch * scene->r.size) / 100;
if ((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) {
- *width *= BLI_rctf_size_x(&scene->r.border);
- *height *= BLI_rctf_size_y(&scene->r.border);
+ *r_width *= BLI_rctf_size_x(&scene->r.border);
+ *r_height *= BLI_rctf_size_y(&scene->r.border);
}
}
/* I know a bit weak... but preview uses not actual image size */
- // XXX else if (image_preview_active(sima, width, height));
+ // XXX else if (image_preview_active(sima, r_width, r_height));
else {
- *width = IMG_SIZE_FALLBACK;
- *height = IMG_SIZE_FALLBACK;
+ *r_width = IMG_SIZE_FALLBACK;
+ *r_height = IMG_SIZE_FALLBACK;
}
ED_space_image_release_buffer(sima, ibuf, lock);
}
-void ED_space_image_get_size_fl(SpaceImage *sima, float size[2])
+void ED_space_image_get_size_fl(SpaceImage *sima, float r_size[2])
{
int size_i[2];
ED_space_image_get_size(sima, &size_i[0], &size_i[1]);
- size[0] = size_i[0];
- size[1] = size_i[1];
+ r_size[0] = size_i[0];
+ r_size[1] = size_i[1];
}
-void ED_space_image_get_aspect(SpaceImage *sima, float *aspx, float *aspy)
+void ED_space_image_get_aspect(SpaceImage *sima, float *r_aspx, float *r_aspy)
{
Image *ima = sima->image;
if ((ima == NULL) || (ima->aspx == 0.0f || ima->aspy == 0.0f)) {
- *aspx = *aspy = 1.0;
+ *r_aspx = *r_aspy = 1.0;
}
else {
- BKE_image_get_aspect(ima, aspx, aspy);
+ BKE_image_get_aspect(ima, r_aspx, r_aspy);
}
}
-void ED_space_image_get_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy)
+void ED_space_image_get_zoom(SpaceImage *sima, ARegion *region, float *r_zoomx, float *r_zoomy)
{
int width, height;
ED_space_image_get_size(sima, &width, &height);
- *zoomx = (float)(BLI_rcti_size_x(&ar->winrct) + 1) /
- (float)(BLI_rctf_size_x(&ar->v2d.cur) * width);
- *zoomy = (float)(BLI_rcti_size_y(&ar->winrct) + 1) /
- (float)(BLI_rctf_size_y(&ar->v2d.cur) * height);
+ *r_zoomx = (float)(BLI_rcti_size_x(&region->winrct) + 1) /
+ (float)(BLI_rctf_size_x(&region->v2d.cur) * width);
+ *r_zoomy = (float)(BLI_rcti_size_y(&region->winrct) + 1) /
+ (float)(BLI_rctf_size_y(&region->v2d.cur) * height);
}
-void ED_space_image_get_uv_aspect(SpaceImage *sima, float *aspx, float *aspy)
+void ED_space_image_get_uv_aspect(SpaceImage *sima, float *r_aspx, float *r_aspy)
{
int w, h;
- ED_space_image_get_aspect(sima, aspx, aspy);
+ ED_space_image_get_aspect(sima, r_aspx, r_aspy);
ED_space_image_get_size(sima, &w, &h);
- *aspx *= (float)w;
- *aspy *= (float)h;
+ *r_aspx *= (float)w;
+ *r_aspy *= (float)h;
- if (*aspx < *aspy) {
- *aspy = *aspy / *aspx;
- *aspx = 1.0f;
+ if (*r_aspx < *r_aspy) {
+ *r_aspy = *r_aspy / *r_aspx;
+ *r_aspx = 1.0f;
}
else {
- *aspx = *aspx / *aspy;
- *aspy = 1.0f;
+ *r_aspx = *r_aspx / *r_aspy;
+ *r_aspy = 1.0f;
}
}
-void ED_image_get_uv_aspect(Image *ima, ImageUser *iuser, float *aspx, float *aspy)
+void ED_image_get_uv_aspect(Image *ima, ImageUser *iuser, float *r_aspx, float *r_aspy)
{
if (ima) {
int w, h;
- BKE_image_get_aspect(ima, aspx, aspy);
+ BKE_image_get_aspect(ima, r_aspx, r_aspy);
BKE_image_get_size(ima, iuser, &w, &h);
- *aspx *= (float)w;
- *aspy *= (float)h;
+ *r_aspx *= (float)w;
+ *r_aspy *= (float)h;
}
else {
- *aspx = 1.0f;
- *aspy = 1.0f;
+ *r_aspx = 1.0f;
+ *r_aspy = 1.0f;
}
}
/* takes event->mval */
-void ED_image_mouse_pos(SpaceImage *sima, ARegion *ar, const int mval[2], float co[2])
+void ED_image_mouse_pos(SpaceImage *sima, ARegion *region, const int mval[2], float co[2])
{
int sx, sy, width, height;
float zoomx, zoomy;
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ ED_space_image_get_zoom(sima, region, &zoomx, &zoomy);
ED_space_image_get_size(sima, &width, &height);
- UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&region->v2d, 0.0f, 0.0f, &sx, &sy);
co[0] = ((mval[0] - sx) / zoomx) / width;
co[1] = ((mval[1] - sy) / zoomy) / height;
@@ -316,29 +340,33 @@ void ED_image_view_center_to_point(SpaceImage *sima, float x, float y)
sima->yof = (y - 0.5f) * height * aspy;
}
-void ED_image_point_pos(SpaceImage *sima, ARegion *ar, float x, float y, float *xr, float *yr)
+void ED_image_point_pos(
+ SpaceImage *sima, ARegion *region, float x, float y, float *r_x, float *r_y)
{
int sx, sy, width, height;
float zoomx, zoomy;
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ ED_space_image_get_zoom(sima, region, &zoomx, &zoomy);
ED_space_image_get_size(sima, &width, &height);
- UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&region->v2d, 0.0f, 0.0f, &sx, &sy);
- *xr = ((x - sx) / zoomx) / width;
- *yr = ((y - sy) / zoomy) / height;
+ *r_x = ((x - sx) / zoomx) / width;
+ *r_y = ((y - sy) / zoomy) / height;
}
-void ED_image_point_pos__reverse(SpaceImage *sima, ARegion *ar, const float co[2], float r_co[2])
+void ED_image_point_pos__reverse(SpaceImage *sima,
+ ARegion *region,
+ const float co[2],
+ float r_co[2])
{
float zoomx, zoomy;
int width, height;
int sx, sy;
- UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &sx, &sy);
+ UI_view2d_view_to_region(&region->v2d, 0.0f, 0.0f, &sx, &sy);
ED_space_image_get_size(sima, &width, &height);
- ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
+ ED_space_image_get_zoom(sima, region, &zoomx, &zoomy);
r_co[0] = (co[0] * width * zoomx) + (float)sx;
r_co[1] = (co[1] * height * zoomy) + (float)sy;
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index f3ec68db562..ae26363ad79 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -37,8 +37,8 @@ struct wmOperatorType;
extern const char *image_context_dir[]; /* doc access */
/* image_draw.c */
-void draw_image_main(const struct bContext *C, struct ARegion *ar);
-void draw_image_cache(const struct bContext *C, struct ARegion *ar);
+void draw_image_main(const struct bContext *C, struct ARegion *region);
+void draw_image_cache(const struct bContext *C, struct ARegion *region);
void draw_image_grease_pencil(struct bContext *C, bool onlyv2d);
void draw_image_sample_line(struct SpaceImage *sima);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 17c6f76a1d9..7bd1b8e8291 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -21,11 +21,11 @@
* \ingroup spimage
*/
-#include <stddef.h>
-#include <string.h>
+#include <errno.h>
#include <fcntl.h>
+#include <stddef.h>
#include <stdlib.h>
-#include <errno.h>
+#include <string.h>
#ifndef WIN32
# include <unistd.h>
#else
@@ -46,31 +46,31 @@
#include "BLT_translation.h"
#include "DNA_camera_types.h"
-#include "DNA_object_types.h"
#include "DNA_node_types.h"
+#include "DNA_object_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
+#include "BKE_global.h"
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_image_save.h"
-#include "BKE_global.h"
-#include "BKE_library.h"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_packedFile.h"
#include "BKE_paint.h"
#include "BKE_report.h"
-#include "BKE_screen.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "GPU_draw.h"
-#include "GPU_state.h"
#include "GPU_immediate.h"
+#include "GPU_state.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@@ -90,8 +90,8 @@
#include "ED_render.h"
#include "ED_screen.h"
#include "ED_space_api.h"
-#include "ED_uvedit.h"
#include "ED_util.h"
+#include "ED_uvedit.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -111,7 +111,7 @@
* \{ */
static void sima_zoom_set(
- SpaceImage *sima, ARegion *ar, float zoom, const float location[2], const bool zoom_to_pos)
+ SpaceImage *sima, ARegion *region, float zoom, const float location[2], const bool zoom_to_pos)
{
float oldzoom = sima->zoom;
int width, height;
@@ -128,10 +128,10 @@ static void sima_zoom_set(
if ((width < 4) && (height < 4) && sima->zoom < oldzoom) {
sima->zoom = oldzoom;
}
- else if (BLI_rcti_size_x(&ar->winrct) <= sima->zoom) {
+ else if (BLI_rcti_size_x(&region->winrct) <= sima->zoom) {
sima->zoom = oldzoom;
}
- else if (BLI_rcti_size_y(&ar->winrct) <= sima->zoom) {
+ else if (BLI_rcti_size_y(&region->winrct) <= sima->zoom) {
sima->zoom = oldzoom;
}
}
@@ -150,16 +150,19 @@ static void sima_zoom_set(
}
}
-static void sima_zoom_set_factor(
- SpaceImage *sima, ARegion *ar, float zoomfac, const float location[2], const bool zoom_to_pos)
+static void sima_zoom_set_factor(SpaceImage *sima,
+ ARegion *region,
+ float zoomfac,
+ const float location[2],
+ const bool zoom_to_pos)
{
- sima_zoom_set(sima, ar, sima->zoom * zoomfac, location, zoom_to_pos);
+ sima_zoom_set(sima, region, sima->zoom * zoomfac, location, zoom_to_pos);
}
/**
* Fits the view to the bounds exactly, caller should add margin if needed.
*/
-static void sima_zoom_set_from_bounds(SpaceImage *sima, ARegion *ar, const rctf *bounds)
+static void sima_zoom_set_from_bounds(SpaceImage *sima, ARegion *region, const rctf *bounds)
{
int image_size[2];
float aspx, aspy;
@@ -175,13 +178,13 @@ static void sima_zoom_set_from_bounds(SpaceImage *sima, ARegion *ar, const rctf
sima->yof = roundf((BLI_rctf_cent_y(bounds) - 0.5f) * image_size[1]);
float size_xy[2], size;
- size_xy[0] = BLI_rcti_size_x(&ar->winrct) / (BLI_rctf_size_x(bounds) * image_size[0]);
- size_xy[1] = BLI_rcti_size_y(&ar->winrct) / (BLI_rctf_size_y(bounds) * image_size[1]);
+ size_xy[0] = BLI_rcti_size_x(&region->winrct) / (BLI_rctf_size_x(bounds) * image_size[0]);
+ size_xy[1] = BLI_rcti_size_y(&region->winrct) / (BLI_rctf_size_y(bounds) * image_size[1]);
size = min_ff(size_xy[0], size_xy[1]);
CLAMP_MAX(size, 100.0f);
- sima_zoom_set(sima, ar, size, NULL, false);
+ sima_zoom_set(sima, region, size, NULL, false);
}
static Image *image_from_context(const bContext *C)
@@ -235,7 +238,7 @@ static bool image_from_context_has_data_poll(bContext *C)
/**
* Use this when the image buffer is accessed without the image user.
*/
-static bool image_from_contect_has_data_poll_no_image_user(bContext *C)
+static bool image_from_context_has_data_poll_no_image_user(bContext *C)
{
Image *ima = image_from_context(C);
@@ -252,10 +255,10 @@ static bool image_not_packed_poll(bContext *C)
bool space_image_main_region_poll(bContext *C)
{
SpaceImage *sima = CTX_wm_space_image(C);
- /* XXX ARegion *ar = CTX_wm_region(C); */
+ /* XXX ARegion *region = CTX_wm_region(C); */
if (sima) {
- return true; /* XXX (ar && ar->type->regionid == RGN_TYPE_WINDOW); */
+ return true; /* XXX (region && region->type->regionid == RGN_TYPE_WINDOW); */
}
return false;
}
@@ -462,14 +465,14 @@ typedef struct ViewZoomData {
/* */
SpaceImage *sima;
- ARegion *ar;
+ ARegion *region;
} ViewZoomData;
static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
ViewZoomData *vpd;
op->customdata = vpd = MEM_callocN(sizeof(ViewZoomData), "ImageViewZoomData");
@@ -486,7 +489,7 @@ static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *eve
vpd->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
UI_view2d_region_to_view(
- &ar->v2d, event->mval[0], event->mval[1], &vpd->location[0], &vpd->location[1]);
+ &region->v2d, event->mval[0], event->mval[1], &vpd->location[0], &vpd->location[1]);
if (U.viewzoom == USER_ZOOM_CONT) {
/* needs a timer to continue redrawing */
@@ -495,7 +498,7 @@ static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *eve
}
vpd->sima = sima;
- vpd->ar = ar;
+ vpd->region = region;
WM_event_add_modal_handler(C, op);
}
@@ -523,11 +526,11 @@ static void image_view_zoom_exit(bContext *C, wmOperator *op, bool cancel)
static int image_view_zoom_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
- sima_zoom_set_factor(sima, ar, RNA_float_get(op->ptr, "factor"), NULL, false);
+ sima_zoom_set_factor(sima, region, RNA_float_get(op->ptr, "factor"), NULL, false);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -542,10 +545,11 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
{
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
float delta, factor, location[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
+ UI_view2d_region_to_view(
+ &region->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
delta = event->prevx - event->x + event->prevy - event->y;
@@ -557,11 +561,11 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
RNA_float_set(op->ptr, "factor", factor);
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
sima_zoom_set(sima,
- ar,
+ region,
sima->zoom * factor,
location,
(use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -616,8 +620,8 @@ static void image_zoom_apply(ViewZoomData *vpd,
}
RNA_float_set(op->ptr, "factor", factor);
- sima_zoom_set(vpd->sima, vpd->ar, vpd->zoom * factor, vpd->location, zoom_to_pos);
- ED_region_tag_redraw(vpd->ar);
+ sima_zoom_set(vpd->sima, vpd->region, vpd->zoom * factor, vpd->location, zoom_to_pos);
+ ED_region_tag_redraw(vpd->region);
}
static int image_view_zoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
@@ -715,7 +719,7 @@ static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
}
else {
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
float pan_vec[3];
const wmNDOFMotionData *ndof = event->customdata;
@@ -726,11 +730,11 @@ static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
mul_v2_fl(pan_vec, (speed * ndof->dt) / sima->zoom);
pan_vec[2] *= -ndof->dt;
- sima_zoom_set_factor(sima, ar, 1.0f + pan_vec[2], NULL, false);
+ sima_zoom_set_factor(sima, region, 1.0f + pan_vec[2], NULL, false);
sima->xof += pan_vec[0];
sima->yof += pan_vec[1];
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -766,14 +770,14 @@ void IMAGE_OT_view_ndof(wmOperatorType *ot)
static int image_view_all_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima;
- ARegion *ar;
+ ARegion *region;
float aspx, aspy, zoomx, zoomy, w, h;
int width, height;
const bool fit_view = RNA_boolean_get(op->ptr, "fit_view");
/* retrieve state */
sima = CTX_wm_space_image(C);
- ar = CTX_wm_region(C);
+ region = CTX_wm_region(C);
ED_space_image_get_size(sima, &width, &height);
ED_space_image_get_aspect(sima, &aspx, &aspy);
@@ -781,9 +785,32 @@ static int image_view_all_exec(bContext *C, wmOperator *op)
w = width * aspx;
h = height * aspy;
+ float xof = 0.0f, yof = 0.0f;
+ if ((sima->image == NULL) || (sima->image->source == IMA_SRC_TILED)) {
+ /* Extend the shown area to cover all UDIM tiles. */
+ int x_tiles, y_tiles;
+ if (sima->image == NULL) {
+ x_tiles = sima->tile_grid_shape[0];
+ y_tiles = sima->tile_grid_shape[1];
+ }
+ else {
+ x_tiles = y_tiles = 1;
+ LISTBASE_FOREACH (ImageTile *, tile, &sima->image->tiles) {
+ int tile_x = (tile->tile_number - 1001) % 10;
+ int tile_y = (tile->tile_number - 1001) / 10;
+ x_tiles = max_ii(x_tiles, tile_x + 1);
+ y_tiles = max_ii(y_tiles, tile_y + 1);
+ }
+ }
+ xof = 0.5f * (x_tiles - 1.0f) * w;
+ yof = 0.5f * (y_tiles - 1.0f) * h;
+ w *= x_tiles;
+ h *= y_tiles;
+ }
+
/* check if the image will fit in the image with (zoom == 1) */
- width = BLI_rcti_size_x(&ar->winrct) + 1;
- height = BLI_rcti_size_y(&ar->winrct) + 1;
+ width = BLI_rcti_size_x(&region->winrct) + 1;
+ height = BLI_rcti_size_y(&region->winrct) + 1;
if (fit_view) {
const int margin = 5; /* margin from border */
@@ -791,7 +818,7 @@ static int image_view_all_exec(bContext *C, wmOperator *op)
zoomx = (float)width / (w + 2 * margin);
zoomy = (float)height / (h + 2 * margin);
- sima_zoom_set(sima, ar, min_ff(zoomx, zoomy), NULL, false);
+ sima_zoom_set(sima, region, min_ff(zoomx, zoomy), NULL, false);
}
else {
if ((w >= width || h >= height) && (width > 0 && height > 0)) {
@@ -799,16 +826,17 @@ static int image_view_all_exec(bContext *C, wmOperator *op)
zoomy = (float)height / h;
/* find the zoom value that will fit the image in the image space */
- sima_zoom_set(sima, ar, 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy)), NULL, false);
+ sima_zoom_set(sima, region, 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy)), NULL, false);
}
else {
- sima_zoom_set(sima, ar, 1.0f, NULL, false);
+ sima_zoom_set(sima, region, 1.0f, NULL, false);
}
}
- sima->xof = sima->yof = 0.0f;
+ sima->xof = xof;
+ sima->yof = yof;
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -843,11 +871,11 @@ void IMAGE_OT_view_all(wmOperatorType *ot)
static int view_center_cursor_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
ED_image_view_center_to_point(sima, sima->cursor[0], sima->cursor[1]);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -867,13 +895,13 @@ void IMAGE_OT_view_center_cursor(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name View Selected Operator
+/** \name Frame Selected Operator
* \{ */
static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceImage *sima;
- ARegion *ar;
+ ARegion *region;
Scene *scene;
ViewLayer *view_layer;
Object *obedit;
@@ -881,7 +909,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
/* retrieve state */
sima = CTX_wm_space_image(C);
- ar = CTX_wm_region(C);
+ region = CTX_wm_region(C);
scene = CTX_data_scene(C);
view_layer = CTX_data_view_layer(C);
obedit = CTX_data_edit_object(C);
@@ -910,9 +938,9 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
/* add some margin */
BLI_rctf_scale(&bounds, 1.4f);
- sima_zoom_set_from_bounds(sima, ar, &bounds);
+ sima_zoom_set_from_bounds(sima, region, &bounds);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -943,25 +971,26 @@ void IMAGE_OT_view_selected(wmOperatorType *ot)
static int image_view_zoom_in_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
float location[2];
RNA_float_get_array(op->ptr, "location", location);
sima_zoom_set_factor(
- sima, ar, powf(2.0f, 1.0f / 3.0f), location, U.uiflag & USER_ZOOM_TO_MOUSEPOS);
+ sima, region, powf(2.0f, 1.0f / 3.0f), location, U.uiflag & USER_ZOOM_TO_MOUSEPOS);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
static int image_view_zoom_in_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
float location[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
+ UI_view2d_region_to_view(
+ &region->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
RNA_float_set_array(op->ptr, "location", location);
return image_view_zoom_in_exec(C, op);
@@ -1001,25 +1030,26 @@ void IMAGE_OT_view_zoom_in(wmOperatorType *ot)
static int image_view_zoom_out_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
float location[2];
RNA_float_get_array(op->ptr, "location", location);
sima_zoom_set_factor(
- sima, ar, powf(0.5f, 1.0f / 3.0f), location, U.uiflag & USER_ZOOM_TO_MOUSEPOS);
+ sima, region, powf(0.5f, 1.0f / 3.0f), location, U.uiflag & USER_ZOOM_TO_MOUSEPOS);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
static int image_view_zoom_out_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
float location[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
+ UI_view2d_region_to_view(
+ &region->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
RNA_float_set_array(op->ptr, "location", location);
return image_view_zoom_out_exec(C, op);
@@ -1065,15 +1095,15 @@ void IMAGE_OT_view_zoom_out(wmOperatorType *ot)
static int image_view_zoom_ratio_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
- sima_zoom_set(sima, ar, RNA_float_get(op->ptr, "ratio"), NULL, false);
+ sima_zoom_set(sima, region, RNA_float_get(op->ptr, "ratio"), NULL, false);
/* ensure pixel exact locations for draw */
sima->xof = (int)sima->xof;
sima->yof = (int)sima->yof;
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -1113,13 +1143,13 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
static int image_view_zoom_border_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
rctf bounds;
const bool zoom_in = !RNA_boolean_get(op->ptr, "zoom_out");
WM_operator_properties_border_to_rctf(op, &bounds);
- UI_view2d_region_to_view_rctf(&ar->v2d, &bounds, &bounds);
+ UI_view2d_region_to_view_rctf(&region->v2d, &bounds, &bounds);
const struct {
float xof;
@@ -1131,7 +1161,7 @@ static int image_view_zoom_border_exec(bContext *C, wmOperator *op)
.zoom = sima->zoom,
};
- sima_zoom_set_from_bounds(sima, ar, &bounds);
+ sima_zoom_set_from_bounds(sima, region, &bounds);
/* zoom out */
if (!zoom_in) {
@@ -1140,7 +1170,7 @@ static int image_view_zoom_border_exec(bContext *C, wmOperator *op)
sima->zoom = sima_view_prev.zoom * (sima_view_prev.zoom / sima->zoom);
}
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
}
@@ -1183,18 +1213,6 @@ typedef struct ImageOpenData {
ImageFormatData im_format;
} ImageOpenData;
-typedef struct ImageFrameRange {
- struct ImageFrameRange *next, *prev;
- ListBase frames;
- /** The full path of the first file in the list of image files */
- char filepath[FILE_MAX];
-} ImageFrameRange;
-
-typedef struct ImageFrame {
- struct ImageFrame *next, *prev;
- int framenr;
-} ImageFrame;
-
static void image_open_init(bContext *C, wmOperator *op)
{
ImageOpenData *iod;
@@ -1209,179 +1227,18 @@ static void image_open_cancel(bContext *UNUSED(C), wmOperator *op)
op->customdata = NULL;
}
-/**
- * Get a list of frames from the list of image files matching the first file name sequence pattern.
- * \param ptr[in]: The RNA pointer containing the "directory" entry and "files" collection.
- * \param frames_all[out]: the list of frame numbers found in the files matching
- * the first one by name.
- */
-static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_all)
-{
- char dir[FILE_MAXDIR];
- const bool do_frame_range = RNA_boolean_get(ptr, "use_sequence_detection");
- ImageFrameRange *frame_range = NULL;
-
- RNA_string_get(ptr, "directory", dir);
- RNA_BEGIN (ptr, itemptr, "files") {
- char base_head[FILE_MAX], base_tail[FILE_MAX];
- char head[FILE_MAX], tail[FILE_MAX];
- unsigned short digits;
- char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
- ImageFrame *frame = MEM_callocN(sizeof(ImageFrame), "image_frame");
-
- /* use the first file in the list as base filename */
- frame->framenr = BLI_stringdec(filename, head, tail, &digits);
-
- /* still in the same sequence */
- if (do_frame_range && (frame_range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) &&
- (STREQLEN(base_tail, tail, FILE_MAX))) {
- /* pass */
- }
- else {
- /* start a new frame range */
- frame_range = MEM_callocN(sizeof(*frame_range), __func__);
- BLI_join_dirfile(frame_range->filepath, sizeof(frame_range->filepath), dir, filename);
- BLI_addtail(frames_all, frame_range);
-
- BLI_strncpy(base_head, head, sizeof(base_head));
- BLI_strncpy(base_tail, tail, sizeof(base_tail));
- }
-
- BLI_addtail(&frame_range->frames, frame);
- MEM_freeN(filename);
- }
- RNA_END;
-}
-
-static int image_cmp_frame(const void *a, const void *b)
-{
- const ImageFrame *frame_a = a;
- const ImageFrame *frame_b = b;
-
- if (frame_a->framenr < frame_b->framenr) {
- return -1;
- }
- if (frame_a->framenr > frame_b->framenr) {
- return 1;
- }
- return 0;
-}
-
-/* Checks whether the given filepath refers to a UDIM texture.
- * If yes, the range from 1001 to the highest tile is returned, otherwise 0.
- *
- * If the result is positive, the filepath will be overwritten with that of
- * the 1001 tile.
- * udim_tiles may get filled even if the result ultimately is false! */
-static int image_get_udim(char *filepath, LinkNodePair *udim_tiles)
-{
- char filename[FILE_MAX], dirname[FILE_MAXDIR];
- BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
-
- unsigned short digits;
- char base_head[FILE_MAX], base_tail[FILE_MAX];
- int id = BLI_stringdec(filename, base_head, base_tail, &digits);
-
- if (id < 1001 || id >= IMA_UDIM_MAX) {
- return 0;
- }
-
- bool is_udim = true;
- bool has_primary = false;
- int max_udim = 0;
-
- struct direntry *dir;
- uint totfile = BLI_filelist_dir_contents(dirname, &dir);
- for (int i = 0; i < totfile; i++) {
- if (!(dir[i].type & S_IFREG)) {
- continue;
- }
- char head[FILE_MAX], tail[FILE_MAX];
- id = BLI_stringdec(dir[i].relname, head, tail, &digits);
-
- if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
- !(STREQLEN(base_tail, tail, FILE_MAX))) {
- continue;
- }
-
- if (id < 1001 || id >= IMA_UDIM_MAX) {
- is_udim = false;
- break;
- }
- if (id == 1001) {
- has_primary = true;
- }
-
- BLI_linklist_append(udim_tiles, POINTER_FROM_INT(id));
- max_udim = max_ii(max_udim, id);
- }
- BLI_filelist_free(dir, totfile);
-
- if (is_udim && has_primary) {
- char primary_filename[FILE_MAX];
- BLI_stringenc(primary_filename, base_head, base_tail, digits, 1001);
- BLI_join_dirfile(filepath, FILE_MAX, dirname, primary_filename);
- return max_udim - 1000;
- }
- return 0;
-}
-
-/**
- * Return the start (offset) and the length of the sequence of
- * continuous frames in the list of frames.
- *
- * \param frames: [in] the list of frame numbers, as a side-effect the list is sorted.
- * \param ofs: [out] offset the first frame number in the sequence.
- * \return the number of contiguous frames in the sequence
- */
-static int image_sequence_get_len(ImageFrameRange *frame_range,
- int *ofs,
- char *filepath_range,
- LinkNodePair *udim_tiles)
-{
- ImageFrame *frame;
-
- BLI_listbase_sort(&frame_range->frames, image_cmp_frame);
- BLI_strncpy(filepath_range, frame_range->filepath, FILE_MAX);
-
- frame = frame_range->frames.first;
- if (frame != NULL) {
- int frame_curr = frame->framenr;
- (*ofs) = frame_curr;
-
- if (udim_tiles != NULL) {
- int len_udim = image_get_udim(filepath_range, udim_tiles);
- if (len_udim > 0) {
- *ofs = 1001;
- return len_udim;
- }
- }
-
- while (frame != NULL && (frame->framenr == frame_curr)) {
- frame_curr++;
- frame = frame->next;
- }
- return frame_curr - (*ofs);
- }
- *ofs = 0;
- return 0;
-}
-
static Image *image_open_single(Main *bmain,
wmOperator *op,
- const char *filepath,
+ ImageFrameRange *range,
const char *relbase,
bool is_relative_path,
- bool use_multiview,
- int frame_seq_len,
- int frame_seq_ofs,
- LinkNodePair *udim_tiles)
+ bool use_multiview)
{
bool exists = false;
Image *ima = NULL;
errno = 0;
- ima = BKE_image_load_exists_ex(bmain, filepath, &exists);
+ ima = BKE_image_load_exists_ex(bmain, range->filepath, &exists);
if (!ima) {
if (op->customdata) {
@@ -1390,7 +1247,7 @@ static Image *image_open_single(Main *bmain,
BKE_reportf(op->reports,
RPT_ERROR,
"Cannot read '%s': %s",
- filepath,
+ range->filepath,
errno ? strerror(errno) : TIP_("unsupported image format"));
return NULL;
}
@@ -1415,11 +1272,11 @@ static Image *image_open_single(Main *bmain,
BKE_image_free_views(ima);
}
- if ((frame_seq_len > 1) && (ima->source == IMA_SRC_FILE)) {
- if (udim_tiles && frame_seq_ofs == 1001) {
+ if ((range->length > 1) && (ima->source == IMA_SRC_FILE)) {
+ if (range->udim_tiles.first && range->offset == 1001) {
ima->source = IMA_SRC_TILED;
- for (LinkNode *node = udim_tiles->list; node; node = node->next) {
- BKE_image_add_tile(ima, POINTER_AS_INT(node->link), NULL);
+ for (LinkData *node = range->udim_tiles.first; node; node = node->next) {
+ BKE_image_add_tile(ima, POINTER_AS_INT(node->data), NULL);
}
}
else {
@@ -1440,7 +1297,6 @@ static int image_open_exec(bContext *C, wmOperator *op)
ImageUser *iuser = NULL;
ImageOpenData *iod = op->customdata;
Image *ima = NULL;
- char filepath[FILE_MAX];
int frame_seq_len = 0;
int frame_ofs = 1;
@@ -1452,83 +1308,21 @@ static int image_open_exec(bContext *C, wmOperator *op)
image_open_init(C, op);
}
- RNA_string_get(op->ptr, "filepath", filepath);
-
- if (RNA_struct_property_is_set(op->ptr, "directory") &&
- RNA_struct_property_is_set(op->ptr, "files")) {
- bool was_relative = BLI_path_is_rel(filepath);
- ListBase frame_ranges_all;
-
- BLI_listbase_clear(&frame_ranges_all);
- image_sequence_get_frame_ranges(op->ptr, &frame_ranges_all);
- for (ImageFrameRange *frame_range = frame_ranges_all.first; frame_range;
- frame_range = frame_range->next) {
- int frame_range_ofs;
+ ListBase ranges = ED_image_filesel_detect_sequences(bmain, op, use_udim);
+ for (ImageFrameRange *range = ranges.first; range; range = range->next) {
+ Image *ima_range = image_open_single(
+ bmain, op, range, BKE_main_blendfile_path(bmain), is_relative_path, use_multiview);
- LinkNodePair udim_tiles = {NULL};
- LinkNodePair *udim_tiles_ptr = use_udim ? (&udim_tiles) : NULL;
-
- char filepath_range[FILE_MAX];
- int frame_range_seq_len = image_sequence_get_len(
- frame_range, &frame_range_ofs, filepath_range, udim_tiles_ptr);
- BLI_freelistN(&frame_range->frames);
-
- if (was_relative) {
- BLI_path_rel(filepath_range, BKE_main_blendfile_path(bmain));
- }
-
- Image *ima_range = image_open_single(bmain,
- op,
- filepath_range,
- BKE_main_blendfile_path(bmain),
- is_relative_path,
- use_multiview,
- frame_range_seq_len,
- frame_range_ofs,
- udim_tiles_ptr);
-
- /* take the first image */
- if ((ima == NULL) && ima_range) {
- ima = ima_range;
- frame_seq_len = frame_range_seq_len;
- frame_ofs = frame_range_ofs;
- }
-
- BLI_linklist_free(udim_tiles.list, NULL);
+ /* take the first image */
+ if ((ima == NULL) && ima_range) {
+ ima = ima_range;
+ frame_seq_len = range->length;
+ frame_ofs = range->offset;
}
- BLI_freelistN(&frame_ranges_all);
- }
- else {
- /* for drag & drop etc. */
-
- LinkNodePair udim_tiles = {NULL};
- frame_seq_len = 1;
- char filepath_range[FILE_MAX];
- BLI_strncpy(filepath_range, filepath, FILE_MAX);
-
- if (use_udim > 0) {
- /* Try to find UDIM tiles corresponding to the image */
- int udim_len = image_get_udim(filepath_range, &udim_tiles);
-
- /* If we found something, mark the image as tiled. */
- if (udim_len) {
- frame_seq_len = udim_len;
- frame_ofs = 1001;
- }
- }
-
- ima = image_open_single(bmain,
- op,
- filepath_range,
- BKE_main_blendfile_path(bmain),
- is_relative_path,
- use_multiview,
- frame_seq_len,
- frame_ofs,
- &udim_tiles);
- BLI_linklist_free(udim_tiles.list, NULL);
+ BLI_freelistN(&range->udim_tiles);
}
+ BLI_freelistN(&ranges);
if (ima == NULL) {
return OPERATOR_CANCELLED;
@@ -1877,6 +1671,12 @@ void IMAGE_OT_replace(wmOperatorType *ot)
/** \name Save Image As Operator
* \{ */
+typedef struct ImageSaveData {
+ ImageUser *iuser;
+ Image *image;
+ ImageFormatData im_format;
+} ImageSaveData;
+
static char imtype_best_depth(ImBuf *ibuf, const char imtype)
{
const char depth_ok = BKE_imtype_valid_depths(imtype);
@@ -1956,9 +1756,6 @@ static int image_save_options_init(Main *bmain,
opts->im_format.views_format = ima->views_format;
}
- ///* XXX - this is lame, we need to make these available too! */
- // opts->subimtype = scene->r.subimtype;
-
BLI_strncpy(opts->filepath, ibuf->name, sizeof(opts->filepath));
/* sanitize all settings */
@@ -2006,6 +1803,8 @@ static int image_save_options_init(Main *bmain,
/* color management */
BKE_color_managed_display_settings_copy(&opts->im_format.display_settings,
&scene->display_settings);
+
+ BKE_color_managed_view_settings_free(&opts->im_format.view_settings);
BKE_color_managed_view_settings_copy(&opts->im_format.view_settings, &scene->view_settings);
}
@@ -2014,12 +1813,14 @@ static int image_save_options_init(Main *bmain,
return (ibuf != NULL);
}
-static void image_save_options_from_op(Main *bmain, ImageSaveOptions *opts, wmOperator *op)
+static void image_save_options_from_op(Main *bmain,
+ ImageSaveOptions *opts,
+ wmOperator *op,
+ ImageFormatData *imf)
{
- if (op->customdata) {
+ if (imf) {
BKE_color_managed_view_settings_free(&opts->im_format.view_settings);
-
- opts->im_format = *(ImageFormatData *)op->customdata;
+ opts->im_format = *imf;
}
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
@@ -2031,20 +1832,17 @@ static void image_save_options_from_op(Main *bmain, ImageSaveOptions *opts, wmOp
static void image_save_options_to_op(ImageSaveOptions *opts, wmOperator *op)
{
if (op->customdata) {
- BKE_color_managed_view_settings_free(&((ImageFormatData *)op->customdata)->view_settings);
-
- *(ImageFormatData *)op->customdata = opts->im_format;
+ ImageSaveData *isd = op->customdata;
+ BKE_color_managed_view_settings_free(&isd->im_format.view_settings);
+ isd->im_format = opts->im_format;
}
RNA_string_set(op->ptr, "filepath", opts->filepath);
}
-static bool save_image_op(const bContext *C, wmOperator *op, ImageSaveOptions *opts)
+static bool save_image_op(
+ Main *bmain, Image *ima, ImageUser *iuser, wmOperator *op, ImageSaveOptions *opts)
{
- Main *bmain = CTX_data_main(C);
- Image *ima = image_from_context(C);
- ImageUser *iuser = image_user_from_context(C);
-
opts->relative = (RNA_struct_find_property(op->ptr, "relative_path") &&
RNA_boolean_get(op->ptr, "relative_path"));
opts->save_copy = (RNA_struct_find_property(op->ptr, "copy") &&
@@ -2061,7 +1859,7 @@ static bool save_image_op(const bContext *C, wmOperator *op, ImageSaveOptions *o
/* Remember file path for next save. */
BLI_strncpy(G.ima, opts->filepath, sizeof(G.ima));
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+ WM_main_add_notifier(NC_IMAGE | NA_EDITED, ima);
return ok;
}
@@ -2069,8 +1867,8 @@ static bool save_image_op(const bContext *C, wmOperator *op, ImageSaveOptions *o
static void image_save_as_free(wmOperator *op)
{
if (op->customdata) {
- ImageFormatData *im_format = (ImageFormatData *)op->customdata;
- BKE_color_managed_view_settings_free(&im_format->view_settings);
+ ImageSaveData *isd = op->customdata;
+ BKE_color_managed_view_settings_free(&isd->im_format.view_settings);
MEM_freeN(op->customdata);
op->customdata = NULL;
@@ -2081,20 +1879,32 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Image *image = image_from_context(C);
- ImageUser *iuser = image_user_from_context(C);
ImageSaveOptions opts;
+ Image *image = NULL;
+ ImageUser *iuser = NULL;
+ ImageFormatData *imf = NULL;
+ if (op->customdata) {
+ ImageSaveData *isd = op->customdata;
+ image = isd->image;
+ iuser = isd->iuser;
+ imf = &isd->im_format;
+ }
+ else {
+ image = image_from_context(C);
+ iuser = image_user_from_context(C);
+ }
+
BKE_image_save_options_init(&opts, bmain, scene);
/* just in case to initialize values,
* these should be set on invoke or by the caller. */
image_save_options_init(bmain, &opts, image, iuser, false, false);
- image_save_options_from_op(bmain, &opts, op);
+ image_save_options_from_op(bmain, &opts, op, imf);
opts.do_newpath = true;
- save_image_op(C, op, &opts);
+ save_image_op(bmain, image, iuser, op, &opts);
if (opts.save_copy == false) {
BKE_image_free_packedfiles(image);
@@ -2107,8 +1917,8 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
static bool image_save_as_check(bContext *UNUSED(C), wmOperator *op)
{
- ImageFormatData *imf = op->customdata;
- return WM_operator_filesel_ensure_ext_imtype(op, imf);
+ ImageSaveData *isd = op->customdata;
+ return WM_operator_filesel_ensure_ext_imtype(op, &isd->im_format);
}
static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -2140,8 +1950,12 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
RNA_boolean_set(op->ptr, "save_as_render", save_as_render);
- op->customdata = MEM_mallocN(sizeof(opts.im_format), __func__);
- memcpy(op->customdata, &opts.im_format, sizeof(opts.im_format));
+ ImageSaveData *isd = MEM_callocN(sizeof(*isd), __func__);
+ isd->image = ima;
+ isd->iuser = iuser;
+
+ memcpy(&isd->im_format, &opts.im_format, sizeof(opts.im_format));
+ op->customdata = isd;
/* show multiview save options only if image has multiviews */
prop = RNA_struct_find_property(op->ptr, "show_multiview");
@@ -2174,12 +1988,12 @@ static bool image_save_as_draw_check_prop(PointerRNA *ptr,
static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
{
uiLayout *layout = op->layout;
- ImageFormatData *imf = op->customdata;
+ ImageSaveData *isd = op->customdata;
PointerRNA imf_ptr, ptr;
const bool is_multiview = RNA_boolean_get(op->ptr, "show_multiview");
/* image template */
- RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
+ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &isd->im_format, &imf_ptr);
uiTemplateImageSettings(layout, &imf_ptr, false);
/* main draw call */
@@ -2319,6 +2133,7 @@ static int image_save_exec(bContext *C, wmOperator *op)
ImageUser *iuser = image_user_from_context(C);
Scene *scene = CTX_data_scene(C);
ImageSaveOptions opts;
+ bool ok = false;
if (BKE_image_has_packedfile(image)) {
/* Save packed files to memory. */
@@ -2330,21 +2145,28 @@ static int image_save_exec(bContext *C, wmOperator *op)
if (image_save_options_init(bmain, &opts, image, iuser, false, false) == 0) {
return OPERATOR_CANCELLED;
}
- image_save_options_from_op(bmain, &opts, op);
+ image_save_options_from_op(bmain, &opts, op, NULL);
if (BLI_exists(opts.filepath) && BLI_file_is_writable(opts.filepath)) {
- if (save_image_op(C, op, &opts)) {
+ if (save_image_op(bmain, image, iuser, op, &opts)) {
/* report since this can be called from key-shortcuts */
BKE_reportf(op->reports, RPT_INFO, "Saved Image '%s'", opts.filepath);
+ ok = true;
}
}
else {
BKE_reportf(
op->reports, RPT_ERROR, "Cannot save image, path '%s' is not writable", opts.filepath);
- return OPERATOR_CANCELLED;
}
- return OPERATOR_FINISHED;
+ BKE_color_managed_view_settings_free(&opts.im_format.view_settings);
+
+ if (ok) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static int image_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -2486,7 +2308,7 @@ static bool image_should_be_saved_when_modified(Image *ima)
static bool image_should_be_saved(Image *ima, bool *is_format_writable)
{
if (BKE_image_is_dirty_writable(ima, is_format_writable) &&
- (ima->source == IMA_SRC_FILE || ima->source == IMA_SRC_GENERATED)) {
+ ELEM(ima->source, IMA_SRC_FILE, IMA_SRC_GENERATED, IMA_SRC_TILED)) {
return image_should_be_saved_when_modified(ima);
}
else {
@@ -2499,12 +2321,12 @@ static bool image_has_valid_path(Image *ima)
return strchr(ima->name, '\\') || strchr(ima->name, '/');
}
-bool ED_image_should_save_modified(const bContext *C)
+bool ED_image_should_save_modified(const Main *bmain)
{
ReportList reports;
BKE_reports_init(&reports, RPT_STORE);
- uint modified_images_count = ED_image_save_all_modified_info(C, &reports);
+ uint modified_images_count = ED_image_save_all_modified_info(bmain, &reports);
bool should_save = modified_images_count || !BLI_listbase_is_empty(&reports.list);
BKE_reports_clear(&reports);
@@ -2512,9 +2334,8 @@ bool ED_image_should_save_modified(const bContext *C)
return should_save;
}
-int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
+int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports)
{
- Main *bmain = CTX_data_main(C);
GSet *unique_paths = BLI_gset_str_new(__func__);
int num_saveable_images = 0;
@@ -2530,7 +2351,7 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
else {
BKE_reportf(reports,
RPT_WARNING,
- "Packed library image: %s from library %s can't be saved",
+ "Packed library image can't be saved: \"%s\" from \"%s\"",
ima->id.name + 2,
ima->id.lib->name);
}
@@ -2538,7 +2359,7 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
else if (!is_format_writable) {
BKE_reportf(reports,
RPT_WARNING,
- "Image %s can't be saved automatically, must use a different file format",
+ "Image can't be saved, use a different file format: \"%s\"",
ima->id.name + 2);
}
else {
@@ -2547,7 +2368,7 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
if (BLI_gset_haskey(unique_paths, ima->name)) {
BKE_reportf(reports,
RPT_WARNING,
- "File path used by more than one saved image: %s",
+ "Multiple images can't be saved to an identical path: \"%s\"",
ima->name);
}
else {
@@ -2555,11 +2376,8 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
}
}
else {
- BKE_reportf(reports,
- RPT_WARNING,
- "Image %s can't be saved, no valid file path: %s",
- ima->id.name + 2,
- ima->name);
+ BKE_reportf(
+ reports, RPT_WARNING, "Image can't be saved, no valid file path: \"%s\"", ima->name);
}
}
}
@@ -2571,9 +2389,10 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
bool ED_image_save_all_modified(const bContext *C, ReportList *reports)
{
- ED_image_save_all_modified_info(C, reports);
-
Main *bmain = CTX_data_main(C);
+
+ ED_image_save_all_modified_info(bmain, reports);
+
bool ok = true;
for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
@@ -2601,7 +2420,7 @@ bool ED_image_save_all_modified(const bContext *C, ReportList *reports)
static bool image_save_all_modified_poll(bContext *C)
{
- int num_files = ED_image_save_all_modified_info(C, NULL);
+ int num_files = ED_image_save_all_modified_info(CTX_data_main(C), NULL);
return num_files > 0;
}
@@ -2797,7 +2616,7 @@ static int image_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
/* Better for user feedback. */
RNA_string_set(op->ptr, "name", DATA_(IMA_DEF_NAME));
- return WM_operator_props_dialog_popup(C, op, 300, 100);
+ return WM_operator_props_dialog_popup(C, op, 300);
}
static void image_new_draw(bContext *UNUSED(C), wmOperator *op)
@@ -2929,7 +2748,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, 0);
+ ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &sima->iuser);
if (is_paint) {
ED_imapaint_clear_partial_redraw();
@@ -3011,7 +2830,7 @@ void IMAGE_OT_invert(wmOperatorType *ot)
/* api callbacks */
ot->exec = image_invert_exec;
- ot->poll = image_from_contect_has_data_poll_no_image_user;
+ ot->poll = image_from_context_has_data_poll_no_image_user;
/* properties */
prop = RNA_def_boolean(ot->srna, "invert_r", 0, "Red", "Invert Red Channel");
@@ -3043,7 +2862,7 @@ static int image_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
RNA_property_int_set_array(op->ptr, prop, size);
BKE_image_release_ibuf(ima, ibuf, NULL);
}
- return WM_operator_props_dialog_popup(C, op, 200, 200);
+ return WM_operator_props_dialog_popup(C, op, 200);
}
static int image_scale_exec(bContext *C, wmOperator *op)
@@ -3073,7 +2892,7 @@ static int image_scale_exec(bContext *C, wmOperator *op)
RNA_property_int_set_array(op->ptr, prop, size);
}
- ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, 0);
+ ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &sima->iuser);
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
IMB_scaleImBuf(ibuf, size[0], size[1]);
@@ -3100,7 +2919,7 @@ void IMAGE_OT_resize(wmOperatorType *ot)
/* api callbacks */
ot->invoke = image_scale_invoke;
ot->exec = image_scale_exec;
- ot->poll = image_from_contect_has_data_poll_no_image_user;
+ ot->poll = image_from_context_has_data_poll_no_image_user;
/* properties */
RNA_def_int_vector(ot->srna, "size", 2, NULL, 1, INT_MAX, "Size", "", 1, SHRT_MAX);
@@ -3124,7 +2943,8 @@ static bool image_pack_test(bContext *C, wmOperator *op)
}
if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_TILED)) {
- BKE_report(op->reports, RPT_ERROR, "Packing movies or image sequences not supported");
+ BKE_report(
+ op->reports, RPT_ERROR, "Packing movies, image sequences or tiled images not supported");
return 0;
}
@@ -3174,14 +2994,15 @@ void IMAGE_OT_pack(wmOperatorType *ot)
static int image_unpack_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Image *ima = image_from_context(C);
int method = RNA_enum_get(op->ptr, "method");
- /* find the suppplied image by name */
+ /* find the supplied image by name */
if (RNA_struct_property_is_set(op->ptr, "id")) {
char imaname[MAX_ID_NAME - 2];
RNA_string_get(op->ptr, "id", imaname);
- ima = BLI_findstring(&CTX_data_main(C)->images, imaname, offsetof(ID, name) + 2);
+ ima = BLI_findstring(&bmain->images, imaname, offsetof(ID, name) + 2);
if (!ima) {
ima = image_from_context(C);
}
@@ -3192,7 +3013,8 @@ static int image_unpack_exec(bContext *C, wmOperator *op)
}
if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_TILED)) {
- BKE_report(op->reports, RPT_ERROR, "Unpacking movies or image sequences not supported");
+ BKE_report(
+ op->reports, RPT_ERROR, "Unpacking movies, image sequences or tiled images not supported");
return OPERATOR_CANCELLED;
}
@@ -3225,7 +3047,8 @@ static int image_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
}
if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_TILED)) {
- BKE_report(op->reports, RPT_ERROR, "Unpacking movies or image sequences not supported");
+ BKE_report(
+ op->reports, RPT_ERROR, "Unpacking movies, image sequences or tiled images not supported");
return OPERATOR_CANCELLED;
}
@@ -3300,7 +3123,7 @@ typedef struct ImageSampleInfo {
int use_default_view;
} ImageSampleInfo;
-static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
+static void image_sample_draw(const bContext *C, ARegion *region, void *arg_info)
{
ImageSampleInfo *info = arg_info;
if (!info->draw) {
@@ -3309,7 +3132,7 @@ static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
Scene *scene = CTX_data_scene(C);
ED_image_draw_info(scene,
- ar,
+ region,
info->color_manage,
info->use_default_view,
info->channels,
@@ -3335,9 +3158,10 @@ static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
/* TODO(campbell): lock to pixels. */
rctf sample_rect_fl;
- BLI_rctf_init_pt_radius(&sample_rect_fl,
- (float[2]){event->x - ar->winrct.xmin, event->y - ar->winrct.ymin},
- (float)(info->sample_size / 2.0f) * sima->zoom);
+ BLI_rctf_init_pt_radius(
+ &sample_rect_fl,
+ (float[2]){event->x - region->winrct.xmin, event->y - region->winrct.ymin},
+ (float)(info->sample_size / 2.0f) * sima->zoom);
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(GL_XOR);
@@ -3354,13 +3178,13 @@ static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
}
/* Returns color in linear space, matching ED_space_node_color_sample(). */
-bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
+bool ED_space_image_color_sample(SpaceImage *sima, ARegion *region, int mval[2], float r_col[3])
{
if (sima->image == NULL) {
return false;
}
float uv[2];
- UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &uv[0], &uv[1]);
+ UI_view2d_region_to_view(&region->v2d, mval[0], mval[1], &uv[0], &uv[1]);
int tile = BKE_image_get_tile_from_pos(sima->image, uv, uv, NULL);
void *lock;
@@ -3475,11 +3299,11 @@ static void image_sample_rect_color_float(ImBuf *ibuf, const rcti *rect, float r
static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
Image *image = ED_space_image(sima);
float uv[2];
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &uv[0], &uv[1]);
+ UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &uv[0], &uv[1]);
int tile = BKE_image_get_tile_from_pos(sima->image, uv, uv, NULL);
void *lock;
@@ -3619,10 +3443,10 @@ static void image_sample_exit(bContext *C, wmOperator *op)
static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
ImageSampleInfo *info;
- if (ar->regiontype == RGN_TYPE_WINDOW) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
if (event->mval[1] <= 16 && ED_space_image_show_cache(sima)) {
return OPERATOR_PASS_THROUGH;
}
@@ -3634,9 +3458,9 @@ static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event
info = MEM_callocN(sizeof(ImageSampleInfo), "ImageSampleInfo");
- info->art = ar->type;
+ info->art = region->type;
info->draw_handle = ED_region_draw_cb_activate(
- ar->type, image_sample_draw, info, REGION_DRAW_POST_PIXEL);
+ region->type, image_sample_draw, info, REGION_DRAW_POST_PIXEL);
info->sample_size = RNA_int_get(op->ptr, "size");
op->customdata = info;
@@ -3701,7 +3525,7 @@ void IMAGE_OT_sample(wmOperatorType *ot)
static int image_sample_line_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
Image *ima = ED_space_image(sima);
@@ -3711,8 +3535,8 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
int y_end = RNA_int_get(op->ptr, "yend");
float uv1[2], uv2[2], ofs[2];
- UI_view2d_region_to_view(&ar->v2d, x_start, y_start, &uv1[0], &uv1[1]);
- UI_view2d_region_to_view(&ar->v2d, x_end, y_end, &uv2[0], &uv2[1]);
+ UI_view2d_region_to_view(&region->v2d, x_start, y_start, &uv1[0], &uv1[1]);
+ UI_view2d_region_to_view(&region->v2d, x_end, y_end, &uv2[0], &uv2[1]);
/* If the image has tiles, shift the positions accordingly. */
int tile = BKE_image_get_tile_from_pos(ima, uv1, uv1, ofs);
@@ -4014,19 +3838,19 @@ static int change_frame_exec(bContext *C, wmOperator *op)
static int frame_from_event(bContext *C, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
int framenr = 0;
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
+ if (region->regiontype == RGN_TYPE_WINDOW) {
+ float sfra = SFRA, efra = EFRA, framelen = region->winx / (efra - sfra + 1);
framenr = sfra + event->mval[0] / framelen;
}
else {
float viewx, viewy;
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
+ UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
framenr = round_fl_to_int(viewx);
}
@@ -4036,13 +3860,13 @@ static int frame_from_event(bContext *C, const wmEvent *event)
static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
- if (ar->regiontype == RGN_TYPE_WINDOW) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
SpaceImage *sima = CTX_wm_space_image(C);
/* Local coordinate visible rect inside region, to accommodate overlapping ui. */
- const rcti *rect_visible = ED_region_visible_rect(ar);
+ const rcti *rect_visible = ED_region_visible_rect(region);
const int region_bottom = rect_visible->ymin;
if (event->mval[1] > (region_bottom + 16 * UI_DPI_FAC) || !ED_space_image_show_cache(sima)) {
@@ -4063,7 +3887,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
- case ESCKEY:
+ case EVT_ESCKEY:
return OPERATOR_FINISHED;
case MOUSEMOVE:
@@ -4111,7 +3935,7 @@ static int image_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
SpaceImage *sima = CTX_wm_space_image(C);
Image *ima;
- ima = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
+ ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
if (sima->image == NULL) {
ED_space_image_set(bmain, sima, NULL, ima, false);
}
@@ -4143,7 +3967,7 @@ void IMAGE_OT_read_viewlayers(wmOperatorType *ot)
static int render_border_exec(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
Render *re = RE_GetSceneRender(scene);
RenderData *rd;
@@ -4162,7 +3986,7 @@ static int render_border_exec(bContext *C, wmOperator *op)
/* get rectangle from operator */
WM_operator_properties_border_to_rctf(op, &border);
- UI_view2d_region_to_view_rctf(&ar->v2d, &border, &border);
+ UI_view2d_region_to_view_rctf(&region->v2d, &border, &border);
/* actually set border */
CLAMP(border.xmin, 0.0f, 1.0f);
@@ -4240,7 +4064,9 @@ void IMAGE_OT_clear_render_border(wmOperatorType *ot)
/** \} */
-/* ********************* Add tile operator ****************** */
+/* -------------------------------------------------------------------- */
+/** \name Add Tile Operator
+ * \{ */
static bool do_fill_tile(PointerRNA *ptr, Image *ima, ImageTile *tile)
{
@@ -4346,7 +4172,13 @@ static int tile_add_exec(bContext *C, wmOperator *op)
Image *ima = CTX_data_edit_image(C);
int start_tile = RNA_int_get(op->ptr, "number");
- int end_tile = min_ii(start_tile + RNA_int_get(op->ptr, "count"), IMA_UDIM_MAX);
+ int end_tile = start_tile + RNA_int_get(op->ptr, "count");
+
+ if (start_tile < 1001 || end_tile > IMA_UDIM_MAX) {
+ BKE_report(op->reports, RPT_ERROR, "Invalid UDIM index range was specified");
+ return OPERATOR_CANCELLED;
+ }
+
bool fill_tile = RNA_boolean_get(op->ptr, "fill");
char *label = RNA_string_get_alloc(op->ptr, "label", NULL, 0);
@@ -4395,7 +4227,7 @@ static int tile_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev
RNA_int_set(op->ptr, "count", 1);
RNA_string_set(op->ptr, "label", "");
- return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y);
+ return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X);
}
static void tile_add_draw(bContext *UNUSED(C), wmOperator *op)
@@ -4442,15 +4274,26 @@ void IMAGE_OT_tile_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_int(
- ot->srna, "number", 1002, 1001, INT_MAX, "Number", "UDIM number of the tile", 1001, 1099);
+ RNA_def_int(ot->srna,
+ "number",
+ 1002,
+ 1001,
+ IMA_UDIM_MAX,
+ "Number",
+ "UDIM number of the tile",
+ 1001,
+ 1099);
RNA_def_int(ot->srna, "count", 1, 1, INT_MAX, "Count", "How many tiles to add", 1, 1000);
RNA_def_string(ot->srna, "label", NULL, 0, "Label", "Optional tile label");
RNA_def_boolean(ot->srna, "fill", true, "Fill", "Fill new tile with a generated image");
def_fill_tile(ot->srna);
}
-/* ********************* Remove tile operator ****************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Remove Tile Operator
+ * \{ */
static bool tile_remove_poll(bContext *C)
{
@@ -4491,7 +4334,11 @@ void IMAGE_OT_tile_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ********************* Fill tile operator ****************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Fill Tile Operator
+ * \{ */
static bool tile_fill_poll(bContext *C)
{
@@ -4522,7 +4369,7 @@ static int tile_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
{
initialize_fill_tile(op->ptr, CTX_data_edit_image(C), NULL);
- return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, 5 * UI_UNIT_Y);
+ return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X);
}
static void tile_fill_draw(bContext *UNUSED(C), wmOperator *op)
diff --git a/source/blender/editors/space_image/image_sequence.c b/source/blender/editors/space_image/image_sequence.c
new file mode 100644
index 00000000000..cc6fe38866d
--- /dev/null
+++ b/source/blender/editors/space_image/image_sequence.c
@@ -0,0 +1,248 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup spimage
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_fileops.h"
+#include "BLI_fileops_types.h"
+#include "BLI_linklist.h"
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_access.h"
+
+#include "BKE_image.h"
+#include "BKE_main.h"
+
+#include "ED_image.h"
+
+#include "WM_types.h"
+
+typedef struct ImageFrame {
+ struct ImageFrame *next, *prev;
+ int framenr;
+} ImageFrame;
+
+/**
+ * Get a list of frames from the list of image files matching the first file
+ * name sequence pattern. The files and directory are read from standard
+ * fileselect operator properties.
+ *
+ * The output is a list of frame ranges, each containing a list of frames with matching names.
+ */
+static void image_sequence_get_frame_ranges(wmOperator *op, ListBase *ranges)
+{
+ char dir[FILE_MAXDIR];
+ const bool do_frame_range = RNA_boolean_get(op->ptr, "use_sequence_detection");
+ ImageFrameRange *range = NULL;
+
+ RNA_string_get(op->ptr, "directory", dir);
+ RNA_BEGIN (op->ptr, itemptr, "files") {
+ char base_head[FILE_MAX], base_tail[FILE_MAX];
+ char head[FILE_MAX], tail[FILE_MAX];
+ unsigned short digits;
+ char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
+ ImageFrame *frame = MEM_callocN(sizeof(ImageFrame), "image_frame");
+
+ /* use the first file in the list as base filename */
+ frame->framenr = BLI_stringdec(filename, head, tail, &digits);
+
+ /* still in the same sequence */
+ if (do_frame_range && (range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) &&
+ (STREQLEN(base_tail, tail, FILE_MAX))) {
+ /* pass */
+ }
+ else {
+ /* start a new frame range */
+ range = MEM_callocN(sizeof(*range), __func__);
+ BLI_join_dirfile(range->filepath, sizeof(range->filepath), dir, filename);
+ BLI_addtail(ranges, range);
+
+ BLI_strncpy(base_head, head, sizeof(base_head));
+ BLI_strncpy(base_tail, tail, sizeof(base_tail));
+ }
+
+ BLI_addtail(&range->frames, frame);
+ MEM_freeN(filename);
+ }
+ RNA_END;
+}
+
+static int image_cmp_frame(const void *a, const void *b)
+{
+ const ImageFrame *frame_a = a;
+ const ImageFrame *frame_b = b;
+
+ if (frame_a->framenr < frame_b->framenr) {
+ return -1;
+ }
+ if (frame_a->framenr > frame_b->framenr) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Checks whether the given filepath refers to a UDIM texture.
+ * If yes, the range from 1001 to the highest tile is returned, otherwise 0.
+ *
+ * If the result is positive, the filepath will be overwritten with that of
+ * the 1001 tile.
+ *
+ * udim_tiles may get filled even if the result ultimately is false!
+ */
+static int image_get_udim(char *filepath, ListBase *udim_tiles)
+{
+ char filename[FILE_MAX], dirname[FILE_MAXDIR];
+ BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
+
+ unsigned short digits;
+ char base_head[FILE_MAX], base_tail[FILE_MAX];
+ int id = BLI_stringdec(filename, base_head, base_tail, &digits);
+
+ if (id < 1001 || id >= IMA_UDIM_MAX) {
+ return 0;
+ }
+
+ bool is_udim = true;
+ bool has_primary = false;
+ int max_udim = 0;
+
+ struct direntry *dir;
+ uint totfile = BLI_filelist_dir_contents(dirname, &dir);
+ for (int i = 0; i < totfile; i++) {
+ if (!(dir[i].type & S_IFREG)) {
+ continue;
+ }
+ char head[FILE_MAX], tail[FILE_MAX];
+ id = BLI_stringdec(dir[i].relname, head, tail, &digits);
+
+ if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
+ !(STREQLEN(base_tail, tail, FILE_MAX))) {
+ continue;
+ }
+
+ if (id < 1001 || id >= IMA_UDIM_MAX) {
+ is_udim = false;
+ break;
+ }
+ if (id == 1001) {
+ has_primary = true;
+ }
+
+ BLI_addtail(udim_tiles, BLI_genericNodeN(POINTER_FROM_INT(id)));
+ max_udim = max_ii(max_udim, id);
+ }
+ BLI_filelist_free(dir, totfile);
+
+ if (is_udim && has_primary) {
+ char primary_filename[FILE_MAX];
+ BLI_stringenc(primary_filename, base_head, base_tail, digits, 1001);
+ BLI_join_dirfile(filepath, FILE_MAX, dirname, primary_filename);
+ return max_udim - 1000;
+ }
+ return 0;
+}
+
+/**
+ * From a list of frames, compute the start (offset) and length of the sequence
+ * of contiguous frames. If UDIM is detect, it will return UDIM tiles as well.
+ */
+static void image_detect_frame_range(ImageFrameRange *range, const bool detect_udim)
+{
+ /* UDIM */
+ if (detect_udim) {
+ int len_udim = image_get_udim(range->filepath, &range->udim_tiles);
+
+ if (len_udim > 0) {
+ range->offset = 1001;
+ range->length = len_udim;
+ return;
+ }
+ }
+
+ /* Image Sequence */
+ BLI_listbase_sort(&range->frames, image_cmp_frame);
+
+ ImageFrame *frame = range->frames.first;
+ if (frame != NULL) {
+ int frame_curr = frame->framenr;
+ range->offset = frame_curr;
+
+ while (frame != NULL && (frame->framenr == frame_curr)) {
+ frame_curr++;
+ frame = frame->next;
+ }
+
+ range->length = frame_curr - range->offset;
+ }
+ else {
+ range->length = 1;
+ range->offset = 0;
+ }
+}
+
+/* Used for both images and volume file loading. */
+ListBase ED_image_filesel_detect_sequences(Main *bmain, wmOperator *op, const bool detect_udim)
+{
+ ListBase ranges;
+ BLI_listbase_clear(&ranges);
+
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+
+ /* File browser. */
+ if (RNA_struct_property_is_set(op->ptr, "directory") &&
+ RNA_struct_property_is_set(op->ptr, "files")) {
+ const bool was_relative = BLI_path_is_rel(filepath);
+
+ image_sequence_get_frame_ranges(op, &ranges);
+ for (ImageFrameRange *range = ranges.first; range; range = range->next) {
+ image_detect_frame_range(range, detect_udim);
+ BLI_freelistN(&range->frames);
+
+ if (was_relative) {
+ BLI_path_rel(range->filepath, BKE_main_blendfile_path(bmain));
+ }
+ }
+ }
+ /* Filepath property for drag & drop etc. */
+ else {
+ ImageFrameRange *range = MEM_callocN(sizeof(*range), __func__);
+ BLI_addtail(&ranges, range);
+
+ BLI_strncpy(range->filepath, filepath, FILE_MAX);
+ image_detect_frame_range(range, detect_udim);
+ }
+
+ return ranges;
+}
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index 79aa4d2ed7f..1394c05d7bc 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -34,16 +34,16 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_utildefines.h"
+#include "BLI_math.h"
#include "BLI_threads.h"
+#include "BLI_utildefines.h"
#include "DNA_image_types.h"
-#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_windowmanager_types.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -55,10 +55,10 @@
#include "DEG_depsgraph.h"
+#include "ED_object.h"
#include "ED_paint.h"
#include "ED_undo.h"
#include "ED_util.h"
-#include "ED_object.h"
#include "GPU_draw.h"
@@ -107,7 +107,11 @@ typedef struct PaintTile {
struct PaintTile *next, *prev;
Image *image;
ImBuf *ibuf;
- int tile_number;
+ /* For 2D image painting the ImageUser uses most of the values.
+ * Even though views and passes are stored they are currently not supported for painting.
+ * For 3D projection painting this only uses a tile & frame number.
+ * The scene pointer must be cleared (or temporarily set it as needed, but leave cleared). */
+ ImageUser iuser;
union {
float *fp;
uint *uint;
@@ -149,7 +153,7 @@ static void ptile_invalidate_list(ListBase *paint_tiles)
void *ED_image_paint_tile_find(ListBase *paint_tiles,
Image *image,
ImBuf *ibuf,
- int tile_number,
+ ImageUser *iuser,
int x_tile,
int y_tile,
ushort **r_mask,
@@ -157,11 +161,11 @@ void *ED_image_paint_tile_find(ListBase *paint_tiles,
{
for (PaintTile *ptile = paint_tiles->first; ptile; ptile = ptile->next) {
if (ptile->x_tile == x_tile && ptile->y_tile == y_tile) {
- if (ptile->image == image && ptile->ibuf == ibuf && ptile->tile_number == tile_number) {
+ if (ptile->image == image && ptile->ibuf == ibuf && ptile->iuser.tile == iuser->tile) {
if (r_mask) {
/* allocate mask if requested. */
if (!ptile->mask) {
- ptile->mask = MEM_callocN(sizeof(ushort) * SQUARE(ED_IMAGE_UNDO_TILE_SIZE),
+ ptile->mask = MEM_callocN(sizeof(ushort) * square_i(ED_IMAGE_UNDO_TILE_SIZE),
"UndoImageTile.mask");
}
*r_mask = ptile->mask;
@@ -180,7 +184,7 @@ void *ED_image_paint_tile_push(ListBase *paint_tiles,
Image *image,
ImBuf *ibuf,
ImBuf **tmpibuf,
- int tile_number,
+ ImageUser *iuser,
int x_tile,
int y_tile,
ushort **r_mask,
@@ -195,7 +199,7 @@ void *ED_image_paint_tile_push(ListBase *paint_tiles,
/* in projective painting we keep accounting of tiles, so if we need one pushed, just push! */
if (find_prev) {
void *data = ED_image_paint_tile_find(
- paint_tiles, image, ibuf, tile_number, x_tile, y_tile, r_mask, true);
+ paint_tiles, image, ibuf, iuser, x_tile, y_tile, r_mask, true);
if (data) {
return data;
}
@@ -209,19 +213,20 @@ void *ED_image_paint_tile_push(ListBase *paint_tiles,
ptile->image = image;
ptile->ibuf = ibuf;
- ptile->tile_number = tile_number;
+ ptile->iuser = *iuser;
+ ptile->iuser.scene = NULL;
ptile->x_tile = x_tile;
ptile->y_tile = y_tile;
/* add mask explicitly here */
if (r_mask) {
- *r_mask = ptile->mask = MEM_callocN(sizeof(ushort) * SQUARE(ED_IMAGE_UNDO_TILE_SIZE),
+ *r_mask = ptile->mask = MEM_callocN(sizeof(ushort) * square_i(ED_IMAGE_UNDO_TILE_SIZE),
"PaintTile.mask");
}
ptile->rect.pt = MEM_mapallocN((ibuf->rect_float ? sizeof(float[4]) : sizeof(char[4])) *
- SQUARE(ED_IMAGE_UNDO_TILE_SIZE),
+ square_i(ED_IMAGE_UNDO_TILE_SIZE),
"PaintTile.rect");
ptile->use_float = has_float;
@@ -264,10 +269,7 @@ static void ptile_restore_runtime_list(ListBase *paint_tiles)
for (PaintTile *ptile = paint_tiles->first; ptile; ptile = ptile->next) {
Image *image = ptile->image;
- ImageUser iuser;
- BKE_imageuser_default(&iuser);
- iuser.tile = ptile->tile_number;
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, &ptile->iuser, NULL);
const bool has_float = (ibuf->rect_float != NULL);
if (has_float) {
@@ -333,10 +335,10 @@ static UndoImageTile *utile_alloc(bool has_float)
{
UndoImageTile *utile = MEM_callocN(sizeof(*utile), "ImageUndoTile");
if (has_float) {
- utile->rect.fp = MEM_mallocN(sizeof(float[4]) * SQUARE(ED_IMAGE_UNDO_TILE_SIZE), __func__);
+ utile->rect.fp = MEM_mallocN(sizeof(float[4]) * square_i(ED_IMAGE_UNDO_TILE_SIZE), __func__);
}
else {
- utile->rect.uint = MEM_mallocN(sizeof(uint) * SQUARE(ED_IMAGE_UNDO_TILE_SIZE), __func__);
+ utile->rect.uint = MEM_mallocN(sizeof(uint) * square_i(ED_IMAGE_UNDO_TILE_SIZE), __func__);
}
return utile;
}
@@ -659,22 +661,23 @@ static UndoImageHandle *uhandle_lookup(ListBase *undo_handles, const Image *imag
return NULL;
}
-static UndoImageHandle *uhandle_add(ListBase *undo_handles, Image *image, int tile_number)
+static UndoImageHandle *uhandle_add(ListBase *undo_handles, Image *image, ImageUser *iuser)
{
- BLI_assert(uhandle_lookup(undo_handles, image, tile_number) == NULL);
+ BLI_assert(uhandle_lookup(undo_handles, image, iuser->tile) == NULL);
UndoImageHandle *uh = MEM_callocN(sizeof(*uh), __func__);
uh->image_ref.ptr = image;
+ uh->iuser = *iuser;
+ BLI_assert(uh->iuser.scene == NULL);
uh->iuser.ok = 1;
- uh->iuser.tile = tile_number;
BLI_addtail(undo_handles, uh);
return uh;
}
-static UndoImageHandle *uhandle_ensure(ListBase *undo_handles, Image *image, int tile_number)
+static UndoImageHandle *uhandle_ensure(ListBase *undo_handles, Image *image, ImageUser *iuser)
{
- UndoImageHandle *uh = uhandle_lookup(undo_handles, image, tile_number);
+ UndoImageHandle *uh = uhandle_lookup(undo_handles, image, iuser->tile);
if (uh == NULL) {
- uh = uhandle_add(undo_handles, image, tile_number);
+ uh = uhandle_add(undo_handles, image, iuser);
}
return uh;
}
@@ -779,7 +782,7 @@ static bool image_undosys_step_encode(struct bContext *C,
/* Initialize undo tiles from ptiles (if they exist). */
for (PaintTile *ptile = us->paint_tiles.first, *ptile_next; ptile; ptile = ptile_next) {
if (ptile->valid) {
- UndoImageHandle *uh = uhandle_ensure(&us->handles, ptile->image, ptile->tile_number);
+ UndoImageHandle *uh = uhandle_ensure(&us->handles, ptile->image, &ptile->iuser);
UndoImageBuf *ubuf_pre = uhandle_ensure_ubuf(uh, ptile->image, ptile->ibuf);
UndoImageTile *utile = MEM_callocN(sizeof(*utile), "UndoImageTile");
@@ -1047,12 +1050,12 @@ void ED_image_undo_push_begin(const char *name, int paint_mode)
void ED_image_undo_push_begin_with_image(const char *name,
Image *image,
ImBuf *ibuf,
- int tile_number)
+ ImageUser *iuser)
{
ImageUndoStep *us = image_undo_push_begin(name, PAINT_MODE_TEXTURE_2D);
- BLI_assert(BKE_image_get_tile(image, tile_number));
- UndoImageHandle *uh = uhandle_ensure(&us->handles, image, tile_number);
+ BLI_assert(BKE_image_get_tile(image, iuser->tile));
+ UndoImageHandle *uh = uhandle_ensure(&us->handles, image, iuser);
UndoImageBuf *ubuf_pre = uhandle_ensure_ubuf(uh, image, ibuf);
BLI_assert(ubuf_pre->post == NULL);
@@ -1061,7 +1064,7 @@ void ED_image_undo_push_begin_with_image(const char *name,
us_reference = (ImageUndoStep *)us_reference->step.prev;
}
UndoImageBuf *ubuf_reference = (us_reference ? ubuf_lookup_from_reference(
- us_reference, image, tile_number, ubuf_pre) :
+ us_reference, image, iuser->tile, ubuf_pre) :
NULL);
if (ubuf_reference) {
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 833bcb6537a..14cc6a9e151 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -22,12 +22,12 @@
*/
#include "DNA_gpencil_types.h"
-#include "DNA_mesh_types.h"
+#include "DNA_image_types.h"
#include "DNA_mask_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_image_types.h"
#include "MEM_guardedalloc.h"
@@ -40,7 +40,7 @@
#include "BKE_editmesh.h"
#include "BKE_image.h"
#include "BKE_layer.h"
-#include "BKE_library.h"
+#include "BKE_lib_id.h"
#include "BKE_material.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
@@ -59,23 +59,23 @@
#include "ED_mesh.h"
#include "ED_node.h"
#include "ED_render.h"
-#include "ED_space_api.h"
#include "ED_screen.h"
-#include "ED_uvedit.h"
+#include "ED_space_api.h"
#include "ED_transform.h"
+#include "ED_uvedit.h"
#include "WM_api.h"
-#include "WM_types.h"
#include "WM_message.h"
+#include "WM_types.h"
-#include "UI_resources.h"
#include "UI_interface.h"
+#include "UI_resources.h"
#include "UI_view2d.h"
-#include "image_intern.h"
-#include "GPU_framebuffer.h"
#include "GPU_batch_presets.h"
+#include "GPU_framebuffer.h"
#include "GPU_viewport.h"
+#include "image_intern.h"
/* TODO(fclem) remove bad level calls */
#include "../draw/DRW_engine.h"
@@ -86,11 +86,11 @@
static void image_scopes_tag_refresh(ScrArea *sa)
{
SpaceImage *sima = (SpaceImage *)sa->spacedata.first;
- ARegion *ar;
+ ARegion *region;
/* only while histogram is visible */
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_TOOL_PROPS && ar->flag & RGN_FLAG_HIDDEN) {
+ for (region = sa->regionbase.first; region; region = region->next) {
+ if (region->regiontype == RGN_TYPE_TOOL_PROPS && region->flag & RGN_FLAG_HIDDEN) {
return;
}
}
@@ -119,7 +119,7 @@ static void image_user_refresh_scene(const bContext *C, SpaceImage *sima)
static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
- ARegion *ar;
+ ARegion *region;
SpaceImage *simage;
simage = MEM_callocN(sizeof(SpaceImage), "initimage");
@@ -138,41 +138,41 @@ static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(sce
simage->tile_grid_shape[1] = 1;
/* tool header */
- ar = MEM_callocN(sizeof(ARegion), "tool header for image");
+ region = MEM_callocN(sizeof(ARegion), "tool header for image");
- BLI_addtail(&simage->regionbase, ar);
- ar->regiontype = RGN_TYPE_TOOL_HEADER;
- ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
- ar->flag = RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER;
+ BLI_addtail(&simage->regionbase, region);
+ region->regiontype = RGN_TYPE_TOOL_HEADER;
+ region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
+ region->flag = RGN_FLAG_HIDDEN | RGN_FLAG_HIDDEN_BY_USER;
/* header */
- ar = MEM_callocN(sizeof(ARegion), "header for image");
+ region = MEM_callocN(sizeof(ARegion), "header for image");
- BLI_addtail(&simage->regionbase, ar);
- ar->regiontype = RGN_TYPE_HEADER;
- ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
+ BLI_addtail(&simage->regionbase, region);
+ region->regiontype = RGN_TYPE_HEADER;
+ region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
/* buttons/list view */
- ar = MEM_callocN(sizeof(ARegion), "buttons for image");
+ region = MEM_callocN(sizeof(ARegion), "buttons for image");
- BLI_addtail(&simage->regionbase, ar);
- ar->regiontype = RGN_TYPE_UI;
- ar->alignment = RGN_ALIGN_RIGHT;
- ar->flag = RGN_FLAG_HIDDEN;
+ BLI_addtail(&simage->regionbase, region);
+ region->regiontype = RGN_TYPE_UI;
+ region->alignment = RGN_ALIGN_RIGHT;
+ region->flag = RGN_FLAG_HIDDEN;
/* scopes/uv sculpt/paint */
- ar = MEM_callocN(sizeof(ARegion), "buttons for image");
+ region = MEM_callocN(sizeof(ARegion), "buttons for image");
- BLI_addtail(&simage->regionbase, ar);
- ar->regiontype = RGN_TYPE_TOOLS;
- ar->alignment = RGN_ALIGN_LEFT;
- ar->flag = RGN_FLAG_HIDDEN;
+ BLI_addtail(&simage->regionbase, region);
+ region->regiontype = RGN_TYPE_TOOLS;
+ region->alignment = RGN_ALIGN_LEFT;
+ region->flag = RGN_FLAG_HIDDEN;
/* main area */
- ar = MEM_callocN(sizeof(ARegion), "main area for image");
+ region = MEM_callocN(sizeof(ARegion), "main area for image");
- BLI_addtail(&simage->regionbase, ar);
- ar->regiontype = RGN_TYPE_WINDOW;
+ BLI_addtail(&simage->regionbase, region);
+ region->regiontype = RGN_TYPE_WINDOW;
return (SpaceLink *)simage;
}
@@ -498,7 +498,7 @@ static void image_widgets(void)
/************************** main region ***************************/
/* sets up the fields of the View2D from zoom and offset */
-static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
+static void image_main_region_set_view2d(SpaceImage *sima, ARegion *region)
{
Image *ima = ED_space_image(sima);
@@ -512,79 +512,79 @@ static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
h *= ima->aspy / ima->aspx;
}
- int winx = BLI_rcti_size_x(&ar->winrct) + 1;
- int winy = BLI_rcti_size_y(&ar->winrct) + 1;
+ int winx = BLI_rcti_size_x(&region->winrct) + 1;
+ int winy = BLI_rcti_size_y(&region->winrct) + 1;
/* For region overlap, move center so image doesn't overlap header. */
- const rcti *visible_rect = ED_region_visible_rect(ar);
+ const rcti *visible_rect = ED_region_visible_rect(region);
const int visible_winy = BLI_rcti_size_y(visible_rect) + 1;
int visible_centerx = 0;
int visible_centery = visible_rect->ymin + (visible_winy - winy) / 2;
- ar->v2d.tot.xmin = 0;
- ar->v2d.tot.ymin = 0;
- ar->v2d.tot.xmax = w;
- ar->v2d.tot.ymax = h;
+ region->v2d.tot.xmin = 0;
+ region->v2d.tot.ymin = 0;
+ region->v2d.tot.xmax = w;
+ region->v2d.tot.ymax = h;
- ar->v2d.mask.xmin = ar->v2d.mask.ymin = 0;
- ar->v2d.mask.xmax = winx;
- ar->v2d.mask.ymax = winy;
+ region->v2d.mask.xmin = region->v2d.mask.ymin = 0;
+ region->v2d.mask.xmax = winx;
+ region->v2d.mask.ymax = winy;
/* which part of the image space do we see? */
- float x1 = ar->winrct.xmin + visible_centerx + (winx - sima->zoom * w) / 2.0f;
- float y1 = ar->winrct.ymin + visible_centery + (winy - sima->zoom * h) / 2.0f;
+ float x1 = region->winrct.xmin + visible_centerx + (winx - sima->zoom * w) / 2.0f;
+ float y1 = region->winrct.ymin + visible_centery + (winy - sima->zoom * h) / 2.0f;
x1 -= sima->zoom * sima->xof;
y1 -= sima->zoom * sima->yof;
/* relative display right */
- ar->v2d.cur.xmin = ((ar->winrct.xmin - (float)x1) / sima->zoom);
- ar->v2d.cur.xmax = ar->v2d.cur.xmin + ((float)winx / sima->zoom);
+ region->v2d.cur.xmin = ((region->winrct.xmin - (float)x1) / sima->zoom);
+ region->v2d.cur.xmax = region->v2d.cur.xmin + ((float)winx / sima->zoom);
/* relative display left */
- ar->v2d.cur.ymin = ((ar->winrct.ymin - (float)y1) / sima->zoom);
- ar->v2d.cur.ymax = ar->v2d.cur.ymin + ((float)winy / sima->zoom);
+ region->v2d.cur.ymin = ((region->winrct.ymin - (float)y1) / sima->zoom);
+ region->v2d.cur.ymax = region->v2d.cur.ymin + ((float)winy / sima->zoom);
/* normalize 0.0..1.0 */
- ar->v2d.cur.xmin /= w;
- ar->v2d.cur.xmax /= w;
- ar->v2d.cur.ymin /= h;
- ar->v2d.cur.ymax /= h;
+ region->v2d.cur.xmin /= w;
+ region->v2d.cur.xmax /= w;
+ region->v2d.cur.ymin /= h;
+ region->v2d.cur.ymax /= h;
}
/* add handlers, stuff you only do once or on area/region changes */
-static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
+static void image_main_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
// image space manages own v2d
- // UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
+ // UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_STANDARD, region->winx, region->winy);
/* mask polls mode */
keymap = WM_keymap_ensure(wm->defaultconf, "Mask Editing", 0, 0);
- WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
+ WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
/* image paint polls for mode */
keymap = WM_keymap_ensure(wm->defaultconf, "Curve", 0, 0);
- WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
+ WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
keymap = WM_keymap_ensure(wm->defaultconf, "Paint Curve", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
keymap = WM_keymap_ensure(wm->defaultconf, "Image Paint", 0, 0);
- WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
+ WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
keymap = WM_keymap_ensure(wm->defaultconf, "UV Editor", 0, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
/* own keymaps */
keymap = WM_keymap_ensure(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
keymap = WM_keymap_ensure(wm->defaultconf, "Image", SPACE_IMAGE, 0);
- WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
+ WM_event_add_keymap_handler_v2d_mask(&region->handlers, keymap);
}
-static void image_main_region_draw(const bContext *C, ARegion *ar)
+static void image_main_region_draw(const bContext *C, ARegion *region)
{
/* draw entirely, view changes should be handled here */
SpaceImage *sima = CTX_wm_space_image(C);
@@ -596,7 +596,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
bool show_curve = false;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- View2D *v2d = &ar->v2d;
+ View2D *v2d = &region->v2d;
// View2DScrollers *scrollers;
float col[3];
@@ -604,32 +604,36 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
* old context since we now use it for drawing the entire area. */
gpu_batch_presets_reset();
- GPUViewport *viewport =
- ar->draw_buffer->viewport[ar->draw_buffer->stereo ? sima->iuser.multiview_eye : 0];
+ GPUViewport *viewport = region->draw_buffer->viewport;
DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
GPU_framebuffer_bind(fbl->default_fb);
+ GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
+ GPU_clear(GPU_COLOR_BIT);
+
+ GPU_framebuffer_bind(fbl->overlay_fb);
+ glDisable(GL_FRAMEBUFFER_SRGB);
/* XXX not supported yet, disabling for now */
scene->r.scemode &= ~R_COMP_CROP;
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0f);
+ GPU_clear_color(col[0], col[1], col[2], 1.0f);
GPU_clear(GPU_COLOR_BIT);
GPU_depth_test(false);
image_user_refresh_scene(C, sima);
/* we set view2d from own zoom and offset each time */
- image_main_region_set_view2d(sima, ar);
+ image_main_region_set_view2d(sima, region);
/* we draw image in pixelspace */
- draw_image_main(C, ar);
+ draw_image_main(C, region);
/* and uvs in 0.0-1.0 space */
UI_view2d_view_ortho(v2d);
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
+ ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW);
ED_uvedit_draw_main(sima, scene, view_layer, obedit, obact, depsgraph);
@@ -644,7 +648,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
show_curve = true;
}
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
+ ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
if (sima->flag & SI_SHOW_GPENCIL) {
/* Grease Pencil too (in addition to UV's) */
@@ -684,7 +688,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
ED_mask_draw_region(depsgraph,
mask,
- ar,
+ region,
sima->mask_info.draw_flag,
sima->mask_info.draw_type,
sima->mask_info.overlay_mode,
@@ -700,51 +704,54 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
if (show_uvedit || mask || show_curve) {
UI_view2d_view_ortho(v2d);
- ED_image_draw_cursor(ar, sima->cursor);
+ ED_image_draw_cursor(region, sima->cursor);
UI_view2d_view_restore(C);
}
- WM_gizmomap_draw(ar->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
+ WM_gizmomap_draw(region->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
- draw_image_cache(C, ar);
+ draw_image_cache(C, region);
}
-static void image_main_region_listener(
- wmWindow *UNUSED(win), ScrArea *sa, ARegion *ar, wmNotifier *wmn, const Scene *UNUSED(scene))
+static void image_main_region_listener(wmWindow *UNUSED(win),
+ ScrArea *sa,
+ ARegion *region,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
/* context changes */
switch (wmn->category) {
case NC_GEOM:
if (ELEM(wmn->data, ND_DATA, ND_SELECT)) {
- WM_gizmomap_tag_refresh(ar->gizmo_map);
+ WM_gizmomap_tag_refresh(region->gizmo_map);
}
break;
case NC_GPENCIL:
if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
else if (wmn->data & ND_GPENCIL_EDITMODE) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
case NC_IMAGE:
if (wmn->action == NA_PAINTING) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
- WM_gizmomap_tag_refresh(ar->gizmo_map);
+ WM_gizmomap_tag_refresh(region->gizmo_map);
break;
case NC_MATERIAL:
if (wmn->data == ND_SHADING_LINKS) {
SpaceImage *sima = sa->spacedata.first;
if (sima->iuser.scene && (sima->iuser.scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE)) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
}
break;
case NC_SCREEN:
if (ELEM(wmn->data, ND_LAYER)) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
}
@@ -753,18 +760,18 @@ static void image_main_region_listener(
/* *********************** buttons region ************************ */
/* add handlers, stuff you only do once or on area/region changes */
-static void image_buttons_region_init(wmWindowManager *wm, ARegion *ar)
+static void image_buttons_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
- ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
- ED_region_panels_init(wm, ar);
+ region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
+ ED_region_panels_init(wm, region);
keymap = WM_keymap_ensure(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
}
-static void image_buttons_region_layout(const bContext *C, ARegion *ar)
+static void image_buttons_region_layout(const bContext *C, ARegion *region)
{
const enum eContextObjectMode mode = CTX_data_mode_enum(C);
const char *contexts_base[3] = {NULL};
@@ -788,10 +795,11 @@ static void image_buttons_region_layout(const bContext *C, ARegion *ar)
}
const bool vertical = true;
- ED_region_panels_layout_ex(C, ar, &ar->type->paneltypes, contexts_base, -1, vertical, NULL);
+ ED_region_panels_layout_ex(
+ C, region, &region->type->paneltypes, contexts_base, -1, vertical, NULL);
}
-static void image_buttons_region_draw(const bContext *C, ARegion *ar)
+static void image_buttons_region_draw(const bContext *C, ARegion *region)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
@@ -799,7 +807,7 @@ static void image_buttons_region_draw(const bContext *C, ARegion *ar)
/* TODO(lukas): Support tiles in scopes? */
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock, 0);
/* XXX performance regression if name of scopes category changes! */
- PanelCategoryStack *category = UI_panel_category_active_find(ar, "Scopes");
+ PanelCategoryStack *category = UI_panel_category_active_find(region, "Scopes");
/* only update scopes if scope category is active */
if (category) {
@@ -819,12 +827,12 @@ static void image_buttons_region_draw(const bContext *C, ARegion *ar)
ED_space_image_release_buffer(sima, ibuf, lock);
/* Layout handles details. */
- ED_region_panels_draw(C, ar);
+ ED_region_panels_draw(C, region);
}
static void image_buttons_region_listener(wmWindow *UNUSED(win),
ScrArea *UNUSED(sa),
- ARegion *ar,
+ ARegion *region,
wmNotifier *wmn,
const Scene *UNUSED(scene))
{
@@ -834,33 +842,33 @@ static void image_buttons_region_listener(wmWindow *UNUSED(win),
case NC_MATERIAL:
/* sending by texture render job and needed to properly update displaying
* brush texture icon */
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
break;
case NC_SCENE:
switch (wmn->data) {
case ND_MODE:
case ND_RENDER_RESULT:
case ND_COMPO_RESULT:
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
break;
}
break;
case NC_IMAGE:
if (wmn->action != NA_PAINTING) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
case NC_NODE:
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
break;
case NC_GPENCIL:
if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
case NC_BRUSH:
if (wmn->action == NA_EDITED) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
}
@@ -869,25 +877,25 @@ static void image_buttons_region_listener(wmWindow *UNUSED(win),
/* *********************** scopes region ************************ */
/* add handlers, stuff you only do once or on area/region changes */
-static void image_tools_region_init(wmWindowManager *wm, ARegion *ar)
+static void image_tools_region_init(wmWindowManager *wm, ARegion *region)
{
wmKeyMap *keymap;
- ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
- ED_region_panels_init(wm, ar);
+ region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
+ ED_region_panels_init(wm, region);
keymap = WM_keymap_ensure(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ WM_event_add_keymap_handler(&region->handlers, keymap);
}
-static void image_tools_region_draw(const bContext *C, ARegion *ar)
+static void image_tools_region_draw(const bContext *C, ARegion *region)
{
- ED_region_panels(C, ar);
+ ED_region_panels(C, region);
}
static void image_tools_region_listener(wmWindow *UNUSED(win),
ScrArea *UNUSED(sa),
- ARegion *ar,
+ ARegion *region,
wmNotifier *wmn,
const Scene *UNUSED(scene))
{
@@ -895,13 +903,13 @@ static void image_tools_region_listener(wmWindow *UNUSED(win),
switch (wmn->category) {
case NC_GPENCIL:
if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
case NC_BRUSH:
/* NA_SELECTED is used on brush changes */
if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
case NC_SCENE:
@@ -909,17 +917,17 @@ static void image_tools_region_listener(wmWindow *UNUSED(win),
case ND_MODE:
case ND_RENDER_RESULT:
case ND_COMPO_RESULT:
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
break;
}
break;
case NC_IMAGE:
if (wmn->action != NA_PAINTING) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
case NC_NODE:
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
break;
}
}
@@ -927,24 +935,24 @@ static void image_tools_region_listener(wmWindow *UNUSED(win),
/************************* header region **************************/
/* add handlers, stuff you only do once or on area/region changes */
-static void image_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
+static void image_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
{
- ED_region_header_init(ar);
+ ED_region_header_init(region);
}
-static void image_header_region_draw(const bContext *C, ARegion *ar)
+static void image_header_region_draw(const bContext *C, ARegion *region)
{
ScrArea *sa = CTX_wm_area(C);
SpaceImage *sima = sa->spacedata.first;
image_user_refresh_scene(C, sima);
- ED_region_header(C, ar);
+ ED_region_header(C, region);
}
static void image_header_region_listener(wmWindow *UNUSED(win),
ScrArea *UNUSED(sa),
- ARegion *ar,
+ ARegion *region,
wmNotifier *wmn,
const Scene *UNUSED(scene))
{
@@ -954,7 +962,7 @@ static void image_header_region_listener(wmWindow *UNUSED(win),
switch (wmn->data) {
case ND_MODE:
case ND_TOOLSETTINGS:
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
break;
}
break;
@@ -962,13 +970,13 @@ static void image_header_region_listener(wmWindow *UNUSED(win),
switch (wmn->data) {
case ND_DATA:
case ND_SELECT:
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
break;
}
break;
case NC_BRUSH:
if (wmn->action == NA_EDITED) {
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(region);
}
break;
}