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.
This commit is contained in:
Antony Riakiotakis 2014-10-31 14:37:36 +01:00
parent 46c11c7b7d
commit a6a3989617
11 changed files with 168 additions and 48 deletions

@ -794,7 +794,7 @@ class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
col.separator() col.separator()
col.label("Missing UVs", icon='INFO') col.label("Missing UVs", icon='INFO')
col.label("Unwrap the mesh in edit mode or generate a simple UVs") 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.mode == 'MATERIAL':
if toolsettings.missing_materials: if toolsettings.missing_materials:

@ -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_calc_tessface(struct Mesh *mesh);
void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges, int calc_tessface); 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); 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_index(struct Mesh *me, const int n);
bool ED_mesh_uv_texture_remove_active(struct Mesh *me); bool ED_mesh_uv_texture_remove_active(struct Mesh *me);

@ -31,6 +31,7 @@
#define __ED_UVEDIT_H__ #define __ED_UVEDIT_H__
struct ARegionType; struct ARegionType;
struct BMesh;
struct BMEditMesh; struct BMEditMesh;
struct BMFace; struct BMFace;
struct BMLoop; 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); 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]); 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, 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); 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_end(short cancel);
void ED_uvedit_live_unwrap(struct Scene *scene, struct Object *obedit); 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 */ /* 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); void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel);
/* uvedit_draw.c */ /* uvedit_draw.c */
void draw_image_cursor(struct ARegion *ar, const float cursor[2]); 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); void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact);

@ -336,6 +336,26 @@ int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set)
return layernum_dst; 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) 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); CustomData *pdata = GET_CD_DATA(me, pdata), *ldata = GET_CD_DATA(me, ldata);

@ -105,6 +105,9 @@
#include "IMB_colormanagement.h" #include "IMB_colormanagement.h"
#include "bmesh.h"
//#include "bmesh_tools.h"
#include "paint_intern.h" #include "paint_intern.h"
/* Defines and Structs */ /* Defines and Structs */
@ -5233,7 +5236,7 @@ static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator
BKE_texpaint_slot_refresh_cache(scene, ma); BKE_texpaint_slot_refresh_cache(scene, ma);
DAG_id_tag_update(&ma->id, 0); 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 */ /* 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; return OPERATOR_FINISHED;
@ -5254,3 +5257,64 @@ void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot)
/* flags */ /* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; 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;
}

@ -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_add_texture_paint_slot(struct wmOperatorType *ot);
void PAINT_OT_delete_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_image_paint(struct wmOperatorType *ot);
void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot);
/* uv sculpting */ /* uv sculpting */
int uv_sculpt_poll(struct bContext *C); int uv_sculpt_poll(struct bContext *C);

@ -1085,6 +1085,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_brush_colors_flip); WM_operatortype_append(PAINT_OT_brush_colors_flip);
WM_operatortype_append(PAINT_OT_add_texture_paint_slot); WM_operatortype_append(PAINT_OT_add_texture_paint_slot);
WM_operatortype_append(PAINT_OT_delete_texture_paint_slot); WM_operatortype_append(PAINT_OT_delete_texture_paint_slot);
WM_operatortype_append(PAINT_OT_add_simple_uvs);
/* weight */ /* weight */
WM_operatortype_append(PAINT_OT_weight_paint_toggle); WM_operatortype_append(PAINT_OT_weight_paint_toggle);

@ -41,6 +41,7 @@ struct SpaceImage;
struct UvElementMap; struct UvElementMap;
struct wmOperatorType; struct wmOperatorType;
struct BMEditMesh; struct BMEditMesh;
struct BMesh;
struct BMFace; struct BMFace;
struct BMLoop; struct BMLoop;
struct BMEdge; struct BMEdge;
@ -71,7 +72,7 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM
/* utility tool functions */ /* utility tool functions */
void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); 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 */ /* operators */

@ -668,6 +668,24 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2],
return changed; 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]) static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[2])
{ {
BMEditMesh *em = BKE_editmesh_from_object(obedit); BMEditMesh *em = BKE_editmesh_from_object(obedit);

@ -1660,7 +1660,7 @@ static int stitch_init(bContext *C, wmOperator *op)
return 0; return 0;
} }
uvedit_get_aspect(scene, obedit, em, &aspx, &aspy); uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy);
state->aspect = aspx / aspy; state->aspect = aspx / aspy;
/* Entirely possible if redoing last operator that static island is bigger than total number of islands. /* Entirely possible if redoing last operator that static island is bigger than total number of islands.

@ -190,21 +190,21 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit)
return false; 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 sloppy = true;
bool selected = false; bool selected = false;
BMFace *efa; BMFace *efa;
Image *ima; Image *ima;
efa = BM_mesh_active_face_get(em->bm, sloppy, selected); efa = BM_mesh_active_face_get(bm, sloppy, selected);
if (efa) { if (efa) {
if (BKE_scene_use_new_shading_nodes(scene)) { if (BKE_scene_use_new_shading_nodes(scene)) {
ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL);
} }
else { 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; 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); 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 implicit, const bool fill, const bool sel,
const bool correct_aspect) const bool correct_aspect)
{ {
BMesh *bm = em->bm;
ParamHandle *handle; ParamHandle *handle;
BMFace *efa; BMFace *efa;
BMLoop *l; BMLoop *l;
@ -262,20 +261,19 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
handle = param_construct_begin(); handle = param_construct_begin();
if (correct_aspect) { if (correct_aspect) {
float aspx, aspy; float aspx, aspy;
uvedit_get_aspect(scene, ob, em, &aspx, &aspy); uvedit_get_aspect(scene, ob, bm, &aspx, &aspy);
if (aspx != aspy) if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy); param_aspect_ratio(handle, aspx, aspy);
} }
/* we need the vert indices */ /* 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)) { if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue; continue;
@ -299,7 +297,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
} }
if (!implicit) { 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)) { if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) {
ParamKey vkeys[2]; ParamKey vkeys[2];
vkeys[0] = (ParamKey)BM_elem_index_get(eed->v1); 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) { if (correct_aspect) {
float aspx, aspy; float aspx, aspy;
uvedit_get_aspect(scene, ob, em, &aspx, &aspy); uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy);
if (aspx != aspy) if (aspx != aspy)
param_aspect_ratio(handle, 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->blend = RNA_float_get(op->ptr, "blend");
ms->iterations = RNA_int_get(op->ptr, "iterations"); ms->iterations = RNA_int_get(op->ptr, "iterations");
ms->i = 0; 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(); ms->lasttime = PIL_check_seconds_timer();
param_stretch_begin(ms->handle); param_stretch_begin(ms->handle);
@ -701,16 +699,23 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
/* ******************** Pack Islands operator **************** */ /* ******************** 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) static int pack_islands_exec(bContext *C, wmOperator *op)
{ {
Scene *scene = CTX_data_scene(C); Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C); Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit); BMEditMesh *em = BKE_editmesh_from_object(obedit);
ParamHandle *handle;
bool implicit = true;
bool do_rotate = RNA_boolean_get(op->ptr, "rotate"); 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; return OPERATOR_CANCELLED;
} }
@ -719,10 +724,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
else else
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
handle = construct_param_handle(scene, obedit, em, implicit, 0, 1, 1); ED_uvedit_pack_islands(scene, obedit, em->bm, true, true, do_rotate);
param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate);
param_flush(handle);
param_delete(handle);
DAG_id_tag_update(obedit->data, 0); DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); 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; 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_average(handle);
param_flush(handle); param_flush(handle);
param_delete(handle); param_delete(handle);
@ -807,7 +809,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
if (use_subsurf) if (use_subsurf)
liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true); liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true);
else 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); 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); 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) if (aspx == aspy)
return; return;
@ -1136,7 +1138,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
if (use_subsurf) if (use_subsurf)
handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect); handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect);
else 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_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
param_lscm_solve(handle); param_lscm_solve(handle);
@ -1599,39 +1601,30 @@ void UV_OT_cylinder_project(wmOperatorType *ot)
/******************* Cube Project operator ****************/ /******************* 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; BMFace *efa;
BMLoop *l; BMLoop *l;
BMIter iter, liter; BMIter iter, liter;
/* MTexPoly *tf; */ /* UNUSED */ /* MTexPoly *tf; */ /* UNUSED */
MLoopUV *luv; MLoopUV *luv;
float cube_size, *loc, dx, dy; float *loc, dx, dy;
int cox, coy; int cox, coy;
int cd_loop_uv_offset; int cd_loop_uv_offset;
/* add uvs if they don't exist yet */ cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
return OPERATOR_CANCELLED;
}
cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); loc = ob->obmat[3];
loc = obedit->obmat[3];
cube_size = RNA_float_get(op->ptr, "cube_size");
/* choose x,y,z axis for projection depending on the largest normal /* choose x,y,z axis for projection depending on the largest normal
* component, but clusters all together around the center of map. */ * 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; int first = 1;
/* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ /* 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; continue;
axis_dominant_v3(&cox, &coy, efa->no); axis_dominant_v3(&cox, &coy, efa->no);
@ -1655,6 +1648,22 @@ static int cube_project_exec(bContext *C, wmOperator *op)
} }
} }
}
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); uv_map_clip_correct(scene, obedit, em, op);
DAG_id_tag_update(obedit->data, 0); DAG_id_tag_update(obedit->data, 0);