[Bf-blender-cvs] [a2bb480] soc-2016-uv_tools: Added "Scale to bounds" operator to scale selected islands to UV boundaries
Phil Gosch
noreply at git.blender.org
Thu Jun 9 16:51:27 CEST 2016
Commit: a2bb48080d59879b43309ae5c27e9ffda053a4d8
Author: Phil Gosch
Date: Thu Jun 9 16:50:49 2016 +0200
Branches: soc-2016-uv_tools
https://developer.blender.org/rBa2bb48080d59879b43309ae5c27e9ffda053a4d8
Added "Scale to bounds" operator to scale selected islands to UV boundaries
Options:
* Keep aspect ratio: If checked the aspect ratio of the selected uv islands is preserved
* Individual: If checked the individual uv islands are all scaled to fit the bounds, otherwise the selections are scaled as a whole
Note: Menu locations/shortcuts are to be discussed with users and not to be seen as final
===================================================================
M release/scripts/startup/bl_ui/space_image.py
M source/blender/editors/include/ED_uvedit.h
M source/blender/editors/uvedit/uvedit_ops.c
M source/blender/editors/uvedit/uvedit_unwrap_ops.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 49a4d3d..aadd003 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -348,6 +348,7 @@ class IMAGE_MT_uvs(Menu):
layout.operator("uv.mark_seam", text="Clear Seam").clear = True
layout.operator("uv.seams_from_islands")
layout.operator("mesh.faces_mirror_uv")
+ layout.operator("uv.scale_to_bounds")
layout.separator()
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index f812fe5..119e23d 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -109,6 +109,9 @@ void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel)
/* select shortest path */
bool ED_uvedit_shortest_path_select(struct Scene *scene, struct Object *ob, struct BMesh *bm, bool topo_dist);
+/* scale to bounds */
+void ED_uvedit_scale_to_bounds(struct Scene *scene, struct Object *ob,struct BMesh *bm);
+
/* uvedit_draw.c */
void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]);
void ED_uvedit_draw_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 5caeac8..7b526e6 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -1617,6 +1617,99 @@ static void UV_OT_select_shortest_path(wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "topological_distance", 0, "Topological Distance", "Find the minimum number of steps, ignoring spatial distance");
}
+/* ******************** scale to bounds operator **************** */
+
+static int uv_scale_to_bounds_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Image *ima = CTX_data_edit_image(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ MLoopUV *luv;
+ MTexPoly *tf;
+ float dx, dy, min[2], max[2];
+
+ const bool keep_aspect = RNA_boolean_get(op->ptr, "keep_aspect_ratio");
+ const bool individual = RNA_boolean_get(op->ptr, "individual_islands");
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
+ if (individual){
+ ED_uvedit_scale_to_bounds(scene, obedit, bm);
+
+ return OPERATOR_FINISHED;
+ }
+
+ INIT_MINMAX2(min, max);
+
+ BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
+
+ if (!uvedit_face_visible_test(scene, ima, efa, tf) || !uvedit_face_select_test(scene, efa, cd_loop_uv_offset))
+ continue;
+
+ BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ minmax_v2v2_v2(min, max, luv->uv);
+ }
+ }
+
+ /* rescale UV to be in 1/1 */
+ dx = (max[0] - min[0]);
+ dy = (max[1] - min[1]);
+
+ if (dx > 0.0f)
+ dx = 1.0f / dx;
+ if (dy > 0.0f)
+ dy = 1.0f / dy;
+
+ if (keep_aspect) {
+ if (dx >= dy) dx = dy;
+ else if (dy > dx) dy = dx;
+ }
+
+ BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
+
+ if (!uvedit_face_visible_test(scene, ima, efa, tf) || !uvedit_face_select_test(scene, efa, cd_loop_uv_offset))
+ continue;
+
+ BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+
+ luv->uv[0] = (luv->uv[0] - min[0]) * dx;
+ luv->uv[1] = (luv->uv[1] - min[1]) * dy;
+ }
+ }
+
+ DAG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UV_OT_scale_to_bounds(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Scale To Bounds";
+ ot->description = "Scale the selection to fit UV boundaries";
+ ot->idname = "UV_OT_scale_to_bounds";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = uv_scale_to_bounds_exec;
+ ot->poll = ED_operator_uvedit;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "keep_aspect_ratio", 1, "Keep Aspect Ratio", "Keep the current aspect ratio of the selection");
+ RNA_def_boolean(ot->srna, "individual_islands", 0, "Individual", "Scale individual islands or the selection as a whole");
+}
/* ******************** align operator **************** */
@@ -4397,6 +4490,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_snap_cursor);
WM_operatortype_append(UV_OT_snap_selected);
+ WM_operatortype_append(UV_OT_scale_to_bounds);
WM_operatortype_append(UV_OT_align);
WM_operatortype_append(UV_OT_stitch);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index df0473d..1131f7c 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -750,6 +750,17 @@ bool ED_uvedit_shortest_path_select(Scene *scene, Object *ob, BMesh *bm, bool to
return path_found;
}
+/* ******************** Scale To Bounds operator **************** */
+void ED_uvedit_scale_to_bounds(Scene *scene, Object *ob, BMesh *bm)
+{
+ ParamHandle *handle;
+ int hparams = set_handle_params(true, false, true, true, false);
+ handle = construct_param_handle(scene, ob, bm, hparams);
+ param_scale_bounds(handle);
+ param_flush(handle);
+ param_delete(handle);
+}
+
/* ******************** Pack Islands operator **************** */
void ED_uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate)
More information about the Bf-blender-cvs
mailing list