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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-02-07 04:27:46 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-02-07 04:27:46 +0300
commit591ab657d609821b891303f638f9a482a8370640 (patch)
treed2989efa86811aef84e9d60301f587e58acfea97 /source/blender/editors/uvedit/uvedit_ops.c
parentd3dd4f6a866ed0a28caa1e7c5a5011901d78fdcd (diff)
2.5: UV Editor, more operators.
Border Select Circle Select Pin Select Pinned Unwrap Minimize Stretch Pack Islands Average Islands Scale Snap Cursor Snap Selection
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_ops.c')
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c1043
1 files changed, 578 insertions, 465 deletions
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 71e64886e34..86f5c782ca3 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -54,8 +54,6 @@
#include "BKE_report.h"
#include "BKE_utildefines.h"
-#include "IMB_imbuf_types.h" // XXX remove?
-
#include "BIF_transform.h"
#include "ED_mesh.h"
@@ -71,15 +69,11 @@
#include "UI_view2d.h"
#include "uvedit_intern.h"
-
-/* local prototypes */
-static void sel_uvco_inside_radius(SpaceImage *sima, Scene *scene, short sel, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, short select_index);
-void uvedit_selectionCB(SpaceImage *sima, Scene *scene, ARegion *ar, short selecting, Object *obedit, short *mval, float rad); /* used in edit.c */
-void uvface_setsel__internal(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, short select);
+#include "../space_image/image_intern.h"
/************************* state testing ************************/
-int ED_uvedit_test_silent(Object *obedit)
+int ED_uvedit_test(Object *obedit)
{
if(obedit->type != OB_MESH)
return 0;
@@ -87,14 +81,6 @@ int ED_uvedit_test_silent(Object *obedit)
return EM_texFaceCheck(((Mesh*)obedit->data)->edit_mesh);
}
-int ED_uvedit_test(Object *obedit)
-{
- // XXX if(!obedit)
- // XXX error("Enter Edit Mode to perform this action");
-
- return ED_uvedit_test_silent(obedit);
-}
-
/************************* assign image ************************/
void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *previma)
@@ -162,7 +148,7 @@ void ED_uvedit_set_tile(Scene *scene, Object *obedit, Image *ima, int curtile, i
MTFace *tf;
/* verify if we have something to do */
- if(!ima || !ED_uvedit_test_silent(obedit))
+ if(!ima || !ED_uvedit_test(obedit))
return;
/* skip assigning these procedural images... */
@@ -193,19 +179,11 @@ void ED_uvedit_set_tile(Scene *scene, Object *obedit, Image *ima, int curtile, i
/*********************** space conversion *********************/
-static void uvedit_pixel_to_float(bContext *C, float *dist, float pixeldist)
+static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist)
{
- ImBuf *ibuf= CTX_data_edit_image_buffer(C);
- float width, height;
+ int width, height;
- if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
- width= ibuf->x;
- height= ibuf->y;
- }
- else {
- width= 256.0f;
- height= 256.0f;
- }
+ get_space_image_size(sima, &width, &height);
dist[0]= pixeldist/width;
dist[1]= pixeldist/height;
@@ -946,12 +924,6 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2]
/* ******************** mirror operator **************** */
-/* XXX */
-#if 0
- short mode= 0;
- mode= pupmenu("Mirror%t|X Axis%x1|Y Axis%x2|");
-#endif
-
static int mirror_exec(bContext *C, wmOperator *op)
{
float mat[3][3];
@@ -984,7 +956,7 @@ void UV_OT_mirror(wmOperatorType *ot)
/* identifiers */
ot->name= "Mirror";
ot->idname= "UV_OT_mirror";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= mirror_exec;
@@ -996,22 +968,6 @@ void UV_OT_mirror(wmOperatorType *ot)
/* ******************** align operator **************** */
-/* XXX */
-#if 0
-void weld_align_menu_tface_uv(bContext *C)
-{
- short mode= 0;
-
- mode= pupmenu("Weld/Align%t|Weld%x1|Align Auto%x2|Align X%x3|Align Y%x4");
-
- if(mode==-1) return;
- if(mode==1) weld_align_uv(C, 'w');
- else if(mode==2) weld_align_uv(C, 'a');
- else if(mode==3) weld_align_uv(C, 'x');
- else if(mode==4) weld_align_uv(C, 'y');
-}
-#endif
-
static void weld_align_uv(bContext *C, int tool)
{
Scene *scene;
@@ -1083,7 +1039,7 @@ static void weld_align_uv(bContext *C, int tool)
}
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); // XXX
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
}
static int align_exec(bContext *C, wmOperator *op)
@@ -1104,7 +1060,7 @@ void UV_OT_align(wmOperatorType *ot)
/* identifiers */
ot->name= "Align";
ot->idname= "UV_OT_align";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= align_exec;
@@ -1128,7 +1084,7 @@ void UV_OT_weld(wmOperatorType *ot)
/* identifiers */
ot->name= "Weld";
ot->idname= "UV_OT_weld";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= weld_exec;
@@ -1145,6 +1101,7 @@ typedef struct UVVertAverage {
static int stitch_exec(bContext *C, wmOperator *op)
{
+ SpaceImage *sima;
Scene *scene;
Object *obedit;
EditMesh *em;
@@ -1153,6 +1110,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
Image *ima;
MTFace *tf;
+ sima= (SpaceImage*)CTX_wm_space_data(C);
scene= CTX_data_scene(C);
obedit= CTX_data_edit_object(C);
em= ((Mesh*)obedit->data)->edit_mesh;
@@ -1165,7 +1123,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
int a, vtot;
pixels= RNA_float_get(op->ptr, "limit");
- uvedit_pixel_to_float(C, limit, pixels);
+ uvedit_pixel_to_float(sima, limit, pixels);
EM_init_index_arrays(em, 0, 0, 1);
vmap= EM_make_uv_vert_map(em, 1, 0, limit);
@@ -1298,7 +1256,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
}
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); // XXX
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
return OPERATOR_FINISHED;
}
@@ -1308,7 +1266,7 @@ void UV_OT_stitch(wmOperatorType *ot)
/* identifiers */
ot->name= "Stitch";
ot->idname= "UV_OT_stitch";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= stitch_exec;
@@ -1336,7 +1294,7 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
ima= CTX_data_edit_image(C);
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
- // XXX selectswap_mesh();
+ EM_select_swap(em);
}
else {
for(efa= em->faces.first; efa; efa= efa->next) {
@@ -1361,7 +1319,7 @@ void UV_OT_select_invert(wmOperatorType *ot)
/* identifiers */
ot->name= "Select Invert";
ot->idname= "UV_OT_select_invert";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= select_inverse_exec;
@@ -1386,7 +1344,7 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
ima= CTX_data_edit_image(C);
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
- // XXX deselectall_mesh();
+ EM_toggle_select_all(em);
}
else {
sel= 0;
@@ -1426,9 +1384,9 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
void UV_OT_de_select_all(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Select/Deselect All";
+ ot->name= "Select or Deselect All";
ot->idname= "UV_OT_de_select_all";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= de_select_all_exec;
@@ -1474,8 +1432,8 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
int flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
float limit[2], *hituv[4], penalty[2];
- uvedit_pixel_to_float(C, limit, 0.05f);
- uvedit_pixel_to_float(C, penalty, 5.0f);
+ uvedit_pixel_to_float(sima, limit, 0.05f);
+ uvedit_pixel_to_float(sima, penalty, 5.0f);
/* retrieve operation mode */
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
@@ -1494,9 +1452,6 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
sync= 0;
selectmode= scene->toolsettings->uv_selectmode;
sticky= sima->sticky;
-
- /* XXX if(sticky == SI_STICKY_VERTEX && (G.qual & LR_CTRLKEY))
- sticky= SI_STICKY_DISABLE;*/
}
/* find nearest element */
@@ -1711,10 +1666,6 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
}
}
- // XXX force_draw(1);
- // XXX BIF_undo_push("Select UV");
- // XXX rightmouse_transform();
-
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
@@ -1753,7 +1704,7 @@ void UV_OT_select(wmOperatorType *ot)
/* identifiers */
ot->name= "Select";
ot->idname= "UV_OT_select";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= select_exec;
@@ -1801,7 +1752,7 @@ void UV_OT_loop_select(wmOperatorType *ot)
/* identifiers */
ot->name= "Loop Select";
ot->idname= "UV_OT_loop_select";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= loop_select_exec;
@@ -1819,6 +1770,7 @@ void UV_OT_loop_select(wmOperatorType *ot)
static int select_linked_exec(bContext *C, wmOperator *op)
{
+ SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Image *ima= CTX_data_edit_image(C);
@@ -1832,7 +1784,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
}
extend= RNA_boolean_get(op->ptr, "extend");
- uvedit_pixel_to_float(C, limit, 0.05f);
+ uvedit_pixel_to_float(sima, limit, 0.05f);
select_linked(scene, ima, em, limit, NULL, extend);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
@@ -1846,7 +1798,7 @@ void UV_OT_select_linked(wmOperatorType *ot)
/* identifiers */
ot->name= "Select Linked";
ot->idname= "UV_OT_select_linked";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= select_linked_exec;
@@ -1899,7 +1851,7 @@ void UV_OT_unlink_selection(wmOperatorType *ot)
/* identifiers */
ot->name= "Unlink Selection";
ot->idname= "UV_OT_unlink_selection";
- ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
ot->exec= unlink_selection_exec;
@@ -1908,118 +1860,453 @@ void UV_OT_unlink_selection(wmOperatorType *ot)
/* ******************** border select operator **************** */
-void borderselect_sima(bContext *C, SpaceImage *sima, Scene *scene, Image *ima, Object *obedit, short whichuvs)
+/* This function sets the selection on tagged faces, need because settings the
+ * selection a face is done in a number of places but it also needs to respect
+ * the sticky modes for the UV verts, so dealing with the sticky modes is best
+ * done in a seperate function.
+ *
+ * De-selects faces that have been tagged on efa->tmp.l. */
+
+static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, short select)
+{
+ /* Selecting UV Faces with some modes requires us to change
+ * the selection in other faces (depending on the sticky mode).
+ *
+ * This only needs to be done when the Mesh is not used for
+ * selection (so for sticky modes, vertex or location based). */
+
+ EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditFace *efa;
+ MTFace *tf;
+ int nverts, i;
+
+ if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
+ /* Tag all verts as untouched, then touch the ones that have a face center
+ * in the loop and select all MTFace UV's that use a touched vert. */
+ EditVert *eve;
+
+ for(eve= em->verts.first; eve; eve= eve->next)
+ eve->tmp.l = 0;
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->tmp.l) {
+ if(efa->v4)
+ efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= efa->v4->tmp.l=1;
+ else
+ efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= 1;
+ }
+ }
+
+ /* now select tagged verts */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ nverts= efa->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ if((*(&efa->v1 + i))->tmp.l) {
+ if(select)
+ uvedit_uv_select(scene, efa, tf, i);
+ else
+ uvedit_uv_deselect(scene, efa, tf, i);
+ }
+ }
+ }
+ }
+ else if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
+ EditFace *efa_vlist;
+ MTFace *tf_vlist;
+ UvMapVert *start_vlist=NULL, *vlist_iter;
+ struct UvVertMap *vmap;
+ float limit[2];
+ int efa_index;
+ //EditVert *eve; /* removed vert counting for now */
+ //int a;
+
+ uvedit_pixel_to_float(sima, limit, 0.05);
+
+ EM_init_index_arrays(em, 0, 0, 1);
+ vmap= EM_make_uv_vert_map(em, 0, 0, limit);
+
+ /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */
+ /*for(a=0, eve= em->verts.first; eve; a++, eve= eve->next)
+ eve->tmp.l = a; */
+
+ if(vmap == NULL)
+ return;
+
+ for(efa_index=0, efa= em->faces.first; efa; efa_index++, efa= efa->next) {
+ if(efa->tmp.l) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ nverts= efa->v4? 4: 3;
+
+ for(i=0; i<nverts; i++) {
+ if(select)
+ uvedit_uv_select(scene, efa, tf, i);
+ else
+ uvedit_uv_deselect(scene, efa, tf, i);
+
+ vlist_iter= EM_get_uv_map_vert(vmap, (*(&efa->v1 + i))->tmp.l);
+
+ while (vlist_iter) {
+ if(vlist_iter->separate)
+ start_vlist = vlist_iter;
+
+ if(efa_index == vlist_iter->f)
+ break;
+
+ vlist_iter = vlist_iter->next;
+ }
+
+ vlist_iter = start_vlist;
+ while (vlist_iter) {
+
+ if(vlist_iter != start_vlist && vlist_iter->separate)
+ break;
+
+ if(efa_index != vlist_iter->f) {
+ efa_vlist = EM_get_face_for_index(vlist_iter->f);
+ tf_vlist = CustomData_em_get(&em->fdata, efa_vlist->data, CD_MTFACE);
+
+ if(select)
+ uvedit_uv_select(scene, efa_vlist, tf_vlist, vlist_iter->tfindex);
+ else
+ uvedit_uv_deselect(scene, efa_vlist, tf_vlist, vlist_iter->tfindex);
+ }
+ vlist_iter = vlist_iter->next;
+ }
+ }
+ }
+ }
+ EM_free_index_arrays();
+ EM_free_uv_vert_map(vmap);
+
+ }
+ else { /* SI_STICKY_DISABLE or scene->toolsettings->uv_flag & UV_SYNC_SELECTION */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->tmp.l) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if(select)
+ uvedit_face_select(scene, efa, tf);
+ else
+ uvedit_face_deselect(scene, efa, tf);
+ }
+ }
+ }
+}
+
+static int border_select_exec(bContext *C, wmOperator *op)
{
+ SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Image *ima= CTX_data_edit_image(C);
+ ARegion *ar= CTX_wm_region(C);
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
EditFace *efa;
MTFace *tface;
rcti rect;
rctf rectf;
- int val, ok = 1;
- short mval[2], select;
+ int change, pinned, select, faces;
- if(!ED_uvedit_test(obedit)) return;
+ /* get rectangle from operator */
+ rect.xmin= RNA_int_get(op->ptr, "xmin");
+ rect.ymin= RNA_int_get(op->ptr, "ymin");
+ rect.xmax= RNA_int_get(op->ptr, "xmax");
+ rect.ymax= RNA_int_get(op->ptr, "ymax");
+
+ UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
+ UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
- val= 0; // XXX get_border(&rect, 3);
- select = 0; // XXX (val==LEFTMOUSE) ? 1 : 0;
+ /* figure out what to select/deselect */
+ select= (RNA_int_get(op->ptr, "event_type") == LEFTMOUSE); // XXX hardcoded
+ pinned= RNA_boolean_get(op->ptr, "pinned");
- if(val) {
- mval[0]= rect.xmin;
- mval[1]= rect.ymin;
- // XXX areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]= rect.xmax;
- mval[1]= rect.ymax;
- // XXX areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- if(0) { // XXX draw_uvs_face_check() && whichuvs != UV_SELECT_PINNED) {
- float cent[2];
- ok = 0;
- for(efa= em->faces.first; efa; efa= efa->next) {
- /* assume not touched */
- efa->tmp.l = 0;
- tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- if(uvedit_face_visible(scene, ima, efa, tface)) {
- uv_center(tface->uv, cent, efa->v4 != NULL);
- if(BLI_in_rctf(&rectf, cent[0], cent[1])) {
- efa->tmp.l = ok = 1;
- }
+ if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION)
+ faces= (scene->selectmode == SCE_SELECT_FACE);
+ else
+ faces= (scene->toolsettings->uv_selectmode == UV_SELECT_FACE);
+
+ /* do actual selection */
+ if(faces && !pinned) {
+ /* handle face selection mode */
+ float cent[2];
+
+ change= 0;
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ /* assume not touched */
+ efa->tmp.l = 0;
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if(uvedit_face_visible(scene, ima, efa, tface)) {
+ uv_center(tface->uv, cent, efa->v4 != NULL);
+ if(BLI_in_rctf(&rectf, cent[0], cent[1])) {
+ efa->tmp.l = change = 1;
}
}
- /* (de)selects all tagged faces and deals with sticky modes */
- if(ok)
- uvface_setsel__internal(C, sima, scene, obedit, select);
}
- else {
- for(efa= em->faces.first; efa; efa= efa->next) {
- tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- if(uvedit_face_visible(scene, ima, efa, tface)) {
- if(whichuvs == UV_SELECT_ALL || (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) ) {
- /* UV_SYNC_SELECTION - cant do pinned selection */
- if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
- if(select) uvedit_uv_select(scene, efa, tface, 0);
- else uvedit_uv_deselect(scene, efa, tface, 0);
- }
- if(BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
- if(select) uvedit_uv_select(scene, efa, tface, 1);
- else uvedit_uv_deselect(scene, efa, tface, 1);
- }
- if(BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
- if(select) uvedit_uv_select(scene, efa, tface, 2);
- else uvedit_uv_deselect(scene, efa, tface, 2);
- }
- if(efa->v4 && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
- if(select) uvedit_uv_select(scene, efa, tface, 3);
- else uvedit_uv_deselect(scene, efa, tface, 3);
- }
- } else if(whichuvs == UV_SELECT_PINNED) {
- if((tface->unwrap & TF_PIN1) &&
- BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
-
- if(select) uvedit_uv_select(scene, efa, tface, 0);
- else uvedit_uv_deselect(scene, efa, tface, 0);
- }
- if((tface->unwrap & TF_PIN2) &&
- BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
-
- if(select) uvedit_uv_select(scene, efa, tface, 1);
- else uvedit_uv_deselect(scene, efa, tface, 1);
- }
- if((tface->unwrap & TF_PIN3) &&
- BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
-
- if(select) uvedit_uv_select(scene, efa, tface, 2);
- else uvedit_uv_deselect(scene, efa, tface, 2);
- }
- if((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
- if(select) uvedit_uv_select(scene, efa, tface, 3);
- else uvedit_uv_deselect(scene, efa, tface, 3);
- }
+
+ /* (de)selects all tagged faces and deals with sticky modes */
+ if(change)
+ uv_faces_do_sticky(C, sima, scene, obedit, select);
+ }
+ else {
+ /* other selection modes */
+ change= 1;
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if(uvedit_face_visible(scene, ima, efa, tface)) {
+ if(!pinned || (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) ) {
+ /* UV_SYNC_SELECTION - can't do pinned selection */
+ if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
+ if(select) uvedit_uv_select(scene, efa, tface, 0);
+ else uvedit_uv_deselect(scene, efa, tface, 0);
+ }
+ if(BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
+ if(select) uvedit_uv_select(scene, efa, tface, 1);
+ else uvedit_uv_deselect(scene, efa, tface, 1);
+ }
+ if(BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
+ if(select) uvedit_uv_select(scene, efa, tface, 2);
+ else uvedit_uv_deselect(scene, efa, tface, 2);
+ }
+ if(efa->v4 && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
+ if(select) uvedit_uv_select(scene, efa, tface, 3);
+ else uvedit_uv_deselect(scene, efa, tface, 3);
+ }
+ }
+ else if(pinned) {
+ if((tface->unwrap & TF_PIN1) &&
+ BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
+
+ if(select) uvedit_uv_select(scene, efa, tface, 0);
+ else uvedit_uv_deselect(scene, efa, tface, 0);
+ }
+ if((tface->unwrap & TF_PIN2) &&
+ BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
+
+ if(select) uvedit_uv_select(scene, efa, tface, 1);
+ else uvedit_uv_deselect(scene, efa, tface, 1);
+ }
+ if((tface->unwrap & TF_PIN3) &&
+ BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
+
+ if(select) uvedit_uv_select(scene, efa, tface, 2);
+ else uvedit_uv_deselect(scene, efa, tface, 2);
+ }
+ if((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
+ if(select) uvedit_uv_select(scene, efa, tface, 3);
+ else uvedit_uv_deselect(scene, efa, tface, 3);
}
}
}
}
- if(ok) {
- /* make sure newly selected vert selection is updated*/
- if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
- if(scene->selectmode != SCE_SELECT_FACE) {
- if(select) EM_select_flush(em);
- else EM_deselect_flush(em);
- }
+ }
+
+ if(change) {
+ /* make sure newly selected vert selection is updated*/
+ if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
+ if(scene->selectmode != SCE_SELECT_FACE) {
+ if(select) EM_select_flush(em);
+ else EM_deselect_flush(em);
}
- // XXX allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
-
- // XXX BIF_undo_push("Border select UV");
- // XXX scrarea_queue_winredraw(curarea);
}
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+void UV_OT_border_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Border Select";
+ ot->idname= "UV_OT_border_select";
+
+ /* api callbacks */
+ ot->invoke= WM_border_select_invoke;
+ ot->exec= border_select_exec;
+ ot->modal= WM_border_select_modal;
+ ot->poll= ED_operator_uvedit;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "pinned", 0, "Pinned", "Border select pinned UVs only.");
+
+ RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
+}
+
+/* ******************** circle select operator **************** */
+
+static void select_uv_inside_ellipse(SpaceImage *sima, Scene *scene, int select, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, int select_index)
+{
+ /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
+ float x, y, r2, *uv;
+
+ uv= tface->uv[index];
+
+ x= (uv[0] - offset[0])*ell[0];
+ y= (uv[1] - offset[1])*ell[1];
+
+ r2 = x*x + y*y;
+ if(r2 < 1.0) {
+ if(select) uvedit_uv_select(scene, efa, tface, select_index);
+ else uvedit_uv_deselect(scene, efa, tface, select_index);
}
}
-int snap_uv_sel_to_curs(Scene *scene, Image *ima, Object *obedit, View2D *v2d)
+int circle_select_exec(bContext *C, wmOperator *op)
{
+ SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ ARegion *ar= CTX_wm_region(C);
EditFace *efa;
MTFace *tface;
- short change = 0;
+ int x, y, radius, width, height, select;
+ float zoomx, zoomy, offset[2], ellipse[2];
+
+ /* get operator properties */
+ select= (RNA_int_get(op->ptr, "event_type") == LEFTMOUSE); // XXX hardcoded
+ x= RNA_int_get(op->ptr, "x");
+ y= RNA_int_get(op->ptr, "y");
+ radius= RNA_int_get(op->ptr, "radius");
+
+ /* compute ellipse size and location, not a circle since we deal
+ * with non square image. ellipse is normalized, r = 1.0. */
+ get_space_image_size(sima, &width, &height);
+ get_space_image_zoom(sima, ar, &zoomx, &zoomy);
+
+ ellipse[0]= width*zoomx/radius;
+ ellipse[1]= height*zoomy/radius;
+
+ UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]);
+
+ /* do selection */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ select_uv_inside_ellipse(sima, scene, select, efa, tface, 0, offset, ellipse, 0);
+ select_uv_inside_ellipse(sima, scene, select, efa, tface, 1, offset, ellipse, 1);
+ select_uv_inside_ellipse(sima, scene, select, efa, tface, 2, offset, ellipse, 2);
+ if(efa->v4)
+ select_uv_inside_ellipse(sima, scene, select, efa, tface, 3, offset, ellipse, 3);
+ }
+
+ if(select) EM_select_flush(em);
+ else EM_deselect_flush(em);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_circle_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Circle Select";
+ ot->idname= "UV_OT_circle_select";
+
+ /* api callbacks */
+ ot->invoke= WM_gesture_circle_invoke;
+ ot->modal= WM_gesture_circle_modal;
+ ot->exec= circle_select_exec;
+ ot->poll= ED_operator_uvedit;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
+}
+
+/* ******************** snap cursor operator **************** */
+
+static void snap_uv_to_pixel(float *uvco, float w, float h)
+{
+ uvco[0] = ((float)((int)((uvco[0]*w) + 0.5f)))/w;
+ uvco[1] = ((float)((int)((uvco[1]*h) + 0.5f)))/h;
+}
+
+static void snap_cursor_to_pixels(SpaceImage *sima, View2D *v2d)
+{
+ int width= 0, height= 0;
+
+ get_space_image_size(sima, &width, &height);
+ snap_uv_to_pixel(v2d->cursor, width, height);
+}
+
+static int snap_cursor_to_selection(Scene *scene, Image *ima, Object *obedit, View2D *v2d)
+{
+ return uvedit_center(scene, ima, obedit, v2d->cursor, 0);
+}
+
+static int snap_cursor_exec(bContext *C, wmOperator *op)
+{
+ SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Image *ima= CTX_data_edit_image(C);
+ ARegion *ar= CTX_wm_region(C);
+ int change= 0;
+
+ switch(RNA_boolean_get(op->ptr, "target")) {
+ case 0:
+ snap_cursor_to_pixels(sima, &ar->v2d);
+ change= 1;
+ break;
+ case 1:
+ change= snap_cursor_to_selection(scene, ima, obedit, &ar->v2d);
+ break;
+ }
+
+ if(!change)
+ return OPERATOR_CANCELLED;
+
+ ED_region_tag_redraw(ar);
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_snap_cursor(wmOperatorType *ot)
+{
+ static EnumPropertyItem target_items[] = {
+ {0, "PIXELS", "Pixels", ""},
+ {1, "SELECTION", "Selection", ""},
+ {0, NULL, NULL, NULL}};
+
+ /* identifiers */
+ ot->name= "Snap Cursor";
+ ot->idname= "UV_OT_snap_cursor";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec= snap_cursor_exec;
+ ot->poll= ED_operator_uvedit;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UV's to.");
+}
+
+/* ******************** snap selection operator **************** */
+
+static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, View2D *v2d)
+{
+ EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditFace *efa;
+ MTFace *tface;
+ short change= 0;
for(efa= em->faces.first; efa; efa= efa->next) {
tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
@@ -2029,13 +2316,15 @@ int snap_uv_sel_to_curs(Scene *scene, Image *ima, Object *obedit, View2D *v2d)
if(uvedit_uv_selected(scene, efa, tface, 2)) VECCOPY2D(tface->uv[2], v2d->cursor);
if(efa->v4)
if(uvedit_uv_selected(scene, efa, tface, 3)) VECCOPY2D(tface->uv[3], v2d->cursor);
- change = 1;
+
+ change= 1;
}
}
+
return change;
}
-int snap_uv_sel_to_adj_unsel(Scene *scene, Image *ima, Object *obedit)
+static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit)
{
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
EditFace *efa;
@@ -2054,12 +2343,14 @@ int snap_uv_sel_to_adj_unsel(Scene *scene, Image *ima, Object *obedit)
* get unique indicies and to count how much to malloc */
for(efa= em->faces.first; efa; efa= efa->next) {
tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
if(uvedit_face_visible(scene, ima, efa, tface)) {
if(uvedit_uv_selected(scene, efa, tface, 0) && efa->v1->tmp.l==-1) efa->v1->tmp.l= count++;
if(uvedit_uv_selected(scene, efa, tface, 1) && efa->v2->tmp.l==-1) efa->v2->tmp.l= count++;
if(uvedit_uv_selected(scene, efa, tface, 2) && efa->v3->tmp.l==-1) efa->v3->tmp.l= count++;
if(efa->v4)
if(uvedit_uv_selected(scene, efa, tface, 3) && efa->v4->tmp.l==-1) efa->v4->tmp.l= count++;
+
change = 1;
/* optional speedup */
@@ -2074,10 +2365,7 @@ int snap_uv_sel_to_adj_unsel(Scene *scene, Image *ima, Object *obedit)
/* add all UV coords from visible, unselected UV coords as well as counting them to average later */
for(efa= em->faces.first; efa; efa= efa->next) {
-// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-// if(uvedit_face_visible(scene, ima, efa, tface)) {
if((tface=(MTFace *)efa->tmp.p)) {
-
/* is this an unselected UV we can snap to? */
if(efa->v1->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 0))) {
coords[efa->v1->tmp.l*2] += tface->uv[0][0];
@@ -2118,8 +2406,6 @@ int snap_uv_sel_to_adj_unsel(Scene *scene, Image *ima, Object *obedit)
/* copy the averaged unselected UVs back to the selected UVs */
for(efa= em->faces.first; efa; efa= efa->next) {
-// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-// if(uvedit_face_visible(scene, ima, efa, tface)) {
if((tface=(MTFace *)efa->tmp.p)) {
if( uvedit_uv_selected(scene, efa, tface, 0) &&
@@ -2160,16 +2446,11 @@ int snap_uv_sel_to_adj_unsel(Scene *scene, Image *ima, Object *obedit)
MEM_freeN(coords);
MEM_freeN(usercount);
- return change;
-}
-void snap_coord_to_pixel(float *uvco, float w, float h)
-{
- uvco[0] = ((float) ((int)((uvco[0]*w) + 0.5))) / w;
- uvco[1] = ((float) ((int)((uvco[1]*h) + 0.5))) / h;
+ return change;
}
-int snap_uv_sel_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) /* warning, sanity checks must alredy be done */
+static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
{
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
Image *ima= sima->image;
@@ -2179,326 +2460,101 @@ int snap_uv_sel_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) /* war
float w, h;
short change = 0;
- // XXX get_space_image_size(sima, &width, &height);
+ get_space_image_size(sima, &width, &height);
w = (float)width;
h = (float)height;
for(efa= em->faces.first; efa; efa= efa->next) {
tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if(uvedit_face_visible(scene, ima, efa, tface)) {
- if(uvedit_uv_selected(scene, efa, tface, 0)) snap_coord_to_pixel(tface->uv[0], w, h);
- if(uvedit_uv_selected(scene, efa, tface, 1)) snap_coord_to_pixel(tface->uv[1], w, h);
- if(uvedit_uv_selected(scene, efa, tface, 2)) snap_coord_to_pixel(tface->uv[2], w, h);
+ if(uvedit_uv_selected(scene, efa, tface, 0)) snap_uv_to_pixel(tface->uv[0], w, h);
+ if(uvedit_uv_selected(scene, efa, tface, 1)) snap_uv_to_pixel(tface->uv[1], w, h);
+ if(uvedit_uv_selected(scene, efa, tface, 2)) snap_uv_to_pixel(tface->uv[2], w, h);
if(efa->v4)
- if(uvedit_uv_selected(scene, efa, tface, 3)) snap_coord_to_pixel(tface->uv[3], w, h);
+ if(uvedit_uv_selected(scene, efa, tface, 3)) snap_uv_to_pixel(tface->uv[3], w, h);
+
change = 1;
}
}
- return change;
-}
-
-void snap_uv_curs_to_pixels(SpaceImage *sima, View2D *v2d)
-{
- int width= 0, height= 0;
-
- // XXX get_space_image_size(sima, &width, &height);
- snap_coord_to_pixel(v2d->cursor, width, height);
-}
-int snap_uv_curs_to_sel(Scene *scene, Image *ima, Object *obedit, View2D *v2d)
-{
- if(!ED_uvedit_test(obedit)) return 0;
- return uvedit_center(scene, ima, obedit, v2d->cursor, 0);
+ return change;
}
-void snap_menu_sima(SpaceImage *sima, Scene *scene, Object *obedit, View2D *v2d)
+static int snap_selection_exec(bContext *C, wmOperator *op)
{
- short event;
+ SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Image *ima= CTX_data_edit_image(C);
+ ARegion *ar= CTX_wm_region(C);
+ int change= 0;
- if(!ED_uvedit_test(obedit) || !v2d) return; /* !G.v2d should never happen */
-
- event = 0; // XXX pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Selection -> Adjacent Unselected%x3|Cursor -> Selection%x4|Cursor -> Pixel%x5");
- switch (event) {
+ switch(RNA_boolean_get(op->ptr, "target")) {
+ case 0:
+ change= snap_uvs_to_pixels(sima, scene, obedit);
+ break;
case 1:
- if(snap_uv_sel_to_pixels(sima, scene, obedit)) {
- // XXX BIF_undo_push("Snap UV Selection to Pixels");
- DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- }
- break;
+ change= snap_uvs_to_cursor(scene, ima, obedit, &ar->v2d);
+ break;
case 2:
- if(snap_uv_sel_to_curs(scene, sima->image, obedit, v2d)) {
- // XXX BIF_undo_push("Snap UV Selection to Cursor");
- DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- }
- break;
- case 3:
- if(snap_uv_sel_to_adj_unsel(scene, sima->image, obedit)) {
- // XXX BIF_undo_push("Snap UV Selection to Cursor");
- DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- }
- break;
- case 4:
- if(snap_uv_curs_to_sel(scene, sima->image, obedit, v2d))
- // XXX allqueue(REDRAWIMAGE, 0);
- break;
- case 5:
- snap_uv_curs_to_pixels(sima, v2d);
- // XXX scrarea_queue_winredraw(curarea);
- break;
- }
-}
-
-
-/** This is an ugly function to set the Tface selection flags depending
- * on whether its UV coordinates are inside the normalized
- * area with radius rad and offset offset. These coordinates must be
- * normalized to 1.0
- * Just for readability...
- */
-
-static void sel_uvco_inside_radius(SpaceImage *sima, Scene *scene, short sel, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, short select_index)
-{
- // normalized ellipse: ell[0] = scaleX,
- // [1] = scaleY
-
- float *uv = tface->uv[index];
- float x, y, r2;
-
- x = (uv[0] - offset[0]) * ell[0];
- y = (uv[1] - offset[1]) * ell[1];
-
- r2 = x * x + y * y;
- if(r2 < 1.0) {
- if(sel == 0 /* XXX LEFTMOUSE */) uvedit_uv_select(scene, efa, tface, select_index);
- else uvedit_uv_deselect(scene, efa, tface, select_index);
+ change= snap_uvs_to_adjacent_unselected(scene, ima, obedit);
+ break;
}
-}
-
-// see below:
-/** gets image dimensions of the 2D view 'v' */
-static void getSpaceImageDimension(SpaceImage *sima, ARegion *ar, float *xy)
-{
- float zoomx= 0, zoomy= 0;
- int width= 0, height= 0;
- // XXX get_space_image_size(sima, &width, &height);
- // XXX get_space_image_zoom(sima, ar, &zoomx, &zoomy);
+ if(!change)
+ return OPERATOR_CANCELLED;
+
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
- xy[0]= width*zoomx;
- xy[1]= height*zoomy;
+ return OPERATOR_FINISHED;
}
-/** Callback function called by circle_selectCB to enable
- * brush select in UV editor.
- */
-
-void uvedit_selectionCB(SpaceImage *sima, Scene *scene, ARegion *ar, short selecting, Object *obedit, short *mval, float rad)
+void UV_OT_snap_selection(wmOperatorType *ot)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
- EditFace *efa;
- float offset[2];
- MTFace *tface;
- float ellipse[2]; // we need to deal with ellipses, as
- // non square textures require for circle
- // selection. this ellipse is normalized; r = 1.0
-
- getSpaceImageDimension(sima, ar, ellipse);
- ellipse[0] /= rad;
- ellipse[1] /= rad;
+ static EnumPropertyItem target_items[] = {
+ {0, "PIXELS", "Pixels", ""},
+ {1, "CURSOR", "Cursor", ""},
+ {2, "ADJACENT_UNSELECTED", "Adjacent Unselected", ""},
+ {0, NULL, NULL, NULL}};
- // XXX areamouseco_to_ipoco(G.v2d, mval, &offset[0], &offset[1]);
+ /* identifiers */
+ ot->name= "Snap Selection";
+ ot->idname= "UV_OT_snap_selection";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- if(selecting) {
- for(efa= em->faces.first; efa; efa= efa->next) {
- tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- sel_uvco_inside_radius(sima, scene, selecting, efa, tface, 0, offset, ellipse, 0);
- sel_uvco_inside_radius(sima, scene, selecting, efa, tface, 1, offset, ellipse, 1);
- sel_uvco_inside_radius(sima, scene, selecting, efa, tface, 2, offset, ellipse, 2);
- if(efa->v4)
- sel_uvco_inside_radius(sima, scene, selecting, efa, tface, 3, offset, ellipse, 3);
- }
+ /* api callbacks */
+ ot->exec= snap_selection_exec;
+ ot->poll= ED_operator_uvedit;
- /* XXX */
-#if 0
- if(G.f & G_DRAWFACES) { /* full redraw only if necessary */
- draw_sel_circle(0, 0, 0, 0, 0); /* signal */
- force_draw(0);
- }
- else { /* force_draw() is no good here... */
- glDrawBuffer(GL_FRONT);
- draw_uvs_sima();
- bglFlush();
- glDrawBuffer(GL_BACK);
- }
-#endif
-
- if(selecting == 0 /* XXX LEFTMOUSE */) EM_select_flush(em);
- else EM_deselect_flush(em);
-
- if(sima->lock && (scene->toolsettings->uv_flag & UV_SYNC_SELECTION))
- ; // XXX force_draw_plus(SPACE_VIEW3D, 0);
- }
+ /* properties */
+ RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UV's to.");
}
-/* this function sets the selection on tagged faces
- * This is needed because setting the selection on a face is done in
- * a number of places but it also needs to respect the sticky modes
- * for the UV verts - dealing with the sticky modes is best done in a seperate function
- *
- * de-selects faces that have been tagged on efa->tmp.l
- */
-void uvface_setsel__internal(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, short select)
-{
-
- /* All functions calling this should call
- * draw_uvs_face_check()
- */
-
-
- /* selecting UV Faces with some modes requires us to change
- * the selection in other faces (depending on the stickt mode)
- *
- * This only needs to be done when the Mesh is not used for selection
- * (So for sticky modes - vertex or location based)
- * */
-
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
- EditFace *efa;
- MTFace *tf;
- int nverts, i;
-
- if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
- /* tag all verts as untouched,
- * then touch the ones that have a face center in the loop
- * and select all MTFace UV's that use a touched vert */
-
- EditVert *eve;
-
- for(eve= em->verts.first; eve; eve= eve->next)
- eve->tmp.l = 0;
-
- for(efa= em->faces.first; efa; efa= efa->next) {
- if(efa->tmp.l) {
- if(efa->v4)
- efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= efa->v4->tmp.l=1;
- else
- efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= 1;
- }
- }
- /* now select tagged verts */
- for(efa= em->faces.first; efa; efa= efa->next) {
- tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- nverts= efa->v4? 4: 3;
- for(i=0; i<nverts; i++) {
- if((*(&efa->v1 + i))->tmp.l) {
- if(select)
- uvedit_uv_select(scene, efa, tf, i);
- else
- uvedit_uv_deselect(scene, efa, tf, i);
- }
- }
- }
- } else if((scene->toolsettings->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
- EditFace *efa_vlist;
- MTFace *tf_vlist;
- UvMapVert *start_vlist=NULL, *vlist_iter;
- struct UvVertMap *vmap;
- float limit[2];
- int efa_index;
- //EditVert *eve; /* removed vert counting for now */
- //int a;
-
- uvedit_pixel_to_float(C, limit, 0.05);
-
- EM_init_index_arrays(em, 0, 0, 1);
- vmap= EM_make_uv_vert_map(em, 0, 0, limit);
-
- /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */
- /*for(a=0, eve= em->verts.first; eve; a++, eve= eve->next)
- eve->tmp.l = a; */
-
- if(vmap == NULL)
- return;
-
- for(efa_index=0, efa= em->faces.first; efa; efa_index++, efa= efa->next) {
- if(efa->tmp.l) {
- tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- nverts= efa->v4? 4: 3;
-
- for(i=0; i<nverts; i++) {
- if(select)
- uvedit_uv_select(scene, efa, tf, i);
- else
- uvedit_uv_deselect(scene, efa, tf, i);
-
- vlist_iter= EM_get_uv_map_vert(vmap, (*(&efa->v1 + i))->tmp.l);
-
- while (vlist_iter) {
- if(vlist_iter->separate)
- start_vlist = vlist_iter;
-
- if(efa_index == vlist_iter->f)
- break;
+/* ******************** pin operator **************** */
- vlist_iter = vlist_iter->next;
- }
-
- vlist_iter = start_vlist;
- while (vlist_iter) {
-
- if(vlist_iter != start_vlist && vlist_iter->separate)
- break;
-
- if(efa_index != vlist_iter->f) {
- efa_vlist = EM_get_face_for_index(vlist_iter->f);
- tf_vlist = CustomData_em_get(&em->fdata, efa_vlist->data, CD_MTFACE);
-
- if(select)
- uvedit_uv_select(scene, efa_vlist, tf_vlist, vlist_iter->tfindex);
- else
- uvedit_uv_deselect(scene, efa_vlist, tf_vlist, vlist_iter->tfindex);
- }
- vlist_iter = vlist_iter->next;
- }
- }
- }
- }
- EM_free_index_arrays();
- EM_free_uv_vert_map(vmap);
-
- }
- else { /* SI_STICKY_DISABLE or scene->toolsettings->uv_flag & UV_SYNC_SELECTION */
- for(efa= em->faces.first; efa; efa= efa->next) {
- if(efa->tmp.l) {
- tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- if(select)
- uvedit_face_select(scene, efa, tf);
- else
- uvedit_face_deselect(scene, efa, tf);
- }
- }
- }
-}
-
-void pin_tface_uv(Scene *scene, Image *ima, Object *obedit, int mode)
+static int pin_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);
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
EditFace *efa;
MTFace *tface;
-
- if(!ED_uvedit_test(obedit)) return;
+ int clear= RNA_boolean_get(op->ptr, "clear");
for(efa= em->faces.first; efa; efa= efa->next) {
tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
if(uvedit_face_visible(scene, ima, efa, tface)) {
- if(mode ==1) {
+ if(!clear) {
if(uvedit_uv_selected(scene, efa, tface, 0)) tface->unwrap |= TF_PIN1;
if(uvedit_uv_selected(scene, efa, tface, 1)) tface->unwrap |= TF_PIN2;
if(uvedit_uv_selected(scene, efa, tface, 2)) tface->unwrap |= TF_PIN3;
if(efa->v4)
if(uvedit_uv_selected(scene, efa, tface, 3)) tface->unwrap |= TF_PIN4;
}
- else if(mode ==0) {
+ else {
if(uvedit_uv_selected(scene, efa, tface, 0)) tface->unwrap &= ~TF_PIN1;
if(uvedit_uv_selected(scene, efa, tface, 1)) tface->unwrap &= ~TF_PIN2;
if(uvedit_uv_selected(scene, efa, tface, 2)) tface->unwrap &= ~TF_PIN3;
@@ -2508,20 +2564,40 @@ void pin_tface_uv(Scene *scene, Image *ima, Object *obedit, int mode)
}
}
- // XXX BIF_undo_push("Pin UV");
- // XXX scrarea_queue_winredraw(curarea);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_pin(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Pin";
+ ot->idname= "UV_OT_pin";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec= pin_exec;
+ ot->poll= ED_operator_uvedit;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "clear", 0, "Clear", "Clear pinning for the selection instead of setting it.");
}
-void select_pinned_tface_uv(Scene *scene, Image *ima, Object *obedit)
+/* ******************** select pinned operator **************** */
+
+static int select_pinned_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);
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
EditFace *efa;
MTFace *tface;
- if(!ED_uvedit_test(obedit)) return;
-
for(efa= em->faces.first; efa; efa= efa->next) {
tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
if(uvedit_face_visible(scene, ima, efa, tface)) {
if(tface->unwrap & TF_PIN1) uvedit_uv_select(scene, efa, tface, 0);
if(tface->unwrap & TF_PIN2) uvedit_uv_select(scene, efa, tface, 1);
@@ -2529,16 +2605,24 @@ void select_pinned_tface_uv(Scene *scene, Image *ima, Object *obedit)
if(efa->v4) {
if(tface->unwrap & TF_PIN4) uvedit_uv_select(scene, efa, tface, 3);
}
-
}
}
- if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
- // XXX allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
- }
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_select_pinned(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Selected Pinned";
+ ot->idname= "UV_OT_select_pinned";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- // XXX BIF_undo_push("Select Pinned UVs");
- // XXX scrarea_queue_winredraw(curarea);
+ /* api callbacks */
+ ot->exec= select_pinned_exec;
+ ot->poll= ED_operator_uvedit;
}
/* ************************** registration **********************************/
@@ -2551,29 +2635,58 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_loop_select);
WM_operatortype_append(UV_OT_select_linked);
WM_operatortype_append(UV_OT_unlink_selection);
+ WM_operatortype_append(UV_OT_select_pinned);
+ WM_operatortype_append(UV_OT_border_select);
+ WM_operatortype_append(UV_OT_circle_select);
+
+ WM_operatortype_append(UV_OT_snap_cursor);
+ WM_operatortype_append(UV_OT_snap_selection);
WM_operatortype_append(UV_OT_align);
WM_operatortype_append(UV_OT_mirror);
WM_operatortype_append(UV_OT_stitch);
WM_operatortype_append(UV_OT_weld);
+ WM_operatortype_append(UV_OT_pin);
+
+ WM_operatortype_append(UV_OT_unwrap);
+ WM_operatortype_append(UV_OT_minimize_stretch);
+ WM_operatortype_append(UV_OT_average_islands_scale);
+ WM_operatortype_append(UV_OT_pack_islands);
}
void ED_keymap_uvedit(wmWindowManager *wm)
{
ListBase *keymap= WM_keymap_listbase(wm, "UVEdit", 0, 0);
+ /* pick selection */
WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
// XXX not working?
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, KM_ALT)->ptr, "extend", 1);
+ /* border/circle selection */
+ WM_keymap_add_item(keymap, "UV_OT_border_select", BKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_border_select", BKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "pinned", 1);
+ WM_keymap_add_item(keymap, "UV_OT_circle_select", CKEY, KM_PRESS, 0, 0);
+
+ /* selection manipulation */
WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "UV_OT_unlink_selection", LKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "UV_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "UV_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "UV_OT_select_pinned", PKEY, KM_PRESS, KM_SHIFT, 0);
+ /* uv operations */
WM_keymap_add_item(keymap, "UV_OT_stitch", VKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_pin", PKEY, KM_PRESS, KM_ALT, 0)->ptr, "clear", 1);
+
+ /* unwrap */
+ WM_keymap_add_item(keymap, "UV_OT_unwrap", EKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "UV_OT_minimize_stretch", VKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "UV_OT_pack_islands", PKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "UV_OT_average_islands_scale", AKEY, KM_PRESS, KM_CTRL, 0);
transform_keymap_for_space(wm, keymap, SPACE_IMAGE);
}