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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_image/image_ops.c')
-rw-r--r--source/blender/editors/space_image/image_ops.c88
1 files changed, 55 insertions, 33 deletions
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 537132ac428..4036f859231 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -45,6 +45,7 @@
#include "BKE_main.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
+#include "BKE_scene.h"
#include "DEG_depsgraph.h"
@@ -197,10 +198,17 @@ static ImageUser *image_user_from_context(const bContext *C)
return (sima) ? &sima->iuser : NULL;
}
-static ImageUser image_user_from_active_tile(Image *ima)
+static ImageUser image_user_from_context_and_active_tile(const bContext *C, Image *ima)
{
+ /* Try to get image user from context if available, otherwise use default. */
+ ImageUser *iuser_context = image_user_from_context(C);
ImageUser iuser;
- BKE_imageuser_default(&iuser);
+ if (iuser_context) {
+ iuser = *iuser_context;
+ }
+ else {
+ BKE_imageuser_default(&iuser);
+ }
/* Use the file associated with the active tile. Otherwise use the first tile. */
if (ima && ima->source == IMA_SRC_TILED) {
@@ -233,7 +241,7 @@ static bool image_from_context_has_data_poll(bContext *C)
static bool image_from_context_has_data_poll_active_tile(bContext *C)
{
Image *ima = image_from_context(C);
- ImageUser iuser = image_user_from_active_tile(ima);
+ ImageUser iuser = image_user_from_context_and_active_tile(C, ima);
return BKE_image_has_ibuf(ima, &iuser);
}
@@ -1602,7 +1610,7 @@ static int image_file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *
}
}
else if (ima->source == IMA_SRC_TILED) {
- ImageUser iuser = image_user_from_active_tile(ima);
+ ImageUser iuser = image_user_from_context_and_active_tile(C, ima);
BKE_image_user_file_path(&iuser, ima, filepath);
}
@@ -1823,7 +1831,7 @@ static void image_save_options_from_op(Main *bmain, ImageSaveOptions *opts, wmOp
}
static bool save_image_op(
- Main *bmain, Image *ima, ImageUser *iuser, wmOperator *op, ImageSaveOptions *opts)
+ Main *bmain, Image *ima, ImageUser *iuser, wmOperator *op, const ImageSaveOptions *opts)
{
WM_cursor_wait(true);
@@ -2391,7 +2399,7 @@ bool ED_image_save_all_modified(const bContext *C, ReportList *reports)
if (image_has_valid_path(ima)) {
ImageSaveOptions opts;
Scene *scene = CTX_data_scene(C);
- if (!BKE_image_save_options_init(&opts, bmain, scene, ima, NULL, false, false)) {
+ if (BKE_image_save_options_init(&opts, bmain, scene, ima, NULL, false, false)) {
bool saved_successfully = BKE_image_save(reports, bmain, ima, NULL, &opts);
ok = ok && saved_successfully;
}
@@ -2698,7 +2706,7 @@ void IMAGE_OT_new(wmOperatorType *ot)
static int image_flip_exec(bContext *C, wmOperator *op)
{
Image *ima = image_from_context(C);
- ImageUser iuser = image_user_from_active_tile(ima);
+ ImageUser iuser = image_user_from_context_and_active_tile(C, ima);
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
SpaceImage *sima = CTX_wm_space_image(C);
const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT));
@@ -2716,7 +2724,7 @@ static int image_flip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &sima->iuser);
+ ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &iuser);
if (is_paint) {
ED_imapaint_clear_partial_redraw();
@@ -2819,7 +2827,7 @@ void IMAGE_OT_flip(wmOperatorType *ot)
static int image_invert_exec(bContext *C, wmOperator *op)
{
Image *ima = image_from_context(C);
- ImageUser iuser = image_user_from_active_tile(ima);
+ ImageUser iuser = image_user_from_context_and_active_tile(C, ima);
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
SpaceImage *sima = CTX_wm_space_image(C);
const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT));
@@ -2837,7 +2845,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, &sima->iuser);
+ ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &iuser);
if (is_paint) {
ED_imapaint_clear_partial_redraw();
@@ -2943,7 +2951,7 @@ void IMAGE_OT_invert(wmOperatorType *ot)
static int image_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Image *ima = image_from_context(C);
- ImageUser iuser = image_user_from_active_tile(ima);
+ ImageUser iuser = image_user_from_context_and_active_tile(C, ima);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "size");
if (!RNA_property_is_set(op->ptr, prop)) {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
@@ -2957,7 +2965,7 @@ static int image_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
static int image_scale_exec(bContext *C, wmOperator *op)
{
Image *ima = image_from_context(C);
- ImageUser iuser = image_user_from_active_tile(ima);
+ ImageUser iuser = image_user_from_context_and_active_tile(C, ima);
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
SpaceImage *sima = CTX_wm_space_image(C);
const bool is_paint = ((sima != NULL) && (sima->mode == SI_MODE_PAINT));
@@ -2982,7 +2990,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, &sima->iuser);
+ ED_image_undo_push_begin_with_image(op->type->name, ima, ibuf, &iuser);
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
IMB_scaleImBuf(ibuf, size[0], size[1]);
@@ -3464,10 +3472,10 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot)
static int image_clear_render_slot_exec(bContext *C, wmOperator *UNUSED(op))
{
- SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = image_from_context(C);
+ ImageUser *iuser = image_user_from_context(C);
- if (!BKE_image_clear_renderslot(ima, &sima->iuser, ima->render_slot)) {
+ if (!BKE_image_clear_renderslot(ima, iuser, ima->render_slot)) {
return OPERATOR_CANCELLED;
}
@@ -3532,10 +3540,10 @@ void IMAGE_OT_add_render_slot(wmOperatorType *ot)
static int image_remove_render_slot_exec(bContext *C, wmOperator *UNUSED(op))
{
- SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = image_from_context(C);
+ ImageUser *iuser = image_user_from_context(C);
- if (!BKE_image_remove_renderslot(ima, &sima->iuser, ima->render_slot)) {
+ if (!BKE_image_remove_renderslot(ima, iuser, ima->render_slot)) {
return OPERATOR_CANCELLED;
}
@@ -3580,9 +3588,9 @@ static void change_frame_apply(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
/* set the new frame number */
- CFRA = RNA_int_get(op->ptr, "frame");
- FRAMENUMBER_MIN_CLAMP(CFRA);
- SUBFRA = 0.0f;
+ scene->r.cfra = RNA_int_get(op->ptr, "frame");
+ FRAMENUMBER_MIN_CLAMP(scene->r.cfra);
+ scene->r.subframe = 0.0f;
/* do updates */
DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE);
@@ -3603,7 +3611,7 @@ static int frame_from_event(bContext *C, const wmEvent *event)
int framenr = 0;
if (region->regiontype == RGN_TYPE_WINDOW) {
- float sfra = SFRA, efra = EFRA, framelen = region->winx / (efra - sfra + 1);
+ float sfra = scene->r.sfra, efra = scene->r.efra, framelen = region->winx / (efra - sfra + 1);
framenr = sfra + event->mval[0] / framelen;
}
@@ -3725,38 +3733,52 @@ static int render_border_exec(bContext *C, wmOperator *op)
ARegion *region = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
Render *re = RE_GetSceneRender(scene);
- RenderData *rd;
- rctf border;
+ SpaceImage *sima = CTX_wm_space_image(C);
if (re == NULL) {
/* Shouldn't happen, but better be safe close to the release. */
return OPERATOR_CANCELLED;
}
- rd = RE_engine_get_render_data(re);
- if ((rd->mode & (R_BORDER | R_CROP)) == (R_BORDER | R_CROP)) {
- BKE_report(op->reports, RPT_INFO, "Can not set border from a cropped render");
- return OPERATOR_CANCELLED;
- }
+ /* Get information about the previous render, or current scene if no render yet. */
+ int width, height;
+ BKE_render_resolution(&scene->r, false, &width, &height);
+ const RenderData *rd = ED_space_image_has_buffer(sima) ? RE_engine_get_render_data(re) :
+ &scene->r;
- /* get rectangle from operator */
+ /* Get rectangle from the operator. */
+ rctf border;
WM_operator_properties_border_to_rctf(op, &border);
UI_view2d_region_to_view_rctf(&region->v2d, &border, &border);
- /* actually set border */
+ /* Adjust for cropping. */
+ if ((rd->mode & (R_BORDER | R_CROP)) == (R_BORDER | R_CROP)) {
+ border.xmin = rd->border.xmin + border.xmin * (rd->border.xmax - rd->border.xmin);
+ border.xmax = rd->border.xmin + border.xmax * (rd->border.xmax - rd->border.xmin);
+ border.ymin = rd->border.ymin + border.ymin * (rd->border.ymax - rd->border.ymin);
+ border.ymax = rd->border.ymin + border.ymax * (rd->border.ymax - rd->border.ymin);
+ }
+
CLAMP(border.xmin, 0.0f, 1.0f);
CLAMP(border.ymin, 0.0f, 1.0f);
CLAMP(border.xmax, 0.0f, 1.0f);
CLAMP(border.ymax, 0.0f, 1.0f);
- scene->r.border = border;
- /* drawing a border surrounding the entire camera view switches off border rendering
- * or the border covers no pixels */
+ /* Drawing a border surrounding the entire camera view switches off border rendering
+ * or the border covers no pixels. */
if ((border.xmin <= 0.0f && border.xmax >= 1.0f && border.ymin <= 0.0f && border.ymax >= 1.0f) ||
(border.xmin == border.xmax || border.ymin == border.ymax)) {
scene->r.mode &= ~R_BORDER;
}
else {
+ /* Snap border to pixel boundaries, so drawing a border within a pixel selects that pixel. */
+ border.xmin = floorf(border.xmin * width) / width;
+ border.xmax = ceilf(border.xmax * width) / width;
+ border.ymin = floorf(border.ymin * height) / height;
+ border.ymax = ceilf(border.ymax * height) / height;
+
+ /* Set border. */
+ scene->r.border = border;
scene->r.mode |= R_BORDER;
}