From a6a3989617e680327bda2357fe506d86574e2618 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Fri, 31 Oct 2014 14:37:36 +0100 Subject: [PATCH] Texture Paint Add Simple UVs: Add simple uvs now does a cube unwrap and pack operation. Result is not optimal by far but it should not result in crashes and it will be quite usable for simple cases. --- .../startup/bl_ui/space_view3d_toolbar.py | 2 +- source/blender/editors/include/ED_mesh.h | 1 + source/blender/editors/include/ED_uvedit.h | 5 + source/blender/editors/mesh/mesh_data.c | 20 ++++ .../editors/sculpt_paint/paint_image_proj.c | 68 ++++++++++++- .../editors/sculpt_paint/paint_intern.h | 1 + .../blender/editors/sculpt_paint/paint_ops.c | 1 + source/blender/editors/uvedit/uvedit_intern.h | 3 +- source/blender/editors/uvedit/uvedit_ops.c | 18 ++++ .../editors/uvedit/uvedit_smart_stitch.c | 2 +- .../editors/uvedit/uvedit_unwrap_ops.c | 95 ++++++++++--------- 11 files changed, 168 insertions(+), 48 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 81cdaf63271..221888685eb 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -794,7 +794,7 @@ class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel): col.separator() col.label("Missing UVs", icon='INFO') col.label("Unwrap the mesh in edit mode or generate a simple UVs") - col.operator("mesh.uv_texture_add", text="Add Simple UVs") + col.operator("paint.add_simple_uvs") if toolsettings.mode == 'MATERIAL': if toolsettings.missing_materials: diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 6a562da0a0e..c9faad62d6e 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -267,6 +267,7 @@ void ED_mesh_vertices_remove(struct Mesh *mesh, struct ReportList *reports, int void ED_mesh_calc_tessface(struct Mesh *mesh); void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges, int calc_tessface); +void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name); int ED_mesh_uv_texture_add(struct Mesh *me, const char *name, const bool active_set); bool ED_mesh_uv_texture_remove_index(struct Mesh *me, const int n); bool ED_mesh_uv_texture_remove_active(struct Mesh *me); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 4b82fa40c6a..70dc0034f5b 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -31,6 +31,7 @@ #define __ED_UVEDIT_H__ struct ARegionType; +struct BMesh; struct BMEditMesh; struct BMFace; struct BMLoop; @@ -52,6 +53,7 @@ void ED_keymap_uvedit(struct wmKeyConfig *keyconf); void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]); +void ED_uvedit_select_all(struct BMesh *bm); bool ED_object_get_active_image(struct Object *ob, int mat_nr, struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node, struct bNodeTree **r_ntree); @@ -98,10 +100,13 @@ void ED_uvedit_live_unwrap_re_solve(void); void ED_uvedit_live_unwrap_end(short cancel); void ED_uvedit_live_unwrap(struct Scene *scene, struct Object *obedit); +void ED_uvedit_pack_islands(struct Scene *scene, struct Object *ob, struct BMesh *bm, bool selected, bool correct_aspect, bool do_rotate); +void ED_uvedit_cube_project_unwrap(struct Object *ob, struct BMesh *bm, float cube_size, bool use_select); /* single call up unwrap using scene settings, used for edge tag unwrapping */ void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel); + /* uvedit_draw.c */ void draw_image_cursor(struct ARegion *ar, const float cursor[2]); void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 68471bfc2ba..e2ce97a3bdf 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -336,6 +336,26 @@ int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set) return layernum_dst; } +void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name) +{ + BMEditMesh *em; + int layernum_dst; + + if (me->edit_btmesh) { + em = me->edit_btmesh; + + layernum_dst = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY); + if (layernum_dst == 0) + ED_mesh_uv_texture_add(me, name, true); + } + else { + layernum_dst = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); + if (layernum_dst == 0) + ED_mesh_uv_texture_add(me, name, true); + } +} + + bool ED_mesh_uv_texture_remove_index(Mesh *me, const int n) { CustomData *pdata = GET_CD_DATA(me, pdata), *ldata = GET_CD_DATA(me, ldata); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 214084a3610..e1b33489554 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -105,6 +105,9 @@ #include "IMB_colormanagement.h" +#include "bmesh.h" +//#include "bmesh_tools.h" + #include "paint_intern.h" /* Defines and Structs */ @@ -5233,9 +5236,9 @@ static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator BKE_texpaint_slot_refresh_cache(scene, ma); DAG_id_tag_update(&ma->id, 0); - WM_event_add_notifier(C, NC_MATERIAL, CTX_data_scene(C)); + WM_event_add_notifier(C, NC_MATERIAL, ma); /* we need a notifier for data change since we change the displayed modifier uvs */ - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); return OPERATOR_FINISHED; } @@ -5254,3 +5257,64 @@ void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) +{ + /* no checks here, poll function does them for us */ + Object *ob = CTX_data_active_object(C); + Scene *scene = CTX_data_scene(C); + Mesh *me = ob->data; + bool synch_selection = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0; + + BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default); + + /* turn synch selection off, since we are not in edit mode we need to ensure only the uv flags are tested */ + scene->toolsettings->uv_flag &= ~UV_SYNC_SELECTION; + + ED_mesh_uv_texture_ensure(me, NULL); + + BM_mesh_bm_from_me(bm, me, true, false, 0); + + /* select all uv loops first - pack parameters needs this to make sure charts are registered */ + ED_uvedit_select_all(bm); + ED_uvedit_cube_project_unwrap(ob, bm, 1.0, false); + /* set the margin really quickly before the packing operation*/ + scene->toolsettings->uvcalc_margin = 0.001f; + ED_uvedit_pack_islands(scene, ob, bm, false, false, true); + BM_mesh_bm_to_me(bm, me, false); + BM_mesh_free(bm); + + if (synch_selection) + scene->toolsettings->uv_flag |= UV_SYNC_SELECTION; + + DAG_id_tag_update(ob->data, 0); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, scene); + return OPERATOR_FINISHED; +} + +static int add_simple_uvs_poll(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + + if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT) + return false; + + return true; +} + +void PAINT_OT_add_simple_uvs(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add simple UVs"; + ot->description = "Add cube map uvs on mesh"; + ot->idname = "PAINT_OT_add_simple_uvs"; + + /* api callbacks */ + ot->exec = add_simple_uvs_exec; + ot->poll = add_simple_uvs_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index c3b7ec60e71..b89d99cd15d 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -184,6 +184,7 @@ void PAINT_OT_image_from_view(struct wmOperatorType *ot); void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot); void PAINT_OT_delete_texture_paint_slot(struct wmOperatorType *ot); void PAINT_OT_image_paint(struct wmOperatorType *ot); +void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot); /* uv sculpting */ int uv_sculpt_poll(struct bContext *C); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index dc6be9caa53..2a09b0ca614 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -1085,6 +1085,7 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_brush_colors_flip); WM_operatortype_append(PAINT_OT_add_texture_paint_slot); WM_operatortype_append(PAINT_OT_delete_texture_paint_slot); + WM_operatortype_append(PAINT_OT_add_simple_uvs); /* weight */ WM_operatortype_append(PAINT_OT_weight_paint_toggle); diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 52365ff3478..8865bc6775b 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -41,6 +41,7 @@ struct SpaceImage; struct UvElementMap; struct wmOperatorType; struct BMEditMesh; +struct BMesh; struct BMFace; struct BMLoop; struct BMEdge; @@ -71,7 +72,7 @@ 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); +void uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMesh *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..35a9bb9955b 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -668,6 +668,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); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index fcd5267fd44..9359baa5020 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1660,7 +1660,7 @@ static int stitch_init(bContext *C, wmOperator *op) return 0; } - uvedit_get_aspect(scene, obedit, em, &aspx, &aspy); + 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. diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 335d8e6589e..bc08782e54b 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 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); + 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); + 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); @@ -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); + 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; } @@ -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_cube_project_unwrap(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,35 @@ 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_cube_project_unwrap(obedit, em->bm, cube_size, true); + uv_map_clip_correct(scene, obedit, em, op); DAG_id_tag_update(obedit->data, 0);