From 05755d307a140934aba98e55e9c7536c0cba0947 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Sep 2012 05:29:38 +0000 Subject: [PATCH] fix [#31946] Masking doesn't respect pixel ratio --- source/blender/blenkernel/BKE_image.h | 4 ++ source/blender/blenkernel/BKE_mask.h | 8 ++- source/blender/blenkernel/BKE_movieclip.h | 7 ++- source/blender/blenkernel/intern/image.c | 37 +++++++++++ source/blender/blenkernel/intern/mask.c | 42 ++++++++++--- source/blender/blenkernel/intern/movieclip.c | 12 +++- source/blender/editors/include/ED_image.h | 4 +- source/blender/editors/mask/mask_edit.c | 13 +--- .../blender/editors/space_clip/clip_editor.c | 2 +- .../blender/editors/space_image/image_edit.c | 50 ++++----------- .../blender/editors/space_image/image_ops.c | 2 +- source/blender/editors/transform/transform.c | 63 +++++++++++++++---- .../editors/uvedit/uvedit_unwrap_ops.c | 6 +- 13 files changed, 166 insertions(+), 84 deletions(-) diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 10f10cb1d13..67461281674 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -202,6 +202,10 @@ int BKE_image_scale(struct Image *image, int width, int height); /* check if texture has alpha (depth=32) */ int BKE_image_has_alpha(struct Image *image); +void BKE_image_get_size(struct Image *image, struct ImageUser *iuser, int *width, int *height); +void BKE_image_get_size_fl(struct Image *image, struct ImageUser *iuser, float size[2]); +void BKE_image_get_aspect(struct Image *image, float *aspx, float *aspy); + /* image_gen.c */ void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, const float color[4]); void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int height, int width); diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h index 48615e638e8..9ce678d8988 100644 --- a/source/blender/blenkernel/BKE_mask.h +++ b/source/blender/blenkernel/BKE_mask.h @@ -28,6 +28,8 @@ #ifndef __BKE_MASK_H__ #define __BKE_MASK_H__ +struct ImageUser; +struct Image; struct ListBase; struct Main; struct Mask; @@ -103,10 +105,12 @@ struct Mask *BKE_mask_copy(struct Mask *mask); void BKE_mask_free(struct Mask *mask); void BKE_mask_unlink(struct Main *bmain, struct Mask *mask); -void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2]); -void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); +void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); +void BKE_mask_coord_from_image(struct Image *image, struct ImageUser *iuser, float r_co[2], const float co[2]); void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame_size[2]); +void BKE_mask_coord_to_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]); +void BKE_mask_coord_to_image(struct Image *image, struct ImageUser *iuser, float r_co[2], const float co[2]); /* parenting */ diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 739b63ca174..25d2678ea47 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -51,9 +51,10 @@ struct ImBuf *BKE_movieclip_get_postprocessed_ibuf(struct MovieClip *clip, struc struct ImBuf *BKE_movieclip_get_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale, float *angle, int postprocess_flag); struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag, int cache_flag); void BKE_movieclip_get_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height); -int BKE_movieclip_get_duration(struct MovieClip *clip); -void BKE_movieclip_aspect(struct MovieClip *clip, float *aspx, float *aspy); -int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user); +void BKE_movieclip_get_size_fl(struct MovieClip *clip, struct MovieClipUser *user, float size[2]); +int BKE_movieclip_get_duration(struct MovieClip *clip); +void BKE_movieclip_get_aspect(struct MovieClip *clip, float *aspx, float *aspy); +int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user); void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr); void BKE_movieclip_update_scopes(struct MovieClip *clip, struct MovieClipUser *user, struct MovieClipScopes *scopes); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ac307e036bf..3f756e74b26 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2931,3 +2931,40 @@ int BKE_image_has_alpha(struct Image *image) else return 0; } + +void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height) +{ + ImBuf *ibuf = NULL; + void *lock; + + ibuf = BKE_image_acquire_ibuf(image, iuser, &lock); + + if (ibuf && ibuf->x > 0 && ibuf->y > 0) { + *width = ibuf->x; + *height = ibuf->y; + } + else { + *width = IMG_SIZE_FALLBACK; + *height = IMG_SIZE_FALLBACK; + } + + BKE_image_release_ibuf(image, lock); +} + +void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2]) +{ + int width, height; + BKE_image_get_size(image, iuser, &width, &height); + + size[0] = (float)width; + size[1] = (float)height; + +} + +void BKE_image_get_aspect(Image *image, float *aspx, float *aspy) +{ + *aspx = 1.0; + + /* x is always 1 */ + *aspy = image->aspy / image->aspx; +} diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index f73fb3879b8..06d063574a5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -55,6 +55,7 @@ #include "BKE_sequencer.h" #include "BKE_tracking.h" #include "BKE_movieclip.h" +#include "BKE_image.h" static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) { @@ -1010,14 +1011,26 @@ void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float fra } void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) { - int width, height; + float aspx, aspy; float frame_size[2]; /* scaling for the clip */ - BKE_movieclip_get_size(clip, user, &width, &height); + BKE_movieclip_get_size_fl(clip, user, frame_size); + BKE_movieclip_get_aspect(clip, &aspx, &aspy); - frame_size[0] = (float)width; - frame_size[1] = (float)height; + frame_size[1] *= (aspy / aspx); + + BKE_mask_coord_from_frame(r_co, co, frame_size); +} +void BKE_mask_coord_from_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2]) +{ + float aspx, aspy; + float frame_size[2]; + + BKE_image_get_size_fl(image, iuser, frame_size); + BKE_image_get_aspect(image, &aspx, &aspy); + + frame_size[1] *= (aspy / aspx); BKE_mask_coord_from_frame(r_co, co, frame_size); } @@ -1040,14 +1053,27 @@ void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame } void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) { - int width, height; + float aspx, aspy; float frame_size[2]; /* scaling for the clip */ - BKE_movieclip_get_size(clip, user, &width, &height); + BKE_movieclip_get_size_fl(clip, user, frame_size); + BKE_movieclip_get_aspect(clip, &aspx, &aspy); - frame_size[0] = (float)width; - frame_size[1] = (float)height; + frame_size[1] /= (aspy / aspx); + + BKE_mask_coord_to_frame(r_co, co, frame_size); +} +void BKE_mask_coord_to_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2]) +{ + float aspx, aspy; + float frame_size[2]; + + /* scaling for the clip */ + BKE_image_get_size_fl(image, iuser, frame_size); + BKE_image_get_aspect(image, &aspx, &aspy); + + frame_size[1] /= (aspy / aspx); BKE_mask_coord_to_frame(r_co, co, frame_size); } diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 06af812e1a0..268234c7e73 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1001,6 +1001,14 @@ void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, in IMB_freeImBuf(ibuf); } } +void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2]) +{ + int width, height; + BKE_movieclip_get_size(clip, user, &width, &height); + + size[0] = (float)width; + size[1] = (float)height; +} int BKE_movieclip_get_duration(MovieClip *clip) { @@ -1011,9 +1019,9 @@ int BKE_movieclip_get_duration(MovieClip *clip) return clip->len; } -void BKE_movieclip_aspect(MovieClip *clip, float *aspx, float *aspy) +void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy) { - *aspx = *aspy = 1.0; + *aspx = 1.0; /* x is always 1 */ *aspy = clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect; diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index 6f41bef81f4..87f12b8ac9c 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -60,9 +60,7 @@ void ED_space_image_get_uv_aspect(struct SpaceImage *sima, float *aspx, float *a void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings *settings); void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSettings *settings); -void ED_image_get_size(struct Image *ima, int *width, int *height); -void ED_image_get_aspect(struct Image *ima, float *aspx, float *aspy); -void ED_image_get_uv_aspect(struct Image *ima, float *aspx, float *aspy); +void ED_image_get_uv_aspect(struct Image *ima, struct ImageUser *iuser, float *aspx, float *aspy); void ED_image_mouse_pos(struct SpaceImage *sima, struct ARegion *ar, const int mval[2], float co[2]); void ED_image_point_pos(struct SpaceImage *sima, struct ARegion *ar, float x, float y, float *xr, float *yr); void ED_image_point_pos__reverse(struct SpaceImage *sima, struct ARegion *ar, const float co[2], float r_co[2]); diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c index 85a8ae11111..39a19bdaa5f 100644 --- a/source/blender/editors/mask/mask_edit.c +++ b/source/blender/editors/mask/mask_edit.c @@ -109,11 +109,9 @@ void ED_mask_mouse_pos(ScrArea *sa, ARegion *ar, const int mval[2], float co[2]) } case SPACE_IMAGE: { - float frame_size[2]; SpaceImage *sima = sa->spacedata.first; - ED_space_image_get_size_fl(sima, frame_size); ED_image_mouse_pos(sima, ar, mval, co); - BKE_mask_coord_from_frame(co, co, frame_size); + BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co); break; } default: @@ -149,11 +147,9 @@ void ED_mask_point_pos(ScrArea *sa, ARegion *ar, float x, float y, float *xr, fl break; case SPACE_IMAGE: { - float frame_size[2]; SpaceImage *sima = sa->spacedata.first; - ED_space_image_get_size_fl(sima, frame_size); ED_image_point_pos(sima, ar, x, y, &co[0], &co[1]); - BKE_mask_coord_from_frame(co, co, frame_size); + BKE_mask_coord_from_image(sima->image, &sima->iuser, co, co); break; } default: @@ -192,13 +188,10 @@ void ED_mask_point_pos__reverse(ScrArea *sa, ARegion *ar, float x, float y, floa break; case SPACE_IMAGE: { - float frame_size[2]; SpaceImage *sima = sa->spacedata.first; - ED_space_image_get_size_fl(sima, frame_size); - co[0] = x; co[1] = y; - BKE_mask_coord_to_frame(co, co, frame_size); + BKE_mask_coord_to_image(sima->image, &sima->iuser, co, co); ED_image_point_pos__reverse(sima, ar, co, co); break; } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 7a54a39ee48..08ad6aac970 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -158,7 +158,7 @@ void ED_space_clip_get_aspect(SpaceClip *sc, float *aspx, float *aspy) MovieClip *clip = ED_space_clip_get_clip(sc); if (clip) - BKE_movieclip_aspect(clip, aspx, aspy); + BKE_movieclip_get_aspect(clip, aspx, aspy); else *aspx = *aspy = 1.0f; diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index ac9883b411d..360cbc3f026 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -143,27 +143,6 @@ int ED_space_image_has_buffer(SpaceImage *sima) return has_buffer; } -void ED_image_get_size(Image *ima, int *width, int *height) -{ - ImBuf *ibuf = NULL; - void *lock; - - if (ima) - ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); - - if (ibuf && ibuf->x > 0 && ibuf->y > 0) { - *width = ibuf->x; - *height = ibuf->y; - } - else { - *width = IMG_SIZE_FALLBACK; - *height = IMG_SIZE_FALLBACK; - } - - if (ima) - BKE_image_release_ibuf(ima, lock); -} - void ED_space_image_get_size(SpaceImage *sima, int *width, int *height) { Scene *scene = sima->iuser.scene; @@ -205,23 +184,18 @@ void ED_space_image_get_size_fl(SpaceImage *sima, float size[2]) size[1] = size_i[1]; } -void ED_image_get_aspect(Image *ima, float *aspx, float *aspy) -{ - *aspx = *aspy = 1.0; - - if ((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) || - (ima->aspx == 0.0f || ima->aspy == 0.0f)) - { - return; - } - - /* x is always 1 */ - *aspy = ima->aspy / ima->aspx; -} void ED_space_image_get_aspect(SpaceImage *sima, float *aspx, float *aspy) { - ED_image_get_aspect(ED_space_image(sima), aspx, aspy); + Image *ima = sima->image; + if ((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) || + (ima->aspx == 0.0f || ima->aspy == 0.0f)) + { + *aspx = *aspy = 1.0; + } + else { + BKE_image_get_aspect(ima, aspx, aspy); + } } void ED_space_image_get_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy) @@ -254,12 +228,12 @@ void ED_space_image_get_uv_aspect(SpaceImage *sima, float *aspx, float *aspy) } } -void ED_image_get_uv_aspect(Image *ima, float *aspx, float *aspy) +void ED_image_get_uv_aspect(Image *ima, ImageUser *iuser, float *aspx, float *aspy) { int w, h; - ED_image_get_aspect(ima, aspx, aspy); - ED_image_get_size(ima, &w, &h); + BKE_image_get_aspect(ima, aspx, aspy); + BKE_image_get_size(ima, iuser, &w, &h); *aspx *= (float)w; *aspy *= (float)h; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 8d9d1be61e5..86722c5158e 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -632,7 +632,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op)) ima = ED_space_image(sima); ED_space_image_get_size(sima, &width, &height); - ED_image_get_aspect(ima, &aspx, &aspy); + ED_space_image_get_aspect(sima, &aspx, &aspy); width = width * aspx; height = height * aspy; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 23af0d6f8d6..a3fb4e851e2 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -65,6 +65,7 @@ #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_unit.h" +#include "BKE_mask.h" #include "ED_image.h" #include "ED_keyframing.h" @@ -228,9 +229,27 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) project_int_noclip(t->ar, vec, adr); } else if (t->spacetype == SPACE_IMAGE) { + SpaceImage *sima = t->sa->spacedata.first; + if (t->options & CTX_MASK) { + /* not working quite right, TODO (see below too) */ + float aspx, aspy; float v[2]; - ED_mask_point_pos__reverse(t->sa, t->ar, vec[0], vec[1], &v[0], &v[1]); + + ED_space_image_get_aspect(sima, &aspx, &aspy); + + copy_v2_v2(v, vec); + + v[0] = v[0] / aspx; + v[1] = v[1] / aspy; + + BKE_mask_coord_to_image(sima->image, &sima->iuser, v, v); + + v[0] = v[0] / aspx; + v[1] = v[1] / aspy; + + ED_image_point_pos__reverse(sima, t->ar, v, v); + adr[0] = v[0]; adr[1] = v[1]; } @@ -278,23 +297,41 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) adr[1] = out[1]; } else if (t->spacetype == SPACE_CLIP) { - float v[2]; - float aspx = 1.0f, aspy = 1.0f; + SpaceClip *sc = t->sa->spacedata.first; - copy_v2_v2(v, vec); + if (t->options & CTX_MASK) { + /* not working quite right, TODO (see above too) */ + float aspx, aspy; + float v[2]; - if (t->options & CTX_MOVIECLIP) { + ED_space_clip_get_aspect(sc, &aspx, &aspy); + + copy_v2_v2(v, vec); + + v[0] = v[0] / aspx; + v[1] = v[1] / aspy; + + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, v, v); + + v[0] = v[0] / aspx; + v[1] = v[1] / aspy; + + ED_clip_point_stable_pos__reverse(sc, t->ar, v, v); + + adr[0] = v[0]; + adr[1] = v[1]; + } + else if (t->options & CTX_MOVIECLIP) { + float v[2], aspx, aspy; + + copy_v2_v2(v, vec); ED_space_clip_get_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); - } - else if (t->options & CTX_MASK) { - /* MASKTODO - not working as expected */ - ED_space_clip_get_aspect(t->sa->spacedata.first, &aspx, &aspy); - } - v[0] /= aspx; - v[1] /= aspy; + v[0] /= aspx; + v[1] /= aspy; - UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1); + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr + 1); + } } else if (t->spacetype == SPACE_NODE) { UI_view2d_to_region_no_clip((View2D *)t->view, vec[0], vec[1], adr, adr + 1); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index c1fb3ee3807..c95b2e85248 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -201,7 +201,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, float aspx, aspy; tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - ED_image_get_uv_aspect(tf->tpage, &aspx, &aspy); + ED_image_get_uv_aspect(tf->tpage, NULL, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -393,7 +393,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e float aspx, aspy; tf = CustomData_bmesh_get(&em->bm->pdata, editFace->head.data, CD_MTEXPOLY); - ED_image_get_uv_aspect(tf->tpage, &aspx, &aspy); + ED_image_get_uv_aspect(tf->tpage, NULL, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -1021,7 +1021,7 @@ static void correct_uv_aspect(BMEditMesh *em) MTexPoly *tf; tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - ED_image_get_uv_aspect(tf->tpage, &aspx, &aspy); + ED_image_get_uv_aspect(tf->tpage, NULL, &aspx, &aspy); } if (aspx == aspy)