diff options
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_ops.c')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 252 |
1 files changed, 76 insertions, 176 deletions
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index a30274c0f2c..db3c994cfa0 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -47,7 +47,6 @@ #include "DNA_scene_types.h" #include "BLI_math.h" -#include "BLI_lasso.h" #include "BLI_blenlib.h" #include "BLI_array.h" #include "BLI_utildefines.h" @@ -523,23 +522,44 @@ void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit) } /*********************** geometric utilities ***********************/ -void uv_poly_center(BMEditMesh *em, BMFace *f, float r_cent[2]) +void poly_uv_center(BMEditMesh *em, BMFace *f, float cent[2]) { BMLoop *l; MLoopUV *luv; BMIter liter; - zero_v2(r_cent); + zero_v2(cent); BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - add_v2_v2(r_cent, luv->uv); + add_v2_v2(cent, luv->uv); } - mul_v2_fl(r_cent, 1.0f / (float)f->len); + mul_v2_fl(cent, 1.0f / (float)f->len); } -float uv_poly_area(float uv[][2], int len) + +void uv_center(float uv[][2], float cent[2], int quad) +{ + if (quad) { + cent[0] = (uv[0][0] + uv[1][0] + uv[2][0] + uv[3][0]) / 4.0f; + cent[1] = (uv[0][1] + uv[1][1] + uv[2][1] + uv[3][1]) / 4.0f; + } + else { + cent[0] = (uv[0][0] + uv[1][0] + uv[2][0]) / 3.0f; + cent[1] = (uv[0][1] + uv[1][1] + uv[2][1]) / 3.0f; + } +} + +float uv_area(float uv[][2], int quad) +{ + if (quad) + return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]); + else + return area_tri_v2(uv[0], uv[1], uv[2]); +} + +float poly_uv_area(float uv[][2], int len) { //BMESH_TODO: make this not suck //maybe use scanfill? I dunno. @@ -552,7 +572,7 @@ float uv_poly_area(float uv[][2], int len) return 1.0; } -void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len) +void poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len) { int i; for (i = 0; i < len; i++) { @@ -561,7 +581,7 @@ void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float as } } -int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], float r_max[2]) +int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float *min, float *max) { BMEditMesh *em = BMEdit_FromObject(obedit); BMFace *efa; @@ -571,7 +591,7 @@ int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], f MLoopUV *luv; int sel; - INIT_MINMAX2(r_min, r_max); + INIT_MINMAX2(min, max); sel = 0; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -582,7 +602,7 @@ int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], f BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - DO_MINMAX2(luv->uv, r_min, r_max); + DO_MINMAX2(luv->uv, min, max); sel = 1; } } @@ -643,7 +663,7 @@ static int uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2] /************************** find nearest ****************************/ -void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit) +void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, float co[2], NearestHit *hit) { MTexPoly *tf; BMFace *efa; @@ -690,11 +710,13 @@ void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, const float } } -static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, const float co[2], NearestHit *hit) +static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, float co[2], NearestHit *hit) { MTexPoly *tf; BMFace *efa; - BMIter iter; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; float mindist, dist, cent[2]; mindist = 1e10f; @@ -709,9 +731,16 @@ static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, const tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); if (!uvedit_face_visible_test(scene, ima, efa, tf)) continue; + + cent[0] = cent[1] = 0.0f; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - uv_poly_center(em, efa, cent); + add_v2_v2(cent, luv->uv); + } + cent[0] /= efa->len; + cent[1] /= efa->len; dist = fabs(co[0] - cent[0]) + fabs(co[1] - cent[1]); if (dist < mindist) { @@ -723,12 +752,12 @@ static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, const } static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), int id, - const float co[2], const float uv[2]) + float co[2], float uv[2]) { BMLoop *l; MLoopUV *luv; BMIter iter; - float m[3], v1[3], v2[3], c1, c2, *uv1, /* *uv2, */ /* UNUSED */ *uv3; + float m[3], v1[3], v2[3], c1, c2, *uv1 = NULL, /* *uv2, */ /* UNUSED */ *uv3 = NULL; int id1, id2, i; id1 = (id + efa->len - 1) % efa->len; @@ -769,7 +798,7 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i } void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em, - float const co[2], const float penalty[2], NearestHit *hit) + float co[2], float penalty[2], NearestHit *hit) { BMFace *efa; BMLoop *l; @@ -827,7 +856,7 @@ void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em, } } -int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float co[2], float r_uv[2]) +int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, float co[2], float uv[2]) { BMEditMesh *em = BMEdit_FromObject(obedit); BMFace *efa; @@ -836,10 +865,11 @@ int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float c MTexPoly *tf; MLoopUV *luv; float mindist, dist; - int found = FALSE; + int found = 0; mindist = 1e10f; - copy_v2_v2(r_uv, co); + uv[0] = co[0]; + uv[1] = co[1]; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); @@ -853,8 +883,9 @@ int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, const float c if (dist <= mindist) { mindist = dist; - copy_v2_v2(r_uv, luv->uv); - found = TRUE; + uv[0] = luv->uv[0]; + uv[1] = luv->uv[1]; + found = 1; } } } @@ -1074,7 +1105,7 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit /*********************** linked select ***********************/ -static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float limit[2], NearestHit *hit, int extend) +static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, float limit[2], NearestHit *hit, int extend) { BMFace *efa; BMLoop *l; @@ -1685,11 +1716,11 @@ static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], floa return 0; } -static int mouse_select(bContext *C, const float co[2], int extend, int loop) +static int mouse_select(bContext *C, float co[2], int extend, int loop) { SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; + ToolSettings *ts = CTX_data_tool_settings(C); Object *obedit = CTX_data_edit_object(C); Image *ima = CTX_data_edit_image(C); BMEditMesh *em = BMEdit_FromObject(obedit); @@ -1756,8 +1787,8 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop) } /* mark 1 vertex as being hit */ - BLI_array_grow_items(hitv, hit.efa->len); - BLI_array_grow_items(hituv, hit.efa->len); + BLI_array_growitems(hitv, hit.efa->len); + BLI_array_growitems(hituv, hit.efa->len); for (i = 0; i < hit.efa->len; i++) { hitv[i] = 0xFFFFFFFF; } @@ -1777,8 +1808,8 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop) } /* mark 2 edge vertices as being hit */ - BLI_array_grow_items(hitv, hit.efa->len); - BLI_array_grow_items(hituv, hit.efa->len); + BLI_array_growitems(hitv, hit.efa->len); + BLI_array_growitems(hituv, hit.efa->len); fill_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); hitv[hit.lindex] = hit.vert1; @@ -1802,8 +1833,8 @@ static int mouse_select(bContext *C, const float co[2], int extend, int loop) /* mark all face vertices as being hit */ - BLI_array_grow_items(hitv, hit.efa->len); - BLI_array_grow_items(hituv, hit.efa->len); + BLI_array_growitems(hitv, hit.efa->len); + BLI_array_growitems(hituv, hit.efa->len); i = 0; BM_ITER_ELEM (l, &liter, hit.efa, BM_LOOPS_OF_FACE) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); @@ -2091,7 +2122,7 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i { SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; + ToolSettings *ts = CTX_data_tool_settings(C); Object *obedit = CTX_data_edit_object(C); Image *ima = CTX_data_edit_image(C); BMEditMesh *em = BMEdit_FromObject(obedit); @@ -2193,7 +2224,7 @@ static void UV_OT_select_linked_pick(wmOperatorType *ot) static int unlink_selection_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; + ToolSettings *ts = CTX_data_tool_settings(C); Object *obedit = CTX_data_edit_object(C); Image *ima = CTX_data_edit_image(C); BMEditMesh *em = BMEdit_FromObject(obedit); @@ -2279,7 +2310,7 @@ static void uv_select_sync_flush(ToolSettings *ts, BMEditMesh *em, const short s * * De-selects faces that have been tagged on efa->tmp.l. */ -static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, short select) +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). @@ -2287,7 +2318,7 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s * This only needs to be done when the Mesh is not used for * selection (so for sticky modes, vertex or location based). */ - ToolSettings *ts = scene->toolsettings; + ToolSettings *ts = CTX_data_tool_settings(C); BMEditMesh *em = BMEdit_FromObject(obedit); BMFace *efa; BMLoop *l; @@ -2408,7 +2439,7 @@ static int border_select_exec(bContext *C, wmOperator *op) { SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; + ToolSettings *ts = CTX_data_tool_settings(C); Object *obedit = CTX_data_edit_object(C); Image *ima = CTX_data_edit_image(C); ARegion *ar = CTX_wm_region(C); @@ -2457,7 +2488,7 @@ static int border_select_exec(bContext *C, wmOperator *op) tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); if (uvedit_face_visible_test(scene, ima, efa, tf)) { - uv_poly_center(em, efa, cent); + poly_uv_center(em, efa, cent); if (BLI_in_rctf(&rectf, cent[0], cent[1])) { BM_elem_flag_enable(efa, BM_ELEM_TAG); change = 1; @@ -2467,7 +2498,7 @@ static int border_select_exec(bContext *C, wmOperator *op) /* (de)selects all tagged faces and deals with sticky modes */ if (change) - uv_faces_do_sticky(sima, scene, obedit, select); + uv_faces_do_sticky(C, sima, scene, obedit, select); } else { /* other selection modes */ @@ -2502,9 +2533,7 @@ static int border_select_exec(bContext *C, wmOperator *op) if (change) { uv_select_sync_flush(ts, em, select); - if (ts->uv_flag & UV_SYNC_SELECTION) { - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - } + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); return OPERATOR_FINISHED; } @@ -2563,7 +2592,6 @@ static int circle_select_exec(bContext *C, wmOperator *op) { SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BMEdit_FromObject(obedit); ARegion *ar = CTX_wm_region(C); @@ -2601,11 +2629,9 @@ static int circle_select_exec(bContext *C, wmOperator *op) } if (change) { - uv_select_sync_flush(ts, em, select); + uv_select_sync_flush(scene->toolsettings, em, select); - if (ts->uv_flag & UV_SYNC_SELECTION) { - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - } + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); } return OPERATOR_FINISHED; @@ -2635,129 +2661,9 @@ static void UV_OT_circle_select(wmOperatorType *ot) RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); } - -/* ******************** lasso select operator **************** */ - -static void do_lasso_select_mesh_uv(bContext *C, int mcords[][2], short moves, short select) -{ - Image *ima = CTX_data_edit_image(C); - ARegion *ar = CTX_wm_region(C); - Object *obedit = CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; - BMEditMesh *em = BMEdit_FromObject(obedit); - - BMIter iter, liter; - - BMFace *efa; - BMLoop *l; - MTexPoly *tf; - int screen_uv[2], change = TRUE; - rcti rect; - - BLI_lasso_boundbox(&rect, mcords, moves); - - if (ts->uv_selectmode == UV_SELECT_FACE) { /* Face Center Sel */ - change = FALSE; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - /* assume not touched */ - if ((select) != (uvedit_face_select_test(scene, em, efa))) { - float cent[2]; - uv_poly_center(em, efa, cent); - UI_view2d_view_to_region(&ar->v2d, cent[0], cent[1], &screen_uv[0], &screen_uv[1]); - if (BLI_in_rcti(&rect, screen_uv[0], screen_uv[1]) && - BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED)) - { - uvedit_face_select_enable(scene, em, efa, FALSE); - change = TRUE; - } - } - } - } - else { /* Vert Sel */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if (uvedit_face_visible_test(scene, ima, efa, tf)) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if ((select) != (uvedit_uv_select_test(em, scene, l))) { - MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - UI_view2d_view_to_region(&ar->v2d, luv->uv[0], luv->uv[1], &screen_uv[0], &screen_uv[1]); - if (BLI_in_rcti(&rect, screen_uv[0], screen_uv[1]) && - BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED)) - { - if (select) { - uvedit_uv_select_enable(em, scene, l, FALSE); - } - else { - uvedit_uv_select_disable(em, scene, l); - } - } - } - } - } - } - } - if (change) { - uv_select_sync_flush(scene->toolsettings, em, select); - - if (ts->uv_flag & UV_SYNC_SELECTION) { - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - } - } -} - -static int uv_lasso_select_exec(bContext *C, wmOperator *op) -{ - int i = 0; - int mcords[1024][2]; - - RNA_BEGIN (op->ptr, itemptr, "path") { - float loc[2]; - - RNA_float_get_array(&itemptr, "loc", loc); - mcords[i][0] = (int)loc[0]; - mcords[i][1] = (int)loc[1]; - i++; - if (i >= 1024) break; - } - RNA_END; - - if (i > 1) { - short select; - - select = !RNA_boolean_get(op->ptr, "deselect"); - do_lasso_select_mesh_uv(C, mcords, i, select); - - return OPERATOR_FINISHED; - } - return OPERATOR_PASS_THROUGH; -} - -void UV_OT_select_lasso(wmOperatorType *ot) -{ - ot->name = "Lasso Select UV"; - ot->description = "Select UVs using lasso selection"; - ot->idname = "UV_OT_select_lasso"; - - ot->invoke = WM_gesture_lasso_invoke; - ot->modal = WM_gesture_lasso_modal; - ot->exec = uv_lasso_select_exec; - ot->poll = ED_operator_image_active; - ot->cancel = WM_gesture_lasso_cancel; - - /* flags */ - ot->flag = OPTYPE_UNDO; - - RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); - RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); - RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); -} - - - /* ******************** snap cursor operator **************** */ -static void snap_uv_to_pixel(float uvco[2], float w, float h) +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; @@ -3122,9 +3028,9 @@ static int bm_face_is_all_uv_sel(BMesh *bm, BMFace *f, int bool_test) static int hide_exec(bContext *C, wmOperator *op) { SpaceImage *sima = CTX_wm_space_image(C); + ToolSettings *ts = CTX_data_tool_settings(C); Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; BMEditMesh *em = BMEdit_FromObject(obedit); BMFace *efa; BMLoop *l; @@ -3237,9 +3143,9 @@ static void UV_OT_hide(wmOperatorType *ot) static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceImage *sima = CTX_wm_space_image(C); + ToolSettings *ts = CTX_data_tool_settings(C); Object *obedit = CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; + /*Scene *scene = CTX_data_scene(C);*/ /*UNUSED*/ BMEditMesh *em = BMEdit_FromObject(obedit); BMFace *efa; BMLoop *l; @@ -3665,7 +3571,6 @@ void ED_operatortypes_uvedit(void) WM_operatortype_append(UV_OT_unlink_selected); WM_operatortype_append(UV_OT_select_pinned); WM_operatortype_append(UV_OT_select_border); - WM_operatortype_append(UV_OT_select_lasso); WM_operatortype_append(UV_OT_circle_select); WM_operatortype_append(UV_OT_snap_cursor); @@ -3726,11 +3631,6 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "UV_OT_circle_select", CKEY, KM_PRESS, 0, 0); - kmi = WM_keymap_add_item(keymap, "UV_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); - RNA_boolean_set(kmi->ptr, "deselect", FALSE); - kmi = WM_keymap_add_item(keymap, "UV_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "deselect", TRUE); - /* selection manipulation */ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0)->ptr, "extend", FALSE); RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0)->ptr, "extend", FALSE); |