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:
authorCampbell Barton <ideasman42@gmail.com>2017-06-16 00:30:27 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-06-16 00:34:23 +0300
commit4054914813e7ff72acabf6571742cbb0db3f682a (patch)
treeb99568fde0165637f2e6f42809f65cf7ed74a598 /source/blender/editors
parent281a4540e2385d3e2ba3da4a3290529a2ac7fd0f (diff)
UV manipulator from custom widgets branch
This isn't advanced, just adding to get custom manipulator branch from being too much out of sync with 2.8.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/ED_uvedit.h1
-rw-r--r--source/blender/editors/space_image/space_image.c41
-rw-r--r--source/blender/editors/transform/CMakeLists.txt1
-rw-r--r--source/blender/editors/transform/transform_manipulator2d.c271
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c8
5 files changed, 317 insertions, 5 deletions
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index cba2a440959..918489b1159 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -52,6 +52,7 @@ void ED_keymap_uvedit(struct wmKeyConfig *keyconf);
void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma);
bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]);
+bool ED_uvedit_center(Scene *scene, Image *ima, struct Object *obedit, float cent[2], char mode);
void ED_uvedit_select_all(struct BMesh *bm);
bool ED_object_get_active_image(struct Object *ob, int mat_nr,
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 56afdce7bb1..4b06cbe6b33 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -64,6 +64,7 @@
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_uvedit.h"
+#include "ED_transform.h"
#include "BIF_gl.h"
@@ -588,6 +589,27 @@ static int image_context(const bContext *C, const char *member, bContextDataResu
return 0;
}
+static void IMAGE_WGT_manipulator2d(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "UV Transform Manipulator";
+ wgt->idname = "IMAGE_WGT_manipulator2d";
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT;
+
+ wgt->poll = ED_widgetgroup_manipulator2d_poll;
+ wgt->setup = ED_widgetgroup_manipulator2d_setup;
+ wgt->refresh = ED_widgetgroup_manipulator2d_refresh;
+ wgt->draw_prepare = ED_widgetgroup_manipulator2d_draw_prepare;
+}
+
+static void image_widgets(void)
+{
+ wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure(
+ &(const struct wmManipulatorMapType_Params){SPACE_IMAGE, RGN_TYPE_WINDOW});
+
+ WM_manipulatorgrouptype_append_and_link(mmap_type, IMAGE_WGT_manipulator2d);
+}
+
/************************** main region ***************************/
/* sets up the fields of the View2D from zoom and offset */
@@ -651,6 +673,16 @@ static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
// image space manages own v2d
// UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
+ /* manipulators */
+ if (ar->manipulator_map == NULL) {
+ const struct wmManipulatorMapType_Params wmap_params = {
+ .spaceid = SPACE_IMAGE,
+ .regionid = RGN_TYPE_WINDOW,
+ };
+ ar->manipulator_map = WM_manipulatormap_new_from_type(&wmap_params);
+ }
+ WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
+
/* mask polls mode */
keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
@@ -676,7 +708,6 @@ static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_keymap_handler(&ar->handlers, keymap);
keymap = WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
-
}
static void image_main_region_draw(const bContext *C, ARegion *ar)
@@ -794,6 +825,8 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
}
+ WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D);
+
draw_image_cache(C, ar);
/* scrollers? */
@@ -810,6 +843,10 @@ static void image_main_region_listener(
{
/* context changes */
switch (wmn->category) {
+ case NC_GEOM:
+ if (ELEM(wmn->data, ND_DATA, ND_SELECT))
+ WM_manipulatormap_tag_refresh(ar->manipulator_map);
+ break;
case NC_GPENCIL:
if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
ED_region_tag_redraw(ar);
@@ -819,6 +856,7 @@ static void image_main_region_listener(
case NC_IMAGE:
if (wmn->action == NA_PAINTING)
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(ar->manipulator_map);
break;
case NC_MATERIAL:
if (wmn->data == ND_SHADING_LINKS) {
@@ -1049,6 +1087,7 @@ void ED_spacetype_image(void)
st->refresh = image_refresh;
st->listener = image_listener;
st->context = image_context;
+ st->manipulators = image_widgets;
st->id_remap = image_id_remap;
/* regions: main window */
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index 1a41d9ac95a..fda15545ead 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -46,6 +46,7 @@ set(SRC
transform_generics.c
transform_input.c
transform_manipulator.c
+ transform_manipulator2d.c
transform_ops.c
transform_orientations.c
transform_snap.c
diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c
new file mode 100644
index 00000000000..7990834ed8c
--- /dev/null
+++ b/source/blender/editors/transform/transform_manipulator2d.c
@@ -0,0 +1,271 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2016 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/transform/transform_manipulator2d.c
+ * \ingroup edtransform
+ *
+ * \name 2D Transform Manipulator
+ *
+ * Used for UV/Image Editor
+ */
+
+#include "BKE_context.h"
+#include "BKE_editmesh.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
+
+#include "ED_image.h"
+#include "ED_screen.h"
+#include "ED_uvedit.h"
+#include "ED_manipulator_library.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+#include "wm.h" /* XXX */
+
+#include "transform.h" /* own include */
+
+/* axes as index */
+enum {
+ MAN2D_AXIS_TRANS_X = 0,
+ MAN2D_AXIS_TRANS_Y,
+
+ MAN2D_AXIS_LAST,
+};
+
+typedef struct ManipulatorGroup2D {
+ wmManipulator *translate_x,
+ *translate_y;
+
+ /* Current origin in view space, used to update widget origin for possible view changes */
+ float origin[2];
+} ManipulatorGroup2D;
+
+
+/* **************** Utilities **************** */
+
+/* loop over axes */
+#define MAN2D_ITER_AXES_BEGIN(axis, axis_idx) \
+ { \
+ wmManipulator *axis; \
+ int axis_idx; \
+ for (axis_idx = 0; axis_idx < MAN2D_AXIS_LAST; axis_idx++) { \
+ axis = manipulator2d_get_axis_from_index(man, axis_idx);
+
+#define MAN2D_ITER_AXES_END \
+ } \
+ } ((void)0)
+
+static wmManipulator *manipulator2d_get_axis_from_index(const ManipulatorGroup2D *man, const short axis_idx)
+{
+ BLI_assert(IN_RANGE_INCL(axis_idx, (float)MAN2D_AXIS_TRANS_X, (float)MAN2D_AXIS_TRANS_Y));
+
+ switch (axis_idx) {
+ case MAN2D_AXIS_TRANS_X:
+ return man->translate_x;
+ case MAN2D_AXIS_TRANS_Y:
+ return man->translate_y;
+ }
+
+ return NULL;
+}
+
+static void manipulator2d_get_axis_color(const int axis_idx, float *r_col, float *r_col_hi)
+{
+ const float alpha = 0.6f;
+ const float alpha_hi = 1.0f;
+ int col_id;
+
+ switch (axis_idx) {
+ case MAN2D_AXIS_TRANS_X:
+ col_id = TH_AXIS_X;
+ break;
+ case MAN2D_AXIS_TRANS_Y:
+ col_id = TH_AXIS_Y;
+ break;
+ }
+
+ UI_GetThemeColor4fv(col_id, r_col);
+
+ copy_v4_v4(r_col_hi, r_col);
+ r_col[3] *= alpha;
+ r_col_hi[3] *= alpha_hi;
+}
+
+static ManipulatorGroup2D *manipulatorgroup2d_init(wmManipulatorGroup *mgroup)
+{
+ ManipulatorGroup2D *man = MEM_callocN(sizeof(ManipulatorGroup2D), __func__);
+
+ man->translate_x = ED_manipulator_arrow2d_new(mgroup, "translate_x");
+ man->translate_y = ED_manipulator_arrow2d_new(mgroup, "translate_y");
+
+ return man;
+}
+
+/**
+ * Calculates origin in view space, use with #manipulator2d_origin_to_region.
+ */
+static void manipulator2d_calc_origin(const bContext *C, float *r_origin)
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Image *ima = ED_space_image(sima);
+
+ if (sima->around == V3D_AROUND_CURSOR) {
+ copy_v2_v2(r_origin, sima->cursor);
+ }
+ else {
+ ED_uvedit_center(CTX_data_scene(C), ima, CTX_data_edit_object(C), r_origin, sima->around);
+ }
+}
+
+/**
+ * Convert origin (or any other point) from view to region space.
+ */
+BLI_INLINE void manipulator2d_origin_to_region(ARegion *ar, float *r_origin)
+{
+ UI_view2d_view_to_region_fl(&ar->v2d, r_origin[0], r_origin[1], &r_origin[0], &r_origin[1]);
+}
+
+/**
+ * Custom handler for manipulator widgets
+ */
+static void manipulator2d_modal(
+ bContext *C, wmManipulator *widget, const wmEvent *UNUSED(event), const int UNUSED(flag))
+{
+ ARegion *ar = CTX_wm_region(C);
+ float origin[3];
+
+ manipulator2d_calc_origin(C, origin);
+ manipulator2d_origin_to_region(ar, origin);
+ WM_manipulator_set_origin(widget, origin);
+
+ ED_region_tag_redraw(ar);
+}
+
+void ED_widgetgroup_manipulator2d_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ ManipulatorGroup2D *man = manipulatorgroup2d_init(mgroup);
+ mgroup->customdata = man;
+
+ MAN2D_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ const float offset[3] = {0.0f, 0.2f};
+
+ float col[4], col_hi[4];
+ manipulator2d_get_axis_color(axis_idx, col, col_hi);
+
+ /* custom handler! */
+ WM_manipulator_set_fn_custom_modal(axis, manipulator2d_modal);
+ /* set up widget data */
+ ED_manipulator_arrow2d_set_angle(axis, -M_PI_2 * axis_idx);
+ ED_manipulator_arrow2d_set_line_len(axis, 0.8f);
+ WM_manipulator_set_offset(axis, offset);
+ WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH);
+ WM_manipulator_set_scale(axis, U.manipulator_scale);
+ WM_manipulator_set_color(axis, col);
+ WM_manipulator_set_color_highlight(axis, col_hi);
+
+ /* assign operator */
+ PointerRNA *ptr = WM_manipulator_set_operator(axis, "TRANSFORM_OT_translate");
+ int constraint[3] = {0.0f};
+ constraint[(axis_idx + 1) % 2] = 1;
+ if (RNA_struct_find_property(ptr, "constraint_axis"))
+ RNA_boolean_set_array(ptr, "constraint_axis", constraint);
+ RNA_boolean_set(ptr, "release_confirm", 1);
+ }
+ MAN2D_ITER_AXES_END;
+}
+
+void ED_widgetgroup_manipulator2d_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ ManipulatorGroup2D *man = mgroup->customdata;
+ float origin[3];
+
+ manipulator2d_calc_origin(C, origin);
+ copy_v2_v2(man->origin, origin);
+}
+
+void ED_widgetgroup_manipulator2d_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ ManipulatorGroup2D *man = mgroup->customdata;
+ float origin[3] = {UNPACK2(man->origin), 0.0f};
+
+ manipulator2d_origin_to_region(CTX_wm_region(C), origin);
+
+ MAN2D_ITER_AXES_BEGIN(axis, axis_idx)
+ {
+ WM_manipulator_set_origin(axis, origin);
+ }
+ MAN2D_ITER_AXES_END;
+}
+
+/* TODO (Julian)
+ * - Called on every redraw, better to do a more simple poll and check for selection in _refresh
+ * - UV editing only, could be expanded for other things.
+ */
+bool ED_widgetgroup_manipulator2d_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Object *obedit = CTX_data_edit_object(C);
+
+ if (ED_space_image_show_uvedit(sima, obedit)) {
+ Image *ima = ED_space_image(sima);
+ Scene *scene = CTX_data_scene(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ /* check if there's a selected poly */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, ima, efa))
+ continue;
+
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index ced84e04f25..0e33525ceff 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -670,7 +670,7 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[
return (sel != 0);
}
-static bool uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], char mode)
+bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], char mode)
{
bool changed = false;
@@ -1427,7 +1427,7 @@ static void uv_weld_align(bContext *C, int tool)
tool = (max[0] - min[0] >= max[1] - min[1]) ? 'y' : 'x';
}
- uvedit_center(scene, ima, obedit, cent, 0);
+ ED_uvedit_center(scene, ima, obedit, cent, 0);
if (tool == 'x' || tool == 'w') {
BMIter iter, liter;
@@ -3124,7 +3124,7 @@ static void uv_snap_cursor_to_pixels(SpaceImage *sima)
static bool uv_snap_cursor_to_selection(Scene *scene, Image *ima, Object *obedit, SpaceImage *sima)
{
- return uvedit_center(scene, ima, obedit, sima->cursor, sima->around);
+ return ED_uvedit_center(scene, ima, obedit, sima->cursor, sima->around);
}
static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
@@ -3338,7 +3338,7 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op)
case 2:
{
float center[2];
- if (uvedit_center(scene, ima, obedit, center, sima->around)) {
+ if (ED_uvedit_center(scene, ima, obedit, center, sima->around)) {
float offset[2];
sub_v2_v2v2(offset, sima->cursor, center);
changed = uv_snap_uvs_offset(scene, ima, obedit, offset);