diff options
Diffstat (limited to 'source/blender/editors/uvedit')
-rw-r--r-- | source/blender/editors/uvedit/CMakeLists.txt | 6 | ||||
-rw-r--r-- | source/blender/editors/uvedit/SConscript | 6 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_buttons.c | 31 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_draw.c | 39 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_intern.h | 5 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 198 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_parametrizer.c | 22 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_smart_stitch.c | 32 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_unwrap_ops.c | 98 |
9 files changed, 284 insertions, 153 deletions
diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt index 45edbde7482..a90763eed4e 100644 --- a/source/blender/editors/uvedit/CMakeLists.txt +++ b/source/blender/editors/uvedit/CMakeLists.txt @@ -22,12 +22,14 @@ set(INC ../include ../../blenkernel ../../blenlib - ../../blenfont + ../../blentranslation ../../bmesh + ../../gpu ../../makesdna ../../makesrna ../../windowmanager ../../../../intern/guardedalloc + ../../../../intern/glew-mx ) set(INC_SYS @@ -57,4 +59,6 @@ if(WITH_OPENNL) ) endif() +add_definitions(${GL_DEFINITIONS}) + blender_add_lib(bf_editor_uvedit "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/uvedit/SConscript b/source/blender/editors/uvedit/SConscript index 413503191cd..b5cccab4002 100644 --- a/source/blender/editors/uvedit/SConscript +++ b/source/blender/editors/uvedit/SConscript @@ -28,17 +28,19 @@ Import ('env') defs = [] +defs += env['BF_GL_DEFINITIONS'] sources = env.Glob('*.c') incs = [ '#/intern/guardedalloc', - '#/extern/glew/include', + env['BF_GLEW_INC'], + '#/intern/glew-mx', '#/intern/opennl/extern', '../include', - '../../blenfont', '../../blenkernel', '../../blenlib', + '../../blentranslation', '../../bmesh', '../../gpu', '../../makesdna', diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c index 6816e785c1f..ab415c0cb83 100644 --- a/source/blender/editors/uvedit/uvedit_buttons.c +++ b/source/blender/editors/uvedit/uvedit_buttons.c @@ -42,7 +42,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLF_translation.h" +#include "BLT_translation.h" #include "BKE_context.h" #include "BKE_customdata.h" @@ -53,7 +53,6 @@ #include "ED_uvedit.h" #include "UI_interface.h" -#include "UI_resources.h" #include "WM_api.h" #include "WM_types.h" @@ -142,11 +141,25 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block) em = BKE_editmesh_from_object(obedit); if (uvedit_center(scene, em, ima, center)) { + float range_xy[2][2] = { + {-10.0f, 10.0f}, + {-10.0f, 10.0f}, + }; + copy_v2_v2(uvedit_old_center, center); + /* expand UI range by center */ + CLAMP_MAX(range_xy[0][0], uvedit_old_center[0]); + CLAMP_MIN(range_xy[0][1], uvedit_old_center[0]); + CLAMP_MAX(range_xy[1][0], uvedit_old_center[1]); + CLAMP_MIN(range_xy[1][1], uvedit_old_center[1]); + if (!(sima->flag & SI_COORDFLOATS)) { uvedit_old_center[0] *= imx; uvedit_old_center[1] *= imy; + + mul_v2_fl(range_xy[0], imx); + mul_v2_fl(range_xy[1], imy); } if (sima->flag & SI_COORDFLOATS) { @@ -158,12 +171,12 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block) digits = 2; } - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 0, 0, width, UI_UNIT_Y, &uvedit_old_center[0], - -10 * imx, 10.0 * imx, step, digits, ""); - uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("Y:"), width, 0, width, UI_UNIT_Y, &uvedit_old_center[1], - -10 * imy, 10.0 * imy, step, digits, ""); - uiBlockEndAlign(block); + UI_block_align_begin(block); + uiDefButF(block, UI_BTYPE_NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 0, 0, width, UI_UNIT_Y, &uvedit_old_center[0], + UNPACK2(range_xy[0]), step, digits, ""); + uiDefButF(block, UI_BTYPE_NUM, B_UVEDIT_VERTEX, IFACE_("Y:"), width, 0, width, UI_UNIT_Y, &uvedit_old_center[1], + UNPACK2(range_xy[1]), step, digits, ""); + UI_block_align_end(block); } } @@ -212,7 +225,7 @@ static void image_panel_uv(const bContext *C, Panel *pa) uiBlock *block; block = uiLayoutAbsoluteBlock(pa->layout); - uiBlockSetHandleFunc(block, do_uvedit_vertex, NULL); + UI_block_func_handle_set(block, do_uvedit_vertex, NULL); uvedit_vertex_buttons(C, block); } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 36c96a8d011..4e9ab680dc6 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -43,7 +43,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_alloca.h" #include "BLI_buffer.h" #include "BLI_bitmap.h" @@ -71,7 +70,7 @@ static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset); -void draw_image_cursor(ARegion *ar, const float cursor[2]) +void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) { float zoom[2], x_fac, y_fac; @@ -82,7 +81,7 @@ void draw_image_cursor(ARegion *ar, const float cursor[2]) y_fac = zoom[1]; cpack(0xFFFFFF); - glTranslatef(cursor[0], cursor[1], 0.0); + glTranslate2fv(cursor); fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac); fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f); fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac); @@ -325,7 +324,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); a = fabsf(uvang[i] - ang[i]) / (float)M_PI; - weight_to_rgb(col, 1.0f - powf((1.0f - a), 2.0f)); + weight_to_rgb(col, 1.0f - pow2f(1.0f - a)); glColor3fv(col); glVertex2fv(luv->uv); } @@ -506,6 +505,8 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) mloopuv_base = mloopuv; for (a = me->totpoly; a > 0; a--, mpoly++) { + if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1) + continue; glBegin(GL_LINE_LOOP); mloopuv = mloopuv_base + mpoly->loopstart; @@ -597,7 +598,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) /* first try existing derivedmesh */ if (!draw_uvs_dm_shadow(em->derivedFinal)) { /* create one if it does not exist */ - cagedm = editbmesh_get_derived_cage_and_final(scene, obedit, me->edit_btmesh, &finaldm, CD_MASK_BAREMESH | CD_MASK_MTFACE); + cagedm = editbmesh_get_derived_cage_and_final( + scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH | CD_MASK_MTFACE, + &finaldm); /* when sync selection is enabled, all faces are drawn (except for hidden) * so if cage is the same as the final, theres no point in drawing this */ @@ -946,14 +949,30 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glPointSize(1.0); } -void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact) + +static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bool *show_shadow, bool *show_texpaint) +{ + *show_shadow = *show_texpaint = false; + + if (ED_space_image_show_render(sima) || (sima->flag & SI_NO_DRAW_TEXPAINT)) + return; + + if ((sima->mode == SI_MODE_PAINT) && obedit && obedit->type == OB_MESH) { + struct BMEditMesh *em = BKE_editmesh_from_object(obedit); + + *show_shadow = EDBM_mtexpoly_check(em); + } + + *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT); +} + +void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact) { ToolSettings *toolsettings = scene->toolsettings; - int show_uvedit, show_uvshadow, show_texpaint_uvshadow; + bool show_uvedit, show_uvshadow, show_texpaint_uvshadow; - show_texpaint_uvshadow = ED_space_image_show_texpaint(sima, obact); show_uvedit = ED_space_image_show_uvedit(sima, obedit); - show_uvshadow = ED_space_image_show_uvshadow(sima, obedit); + draw_uv_shadows_get(sima, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow); if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) { if (show_uvshadow) @@ -964,7 +983,7 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi draw_uvs_texpaint(sima, scene, obact); if (show_uvedit && !(toolsettings->use_uv_sculpt)) - draw_image_cursor(ar, sima->cursor); + ED_image_draw_cursor(ar, sima->cursor); } } diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 52365ff3478..e028c08091c 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -34,17 +34,13 @@ struct MTexPoly; struct Image; -struct MTFace; struct Object; struct Scene; struct SpaceImage; -struct UvElementMap; struct wmOperatorType; struct BMEditMesh; struct BMFace; struct BMLoop; -struct BMEdge; -struct BMVert; /* visibility and selection */ bool uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa); @@ -71,7 +67,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM /* utility tool functions */ void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); -void uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, float *aspx, float *aspy); /* operators */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 4b341547370..71d557f6fc7 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -53,6 +53,8 @@ #include "BLI_blenlib.h" #include "BLI_array.h" +#include "BLT_translation.h" + #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" @@ -80,6 +82,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "UI_interface.h" +#include "UI_resources.h" #include "UI_view2d.h" #include "uvedit_intern.h" @@ -668,6 +672,24 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], return changed; } +/* Be careful when using this, it bypasses all synchronization options */ +void ED_uvedit_select_all(BMesh *bm) +{ + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; + + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + luv->flag |= MLOOPUV_VERTSEL; + } + } +} + static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[2]) { BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -1010,7 +1032,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH /* setup */ BM_mesh_elem_table_ensure(em->bm, BM_FACE); - vmap = BM_uv_vert_map_create(em->bm, 0, limit); + vmap = BM_uv_vert_map_create(em->bm, limit, false, false); BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); @@ -1096,7 +1118,7 @@ static int uv_select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestH /*********************** linked select ***********************/ -static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float limit[2], NearestHit *hit, bool extend) +static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float limit[2], NearestHit *hit, bool extend, bool select_faces) { BMFace *efa; BMLoop *l; @@ -1113,7 +1135,9 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY); BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */ - vmap = BM_uv_vert_map_create(em->bm, 1, limit); + + /* use winding so we don't consider overlapping islands as connected, see T44320 */ + vmap = BM_uv_vert_map_create(em->bm, limit, !select_faces, true); if (vmap == NULL) return; @@ -1126,15 +1150,24 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); if (uvedit_face_visible_test(scene, ima, efa, tf)) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - if (luv->flag & MLOOPUV_VERTSEL) { + if (select_faces) { + if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { stack[stacksize] = a; stacksize++; flag[a] = 1; + } + } + else { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - break; + if (luv->flag & MLOOPUV_VERTSEL) { + stack[stacksize] = a; + stacksize++; + flag[a] = 1; + + break; + } } } } @@ -1186,13 +1219,21 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo if (!extend) { BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - + if (select_faces) { if (flag[a]) - luv->flag |= MLOOPUV_VERTSEL; + BM_face_select_set(em->bm, efa, true); else - luv->flag &= ~MLOOPUV_VERTSEL; + BM_face_select_set(em->bm, efa, false); + } + else { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + + if (flag[a]) + luv->flag |= MLOOPUV_VERTSEL; + else + luv->flag &= ~MLOOPUV_VERTSEL; + } } } } @@ -1201,17 +1242,23 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo if (!flag[a]) { continue; } - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - if (luv->flag & MLOOPUV_VERTSEL) { + + if (select_faces) { + if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) break; - } } - - if (l) { - break; + else { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + + if (luv->flag & MLOOPUV_VERTSEL) { + break; + } + } + + if (l) { + break; + } } } @@ -1221,10 +1268,15 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo continue; } - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - luv->flag &= ~MLOOPUV_VERTSEL; + if (select_faces) { + BM_face_select_set(em->bm, efa, false); + } + else { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + + luv->flag &= ~MLOOPUV_VERTSEL; + } } } } @@ -1234,10 +1286,15 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo continue; } - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - luv->flag |= MLOOPUV_VERTSEL; + if (select_faces) { + BM_face_select_set(em->bm, efa, true); + } + else { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + + luv->flag |= MLOOPUV_VERTSEL; + } } } } @@ -1291,10 +1348,10 @@ static int uv_select_more_less(bContext *C, const bool select) if (ts->uv_flag & UV_SYNC_SELECTION) { if (select) { - EDBM_select_more(em); + EDBM_select_more(em, true); } else { - EDBM_select_less(em); + EDBM_select_less(em, true); } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); @@ -1753,7 +1810,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op) if ((vert_arr[uv_b_index].weld == false) && (len_manhattan_v2v2(uv_a, uv_b) < threshold)) { - minmax_v2v2_v2(uv_max, uv_min, uv_b); + minmax_v2v2_v2(uv_min, uv_max, uv_b); BLI_array_append(loop_arr, vert_arr[uv_b_index].uv_loop); vert_arr[uv_b_index].weld = true; } @@ -2069,7 +2126,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo /* mark 1 vertex as being hit */ hitv = BLI_array_alloca(hitv, hit.efa->len); hituv = BLI_array_alloca(hituv, hit.efa->len); - fill_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); + copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); hitv[hit.lindex] = BM_elem_index_get(hit.l->v); hituv[hit.lindex] = hit.luv->uv; @@ -2086,7 +2143,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo /* mark 2 edge vertices as being hit */ hitv = BLI_array_alloca(hitv, hit.efa->len); hituv = BLI_array_alloca(hituv, hit.efa->len); - fill_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); + copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF); hitv[hit.lindex] = BM_elem_index_get(hit.l->v); hitv[(hit.lindex + 1) % hit.efa->len] = BM_elem_index_get(hit.l->next->v); @@ -2136,7 +2193,7 @@ static int uv_mouse_select(bContext *C, const float co[2], bool extend, bool loo flush = uv_select_edgeloop(scene, ima, em, &hit, limit, extend); } else if (selectmode == UV_SELECT_ISLAND) { - uv_select_linked(scene, ima, em, limit, &hit, extend); + uv_select_linked(scene, ima, em, limit, &hit, extend, false); } else if (extend) { if (selectmode == UV_SELECT_VERTEX) { @@ -2357,11 +2414,12 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent BMEditMesh *em = BKE_editmesh_from_object(obedit); float limit[2]; int extend; + bool select_faces = (ts->uv_flag & UV_SYNC_SELECTION) && (ts->selectmode & SCE_SELECT_FACE); NearestHit hit, *hit_p = NULL; - if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Cannot select linked when sync selection is enabled"); + if ((ts->uv_flag & UV_SYNC_SELECTION) && !(ts->selectmode & SCE_SELECT_FACE)) { + BKE_report(op->reports, RPT_ERROR, "Select linked only works in face select mode when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2387,7 +2445,7 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent hit_p = &hit; } - uv_select_linked(scene, ima, em, limit, hit_p, extend); + uv_select_linked(scene, ima, em, limit, hit_p, extend, select_faces); DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); @@ -2662,7 +2720,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object uvedit_pixel_to_float(sima, limit, 0.05); BM_mesh_elem_table_ensure(em->bm, BM_FACE); - vmap = BM_uv_vert_map_create(em->bm, 0, limit); + vmap = BM_uv_vert_map_create(em->bm, limit, false, false); if (vmap == NULL) { return; } @@ -2753,7 +2811,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object uvedit_pixel_to_float(sima, limit, 0.05); BM_mesh_elem_table_ensure(em->bm, BM_FACE); - vmap = BM_uv_vert_map_create(em->bm, 0, limit); + vmap = BM_uv_vert_map_create(em->bm, limit, false, false); if (vmap == NULL) { return; } @@ -3046,9 +3104,10 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ? - (ts->selectmode == SCE_SELECT_FACE) : - (ts->uv_selectmode == UV_SELECT_FACE); + const bool use_face_center = ( + (ts->uv_flag & UV_SYNC_SELECTION) ? + (ts->selectmode == SCE_SELECT_FACE) : + (ts->uv_selectmode == UV_SELECT_FACE)); 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); @@ -3171,8 +3230,8 @@ static void UV_OT_select_lasso(wmOperatorType *ot) static void uv_snap_to_pixel(float uvco[2], float w, float h) { - uvco[0] = ((float)((int)((uvco[0] * w) + 0.5f))) / w; - uvco[1] = ((float)((int)((uvco[1] * h) + 0.5f))) / h; + uvco[0] = roundf(uvco[0] * w) / w; + uvco[1] = roundf(uvco[1] * h) / h; } static void uv_snap_cursor_to_pixels(SpaceImage *sima) @@ -3273,7 +3332,7 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f BMFace *efa; BMLoop *l; BMIter iter, liter; - MTexPoly *tface; + MTexPoly *mtexpoly; MLoopUV *luv; bool changed = false; @@ -3281,8 +3340,8 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); - if (!uvedit_face_visible_test(scene, ima, efa, tface)) + mtexpoly = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); + if (!uvedit_face_visible_test(scene, ima, efa, mtexpoly)) continue; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { @@ -3859,6 +3918,15 @@ static int uv_set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *e ARegion *ar = CTX_wm_region(C); float location[2]; + if (ar->regiontype == RGN_TYPE_WINDOW) { + if (event->mval[1] <= 16) { + SpaceImage *sima = CTX_wm_space_image(C); + if (sima && ED_space_image_show_cache(sima)) { + return OPERATOR_PASS_THROUGH; + } + } + } + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); RNA_float_set_array(op->ptr, "location", location); @@ -3975,7 +4043,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) /* This code sets editvert->tmp.l to the index. This will be useful later on. */ BM_mesh_elem_table_ensure(bm, BM_FACE); - vmap = BM_uv_vert_map_create(bm, 0, limit); + vmap = BM_uv_vert_map_create(bm, limit, false, false); BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) { /* flags to determine if we uv is separated from first editface match */ @@ -4080,7 +4148,7 @@ static void UV_OT_seams_from_islands(wmOperatorType *ot) RNA_def_boolean(ot->srna, "mark_sharp", 0, "Mark Sharp", "Mark boundary edges as sharp"); } -static int uv_mark_seam_exec(bContext *C, wmOperator *UNUSED(op)) +static int uv_mark_seam_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); @@ -4090,13 +4158,17 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *UNUSED(op)) BMFace *efa; BMLoop *loop; BMIter iter, liter; + bool clear = RNA_boolean_get(op->ptr, "clear"); const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { - BM_elem_flag_enable(loop->e, BM_ELEM_SEAM); + if (clear) + BM_elem_flag_disable(loop->e, BM_ELEM_SEAM); + else + BM_elem_flag_enable(loop->e, BM_ELEM_SEAM); } } } @@ -4112,10 +4184,27 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +static int uv_mark_seam_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + uiPopupMenu *pup; + uiLayout *layout; + + pup = UI_popup_menu_begin(C, IFACE_("Edges"), ICON_NONE); + layout = UI_popup_menu_layout(pup); + + uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT); + uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Mark Seam"), ICON_NONE, op->type->idname, "clear", false); + uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Seam"), ICON_NONE, op->type->idname, "clear", true); + + UI_popup_menu_end(C, pup); + + return OPERATOR_INTERFACE; +} + static void UV_OT_mark_seam(wmOperatorType *ot) { /* identifiers */ - ot->name = "Mark Seams"; + ot->name = "Mark Seam"; ot->description = "Mark selected UV edges as seams"; ot->idname = "UV_OT_mark_seam"; @@ -4124,7 +4213,10 @@ static void UV_OT_mark_seam(wmOperatorType *ot) /* api callbacks */ ot->exec = uv_mark_seam_exec; + ot->invoke = uv_mark_seam_invoke; ot->poll = ED_operator_uvedit; + + RNA_def_boolean(ot->srna, "clear", false, "Clear Seams", "Clear instead of marking seams"); } diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 79f53e1d971..00615f9bef7 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -35,7 +35,6 @@ #include "BLI_boxpack2d.h" #include "BLI_convexhull2d.h" -#include "uvedit_intern.h" #include "uvedit_parametrizer.h" #include <math.h> @@ -2673,8 +2672,8 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart) } for (i = 0; i < ninterior; i++) { - sys->lambdaPlanar[i] += nlGetVariable(0, i); - sys->lambdaLength[i] += nlGetVariable(0, ninterior + i); + sys->lambdaPlanar[i] += (float)nlGetVariable(0, i); + sys->lambdaLength[i] += (float)nlGetVariable(0, ninterior + i); } } @@ -3403,8 +3402,8 @@ static void p_chart_stretch_minimize(PChart *chart, RNG *rng) static int p_compare_geometric_uv(const void *a, const void *b) { - PVert *v1 = *(PVert **)a; - PVert *v2 = *(PVert **)b; + const PVert *v1 = *(const PVert * const *)a; + const PVert *v2 = *(const PVert * const *)b; if (v1->uv[0] < v2->uv[0]) return -1; @@ -3789,11 +3788,14 @@ static PBool p_node_intersect(SmoothNode *node, float co[2]) /* smoothing */ -static int p_compare_float(const void *a, const void *b) +static int p_compare_float(const void *a_, const void *b_) { - if (*((float *)a) < *((float *)b)) + const float a = *(const float *)a_; + const float b = *(const float *)b_; + + if (a < b) return -1; - else if (*((float *)a) == *((float *)b)) + else if (a == b) return 0; else return 1; @@ -4194,7 +4196,7 @@ void param_delete(ParamHandle *handle) static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts, ParamKey *vkeys, float **co, float **uv, - ParamBool *pin, ParamBool *select, float normal[3]) + ParamBool *pin, ParamBool *select, const float normal[3]) { int *boundary = BLI_array_alloca(boundary, nverts); int i; @@ -4559,7 +4561,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate) box->index = i; /* warning this index skips PCHART_NOPACK boxes */ if (margin > 0.0f) - area += sqrtf(box->w * box->h); + area += (double)sqrtf(box->w * box->h); } if (margin > 0.0f) { diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index fcd5267fd44..828537fd585 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -574,11 +574,11 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2); edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2); if (edgesin > 0.0f) { - rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); + rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); rot_elem++; } else { - rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); + rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); rot_elem_neg++; } } @@ -1354,16 +1354,15 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) /* Stitch hash initialization functions */ static unsigned int uv_edge_hash(const void *key) { - UvEdge *edge = (UvEdge *)key; - return - BLI_ghashutil_uinthash(edge->uv2) + - BLI_ghashutil_uinthash(edge->uv1); + const UvEdge *edge = key; + return (BLI_ghashutil_uinthash(edge->uv2) + + BLI_ghashutil_uinthash(edge->uv1)); } static bool uv_edge_compare(const void *a, const void *b) { - UvEdge *edge1 = (UvEdge *)a; - UvEdge *edge2 = (UvEdge *)b; + const UvEdge *edge1 = a; + const UvEdge *edge2 = b; if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) { return 0; @@ -1602,7 +1601,7 @@ static int stitch_init(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - GHashIterator *ghi; + GHashIterator gh_iter; UvEdge *all_edges; StitchState *state; Scene *scene = CTX_data_scene(C); @@ -1650,17 +1649,17 @@ static int stitch_init(bContext *C, wmOperator *op) /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { - state->element_map = BM_uv_element_map_create(state->em->bm, false, true); + state->element_map = BM_uv_element_map_create(state->em->bm, false, true, true); } else { - state->element_map = BM_uv_element_map_create(state->em->bm, true, true); + state->element_map = BM_uv_element_map_create(state->em->bm, true, true, true); } if (!state->element_map) { state_delete(state); return 0; } - uvedit_get_aspect(scene, obedit, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy); state->aspect = aspx / aspy; /* Entirely possible if redoing last operator that static island is bigger than total number of islands. @@ -1749,14 +1748,11 @@ static int stitch_init(bContext *C, wmOperator *op) } } - - ghi = BLI_ghashIterator_new(edge_hash); total_edges = BLI_ghash_size(edge_hash); state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges"); /* I assume any system will be able to at least allocate an iterator :p */ if (!edges) { - BLI_ghashIterator_free(ghi); state_delete(state); return 0; } @@ -1764,12 +1760,12 @@ static int stitch_init(bContext *C, wmOperator *op) state->total_separate_edges = total_edges; /* fill the edges with data */ - for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_done(ghi); BLI_ghashIterator_step(ghi)) { - edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi)); + i = 0; + GHASH_ITER (gh_iter, edge_hash) { + edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter)); } /* cleanup temporary stuff */ - BLI_ghashIterator_free(ghi); MEM_freeN(all_edges); BLI_ghash_free(edge_hash, NULL, NULL); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 335d8e6589e..f915a4b2e51 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -190,21 +190,21 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit) return false; } -void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy) +void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) { bool sloppy = true; bool selected = false; BMFace *efa; Image *ima; - efa = BM_mesh_active_face_get(em->bm, sloppy, selected); + efa = BM_mesh_active_face_get(bm, sloppy, selected); if (efa) { if (BKE_scene_use_new_shading_nodes(scene)) { ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); } else { - MTexPoly *tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + MTexPoly *tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); ima = tf->tpage; } @@ -247,11 +247,10 @@ static void construct_param_handle_face_add(ParamHandle *handle, Scene *scene, param_face_add(handle, key, i, vkeys, co, uv, pin, select, efa->no); } -static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh *em, +static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm, const bool implicit, const bool fill, const bool sel, const bool correct_aspect) { - BMesh *bm = em->bm; ParamHandle *handle; BMFace *efa; BMLoop *l; @@ -262,20 +261,19 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh handle = param_construct_begin(); - if (correct_aspect) { float aspx, aspy; - uvedit_get_aspect(scene, ob, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, bm, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); } /* we need the vert indices */ - BM_mesh_elem_index_ensure(em->bm, BM_VERT); + BM_mesh_elem_index_ensure(bm, BM_VERT); - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) { continue; @@ -299,7 +297,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh } if (!implicit) { - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) { ParamKey vkeys[2]; vkeys[0] = (ParamKey)BM_elem_index_get(eed->v1); @@ -378,7 +376,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B if (correct_aspect) { float aspx, aspy; - uvedit_get_aspect(scene, ob, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -522,7 +520,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op) ms->blend = RNA_float_get(op->ptr, "blend"); ms->iterations = RNA_int_get(op->ptr, "iterations"); ms->i = 0; - ms->handle = construct_param_handle(scene, obedit, em, implicit, fill_holes, 1, 1); + ms->handle = construct_param_handle(scene, obedit, em->bm, implicit, fill_holes, 1, 1); ms->lasttime = PIL_check_seconds_timer(); param_stretch_begin(ms->handle); @@ -683,7 +681,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) /* identifiers */ ot->name = "Minimize Stretch"; ot->idname = "UV_OT_minimize_stretch"; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR | OPTYPE_BLOCKING; ot->description = "Reduce UV stretching by relaxing angles"; /* api callbacks */ @@ -701,16 +699,23 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) /* ******************** Pack Islands operator **************** */ +void ED_uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate) +{ + ParamHandle *handle; + handle = construct_param_handle(scene, ob, bm, true, false, selected, correct_aspect); + param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); + param_flush(handle); + param_delete(handle); +} + static int pack_islands_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); - ParamHandle *handle; - bool implicit = true; bool do_rotate = RNA_boolean_get(op->ptr, "rotate"); - if (!uvedit_have_selection(scene, em, implicit)) { + if (!uvedit_have_selection(scene, em, true)) { return OPERATOR_CANCELLED; } @@ -719,10 +724,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op) else RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); - handle = construct_param_handle(scene, obedit, em, implicit, 0, 1, 1); - param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate); - param_flush(handle); - param_delete(handle); + ED_uvedit_pack_islands(scene, obedit, em->bm, true, true, do_rotate); DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); @@ -762,7 +764,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } - handle = construct_param_handle(scene, obedit, em, implicit, 0, 1, 1); + handle = construct_param_handle(scene, obedit, em->bm, implicit, 0, 1, 1); param_average(handle); param_flush(handle); param_delete(handle); @@ -807,7 +809,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) if (use_subsurf) liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true); else - liveHandle = construct_param_handle(scene, obedit, em, false, fillholes, false, true); + liveHandle = construct_param_handle(scene, obedit, em->bm, false, fillholes, false, true); param_lscm_begin(liveHandle, PARAM_TRUE, abf); } @@ -1008,7 +1010,7 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em) const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - uvedit_get_aspect(scene, ob, em, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); if (aspx == aspy) return; @@ -1072,7 +1074,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper if (scale_to_bounds) { INIT_MINMAX2(min, max); - + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) continue; @@ -1082,7 +1084,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper minmax_v2v2_v2(min, max, luv->uv); } } - + /* rescale UV to be in 1/1 */ dx = (max[0] - min[0]); dy = (max[1] - min[1]); @@ -1098,7 +1100,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { 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; } @@ -1128,7 +1130,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) ParamHandle *handle; const bool fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0; - const bool correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) != 0; + const bool correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0; bool use_subsurf; modifier_unwrap_state(obedit, scene, &use_subsurf); @@ -1136,7 +1138,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) if (use_subsurf) handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect); else - handle = construct_param_handle(scene, obedit, em, false, fill_holes, sel, correct_aspect); + handle = construct_param_handle(scene, obedit, em->bm, false, fill_holes, sel, correct_aspect); param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); param_lscm_solve(handle); @@ -1599,39 +1601,30 @@ void UV_OT_cylinder_project(wmOperatorType *ot) /******************* Cube Project operator ****************/ -static int cube_project_exec(bContext *C, wmOperator *op) +void ED_uvedit_unwrap_cube_project(Object *ob, BMesh *bm, float cube_size, bool use_select) { - Scene *scene = CTX_data_scene(C); - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; BMLoop *l; BMIter iter, liter; /* MTexPoly *tf; */ /* UNUSED */ MLoopUV *luv; - float cube_size, *loc, dx, dy; + float *loc, dx, dy; int cox, coy; int cd_loop_uv_offset; - /* add uvs if they don't exist yet */ - if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { - return OPERATOR_CANCELLED; - } + cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - - loc = obedit->obmat[3]; - cube_size = RNA_float_get(op->ptr, "cube_size"); + loc = ob->obmat[3]; /* choose x,y,z axis for projection depending on the largest normal * component, but clusters all together around the center of map. */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { int first = 1; /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ - if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) + if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) continue; axis_dominant_v3(&cox, &coy, efa->no); @@ -1642,19 +1635,34 @@ static int cube_project_exec(bContext *C, wmOperator *op) luv->uv[0] = 0.5f + 0.5f * cube_size * (loc[cox] + l->v->co[cox]); luv->uv[1] = 0.5f + 0.5f * cube_size * (loc[coy] + l->v->co[coy]); - + if (first) { dx = floor(luv->uv[0]); dy = floor(luv->uv[1]); first = 0; } - + luv->uv[0] -= dx; luv->uv[1] -= dy; } } +} + +static int cube_project_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + float cube_size = RNA_float_get(op->ptr, "cube_size"); + + /* add uvs if they don't exist yet */ + if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { + return OPERATOR_CANCELLED; + } + + ED_uvedit_unwrap_cube_project(obedit, em->bm, cube_size, true); uv_map_clip_correct(scene, obedit, em, op); DAG_id_tag_update(obedit->data, 0); |