diff options
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_unwrap_ops.c')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_unwrap_ops.c | 654 |
1 files changed, 342 insertions, 312 deletions
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 3ed4df66778..3377fdad9db 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -42,11 +42,13 @@ #include "DNA_scene_types.h" #include "DNA_modifier_types.h" +#include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_editVert.h" #include "BLI_uvproject.h" #include "BLI_utildefines.h" +#include "BLI_rand.h" #include "BLI_string.h" #include "BKE_cdderivedmesh.h" @@ -58,6 +60,14 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_report.h" +#include "BKE_tessmesh.h" + +#include "BLI_math.h" +#include "BLI_edgehash.h" +#include "BLI_editVert.h" +#include "BLI_scanfill.h" +#include "BLI_array.h" +#include "BLI_uvproject.h" #include "PIL_time.h" @@ -80,9 +90,9 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) { Main *bmain= CTX_data_main(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMIter iter; Image *ima; bScreen *sc; ScrArea *sa; @@ -90,15 +100,15 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) SpaceImage *sima; if(ED_uvedit_test(obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); return 1; } - if(em && em->faces.first) - EM_add_data_layer(em, &em->fdata, CD_MTFACE, NULL); - + if(em && em->bm->totface && !CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) { + BM_add_data_layer(em->bm, &em->bm->pdata, CD_MTEXPOLY); + BM_add_data_layer(em->bm, &em->bm->ldata, CD_MLOOPUV); + } + if(!ED_uvedit_test(obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); return 0; } @@ -128,70 +138,69 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL); /* select new UV's */ - for(efa=em->faces.first; efa; efa=efa->next) { - tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uvedit_face_select(scene, efa, tf); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + uvedit_face_select(scene, em, efa); } - BKE_mesh_end_editmesh(obedit->data, em); return 1; } /****************** Parametrizer Conversion ***************/ -static int uvedit_have_selection(Scene *scene, EditMesh *em, short implicit) +static int uvedit_have_selection(Scene *scene, BMEditMesh *em, short implicit) { - EditFace *efa; - MTFace *tf; - + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; + /* verify if we have any selected uv's before unwrapping, so we can cancel the operator early */ - for(efa= em->faces.first; efa; efa= efa->next) { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) { - if(efa->h) + if(BM_TestHFlag(efa, BM_HIDDEN)) continue; } - else if((efa->h) || ((efa->f & SELECT)==0)) + else if(BM_TestHFlag(efa, BM_HIDDEN) || !BM_TestHFlag(efa, BM_SELECT)) continue; - - tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(!tf) - return 1; /* default selected if doesn't exists */ + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + if (!luv) + return 1; + + if (uvedit_uv_selected(em, scene, l)) + break; + } - if(implicit && - !( uvedit_uv_selected(scene, efa, tf, 0) || - uvedit_uv_selected(scene, efa, tf, 1) || - uvedit_uv_selected(scene, efa, tf, 2) || - (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) ) - ) { + if (implicit && !l) continue; - } - + return 1; } return 0; } -static ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, - short fill, short sel, short correct_aspect) +static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, + short implicit, short fill, short sel, + short correct_aspect) { ParamHandle *handle; - EditFace *efa; - EditEdge *eed; - EditVert *ev; - MTFace *tf; - int a; + BMFace *efa; + BMLoop *l; + BMEdge *eed; + BMIter iter, liter; + MTexPoly *tf; handle = param_construct_begin(); if(correct_aspect) { - efa = EM_get_actFace(em, 1); + efa = BM_get_actFace(em->bm, 1); if(efa) { float aspx, aspy; - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); ED_image_uv_aspect(tf->tpage, &aspx, &aspy); @@ -201,71 +210,108 @@ static ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short imp } /* we need the vert indices */ - for(ev= em->verts.first, a=0; ev; ev= ev->next, a++) - ev->tmp.l = a; + BM_ElemIndex_Ensure(em->bm, BM_VERT); - for(efa= em->faces.first; efa; efa= efa->next) { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + EditVert *v, *lastv, *firstv; + EditFace *sefa; ParamKey key, vkeys[4]; ParamBool pin[4], select[4]; + BMLoop *ls[3]; + MLoopUV *luvs[3]; float *co[4]; float *uv[4]; - int nverts; - - if((efa->h) || (sel && (efa->f & SELECT)==0)) - continue; + int lsel; - tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(implicit && - !( uvedit_uv_selected(scene, efa, tf, 0) || - uvedit_uv_selected(scene, efa, tf, 1) || - uvedit_uv_selected(scene, efa, tf, 2) || - (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) ) - ) { + if((BM_TestHFlag(efa, BM_HIDDEN)) || (sel && BM_TestHFlag(efa, BM_SELECT)==0)) continue; + + /* tf= (MTexPoly *)CustomData_em_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ + lsel = 0; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l)) { + lsel = 1; + break; + } } + if (implicit && !lsel) + continue; + key = (ParamKey)efa; - vkeys[0] = (ParamKey)efa->v1->tmp.l; - vkeys[1] = (ParamKey)efa->v2->tmp.l; - vkeys[2] = (ParamKey)efa->v3->tmp.l; - - co[0] = efa->v1->co; - co[1] = efa->v2->co; - co[2] = efa->v3->co; - - uv[0] = tf->uv[0]; - uv[1] = tf->uv[1]; - uv[2] = tf->uv[2]; - - pin[0] = ((tf->unwrap & TF_PIN1) != 0); - pin[1] = ((tf->unwrap & TF_PIN2) != 0); - pin[2] = ((tf->unwrap & TF_PIN3) != 0); - - select[0] = ((uvedit_uv_selected(scene, efa, tf, 0)) != 0); - select[1] = ((uvedit_uv_selected(scene, efa, tf, 1)) != 0); - select[2] = ((uvedit_uv_selected(scene, efa, tf, 2)) != 0); - - if(efa->v4) { - vkeys[3] = (ParamKey)efa->v4->tmp.l; - co[3] = efa->v4->co; - uv[3] = tf->uv[3]; - pin[3] = ((tf->unwrap & TF_PIN4) != 0); - select[3] = (uvedit_uv_selected(scene, efa, tf, 3) != 0); - nverts = 4; + + /*scanfill time!*/ + BLI_begin_edgefill(); + + firstv = lastv = NULL; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + int i; + + v = BLI_addfillvert(l->v->co); + + /*add small random offset*/ + for (i=0; i<3; i++) { + v->co[i] += (BLI_drand()-0.5f)*FLT_EPSILON*50; + } + + v->tmp.p = l; + + if (lastv) { + BLI_addfilledge(lastv, v); + } + + lastv = v; + if (!firstv) + firstv = v; + } + + BLI_addfilledge(firstv, v); + + /*mode 2 enables faster handling of tri/quads*/ + BLI_edgefill(2); + for (sefa = fillfacebase.first; sefa; sefa=sefa->next) { + ls[0] = sefa->v1->tmp.p; + ls[1] = sefa->v2->tmp.p; + ls[2] = sefa->v3->tmp.p; + + luvs[0] = CustomData_bmesh_get(&em->bm->ldata, ls[0]->head.data, CD_MLOOPUV); + luvs[1] = CustomData_bmesh_get(&em->bm->ldata, ls[1]->head.data, CD_MLOOPUV); + luvs[2] = CustomData_bmesh_get(&em->bm->ldata, ls[2]->head.data, CD_MLOOPUV); + + vkeys[0] = (ParamKey)BM_GetIndex(ls[0]->v); + vkeys[1] = (ParamKey)BM_GetIndex(ls[1]->v); + vkeys[2] = (ParamKey)BM_GetIndex(ls[2]->v); + + co[0] = ls[0]->v->co; + co[1] = ls[1]->v->co; + co[2] = ls[2]->v->co; + + uv[0] = luvs[0]->uv; + uv[1] = luvs[1]->uv; + uv[2] = luvs[2]->uv; + + pin[0] = (luvs[0]->flag & MLOOPUV_PINNED) != 0; + pin[1] = (luvs[1]->flag & MLOOPUV_PINNED) != 0; + pin[2] = (luvs[2]->flag & MLOOPUV_PINNED) != 0; + + select[0] = uvedit_uv_selected(em, scene, ls[0]) != 0; + select[1] = uvedit_uv_selected(em, scene, ls[1]) != 0; + select[2] = uvedit_uv_selected(em, scene, ls[2]) != 0; + + if (!p_face_exists(handle,vkeys,0,1,2)) + param_face_add(handle, key, 3, vkeys, co, uv, pin, select); } - else - nverts = 3; - param_face_add(handle, key, nverts, vkeys, co, uv, pin, select); + BLI_end_edgefill(); } if(!implicit) { - for(eed= em->edges.first; eed; eed= eed->next) { - if(eed->seam) { + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if(BM_TestHFlag(eed, BM_SEAM)) { ParamKey vkeys[2]; - vkeys[0] = (ParamKey)eed->v1->tmp.l; - vkeys[1] = (ParamKey)eed->v2->tmp.l; + vkeys[0] = (ParamKey)BM_GetIndex(eed->v1); + vkeys[1] = (ParamKey)BM_GetIndex(eed->v2); param_edge_set_seam(handle, vkeys); } } @@ -276,7 +322,7 @@ static ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short imp return handle; } - +#if 0 /* BMESH_TODO */ static void texface_from_original_index(EditFace *editFace, MTFace *texFace, int index, float **uv, ParamBool *pin, ParamBool *select, Scene *scene) { int i, nverts = (editFace->v4)? 4: 3; @@ -471,12 +517,26 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, EditMesh *edi return handle; } +#else + +static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *editMesh, short fill, short sel, short correct_aspect) +{ + (void)scene; + (void)editMesh; + (void)fill; + (void)sel; + (void)correct_aspect; + return NULL; +} + +#endif /* BMESH_TODO */ + /* ******************** Minimize Stretch operator **************** */ typedef struct MinStretch { Scene *scene; Object *obedit; - EditMesh *em; + BMEditMesh *em; ParamHandle *handle; float blend; double lasttime; @@ -488,13 +548,12 @@ static int minimize_stretch_init(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; MinStretch *ms; int fill_holes= RNA_boolean_get(op->ptr, "fill_holes"); short implicit= 1; if(!uvedit_have_selection(scene, em, implicit)) { - BKE_mesh_end_editmesh(obedit->data, em); return 0; } @@ -675,12 +734,9 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) ot->poll= ED_operator_uvedit; /* properties */ - RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", - "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry"); - RNA_def_float_factor(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", - "Blend factor between stretch minimized and original", 0.0f, 1.0f); - RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", - "Number of iterations to run, 0 is unlimited when run interactively", 0, 100); + RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry"); + RNA_def_float_factor(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original", 0.0f, 1.0f); + RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively", 0, 100); } /* ******************** Pack Islands operator **************** */ @@ -689,12 +745,11 @@ static int pack_islands_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; ParamHandle *handle; short implicit= 1; if(!uvedit_have_selection(scene, em, implicit)) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } @@ -713,7 +768,6 @@ static int pack_islands_exec(bContext *C, wmOperator *op) DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -729,8 +783,7 @@ void UV_OT_pack_islands(wmOperatorType *ot) ot->poll= ED_operator_uvedit; /* properties */ - RNA_def_float_factor(ot->srna, "margin", 0.0f, 0.0f, 1.0f, "Margin", - "Space between islands", 0.0f, 1.0f); + RNA_def_float_factor(ot->srna, "margin", 0.0f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } /* ******************** Average Islands Scale operator **************** */ @@ -739,12 +792,11 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; ParamHandle *handle; short implicit= 1; if(!uvedit_have_selection(scene, em, implicit)) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } @@ -756,7 +808,6 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op)) DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -778,13 +829,12 @@ static ParamHandle *liveHandle = NULL; void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) { - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; short abf = scene->toolsettings->unwrapper == 0; short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; if(!ED_uvedit_test(obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); return; } @@ -794,7 +844,6 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) liveHandle = construct_param_handle(scene, em, 0, fillholes, 0, 1); param_lscm_begin(liveHandle, PARAM_TRUE, abf); - BKE_mesh_end_editmesh(obedit->data, em); } void ED_uvedit_live_unwrap_re_solve(void) @@ -825,9 +874,12 @@ void ED_uvedit_live_unwrap_end(short cancel) #define POLAR_ZX 0 #define POLAR_ZY 1 -static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, Object *ob, EditMesh *em) +static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, + Object *ob, BMEditMesh *em) { - EditFace *efa; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; float min[3], max[3], *cursx; int around= (v3d)? v3d->around: V3D_CENTER; @@ -837,13 +889,12 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, Ob case V3D_CENTER: /* bounding box center */ min[0]= min[1]= min[2]= 1e20f; max[0]= max[1]= max[2]= -1e20f; - - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - DO_MINMAX(efa->v1->co, min, max); - DO_MINMAX(efa->v2->co, min, max); - DO_MINMAX(efa->v3->co, min, max); - if(efa->v4) DO_MINMAX(efa->v4->co, min, max); + + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if(BM_TestHFlag(efa, BM_SELECT)) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + DO_MINMAX(l->v->co, min, max); + } } } mid_v3_v3v3(result, min, max); @@ -918,7 +969,7 @@ static void uv_map_transform(bContext *C, wmOperator *op, float center[3], float /* context checks are messy here, making it work in both 3d view and uv editor */ Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); /* common operator properties */ @@ -945,7 +996,6 @@ static void uv_map_transform(bContext *C, wmOperator *op, float center[3], float else uv_map_rotation_matrix(rotmat, rv3d, obedit, upangledeg, sideangledeg, radius); - BKE_mesh_end_editmesh(obedit->data, em); } static void uv_transform_properties(wmOperatorType *ot, int radius) @@ -971,14 +1021,17 @@ static void uv_transform_properties(wmOperatorType *ot, int radius) "Radius of the sphere or cylinder", 0.0001f, 100.0f); } -static void correct_uv_aspect(EditMesh *em) +static void correct_uv_aspect(BMEditMesh *em) { - EditFace *efa= EM_get_actFace(em, 1); - MTFace *tf; + BMFace *efa= BM_get_actFace(em->bm, 1); + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; float scale, aspx= 1.0f, aspy=1.0f; if(efa) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); ED_image_uv_aspect(tf->tpage, &aspx, &aspy); } @@ -988,30 +1041,28 @@ static void correct_uv_aspect(EditMesh *em) if(aspx > aspy) { scale= aspy/aspx; - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - tf->uv[0][0]= ((tf->uv[0][0]-0.5f)*scale)+0.5f; - tf->uv[1][0]= ((tf->uv[1][0]-0.5f)*scale)+0.5f; - tf->uv[2][0]= ((tf->uv[2][0]-0.5f)*scale)+0.5f; - if(efa->v4) - tf->uv[3][0]= ((tf->uv[3][0]-0.5f)*scale)+0.5f; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if (!BM_TestHFlag(efa, BM_SELECT) || BM_TestHFlag(efa, BM_HIDDEN)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->uv[0] = ((luv->uv[0]-0.5)*scale)+0.5; } } } else { scale= aspx/aspy; - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - tf->uv[0][1]= ((tf->uv[0][1]-0.5f)*scale)+0.5f; - tf->uv[1][1]= ((tf->uv[1][1]-0.5f)*scale)+0.5f; - tf->uv[2][1]= ((tf->uv[2][1]-0.5f)*scale)+0.5f; - if(efa->v4) - tf->uv[3][1]= ((tf->uv[3][1]-0.5f)*scale)+0.5f; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if (!BM_TestHFlag(efa, BM_SELECT)||BM_TestHFlag(efa, BM_HIDDEN)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->uv[1] = ((luv->uv[1]-0.5)*scale)+0.5; } } } @@ -1029,12 +1080,13 @@ static void uv_map_clip_correct_properties(wmOperatorType *ot) "Scale UV coordinates to bounds after unwrapping"); } -static void uv_map_clip_correct(EditMesh *em, wmOperator *op) +static void uv_map_clip_correct(BMEditMesh *em, wmOperator *op) { - EditFace *efa; - MTFace *tf; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; float dx, dy, min[2], max[2]; - int b, nverts; int correct_aspect= RNA_boolean_get(op->ptr, "correct_aspect"); int clip_to_bounds= RNA_boolean_get(op->ptr, "clip_to_bounds"); int scale_to_bounds= RNA_boolean_get(op->ptr, "scale_to_bounds"); @@ -1046,16 +1098,13 @@ static void uv_map_clip_correct(EditMesh *em, wmOperator *op) if(scale_to_bounds) { INIT_MINMAX2(min, max); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - DO_MINMAX2(tf->uv[0], min, max); - DO_MINMAX2(tf->uv[1], min, max); - DO_MINMAX2(tf->uv[2], min, max); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; - if(efa->v4) - DO_MINMAX2(tf->uv[3], min, max); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + DO_MINMAX2(luv->uv, min, max); } } @@ -1068,31 +1117,28 @@ static void uv_map_clip_correct(EditMesh *em, wmOperator *op) if(dy > 0.0f) dy= 1.0f/dy; - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - nverts= (efa->v4)? 4: 3; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; - for(b=0; b<nverts; b++) { - tf->uv[b][0]= (tf->uv[b][0]-min[0])*dx; - tf->uv[b][1]= (tf->uv[b][1]-min[1])*dy; - } + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + luv->uv[0] = (luv->uv[0]-min[0])*dx; + luv->uv[1] = (luv->uv[1]-min[1])*dy; } } } else if(clip_to_bounds) { /* clipping and wrapping */ - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - nverts= (efa->v4)? 4: 3; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; - for(b=0; b<nverts; b++) { - CLAMP(tf->uv[b][0], 0.0f, 1.0f); - CLAMP(tf->uv[b][1], 0.0f, 1.0f); - } + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + CLAMP(luv->uv[0], 0.0f, 1.0f); + CLAMP(luv->uv[1], 0.0f, 1.0f); } } } @@ -1103,9 +1149,9 @@ static void uv_map_clip_correct(EditMesh *em, wmOperator *op) /* assumes UV Map is checked, doesn't run update funcs */ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) { + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; ParamHandle *handle; - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); const short fill_holes= scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; const short correct_aspect= !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT); const short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; @@ -1124,15 +1170,13 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) param_flush(handle); param_delete(handle); - - BKE_mesh_end_editmesh(obedit->data, em); } static int unwrap_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; int method = RNA_enum_get(op->ptr, "method"); int fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); @@ -1142,11 +1186,8 @@ static int unwrap_exec(bContext *C, wmOperator *op) short implicit= 0; if(!uvedit_have_selection(scene, em, implicit)) { - BKE_mesh_end_editmesh(obedit->data, em); - return 0; + return OPERATOR_CANCELLED; } - - BKE_mesh_end_editmesh(obedit->data, em); /* add uvs if they don't exist yet */ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) { @@ -1214,17 +1255,18 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); Camera *camera= NULL; - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - ARegion *ar= CTX_wm_region(C); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + ARegion *ar = CTX_wm_region(C); View3D *v3d= CTX_wm_view3d(C); - RegionView3D *rv3d= ar->regiondata; - EditFace *efa; - MTFace *tf; + RegionView3D *rv3d= CTX_wm_region_view3d(C); + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; float rotmat[4][4]; /* add uvs if they don't exist yet */ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } @@ -1234,17 +1276,15 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) } if(RNA_boolean_get(op->ptr, "orthographic")) { - uv_map_rotation_matrix(rotmat, ar->regiondata, obedit, 90.0f, 0.0f, 1.0f); + uv_map_rotation_matrix(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - project_from_view_ortho(tf->uv[0], efa->v1->co, rotmat); - project_from_view_ortho(tf->uv[1], efa->v2->co, rotmat); - project_from_view_ortho(tf->uv[2], efa->v3->co, rotmat); - if(efa->v4) - project_from_view_ortho(tf->uv[3], efa->v4->co, rotmat); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + project_from_view_ortho(luv->uv, l->v->co, rotmat); } } } @@ -1252,15 +1292,13 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) struct UvCameraInfo *uci= project_camera_info(v3d->camera, obedit->obmat, scene->r.xsch, scene->r.ysch); if(uci) { - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - project_from_camera(tf->uv[0], efa->v1->co, uci); - project_from_camera(tf->uv[1], efa->v2->co, uci); - project_from_camera(tf->uv[2], efa->v3->co, uci); - if(efa->v4) - project_from_camera(tf->uv[3], efa->v4->co, uci); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + project_from_camera(luv->uv, l->v->co, uci); } } @@ -1270,15 +1308,13 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) else { copy_m4_m4(rotmat, obedit->obmat); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; - project_from_view(tf->uv[0], efa->v1->co, rv3d->persmat, rotmat, ar->winx, ar->winy); - project_from_view(tf->uv[1], efa->v2->co, rv3d->persmat, rotmat, ar->winx, ar->winy); - project_from_view(tf->uv[2], efa->v3->co, rv3d->persmat, rotmat, ar->winx, ar->winy); - if(efa->v4) - project_from_view(tf->uv[3], efa->v4->co, rv3d->persmat, rotmat, ar->winx, ar->winy); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + project_from_view(luv->uv, l->v->co, rv3d->persmat, rotmat, ar->winx, ar->winy); } } } @@ -1288,7 +1324,6 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1324,38 +1359,20 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; + Mesh *me = (Mesh*)obedit->data; /* add uvs if they don't exist yet */ - if(!ED_uvedit_ensure_uvs(C, scene, obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); + if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { return OPERATOR_CANCELLED; } - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - tf->uv[0][0]= 0.0f; - tf->uv[0][1]= 0.0f; - - tf->uv[1][0]= 1.0f; - tf->uv[1][1]= 0.0f; - - tf->uv[2][0]= 1.0f; - tf->uv[2][1]= 1.0f; - - tf->uv[3][0]= 0.0f; - tf->uv[3][1]= 1.0f; - } + if (!ED_mesh_uv_loop_reset(C, me)) { + return OPERATOR_CANCELLED; } DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - BKE_mesh_end_editmesh(obedit->data, em); + return OPERATOR_FINISHED; } @@ -1387,55 +1404,71 @@ static void uv_sphere_project(float target[2], float source[3], float center[3], target[0] -= 1.0f; } -static void uv_map_mirror(EditFace *efa, MTFace *tf) +static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf)) { + BMLoop *l; + BMIter liter; + MLoopUV *luv; + BLI_array_declare(uvs); + float **uvs = NULL; float dx; - int nverts, i, mi; + int i, mi; + + i = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + BLI_array_growone(uvs); - nverts= (efa->v4)? 4: 3; + uvs[i] = luv->uv; + i++; + } mi = 0; - for(i=1; i<nverts; i++) - if(tf->uv[i][0] > tf->uv[mi][0]) + for(i=1; i<efa->len; i++) + if(uvs[i][0] > uvs[mi][0]) mi = i; - for(i=0; i<nverts; i++) { + for(i=0; i<efa->len; i++) { if(i != mi) { - dx = tf->uv[mi][0] - tf->uv[i][0]; - if(dx > 0.5f) tf->uv[i][0] += 1.0f; + dx = uvs[mi][0] - uvs[i][0]; + if(dx > 0.5f) uvs[i][0] += 1.0f; } } + + BLI_array_free(uvs); } static int sphere_project_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; float center[3], rotmat[4][4]; /* add uvs if they don't exist yet */ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } uv_map_transform(C, op, center, rotmat); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; - uv_sphere_project(tf->uv[0], efa->v1->co, center, rotmat); - uv_sphere_project(tf->uv[1], efa->v2->co, center, rotmat); - uv_sphere_project(tf->uv[2], efa->v3->co, center, rotmat); - if(efa->v4) - uv_sphere_project(tf->uv[3], efa->v4->co, center, rotmat); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - uv_map_mirror(efa, tf); + uv_sphere_project(luv->uv, l->v->co, center, rotmat); } + + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + uv_map_mirror(em, efa, tf); } uv_map_clip_correct(em, op); @@ -1443,7 +1476,6 @@ static int sphere_project_exec(bContext *C, wmOperator *op) DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1483,31 +1515,33 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; float center[3], rotmat[4][4]; /* add uvs if they don't exist yet */ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } uv_map_transform(C, op, center, rotmat); - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - uv_cylinder_project(tf->uv[0], efa->v1->co, center, rotmat); - uv_cylinder_project(tf->uv[1], efa->v2->co, center, rotmat); - uv_cylinder_project(tf->uv[2], efa->v3->co, center, rotmat); - if(efa->v4) - uv_cylinder_project(tf->uv[3], efa->v4->co, center, rotmat); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - uv_map_mirror(efa, tf); + uv_cylinder_project(luv->uv, l->v->co, center, rotmat); } + + uv_map_mirror(em, efa, tf); } uv_map_clip_correct(em, op); @@ -1515,7 +1549,6 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1541,15 +1574,17 @@ static int cube_project_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; - float no[3], cube_size, *loc, dx, dy; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + /* MTexPoly *tf; */ /* UNUSED */ + MLoopUV *luv; + float cube_size, *loc, dx, dy; int cox, coy; /* add uvs if they don't exist yet */ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } @@ -1559,34 +1594,31 @@ static int cube_project_exec(bContext *C, wmOperator *op) /* choose x,y,z axis for projection depending on the largest normal * component, but clusters all together around the center of map. */ - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - normal_tri_v3( no,efa->v1->co, efa->v2->co, efa->v3->co); - - axis_dominant_v3(&cox, &coy, no); - - tf->uv[0][0]= 0.5f+0.5f*cube_size*(loc[cox] + efa->v1->co[cox]); - tf->uv[0][1]= 0.5f+0.5f*cube_size*(loc[coy] + efa->v1->co[coy]); - dx = floor(tf->uv[0][0]); - dy = floor(tf->uv[0][1]); - tf->uv[0][0] -= dx; - tf->uv[0][1] -= dy; - tf->uv[1][0]= 0.5f+0.5f*cube_size*(loc[cox] + efa->v2->co[cox]); - tf->uv[1][1]= 0.5f+0.5f*cube_size*(loc[coy] + efa->v2->co[coy]); - tf->uv[1][0] -= dx; - tf->uv[1][1] -= dy; - tf->uv[2][0]= 0.5f+0.5f*cube_size*(loc[cox] + efa->v3->co[cox]); - tf->uv[2][1]= 0.5f+0.5f*cube_size*(loc[coy] + efa->v3->co[coy]); - tf->uv[2][0] -= dx; - tf->uv[2][1] -= dy; - - if(efa->v4) { - tf->uv[3][0]= 0.5f+0.5f*cube_size*(loc[cox] + efa->v4->co[cox]); - tf->uv[3][1]= 0.5f+0.5f*cube_size*(loc[coy] + efa->v4->co[coy]); - tf->uv[3][0] -= dx; - tf->uv[3][1] -= dy; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + int first=1; + + /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ + if (!BM_TestHFlag(efa, BM_SELECT)) + continue; + + axis_dominant_v3(&cox, &coy, efa->no); + + dx = dy = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + 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; } } @@ -1595,7 +1627,6 @@ static int cube_project_exec(bContext *C, wmOperator *op) DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1611,7 +1642,6 @@ void UV_OT_cube_project(wmOperatorType *ot) ot->poll= ED_operator_uvmap; /* properties */ - RNA_def_float(ot->srna, "cube_size", 1.0f, 0.0f, FLT_MAX, "Cube Size", - "Size of the cube to project on", 0.001f, 100.0f); + RNA_def_float(ot->srna, "cube_size", 1.0f, 0.0f, FLT_MAX, "Cube Size", "Size of the cube to project on", 0.001f, 100.0f); uv_map_clip_correct_properties(ot); } |