diff options
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_ops.c')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 2357 |
1 files changed, 1286 insertions, 1071 deletions
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 5f836ec4ca7..0df2a70302a 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -33,6 +33,7 @@ #include <stdlib.h> #include <string.h> #include <math.h> +#include <string.h> #include "MEM_guardedalloc.h" @@ -40,11 +41,14 @@ #include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "DNA_node_types.h" +#include "DNA_image_types.h" +#include "DNA_space_types.h" #include "DNA_scene_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_editVert.h" +#include "BLI_array.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -58,6 +62,7 @@ #include "BKE_node.h" #include "BKE_report.h" #include "BKE_scene.h" +#include "BKE_tessmesh.h" #include "ED_image.h" #include "ED_mesh.h" @@ -77,19 +82,23 @@ #include "uvedit_intern.h" +#define EFA_F1_FLAG 2 + /************************* state testing ************************/ int ED_uvedit_test(Object *obedit) { - EditMesh *em; + BMEditMesh *em; int ret; - if(!obedit || obedit->type != OB_MESH) + if (!obedit) + return 0; + + if(obedit->type != OB_MESH) return 0; - em = BKE_mesh_get_editmesh(obedit->data); - ret = EM_texFaceCheck(em); - BKE_mesh_end_editmesh(obedit->data, em); + em = ((Mesh*)obedit->data)->edit_btmesh; + ret = EDBM_texFaceCheck(em); return ret; } @@ -157,9 +166,10 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *ima, Image *previma) { - EditMesh *em; - EditFace *efa; - MTFace *tf; + BMEditMesh *em; + BMFace *efa; + BMIter iter; + MTexPoly *tf; int update= 0; /* skip assigning these procedural images... */ @@ -170,16 +180,15 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im if(!obedit || (obedit->type != OB_MESH)) return; - em= BKE_mesh_get_editmesh(((Mesh*)obedit->data)); - if(!em || !em->faces.first) { - BKE_mesh_end_editmesh(obedit->data, em); + em= ((Mesh*)obedit->data)->edit_btmesh; + if(!em || !em->bm->totface) { return; } if(scene_use_new_shading_nodes(scene)) { /* new shading system, assign image in material */ int sloppy= 1; - EditFace *efa= EM_get_actFace(em, sloppy); + BMFace *efa= BM_active_face_get(em->bm, sloppy); if(efa) ED_object_assign_active_image(bmain, obedit, efa->mat_nr, ima); @@ -188,14 +197,15 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im /* old shading system, assign image to selected faces */ /* ensure we have a uv map */ - if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) { - EM_add_data_layer(em, &em->fdata, CD_MTFACE, NULL); + if(!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) { + BM_data_layer_add(em->bm, &em->bm->pdata, CD_MTEXPOLY); + BM_data_layer_add(em->bm, &em->bm->ldata, CD_MLOOPUV); update= 1; } /* now assign to all visible faces */ - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); if(uvedit_face_visible(scene, previma, efa, tf)) { if(ima) { @@ -204,8 +214,9 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im if(ima->id.us==0) id_us_plus(&ima->id); else id_lib_extern(&ima->id); } - else + else { tf->tpage= NULL; + } update = 1; } @@ -216,16 +227,16 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im DAG_id_tag_update(obedit->data, 0); } - BKE_mesh_end_editmesh(obedit->data, em); } /* dotile - 1, set the tile flag (from the space image) * 2, set the tile index for the faces. */ static int uvedit_set_tile(Object *obedit, Image *ima, int curtile) { - EditMesh *em; - EditFace *efa; - MTFace *tf; + BMEditMesh *em; + BMFace *efa; + BMIter iter; + MTexPoly *tf; /* verify if we have something to do */ if(!ima || !ED_uvedit_test(obedit)) @@ -238,17 +249,16 @@ static int uvedit_set_tile(Object *obedit, Image *ima, int curtile) if(ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE) return 0; - em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + em= ((Mesh*)obedit->data)->edit_btmesh; - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if(efa->h==0 && efa->f & SELECT) + if(!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT)) tf->tile= curtile; /* set tile index */ } DAG_id_tag_update(obedit->data, 0); - BKE_mesh_end_editmesh(obedit->data, em); return 1; } @@ -273,18 +283,17 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist /*************** visibility and selection utilities **************/ -int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa) +int uvedit_face_visible_nolocal(Scene *scene, BMFace *efa) { ToolSettings *ts= scene->toolsettings; if(ts->uv_flag & UV_SYNC_SELECTION) - return (efa->h==0); + return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)==0); else - return (efa->h==0 && (efa->f & SELECT)); + return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)==0 && BM_elem_flag_test(efa, BM_ELEM_SELECT)); } -int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf) -{ +int uvedit_face_visible(Scene *scene, Image *ima, BMFace *efa, MTexPoly *tf) { ToolSettings *ts= scene->toolsettings; if(ts->uv_flag & UV_SHOW_SAME_IMAGE) @@ -293,131 +302,199 @@ int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf) return uvedit_face_visible_nolocal(scene, efa); } -int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf) +int uvedit_face_selected(Scene *scene, BMEditMesh *em, BMFace *efa) { ToolSettings *ts= scene->toolsettings; if(ts->uv_flag & UV_SYNC_SELECTION) - return (efa->f & SELECT); - else - return (!(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) &&(!efa->v4 || tf->flag & TF_SEL4)); + return (BM_elem_flag_test(efa, BM_ELEM_SELECT)); + else { + BMLoop *l; + MLoopUV *luv; + BMIter liter; + + 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->flag & MLOOPUV_VERTSEL)) + return 0; + } + + return 1; + } } -void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf) +int uvedit_face_select(Scene *scene, BMEditMesh *em, BMFace *efa) { ToolSettings *ts= scene->toolsettings; if(ts->uv_flag & UV_SYNC_SELECTION) - EM_select_face(efa, 1); - else - tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + BM_elem_select_set(em->bm, efa, TRUE); + else { + BMLoop *l; + MLoopUV *luv; + BMIter liter; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag |= MLOOPUV_VERTSEL; + } + + return 1; + } + + return 0; } -void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf) +int uvedit_face_deselect(Scene *scene, BMEditMesh *em, BMFace *efa) { ToolSettings *ts= scene->toolsettings; - if(ts->uv_flag & UV_SYNC_SELECTION) - EM_select_face(efa, 0); - else - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + if(ts->uv_flag & UV_SYNC_SELECTION) { + BM_elem_select_set(em->bm, efa, FALSE); + } + else { + BMLoop *l; + MLoopUV *luv; + BMIter liter; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag &= ~MLOOPUV_VERTSEL; + } + + return 1; + } + + return 0; } -int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i) +int uvedit_edge_selected(BMEditMesh *em, Scene *scene, BMLoop *l) { ToolSettings *ts= scene->toolsettings; - int nvert= (efa->v4)? 4: 3; if(ts->uv_flag & UV_SYNC_SELECTION) { - if(ts->selectmode & SCE_SELECT_FACE) - return (efa->f & SELECT); - else if(ts->selectmode & SCE_SELECT_EDGE) - return (*(&efa->e1 + i))->f & SELECT; - else - return (((efa->v1 + i)->f & SELECT) && ((efa->v1 + (i+1)%nvert)->f & SELECT)); + if (ts->selectmode & SCE_SELECT_FACE) { + return BM_elem_flag_test(l->f, BM_ELEM_SELECT); + } + else if (ts->selectmode == SCE_SELECT_EDGE) { + return BM_elem_flag_test(l->e, BM_ELEM_SELECT); + } + else { + return BM_elem_flag_test(l->v, BM_ELEM_SELECT) && + BM_elem_flag_test(l->next->v, BM_ELEM_SELECT); + } + } + else { + MLoopUV *luv1, *luv2; + + luv1 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv2 = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV); + + return (luv1->flag & MLOOPUV_VERTSEL) && (luv2->flag & MLOOPUV_VERTSEL); } - else - return (tf->flag & TF_SEL_MASK(i)) && (tf->flag & TF_SEL_MASK((i+1)%nvert)); } -void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i) +void uvedit_edge_select(BMEditMesh *em, Scene *scene, BMLoop *l) + { ToolSettings *ts= scene->toolsettings; - int nvert= (efa->v4)? 4: 3; if(ts->uv_flag & UV_SYNC_SELECTION) { if(ts->selectmode & SCE_SELECT_FACE) - EM_select_face(efa, 1); + BM_elem_select_set(em->bm, l->f, TRUE); else if(ts->selectmode & SCE_SELECT_EDGE) - EM_select_edge((*(&efa->e1 + i)), 1); + BM_elem_select_set(em->bm, l->e, TRUE); else { - (efa->v1 + i)->f |= SELECT; - (efa->v1 + (i+1)%nvert)->f |= SELECT; + BM_elem_select_set(em->bm, l->e->v1, TRUE); + BM_elem_select_set(em->bm, l->e->v2, TRUE); } } - else - tf->flag |= TF_SEL_MASK(i)|TF_SEL_MASK((i+1)%nvert); + else { + MLoopUV *luv1, *luv2; + + luv1 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv2 = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV); + + luv1->flag |= MLOOPUV_VERTSEL; + luv2->flag |= MLOOPUV_VERTSEL; + } } -void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i) +void uvedit_edge_deselect(BMEditMesh *em, Scene *scene, BMLoop *l) + { ToolSettings *ts= scene->toolsettings; - int nvert= (efa->v4)? 4: 3; if(ts->uv_flag & UV_SYNC_SELECTION) { if(ts->selectmode & SCE_SELECT_FACE) - EM_select_face(efa, 0); + BM_elem_select_set(em->bm, l->f, FALSE); else if(ts->selectmode & SCE_SELECT_EDGE) - EM_select_edge((*(&efa->e1 + i)), 0); + BM_elem_select_set(em->bm, l->e, FALSE); else { - (efa->v1 + i)->f &= ~SELECT; - (efa->v1 + (i+1)%nvert)->f &= ~SELECT; + BM_elem_select_set(em->bm, l->e->v1, FALSE); + BM_elem_select_set(em->bm, l->e->v2, FALSE); } } - else - tf->flag &= ~(TF_SEL_MASK(i)|TF_SEL_MASK((i+1)%nvert)); + else { + MLoopUV *luv1, *luv2; + + luv1 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv2 = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV); + + luv1->flag &= ~MLOOPUV_VERTSEL; + luv2->flag &= ~MLOOPUV_VERTSEL; + } } -int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i) +int uvedit_uv_selected(BMEditMesh *em, Scene *scene, BMLoop *l) { ToolSettings *ts= scene->toolsettings; if(ts->uv_flag & UV_SYNC_SELECTION) { if(ts->selectmode & SCE_SELECT_FACE) - return (efa->f & SELECT); + return BM_elem_flag_test(l->f, BM_ELEM_SELECT); else - return (*(&efa->v1 + i))->f & SELECT; + return BM_elem_flag_test(l->v, BM_ELEM_SELECT); + } + else { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + return luv->flag & MLOOPUV_VERTSEL; } - else - return tf->flag & TF_SEL_MASK(i); } -void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i) +void uvedit_uv_select(BMEditMesh *em, Scene *scene, BMLoop *l) { ToolSettings *ts= scene->toolsettings; if(ts->uv_flag & UV_SYNC_SELECTION) { if(ts->selectmode & SCE_SELECT_FACE) - EM_select_face(efa, 1); + BM_elem_select_set(em->bm, l->f, TRUE); else - (*(&efa->v1 + i))->f |= SELECT; + BM_elem_select_set(em->bm, l->v, TRUE); + } + else { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + luv->flag |= MLOOPUV_VERTSEL; } - else - tf->flag |= TF_SEL_MASK(i); } -void uvedit_uv_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i) +void uvedit_uv_deselect(BMEditMesh *em, Scene *scene, BMLoop *l) { ToolSettings *ts= scene->toolsettings; if(ts->uv_flag & UV_SYNC_SELECTION) { if(ts->selectmode & SCE_SELECT_FACE) - EM_select_face(efa, 0); + BM_elem_select_set(em->bm, l->f, FALSE); else - (*(&efa->v1 + i))->f &= ~SELECT; + BM_elem_select_set(em->bm, l->v, FALSE); + } + else { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + luv->flag &= ~MLOOPUV_VERTSEL; } - else - tf->flag &= ~TF_SEL_MASK(i); } /*********************** live unwrap utilities ***********************/ @@ -432,6 +509,22 @@ void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit) } /*********************** geometric utilities ***********************/ +void poly_uv_center(BMEditMesh *em, BMFace *f, float cent[2]) +{ + BMLoop *l; + MLoopUV *luv; + BMIter liter; + + zero_v2(cent); + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + add_v2_v2(cent, luv->uv); + } + + mul_v2_fl(cent, 1.0f / (float)f->len); +} + void uv_center(float uv[][2], float cent[2], int quad) { @@ -453,6 +546,28 @@ float uv_area(float uv[][2], int quad) return area_tri_v2(uv[0], uv[1], uv[2]); } +float poly_uv_area(float uv[][2], int len) +{ + //BMESH_TODO: make this not suck + //maybe use scanfill? I dunno. + + if(len >= 4) + return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]); + else + return area_tri_v2(uv[0], uv[1], uv[2]); + + return 1.0; +} + +void poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len) +{ + int i; + for (i=0; i<len; i++) { + uv[i][0] = uv_orig[i][0]*aspx; + uv[i][1] = uv_orig[i][1]*aspy; + } +} + void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy) { uv[0][0] = uv_orig[0][0]*aspx; @@ -470,56 +585,66 @@ void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy) int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float *min, float *max) { - 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; int sel; INIT_MINMAX2(min, max); sel= 0; - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) { DO_MINMAX2(tf->uv[0], min, max); sel = 1; } - if(uvedit_uv_selected(scene, efa, tf, 1)) { DO_MINMAX2(tf->uv[1], min, max); sel = 1; } - if(uvedit_uv_selected(scene, efa, tf, 2)) { DO_MINMAX2(tf->uv[2], min, max); sel = 1; } - if(efa->v4 && (uvedit_uv_selected(scene, efa, tf, 3))) { DO_MINMAX2(tf->uv[3], min, max); sel = 1; } + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + DO_MINMAX2(luv->uv, min, max); + sel = 1; + } } } - - BKE_mesh_end_editmesh(obedit->data, em); + return sel; } static int ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[3]) { - 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; unsigned int sel= 0; zero_v3(co); - - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) { add_v3_v3(co, tf->uv[0]); sel++; } - if(uvedit_uv_selected(scene, efa, tf, 1)) { add_v3_v3(co, tf->uv[1]); sel++; } - if(uvedit_uv_selected(scene, efa, tf, 2)) { add_v3_v3(co, tf->uv[2]); sel++; } - if(efa->v4 && (uvedit_uv_selected(scene, efa, tf, 3))) { add_v3_v3(co, tf->uv[3]); sel++; } + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + if (uvedit_uv_selected(em, scene, l)) { + add_v2_v2(co, luv->uv); + sel++; + } } } mul_v3_fl(co, 1.0f/(float)sel); - BKE_mesh_end_editmesh(obedit->data, em); return (sel != 0); } static int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, char mode) { - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); float min[2], max[2]; int change= 0; @@ -539,99 +664,133 @@ static int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, } if(change) { - BKE_mesh_end_editmesh(obedit->data, em); return 1; } - BKE_mesh_end_editmesh(obedit->data, em); return 0; } /************************** find nearest ****************************/ -void uv_find_nearest_edge(Scene *scene, Image *ima, EditMesh *em, float co[2], NearestHit *hit) +void uv_find_nearest_edge(Scene *scene, Image *ima, BMEditMesh *em, float co[2], NearestHit *hit) { - MTFace *tf; - EditFace *efa; - EditVert *eve; + MTexPoly *tf; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv, *nextluv; float mindist, dist; - int i, nverts; + int i; mindist= 1e10f; memset(hit, 0, sizeof(*hit)); - for(i=0, eve=em->verts.first; eve; eve=eve->next, i++) - eve->tmp.l = i; + BM_mesh_elem_index_ensure(em->bm, BM_VERT); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tf)) { - nverts= efa->v4? 4: 3; - - for(i=0; i<nverts; i++) { - dist= dist_to_line_segment_v2(co, tf->uv[i], tf->uv[(i+1)%nverts]); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + 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); + nextluv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV); - if(dist < mindist) { - hit->tf= tf; - hit->efa= efa; - hit->edge= i; - mindist= dist; + dist= dist_to_line_segment_v2(co, luv->uv, nextluv->uv); - hit->vert= (*(&efa->v1 + i))->tmp.l; - hit->vert2= (*(&efa->v1 + ((i+1)%nverts)))->tmp.l; - } + if(dist < mindist) { + hit->tf= tf; + hit->efa= efa; + + hit->l = l; + hit->nextl = l->next; + hit->luv = luv; + hit->nextluv = nextluv; + hit->lindex = i; + hit->vert1 = BM_elem_index_get(hit->l->v); + hit->vert2 = BM_elem_index_get(hit->l->next->v); + + mindist = dist; } + + i++; } } } -static void find_nearest_uv_face(Scene *scene, Image *ima, EditMesh *em, float co[2], NearestHit *hit) +static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, float co[2], NearestHit *hit) { - MTFace *tf; - EditFace *efa; + MTexPoly *tf; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; float mindist, dist, cent[2]; - int i, nverts; mindist= 1e10f; memset(hit, 0, sizeof(*hit)); - - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tf)) { - nverts= efa->v4? 4: 3; - cent[0]= cent[1]= 0.0f; + /*this will fill in hit.vert1 and hit.vert2*/ + uv_find_nearest_edge(scene, ima, em, co, hit); + hit->l = hit->nextl = NULL; + hit->luv = hit->nextluv = NULL; - for(i=0; i<nverts; i++) { - add_v2_v2(cent, tf->uv[i]); - } + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + cent[0]= cent[1]= 0.0f; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - cent[0] /= nverts; - cent[1] /= nverts; - dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]); + add_v2_v2(cent, luv->uv); + } - if(dist < mindist) { - hit->tf= tf; - hit->efa= efa; - mindist= dist; - } + cent[0] /= efa->len; + cent[1] /= efa->len; + dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]); + + if(dist < mindist) { + hit->tf= tf; + hit->efa= efa; + mindist= dist; } } } -static int nearest_uv_between(MTFace *tf, int nverts, int id, float co[2], float uv[2]) +static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), int id, + float co[2], float uv[2]) { - float m[3], v1[3], v2[3], c1, c2; - int id1, id2; + BMLoop *l; + MLoopUV *luv; + BMIter iter; + float m[3], v1[3], v2[3], c1, c2, *uv1, *uv2, *uv3; + int id1, id2, i; - id1= (id+nverts-1)%nverts; - id2= (id+nverts+1)%nverts; + id1= (id+efa->len-1)%efa->len; + id2= (id+efa->len+1)%efa->len; m[0]= co[0]-uv[0]; m[1]= co[1]-uv[1]; - sub_v2_v2v2(v1, tf->uv[id1], tf->uv[id]); - sub_v2_v2v2(v2, tf->uv[id2], tf->uv[id]); + + i = 0; + BM_ITER(l, &iter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + if (i == id1) + uv1 = luv->uv; + else if (i == id) + uv2 = luv->uv; + else if (i == id2) + uv3 = luv->uv; + + i++; + } + + sub_v3_v3v3(v1, uv1, uv); + sub_v3_v3v3(v2, uv3, uv); /* m and v2 on same side of v-v1? */ c1= v1[0]*m[1] - v1[1]*m[0]; @@ -647,86 +806,99 @@ static int nearest_uv_between(MTFace *tf, int nverts, int id, float co[2], float return (c1*c2 >= 0.0f); } -void uv_find_nearest_vert(Scene *scene, Image *ima, EditMesh *em, float co[2], float penalty[2], NearestHit *hit) +void uv_find_nearest_vert(Scene *scene, Image *ima, BMEditMesh *em, + float co[2], float penalty[2], NearestHit *hit) { - EditFace *efa; - EditVert *eve; - MTFace *tf; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; float mindist, dist; - int i, nverts; + int i; + + /*this will fill in hit.vert1 and hit.vert2*/ + uv_find_nearest_edge(scene, ima, em, co, hit); + hit->l = hit->nextl = NULL; + hit->luv = hit->nextluv = NULL; mindist= 1e10f; memset(hit, 0, sizeof(*hit)); - for(i=0, eve=em->verts.first; eve; eve=eve->next, i++) - eve->tmp.l = i; - - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_mesh_elem_index_ensure(em->bm, BM_VERT); - if(uvedit_face_visible(scene, ima, efa, tf)) { - nverts= efa->v4? 4: 3; - - for(i=0; i<nverts; i++) { - if(penalty && uvedit_uv_selected(scene, efa, tf, i)) - dist= fabsf(co[0]-tf->uv[i][0])+penalty[0] + fabsf(co[1]-tf->uv[i][1]) + penalty[1]; - else - dist= fabsf(co[0]-tf->uv[i][0]) + fabsf(co[1]-tf->uv[i][1]); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + 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); - if(dist<=mindist) { - if(dist==mindist) - if(!nearest_uv_between(tf, nverts, i, co, tf->uv[i])) - continue; + if(penalty && uvedit_uv_selected(em, scene, l)) + dist= fabs(co[0]-luv->uv[0])+penalty[0] + fabs(co[1]-luv->uv[1])+penalty[1]; + else + dist= fabs(co[0]-luv->uv[0]) + fabs(co[1]-luv->uv[1]); - mindist= dist; + if(dist<=mindist) { + if(dist==mindist) + if(!nearest_uv_between(em, efa, efa->len, i, co, luv->uv)) { + i++; + continue; + } - hit->uv= i; - hit->tf= tf; - hit->efa= efa; + mindist= dist; - hit->vert= (*(&efa->v1 + i))->tmp.l; - } + hit->l = l; + hit->nextl = l->next; + hit->luv = luv; + hit->nextluv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV); + hit->tf= tf; + hit->efa= efa; + hit->lindex = i; + hit->vert1 = BM_elem_index_get(hit->l->v); } + + i++; } } } int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, float co[2], float uv[2]) { - 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 mindist, dist; - int i, nverts, found= 0; + int found= 0; mindist= 1e10f; uv[0]= co[0]; uv[1]= co[1]; - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tf)) { - nverts= efa->v4? 4: 3; - - for(i=0; i<nverts; i++) { - if(uvedit_uv_selected(scene, efa, tf, i)) - continue; - - dist= fabs(co[0]-tf->uv[i][0]) + fabs(co[1]-tf->uv[i][1]); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + dist= fabs(co[0]-luv->uv[0]) + fabs(co[1]-luv->uv[1]); - if(dist<=mindist) { - mindist= dist; + if(dist<=mindist) { + mindist= dist; - uv[0]= tf->uv[i][0]; - uv[1]= tf->uv[i][1]; - found= 1; - } + uv[0]= luv->uv[0]; + uv[1]= luv->uv[1]; + found= 1; } } } - BKE_mesh_end_editmesh(obedit->data, em); return found; } @@ -748,25 +920,34 @@ static void uv_vertex_loop_flag(UvMapVert *first) first->flag= 1; } -static UvMapVert *uv_vertex_map_get(UvVertMap *vmap, EditFace *efa, int a) +static UvMapVert *uv_vertex_map_get(UvVertMap *vmap, BMFace *efa, int a) { UvMapVert *iterv, *first; - - first= EM_get_uv_map_vert(vmap, (*(&efa->v1 + a))->tmp.l); + BMLoop *l; + + l = BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, a); + first= EDBM_get_uv_map_vert(vmap, BM_elem_index_get(l->v)); for(iterv=first; iterv; iterv=iterv->next) { if(iterv->separate) first= iterv; - if(iterv->f == efa->tmp.l) + if(iterv->f == BM_elem_index_get(efa)) return first; } return NULL; } -UvElement *ED_get_uv_element(UvElementMap *map, EditFace *efa, int index) +/* BMESH_TODO - in some cases we already know the loop so looking up the index isnt needed */ + +UvElement *ED_get_uv_element(UvElementMap *map, BMFace *efa, int index) { - UvElement *element = map->vert[(*(&efa->v1 + index))->tmp.l]; + BMLoop *l; + UvElement *element; + + l = BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, index); + + element = map->vert[BM_elem_index_get(l->v)]; for(; element; element = element->next) if(element->face == efa) @@ -775,10 +956,10 @@ UvElement *ED_get_uv_element(UvElementMap *map, EditFace *efa, int index) return NULL; } -static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface) +static int uv_edge_tag_faces(BMEditMesh *em, UvMapVert *first1, UvMapVert *first2, int *totface) { UvMapVert *iterv1, *iterv2; - EditFace *efa; + BMFace *efa; int tot = 0; /* count number of faces this edge has */ @@ -792,8 +973,8 @@ static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface) if(iterv1->f == iterv2->f) { /* if face already tagged, don't do this edge */ - efa= EM_get_face_for_index(iterv1->f); - if(efa->f1) + efa= EDBM_get_face_for_index(em, iterv1->f); + if(BMO_elem_flag_test(em->bm, efa, EFA_F1_FLAG)) return 0; tot++; @@ -817,8 +998,8 @@ static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface) break; if(iterv1->f == iterv2->f) { - efa= EM_get_face_for_index(iterv1->f); - efa->f1= 1; + efa= EDBM_get_face_for_index(em, iterv1->f); + BMO_elem_flag_enable(em->bm, efa, EFA_F1_FLAG); break; } } @@ -827,41 +1008,45 @@ static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface) return 1; } -static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *hit, float limit[2], int extend) +static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit *hit, float limit[2], int extend) { - EditVert *eve; - EditFace *efa; - MTFace *tf; + BMFace *efa; + BMIter iter, liter; + BMLoop *l; + MTexPoly *tf; UvVertMap *vmap; UvMapVert *iterv1, *iterv2; int a, count, looking, nverts, starttotf, select; /* setup */ - EM_init_index_arrays(em, 0, 0, 1); - vmap= EM_make_uv_vert_map(em, 0, 0, limit); + EDBM_init_index_arrays(em, 0, 0, 1); + vmap= EDBM_make_uv_vert_map(em, 0, 0, limit); - for(count=0, eve=em->verts.first; eve; count++, eve= eve->next) - eve->tmp.l = count; + BM_mesh_elem_index_ensure(em->bm, BM_VERT); - for(count=0, efa= em->faces.first; efa; count++, efa= efa->next) { + count = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { if(!extend) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uvedit_face_deselect(scene, efa, tf); + uvedit_face_deselect(scene, em, efa); } + + BMO_elem_flag_disable(em->bm, efa, EFA_F1_FLAG); - efa->tmp.l= count; - efa->f1= 0; + BM_elem_index_set(efa, count); /* set_inline */ + + count++; } - + em->bm->elem_index_dirty &= ~BM_FACE; + /* set flags for first face and verts */ - nverts= (hit->efa->v4)? 4: 3; - iterv1= uv_vertex_map_get(vmap, hit->efa, hit->edge); - iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->edge+1)%nverts); + nverts= hit->efa->len; + iterv1= uv_vertex_map_get(vmap, hit->efa, hit->lindex); + iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->lindex+1)%nverts); uv_vertex_loop_flag(iterv1); uv_vertex_loop_flag(iterv2); starttotf= 0; - uv_edge_tag_faces(iterv1, iterv2, &starttotf); + uv_edge_tag_faces(em, iterv1, iterv2, &starttotf); /* sorry, first edge isnt even ok */ if(iterv1->flag==0 && iterv2->flag==0) looking= 0; @@ -872,21 +1057,25 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h looking= 0; /* find correct valence edges which are not tagged yet, but connect to tagged one */ - for(efa= em->faces.first; efa; efa=efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(!efa->f1 && uvedit_face_visible(scene, ima, efa, tf)) { - nverts= (efa->v4)? 4: 3; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + if(!BMO_elem_flag_test(em->bm, efa, EFA_F1_FLAG) && uvedit_face_visible(scene, ima, efa, tf)) { + nverts= efa->len; for(a=0; a<nverts; a++) { /* check face not hidden and not tagged */ iterv1= uv_vertex_map_get(vmap, efa, a); iterv2= uv_vertex_map_get(vmap, efa, (a+1)%nverts); + + if (!iterv1 || !iterv2) + continue; /* check if vertex is tagged and has right valence */ if(iterv1->flag || iterv2->flag) { - if(uv_edge_tag_faces(iterv1, iterv2, &starttotf)) { + if(uv_edge_tag_faces(em, iterv1, iterv2, &starttotf)) { looking= 1; - efa->f1= 1; + BMO_elem_flag_enable(em->bm, efa, EFA_F1_FLAG); uv_vertex_loop_flag(iterv1); uv_vertex_loop_flag(iterv2); @@ -899,16 +1088,14 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h } /* do the actual select/deselect */ - nverts= (hit->efa->v4)? 4: 3; - iterv1= uv_vertex_map_get(vmap, hit->efa, hit->edge); - iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->edge+1)%nverts); + nverts= hit->efa->len; + iterv1= uv_vertex_map_get(vmap, hit->efa, hit->lindex); + iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->lindex+1)%nverts); iterv1->flag= 1; iterv2->flag= 1; if(extend) { - tf= CustomData_em_get(&em->fdata, hit->efa->data, CD_MTFACE); - - if(uvedit_uv_selected(scene, hit->efa, tf, hit->edge)) + if(uvedit_uv_selected(em, scene, hit->l)) select= 0; else select= 1; @@ -916,83 +1103,109 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h else select= 1; - for(efa= em->faces.first; efa; efa=efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - nverts= (efa->v4)? 4: 3; - for(a=0; a<nverts; a++) { + a = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { iterv1= uv_vertex_map_get(vmap, efa, a); if(iterv1->flag) { - if(select) uvedit_uv_select(scene, efa, tf, a); - else uvedit_uv_deselect(scene, efa, tf, a); + if(select) uvedit_uv_select(em, scene, l); + else uvedit_uv_deselect(em, scene, l); } + + a++; } } /* cleanup */ - EM_free_uv_vert_map(vmap); - EM_free_index_arrays(); + EDBM_free_uv_vert_map(vmap); + EDBM_free_index_arrays(em); return (select)? 1: -1; } /*********************** linked select ***********************/ -static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2], NearestHit *hit, int extend) +static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, float limit[2], NearestHit *hit, int extend) { - EditFace *efa; - MTFace *tf; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; UvVertMap *vmap; UvMapVert *vlist, *iterv, *startv; int i, nverts, stacksize= 0, *stack; unsigned int a; char *flag; - EM_init_index_arrays(em, 0, 0, 1); /* we can use this too */ - vmap= EM_make_uv_vert_map(em, 1, 0, limit); + EDBM_init_index_arrays(em, 0, 0, 1); /* we can use this too */ + vmap= EDBM_make_uv_vert_map(em, 1, 1, limit); + if(vmap == NULL) return; - stack= MEM_mallocN(sizeof(*stack) * em->totface, "UvLinkStack"); - flag= MEM_callocN(sizeof(*flag) * em->totface, "UvLinkFlag"); + stack= MEM_mallocN(sizeof(*stack)*(em->bm->totface+1), "UvLinkStack"); + flag= MEM_callocN(sizeof(*flag)*em->bm->totface, "UvLinkFlag"); if(!hit) { - for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + a = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if(uvedit_face_visible(scene, ima, efa, tf)) { - const char select_flag= efa->v4 ? (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) : (TF_SEL1|TF_SEL2|TF_SEL3); - if(tf->flag & select_flag) { - stack[stacksize]= a; - stacksize++; - flag[a]= 1; + if(uvedit_face_visible(scene, ima, efa, tf)) { + 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->flag & MLOOPUV_VERTSEL) { + stack[stacksize]= a; + stacksize++; + flag[a]= 1; + + break; + } } } } + a++; } else { - for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) { + a = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { if(efa == hit->efa) { stack[stacksize]= a; stacksize++; flag[a]= 1; break; } + + a++; } } while(stacksize > 0) { + int j; + stacksize--; a= stack[stacksize]; + + j = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if(j==a) + break; + + j++; + } - efa = EM_get_face_for_index(a); + nverts= efa->len; - nverts= efa->v4? 4: 3; + i = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { - for(i=0; i<nverts; i++) { /* make_uv_vert_map_EM sets verts tmp.l to the indices */ - vlist= EM_get_uv_map_vert(vmap, (*(&efa->v1 + i))->tmp.l); + vlist= EDBM_get_uv_map_vert(vmap, BM_elem_index_get(l->v)); startv= vlist; @@ -1012,50 +1225,108 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2] stacksize++; } } + + i++; } } - if(!extend) { - for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(flag[a]) - tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - else - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + if(!extend) { + a = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + if (flag[a]) + luv->flag |= MLOOPUV_VERTSEL; + else + luv->flag &= ~MLOOPUV_VERTSEL; + } + a++; } } else { - for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) { - if(flag[a]) { - const char select_flag= efa->v4 ? (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) : (TF_SEL1|TF_SEL2|TF_SEL3); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if((tf->flag & select_flag)) + a = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!flag[a]) { + a++; + continue; + } + + 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->flag & MLOOPUV_VERTSEL) break; } + + if (l) + break; + + a++; } if(efa) { - for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) { - if(flag[a]) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + a = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!flag[a]) { + a++; + 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->flag &= ~MLOOPUV_VERTSEL; + } + + a++; } } else { - for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) { - if(flag[a]) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + a = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!flag[a]) { + a++; + 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->flag |= MLOOPUV_VERTSEL; } + + a++; } } } MEM_freeN(stack); MEM_freeN(flag); - EM_free_uv_vert_map(vmap); - EM_free_index_arrays(); + EDBM_free_uv_vert_map(vmap); + EDBM_free_index_arrays(em); +} + +/* WATCH IT: this returns first selected UV, + * not ideal in many cases since there could be multiple */ +static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVert *eve) +{ + BMIter liter; + BMLoop *l; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_VERT, eve) { + MTexPoly *tf = CustomData_bmesh_get(&em->bm->pdata, l->f->head.data, CD_MTEXPOLY); + + if (!uvedit_face_visible(scene, ima, l->f, tf)) + continue; + + if (uvedit_uv_selected(em, scene, l)) { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + return luv->uv; + } + } + + return NULL; } /* ******************** align operator **************** */ @@ -1066,32 +1337,35 @@ static void weld_align_uv(bContext *C, int tool) Scene *scene; Object *obedit; Image *ima; - EditMesh *em; - EditFace *efa; - MTFace *tf; + BMEditMesh *em; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; float cent[2], min[2], max[2]; scene= CTX_data_scene(C); obedit= CTX_data_edit_object(C); - em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + em= ((Mesh*)obedit->data)->edit_btmesh; ima= CTX_data_edit_image(C); sima= CTX_wm_space_image(C); INIT_MINMAX2(min, max); if(tool == 'a') { - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BMFace *efa; + BMLoop *l; - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) - DO_MINMAX2(tf->uv[0], min, max) - if(uvedit_uv_selected(scene, efa, tf, 1)) - DO_MINMAX2(tf->uv[1], min, max) - if(uvedit_uv_selected(scene, efa, tf, 2)) - DO_MINMAX2(tf->uv[2], min, max) - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) - DO_MINMAX2(tf->uv[3], min, max) + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + DO_MINMAX2(luv->uv, min, max) + } } } @@ -1101,170 +1375,173 @@ static void weld_align_uv(bContext *C, int tool) uvedit_center(scene, ima, obedit, cent, 0); if(tool == 'x' || tool == 'w') { - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) - tf->uv[0][0]= cent[0]; - if(uvedit_uv_selected(scene, efa, tf, 1)) - tf->uv[1][0]= cent[0]; - if(uvedit_uv_selected(scene, efa, tf, 2)) - tf->uv[2][0]= cent[0]; - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) - tf->uv[3][0]= cent[0]; + BMFace *efa; + BMLoop *l; + + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->uv[0] = cent[0]; + } + } } } if(tool == 'y' || tool == 'w') { - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) - tf->uv[0][1]= cent[1]; - if(uvedit_uv_selected(scene, efa, tf, 1)) - tf->uv[1][1]= cent[1]; - if(uvedit_uv_selected(scene, efa, tf, 2)) - tf->uv[2][1]= cent[1]; - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) - tf->uv[3][1]= cent[1]; + BMFace *efa; + BMLoop *l; + + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->uv[1] = cent[1]; + } + } } } if(tool == 's' || tool == 't' || tool == 'u') { - /* pass 1&2 variables */ - int i, j; - int starttmpl= -1, connectedtostarttmpl= -1, startcorner; - int endtmpl= -1, connectedtoendtmpl= -1, endcorner; - MTFace *startface, *endface; - int itmpl, jtmpl; - EditVert *eve; - int pass; /* first 2 passes find endpoints, 3rd pass moves middle points, 4th pass is fail-on-face-selected */ - EditFace *startefa, *endefa= NULL; /* endefa shouldnt need to be initialized but just incase */ - - /* pass 3 variables */ - float startx, starty, firstm, firstb, midx, midy; - float endx, endy, secondm, secondb, midmovedx, midmovedy; - float IsVertical_check= -1; - float IsHorizontal_check= -1; - - for(i= 0, eve= em->verts.first; eve; eve= eve->next, i++) /* give each point a unique name */ - eve->tmp.l= i; - for(pass= 1; pass <= 3; pass++) { /* do this for each endpoint */ - if(pass == 3){ /* calculate */ - startx= startface->uv[startcorner][0]; - starty= startface->uv[startcorner][1]; - endx= endface->uv[endcorner][0]; - endy= endface->uv[endcorner][1]; - firstm= (endy-starty)/(endx-startx); - firstb= starty-(firstm*startx); - secondm= -1.0f/firstm; - if(startx == endx) IsVertical_check= startx; - if(starty == endy) IsHorizontal_check= starty; - } - for(efa= em->faces.first; efa; efa= efa->next) { /* for each face */ - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); /* get face */ - if(uvedit_face_visible(scene, ima, efa, tf)) { /* if you can see it */ - if(uvedit_face_selected(scene, efa, tf)) { /* if the face is selected, get out now! */ - pass= 4; - break; - } - for(i= 0; (i < 3 || (i == 3 && efa->v4)); i++) { /* for each point of the face */ - itmpl= (*(&efa->v1 + i))->tmp.l; /* get unique name for points */ - if(pass == 3) { /* move */ - if(uvedit_uv_selected(scene, efa, tf, i)) { - if(!(itmpl == starttmpl || itmpl == endtmpl)) { - if(IsVertical_check != -1) tf->uv[i][0]= IsVertical_check; - if(IsHorizontal_check != -1) tf->uv[i][1]= IsHorizontal_check; - if((IsVertical_check == -1) && (IsHorizontal_check == -1)) { - midx= tf->uv[i][0]; - midy= tf->uv[i][1]; - if(tool == 's') { - secondb= midy-(secondm*midx); - midmovedx= (secondb-firstb)/(firstm-secondm); - midmovedy= (secondm*midmovedx)+secondb; - tf->uv[i][0]= midmovedx; - tf->uv[i][1]= midmovedy; - } - else if(tool == 't') { - tf->uv[i][0]= (midy-firstb)/firstm; /* midmovedx */ - } - else if(tool == 'u') { - tf->uv[i][1]= (firstm*midx)+firstb; /* midmovedy */ - } - } - } - } + BMEdge *eed; + BMLoop *l; + BMVert *eve; + BMVert *eve_start; + BMIter iter, liter, eiter; + + /* clear tag */ + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BM_elem_flag_disable(eve, BM_ELEM_TAG); + } + + /* tag verts with a selected UV */ + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_VERT, eve) { + tf = CustomData_bmesh_get(&em->bm->pdata, l->f->head.data, CD_MTEXPOLY); + + if (!uvedit_face_visible(scene, ima, l->f, tf)) + continue; + + if (uvedit_uv_selected(em, scene, l)) { + BM_elem_flag_enable(eve, BM_ELEM_TAG); + break; + } + } + } + + /* flush vertex tags to edges */ + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if (BM_elem_flag_test(eed->v1, BM_ELEM_TAG) && BM_elem_flag_test(eed->v2, BM_ELEM_TAG)) { + BM_elem_flag_enable(eed, BM_ELEM_TAG); + } + else { + BM_elem_flag_disable(eed, BM_ELEM_TAG); + } + } + + /* find a vertex with only one tagged edge */ + eve_start = NULL; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + int tot_eed_tag = 0; + BM_ITER(eed, &eiter, em->bm, BM_EDGES_OF_VERT, eve) { + if (BM_elem_flag_test(eed, BM_ELEM_TAG)) { + tot_eed_tag++; + } + } + + if (tot_eed_tag == 1) { + eve_start = eve; + break; + } + } + + if (eve_start) { + BMVert **eve_line = NULL; + BMVert *eve_next = NULL; + BLI_array_declare(eve_line); + int i; + + eve = eve_start; + + /* walk over edges, building an array of verts in a line */ + while (eve) { + BLI_array_append(eve_line, eve); + /* dont touch again */ + BM_elem_flag_disable(eve, BM_ELEM_TAG); + + eve_next = NULL; + + /* find next eve */ + BM_ITER(eed, &eiter, em->bm, BM_EDGES_OF_VERT, eve) { + if (BM_elem_flag_test(eed, BM_ELEM_TAG)) { + BMVert *eve_other = BM_edge_other_vert(eed, eve); + if (BM_elem_flag_test(eve_other, BM_ELEM_TAG)) { + /* this is a tagged vert we didnt walk over yet, step onto it */ + eve_next = eve_other; + break; } - else { - for(j= 0; (j < 3 || (j == 3 && efa->v4)); j++) { /* also for each point on the face */ - jtmpl= (*(&efa->v1 + j))->tmp.l; - if(i != j && (!efa->v4 || ABS(i-j) != 2)) { /* if the points are connected */ - /* quad (0,1,2,3) 0,1 0,3 1,0 1,2 2,1 2,3 3,0 3,2 - * triangle (0,1,2) 0,1 0,2 1,0 1,2 2,0 2,1 */ - if(uvedit_uv_selected(scene, efa, tf, i) && uvedit_uv_selected(scene, efa, tf, j)) { - /* if the edge is selected */ - if(pass == 1) { /* if finding first endpoint */ - if(starttmpl == -1) { /* if the first endpoint isn't found yet */ - starttmpl= itmpl; /* set unique name for endpoint */ - connectedtostarttmpl= jtmpl; - /* get point that endpoint is connected to */ - startface= tf; /* get face it's on */ - startcorner= i; /* what corner of the face? */ - startefa= efa; - efa= em->faces.first; - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - i= -1; - break; - } - if(starttmpl == itmpl && jtmpl != connectedtostarttmpl) { - starttmpl= -1; /* not an endpoint */ - efa= startefa; - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - i= startcorner; - break; - } - } - else if(pass == 2) { /* if finding second endpoint */ - if(endtmpl == -1 && itmpl != starttmpl) { - endtmpl= itmpl; - connectedtoendtmpl= jtmpl; - endface= tf; - endcorner= i; - endefa= efa; - efa= em->faces.first; - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - i= -1; - break; - } - if(endtmpl == itmpl && jtmpl != connectedtoendtmpl) { - endtmpl= -1; - efa= endefa; - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - i= endcorner; - break; - } - } - } - } - } + } + } + + eve = eve_next; + } + + /* now we have all verts, make into a line */ + if (BLI_array_count(eve_line) > 2) { + + /* we know the returns from these must be valid */ + float *uv_start = uv_sel_co_from_eve(scene, ima, em, eve_line[0]); + float *uv_end = uv_sel_co_from_eve(scene, ima, em, eve_line[BLI_array_count(eve_line) - 1]); + + if (tool == 't') { + uv_start[0] = uv_end[0] = (uv_start[0] + uv_end[0]) * 0.5f; + } + else if (tool == 'u') { + uv_start[1] = uv_end[1] = (uv_start[1] + uv_end[1]) * 0.5f; + } + + /* go over all verts except for endpoints */ + for (i = 0; i < BLI_array_count(eve_line); i++) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_VERT, eve_line[i]) { + tf = CustomData_bmesh_get(&em->bm->pdata, l->f->head.data, CD_MTEXPOLY); + + if (!uvedit_face_visible(scene, ima, l->f, tf)) + continue; + + if (uvedit_uv_selected(em, scene, l)) { + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + closest_to_line_segment_v2(luv->uv, luv->uv, uv_start, uv_end); } } } } - if(pass == 2 && (starttmpl == -1 || endtmpl == -1)) { - /* if endpoints aren't found */ - pass=4; + else { + /* error - not a line, needs 3+ points */ } + + if (eve_line) { + MEM_freeN(eve_line); + } + } + else { + /* error - cant find an endpoint */ } } + uvedit_live_unwrap_update(sima, scene, obedit); 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); } static int align_exec(bContext *C, wmOperator *op) @@ -1321,6 +1598,7 @@ static void UV_OT_weld(wmOperatorType *ot) ot->poll= ED_operator_uvedit; } + /* ******************** (de)select all operator **************** */ static void select_all_perform(bContext *C, int action) @@ -1328,43 +1606,50 @@ static void select_all_perform(bContext *C, int action) Scene *scene; ToolSettings *ts; Object *obedit; - EditMesh *em; - EditFace *efa; + BMEditMesh *em; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; Image *ima; - MTFace *tf; + MTexPoly *tf; + MLoopUV *luv; scene= CTX_data_scene(C); ts= CTX_data_tool_settings(C); obedit= CTX_data_edit_object(C); - em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + em= ((Mesh*)obedit->data)->edit_btmesh; ima= CTX_data_edit_image(C); if(ts->uv_flag & UV_SYNC_SELECTION) { + switch (action) { case SEL_TOGGLE: - EM_toggle_select_all(em); + EDBM_toggle_select_all(((Mesh*)obedit->data)->edit_btmesh); break; case SEL_SELECT: - EM_select_all(em); + EDBM_flag_enable_all(em, BM_ELEM_SELECT); break; case SEL_DESELECT: - EM_deselect_all(em); + EDBM_flag_disable_all(em, BM_ELEM_SELECT); break; case SEL_INVERT: - EM_select_swap(em); + EDBM_select_swap(em); break; } } else { - if (action == SEL_TOGGLE) { action = SEL_SELECT; - for(efa= em->faces.first; efa; efa= efa->next) { - const char select_flag= efa->v4 ? (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) : (TF_SEL1|TF_SEL2|TF_SEL3); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(tf->flag & select_flag) { + if (luv->flag & MLOOPUV_VERTSEL) { action = SEL_DESELECT; break; } @@ -1372,21 +1657,25 @@ static void select_all_perform(bContext *C, int action) } } - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if(uvedit_face_visible(scene, ima, efa, tf)) { - const char select_flag= efa->v4 ? (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) : (TF_SEL1|TF_SEL2|TF_SEL3); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); switch (action) { case SEL_SELECT: - tf->flag |= select_flag; + luv->flag |= MLOOPUV_VERTSEL; break; case SEL_DESELECT: - tf->flag &= ~select_flag; + luv->flag &= ~MLOOPUV_VERTSEL; break; case SEL_INVERT: - tf->flag ^= select_flag; + luv->flag ^= MLOOPUV_VERTSEL; break; } } @@ -1397,14 +1686,12 @@ static void select_all_perform(bContext *C, int action) static int select_all_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); int action= RNA_enum_get(op->ptr, "action"); select_all_perform(C, action); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1425,7 +1712,7 @@ static void UV_OT_select_all(wmOperatorType *ot) /* ******************** mouse select operator **************** */ -static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], float *uv, int sticky) +static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], float *uv, int sticky, int hitlen) { int i; @@ -1434,7 +1721,7 @@ static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], floa if(sticky == SI_STICKY_DISABLE) return 0; - for(i=0; i<4; i++) { + for(i=0; i<hitlen; i++) { if(hitv[i] == v) { if(sticky == SI_STICKY_LOC) { if(fabsf(hituv[i][0]-uv[0]) < limit[0] && fabsf(hituv[i][1]-uv[1]) < limit[1]) @@ -1455,13 +1742,19 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(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; NearestHit hit; - int a, i, select = 1, selectmode, sticky, sync, hitv[4], nvert; - int flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ - float limit[2], *hituv[4], penalty[2]; + int i, select = 1, selectmode, sticky, sync, *hitv=NULL, nvert; + BLI_array_declare(hitv); + int flush = 0, hitlen=0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ + float limit[2], **hituv = NULL; + BLI_array_declare(hituv); + float penalty[2]; /* notice 'limit' is the same no matter the zoom level, since this is like * remove doubles and could annoying if it joined points when zoomed out. @@ -1496,76 +1789,100 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) /* find edge */ uv_find_nearest_edge(scene, ima, em, co, &hit); if(hit.efa == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); + BLI_array_free(hitv); + BLI_array_free(hituv); return OPERATOR_CANCELLED; } + + hitlen = 0; } else if(selectmode == UV_SELECT_VERTEX) { /* find vertex */ uv_find_nearest_vert(scene, ima, em, co, penalty, &hit); if(hit.efa == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); + BLI_array_free(hitv); + BLI_array_free(hituv); return OPERATOR_CANCELLED; } /* mark 1 vertex as being hit */ - for(i=0; i<4; i++) + BLI_array_growitems(hitv, hit.efa->len); + BLI_array_growitems(hituv, hit.efa->len); + for(i=0; i<hit.efa->len; i++) { hitv[i]= 0xFFFFFFFF; + } - hitv[hit.uv]= hit.vert; - hituv[hit.uv]= hit.tf->uv[hit.uv]; + hitv[hit.lindex]= hit.vert1; + hituv[hit.lindex]= hit.luv->uv; + + hitlen = hit.efa->len; } else if(selectmode == UV_SELECT_EDGE) { /* find edge */ uv_find_nearest_edge(scene, ima, em, co, &hit); if(hit.efa == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); + BLI_array_free(hitv); + BLI_array_free(hituv); return OPERATOR_CANCELLED; } /* mark 2 edge vertices as being hit */ - for(i=0; i<4; i++) + BLI_array_growitems(hitv, hit.efa->len); + BLI_array_growitems(hituv, hit.efa->len); + for (i=0; i < hit.efa->len; i++) { hitv[i]= 0xFFFFFFFF; + } + + nvert= hit.efa->len; - nvert= (hit.efa->v4)? 4: 3; + hitv[hit.lindex]= hit.vert1; + hitv[(hit.lindex+1)%nvert]= hit.vert2; + hituv[hit.lindex]= hit.luv->uv; + hituv[(hit.lindex+1)%nvert]= hit.nextluv->uv; - hitv[hit.edge]= hit.vert; - hitv[(hit.edge+1)%nvert]= hit.vert2; - hituv[hit.edge]= hit.tf->uv[hit.edge]; - hituv[(hit.edge+1)%nvert]= hit.tf->uv[(hit.edge+1)%nvert]; + hitlen = hit.efa->len; } else if(selectmode == UV_SELECT_FACE) { /* find face */ find_nearest_uv_face(scene, ima, em, co, &hit); if(hit.efa == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); + BLI_array_free(hitv); + BLI_array_free(hituv); return OPERATOR_CANCELLED; } /* make active */ - EM_set_actFace(em, hit.efa); + BM_active_face_set(em->bm, hit.efa); /* mark all face vertices as being hit */ - for(i=0; i<4; i++) - hituv[i]= hit.tf->uv[i]; - hitv[0]= hit.efa->v1->tmp.l; - hitv[1]= hit.efa->v2->tmp.l; - hitv[2]= hit.efa->v3->tmp.l; + BLI_array_growitems(hitv, hit.efa->len); + BLI_array_growitems(hituv, hit.efa->len); + i = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, hit.efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + hituv[i]= luv->uv; + hitv[i] = BM_elem_index_get(l->v); + i++; + } - if(hit.efa->v4) hitv[3]= hit.efa->v4->tmp.l; - else hitv[3]= 0xFFFFFFFF; + hitlen = hit.efa->len; } else if(selectmode == UV_SELECT_ISLAND) { uv_find_nearest_vert(scene, ima, em, co, NULL, &hit); if(hit.efa==NULL) { - BKE_mesh_end_editmesh(obedit->data, em); + BLI_array_free(hitv); + BLI_array_free(hituv); return OPERATOR_CANCELLED; } + + hitlen = 0; } else { - BKE_mesh_end_editmesh(obedit->data, em); + hitlen = 0; + BLI_array_free(hitv); + BLI_array_free(hituv); return OPERATOR_CANCELLED; } @@ -1579,36 +1896,36 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) else if(extend) { if(selectmode == UV_SELECT_VERTEX) { /* (de)select uv vertex */ - if(uvedit_uv_selected(scene, hit.efa, hit.tf, hit.uv)) { - uvedit_uv_deselect(scene, hit.efa, hit.tf, hit.uv); + if(uvedit_uv_selected(em, scene, hit.l)) { + uvedit_uv_deselect(em, scene, hit.l); select= 0; } else { - uvedit_uv_select(scene, hit.efa, hit.tf, hit.uv); + uvedit_uv_select(em, scene, hit.l); select= 1; } flush = 1; } else if(selectmode == UV_SELECT_EDGE) { /* (de)select edge */ - if(uvedit_edge_selected(scene, hit.efa, hit.tf, hit.edge)) { - uvedit_edge_deselect(scene, hit.efa, hit.tf, hit.edge); + if(uvedit_edge_selected(em, scene, hit.l)) { + uvedit_edge_deselect(em, scene, hit.l); select= 0; } else { - uvedit_edge_select(scene, hit.efa, hit.tf, hit.edge); + uvedit_edge_select(em, scene, hit.l); select= 1; } flush = 1; } else if(selectmode == UV_SELECT_FACE) { /* (de)select face */ - if(uvedit_face_selected(scene, hit.efa, hit.tf)) { - uvedit_face_deselect(scene, hit.efa, hit.tf); + if(uvedit_face_selected(scene, em, hit.efa)) { + uvedit_face_deselect(scene, em, hit.efa); select= 0; } else { - uvedit_face_select(scene, hit.efa, hit.tf); + uvedit_face_select(scene, em, hit.efa); select= 1; } flush = -1; @@ -1616,109 +1933,101 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) /* (de)select sticky uv nodes */ if(sticky != SI_STICKY_DISABLE) { - EditVert *ev; - - for(a=0, ev=em->verts.first; ev; ev = ev->next, a++) - ev->tmp.l = a; - + + BM_mesh_elem_index_ensure(em->bm, BM_VERT); + /* deselect */ if(select==0) { - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(sticky_select(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky)) - uvedit_uv_deselect(scene, efa, tf, 0); - if(sticky_select(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky)) - uvedit_uv_deselect(scene, efa, tf, 1); - if(sticky_select(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky)) - uvedit_uv_deselect(scene, efa, tf, 2); - if(efa->v4) - if(sticky_select(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky)) - uvedit_uv_deselect(scene, efa, tf, 3); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + if(sticky_select(limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen)) + uvedit_uv_deselect(em, scene, l); } } flush = -1; } /* select */ else { - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(sticky_select(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky)) - uvedit_uv_select(scene, efa, tf, 0); - if(sticky_select(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky)) - uvedit_uv_select(scene, efa, tf, 1); - if(sticky_select(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky)) - uvedit_uv_select(scene, efa, tf, 2); - if(efa->v4) - if(sticky_select(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky)) - uvedit_uv_select(scene, efa, tf, 3); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + if(sticky_select(limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen)) + uvedit_uv_select(em, scene, l); } } - + flush = 1; } } } else { /* deselect all */ - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uvedit_face_deselect(scene, efa, tf); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + uvedit_face_deselect(scene, em, efa); } if(selectmode == UV_SELECT_VERTEX) { /* select vertex */ - uvedit_uv_select(scene, hit.efa, hit.tf, hit.uv); + uvedit_uv_select(em, scene, hit.l); flush= 1; } else if(selectmode == UV_SELECT_EDGE) { /* select edge */ - uvedit_edge_select(scene, hit.efa, hit.tf, hit.edge); + uvedit_edge_select(em, scene, hit.l); flush= 1; } else if(selectmode == UV_SELECT_FACE) { /* select face */ - uvedit_face_select(scene, hit.efa, hit.tf); + uvedit_face_select(scene, em, hit.efa); } /* select sticky uvs */ if(sticky != SI_STICKY_DISABLE) { - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tf)) { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { if(sticky == SI_STICKY_DISABLE) continue; + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - if(sticky_select(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky)) - uvedit_uv_select(scene, efa, tf, 0); - if(sticky_select(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky)) - uvedit_uv_select(scene, efa, tf, 1); - if(sticky_select(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky)) - uvedit_uv_select(scene, efa, tf, 2); - if(efa->v4) - if(sticky_select(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky)) - uvedit_uv_select(scene, efa, tf, 3); + if(sticky_select(limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen)) + uvedit_uv_select(em, scene, l); flush= 1; } } } } - + +#if 0 /* BM_elem_select_set API handles all of this? */ + if(sync) { /* flush for mesh selection */ if(ts->selectmode != SCE_SELECT_FACE) { - if(flush==1) EM_select_flush(em); - else if(flush==-1) EM_deselect_flush(em); + if(flush==1) EDBM_select_flush(em); + else if(flush==-1) EDBM_deselect_flush(em); } } - - DAG_id_tag_update(obedit->data, 0); + +#endif + + DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - - BKE_mesh_end_editmesh(obedit->data, em); + + BLI_array_free(hitv); + BLI_array_free(hituv); + return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED; } @@ -1819,7 +2128,7 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; float limit[2]; int extend; @@ -1827,7 +2136,6 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i if(ts->uv_flag & UV_SYNC_SELECTION) { BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled"); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } @@ -1858,7 +2166,6 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1923,31 +2230,45 @@ static int unlink_selection_exec(bContext *C, wmOperator *op) ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(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; if(ts->uv_flag & UV_SYNC_SELECTION) { BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled"); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + int desel = 0; - if(uvedit_face_visible(scene, ima, efa, tf)) { - const char select_flag= efa->v4 ? (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) : (TF_SEL1|TF_SEL2|TF_SEL3); - if(~tf->flag & select_flag) - tf->flag &= ~select_flag; + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + 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->flag & MLOOPUV_VERTSEL)) { + desel = 1; + break; + } + } + + if (desel) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag &= ~MLOOPUV_VERTSEL; + } } } DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1982,78 +2303,78 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje * selection (so for sticky modes, vertex or location based). */ ToolSettings *ts= CTX_data_tool_settings(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; - int nverts, i; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + /* MTexPoly *tf; */ if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) { /* Tag all verts as untouched, then touch the ones that have a face center - * in the loop and select all MTFace UV's that use a touched vert. */ - EditVert *eve; + * in the loop and select all MLoopUV's that use a touched vert. */ + BMVert *eve; - for(eve= em->verts.first; eve; eve= eve->next) - eve->tmp.l = 0; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BM_elem_flag_disable(eve, BM_ELEM_TAG); + } - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->tmp.l) { - if(efa->v4) - efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= efa->v4->tmp.l=1; - else - efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= 1; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + BM_elem_flag_enable(l->v, BM_ELEM_TAG); + } } } /* now select tagged verts */ - for(efa= em->faces.first; efa; efa= efa->next) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - nverts= efa->v4? 4: 3; - for(i=0; i<nverts; i++) { - if((*(&efa->v1 + i))->tmp.l) { - if(select) - uvedit_uv_select(scene, efa, tf, i); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) { + if (select) + uvedit_uv_select(em, scene, l); else - uvedit_uv_deselect(scene, efa, tf, i); + uvedit_uv_deselect(em, scene, l); } } } } else if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) { - EditFace *efa_vlist; - MTFace *tf_vlist; + BMFace *efa_vlist; + /* MTexPoly *tf_vlist; */ /* UNUSED */ UvMapVert *start_vlist=NULL, *vlist_iter; struct UvVertMap *vmap; float limit[2]; unsigned int efa_index; - //EditVert *eve; /* removed vert counting for now */ + //BMVert *eve; /* removed vert counting for now */ //int a; uvedit_pixel_to_float(sima, limit, 0.05); - EM_init_index_arrays(em, 0, 0, 1); - vmap= EM_make_uv_vert_map(em, 0, 0, limit); + EDBM_init_index_arrays(em, 0, 0, 1); + vmap= EDBM_make_uv_vert_map(em, 0, 0, limit); /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */ /*for(a=0, eve= em->verts.first; eve; a++, eve= eve->next) eve->tmp.l = a; */ if(vmap == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); return; } - for(efa_index=0, efa= em->faces.first; efa; efa_index++, efa= efa->next) { - if(efa->tmp.l) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - nverts= efa->v4? 4: 3; - - for(i=0; i<nverts; i++) { + efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); + for (efa_index=0; efa; efa=BM_iter_step(&iter), efa_index++) { + if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { + /* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { if(select) - uvedit_uv_select(scene, efa, tf, i); + uvedit_uv_select(em, scene, l); else - uvedit_uv_deselect(scene, efa, tf, i); + uvedit_uv_deselect(em, scene, l); - vlist_iter= EM_get_uv_map_vert(vmap, (*(&efa->v1 + i))->tmp.l); + vlist_iter= EDBM_get_uv_map_vert(vmap, BM_elem_index_get(l->v)); while (vlist_iter) { if(vlist_iter->separate) @@ -2072,35 +2393,33 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje break; if(efa_index != vlist_iter->f) { - efa_vlist = EM_get_face_for_index(vlist_iter->f); - tf_vlist = CustomData_em_get(&em->fdata, efa_vlist->data, CD_MTFACE); + efa_vlist = EDBM_get_face_for_index(em, vlist_iter->f); + /* tf_vlist = CustomData_bmesh_get(&em->bm->pdata, efa_vlist->head.data, CD_MTEXPOLY); */ /* UNUSED */ if(select) - uvedit_uv_select(scene, efa_vlist, tf_vlist, vlist_iter->tfindex); + uvedit_uv_select(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex)); else - uvedit_uv_deselect(scene, efa_vlist, tf_vlist, vlist_iter->tfindex); + uvedit_uv_deselect(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex)); } vlist_iter = vlist_iter->next; } } } } - EM_free_index_arrays(); - EM_free_uv_vert_map(vmap); + EDBM_free_index_arrays(em); + EDBM_free_uv_vert_map(vmap); } else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */ - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->tmp.l) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { if(select) - uvedit_face_select(scene, efa, tf); + uvedit_face_select(scene, em, efa); else - uvedit_face_deselect(scene, efa, tf); + uvedit_face_deselect(scene, em, efa); } } } - BKE_mesh_end_editmesh(obedit->data, em); } static int border_select_exec(bContext *C, wmOperator *op) @@ -2111,9 +2430,12 @@ static int border_select_exec(bContext *C, wmOperator *op) Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(C); ARegion *ar= CTX_wm_region(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tface; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; rcti rect; rctf rectf; int change, pinned, select, faces, extend; @@ -2147,14 +2469,16 @@ static int border_select_exec(bContext *C, wmOperator *op) change= 0; - for(efa= em->faces.first; efa; efa= efa->next) { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { /* assume not touched */ - efa->tmp.l = 0; - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tface)) { - uv_center(tface->uv, cent, efa->v4 != NULL); + BM_elem_flag_disable(efa, BM_ELEM_TAG); + + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(uvedit_face_visible(scene, ima, efa, tf)) { + poly_uv_center(em, efa, cent); if(BLI_in_rctf(&rectf, cent[0], cent[1])) { - efa->tmp.l = change = 1; + BM_elem_flag_enable(efa, BM_ELEM_TAG); + change = 1; } } } @@ -2166,51 +2490,26 @@ static int border_select_exec(bContext *C, wmOperator *op) else { /* other selection modes */ change= 1; + + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tf)) + continue; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - for(efa= em->faces.first; efa; efa= efa->next) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tface)) { if(!pinned || (ts->uv_flag & UV_SYNC_SELECTION) ) { + /* UV_SYNC_SELECTION - can't do pinned selection */ - if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) { - if(select) uvedit_uv_select(scene, efa, tface, 0); - else uvedit_uv_deselect(scene, efa, tface, 0); + if(BLI_in_rctf(&rectf, luv->uv[0], luv->uv[1])) { + if(select) uvedit_uv_select(em, scene, l); + else uvedit_uv_deselect(em, scene, l); } - if(BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) { - if(select) uvedit_uv_select(scene, efa, tface, 1); - else uvedit_uv_deselect(scene, efa, tface, 1); - } - if(BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) { - if(select) uvedit_uv_select(scene, efa, tface, 2); - else uvedit_uv_deselect(scene, efa, tface, 2); - } - if(efa->v4 && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) { - if(select) uvedit_uv_select(scene, efa, tface, 3); - else uvedit_uv_deselect(scene, efa, tface, 3); - } - } - else if(pinned) { - if((tface->unwrap & TF_PIN1) && - BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) { - - if(select) uvedit_uv_select(scene, efa, tface, 0); - else uvedit_uv_deselect(scene, efa, tface, 0); - } - if((tface->unwrap & TF_PIN2) && - BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) { - - if(select) uvedit_uv_select(scene, efa, tface, 1); - else uvedit_uv_deselect(scene, efa, tface, 1); - } - if((tface->unwrap & TF_PIN3) && - BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) { - - if(select) uvedit_uv_select(scene, efa, tface, 2); - else uvedit_uv_deselect(scene, efa, tface, 2); - } - if((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) { - if(select) uvedit_uv_select(scene, efa, tface, 3); - else uvedit_uv_deselect(scene, efa, tface, 3); + } else if(pinned) { + if ((luv->flag & MLOOPUV_PINNED) && + BLI_in_rctf(&rectf, luv->uv[0], luv->uv[1])) { + if(select) uvedit_uv_select(em, scene, l); + else uvedit_uv_deselect(em, scene, l); } } } @@ -2219,20 +2518,20 @@ static int border_select_exec(bContext *C, wmOperator *op) if(change) { /* make sure newly selected vert selection is updated*/ +#if 0 /* BM_elem_select_set API handles all of this? */ if(ts->uv_flag & UV_SYNC_SELECTION) { if(ts->selectmode != SCE_SELECT_FACE) { - if(select) EM_select_flush(em); - else EM_deselect_flush(em); + if(select) EDBM_select_flush(em); + else EDBM_deselect_flush(em); } } +#endif WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } - - BKE_mesh_end_editmesh(obedit->data, em); + return OPERATOR_CANCELLED; } @@ -2261,20 +2560,22 @@ static void UV_OT_select_border(wmOperatorType *ot) /* ******************** circle select operator **************** */ -static void select_uv_inside_ellipse(Scene *scene, int select, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, int select_index) +static void select_uv_inside_ellipse(BMEditMesh *em, SpaceImage *UNUSED(sima), Scene *scene, int select, + float *offset, float *ell, BMLoop *l, MLoopUV *luv) { /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ float x, y, r2, *uv; - uv= tface->uv[index]; + + uv= luv->uv; x= (uv[0] - offset[0])*ell[0]; y= (uv[1] - offset[1])*ell[1]; r2 = x*x + y*y; if(r2 < 1.0f) { - if(select) uvedit_uv_select(scene, efa, tface, select_index); - else uvedit_uv_deselect(scene, efa, tface, select_index); + if(select) uvedit_uv_select(em, scene, l); + else uvedit_uv_deselect(em, scene, l); } } @@ -2283,10 +2584,12 @@ static int circle_select_exec(bContext *C, wmOperator *op) SpaceImage *sima= CTX_wm_space_image(C); 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; ARegion *ar= CTX_wm_region(C); - EditFace *efa; - MTFace *tface; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; int x, y, radius, width, height, select; float zoomx, zoomy, offset[2], ellipse[2]; int gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); @@ -2308,21 +2611,19 @@ static int circle_select_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]); /* do selection */ - for(efa= em->faces.first; efa; efa= efa->next) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - select_uv_inside_ellipse(scene, select, efa, tface, 0, offset, ellipse, 0); - select_uv_inside_ellipse(scene, select, efa, tface, 1, offset, ellipse, 1); - select_uv_inside_ellipse(scene, select, efa, tface, 2, offset, ellipse, 2); - if(efa->v4) - select_uv_inside_ellipse(scene, select, efa, tface, 3, offset, ellipse, 3); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + select_uv_inside_ellipse(em, sima, scene, select, offset, ellipse, l, luv); + } } +#if 0 //I think the BM_elem_select_set api stuff handles all this as necassary? if(select) EM_select_flush(em); else EM_deselect_flush(em); - +#endif WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -2422,97 +2723,93 @@ static void UV_OT_snap_cursor(wmOperatorType *ot) static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, SpaceImage *sima) { - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tface; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tface; + MLoopUV *luv; short change= 0; - for(efa= em->faces.first; efa; efa= efa->next) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tface)) { - if(uvedit_uv_selected(scene, efa, tface, 0)) copy_v2_v2(tface->uv[0], sima->cursor); - if(uvedit_uv_selected(scene, efa, tface, 1)) copy_v2_v2(tface->uv[1], sima->cursor); - if(uvedit_uv_selected(scene, efa, tface, 2)) copy_v2_v2(tface->uv[2], sima->cursor); - if(efa->v4) - if(uvedit_uv_selected(scene, efa, tface, 3)) copy_v2_v2(tface->uv[3], sima->cursor); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tface)) + continue; - change= 1; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if(uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(luv->uv, sima->cursor); + change= 1; + } } } - BKE_mesh_end_editmesh(obedit->data, em); return change; } static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit) { - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - EditVert *eve; - MTFace *tface; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + BMVert *eve; + MTexPoly *tface; + MLoopUV *luv; short change = 0; int count = 0; float *coords; short *usercount, users; - + + /* BMESH_TODO - stop setting the index, bad juju + * not totally simple because 3 states and because the count is not + * based on the global vertex index :S - campbell */ + /* set all verts to -1 : an unused index*/ - for(eve= em->verts.first; eve; eve= eve->next) - eve->tmp.l=-1; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) + BM_elem_index_set(eve, -1); /* set_dirty! */ + em->bm->elem_index_dirty |= BM_VERT; /* index every vert that has a selected UV using it, but only once so as to * get unique indices and to count how much to malloc */ - for(efa= em->faces.first; efa; efa= efa->next) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tface)) { - if(uvedit_uv_selected(scene, efa, tface, 0) && efa->v1->tmp.l==-1) efa->v1->tmp.l= count++; - if(uvedit_uv_selected(scene, efa, tface, 1) && efa->v2->tmp.l==-1) efa->v2->tmp.l= count++; - if(uvedit_uv_selected(scene, efa, tface, 2) && efa->v3->tmp.l==-1) efa->v3->tmp.l= count++; - if(efa->v4) - if(uvedit_uv_selected(scene, efa, tface, 3) && efa->v4->tmp.l==-1) efa->v4->tmp.l= count++; - - change = 1; - - /* optional speedup */ - efa->tmp.p = tface; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tface)) { + BM_elem_flag_disable(efa, BM_ELEM_TAG); + continue; + } else { + BM_elem_flag_enable(efa, BM_ELEM_TAG); + } + + change = 1; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l) && BM_elem_index_get(l->v) == -1) { + BM_elem_index_set(l->v, count); /* set_dirty! */ + count++; + } } - else - efa->tmp.p = NULL; } + em->bm->elem_index_dirty |= BM_VERT; /* set above but include for completeness since they are made dirty again */ coords = MEM_callocN(sizeof(float)*count*2, "snap to adjacent coords"); usercount = MEM_callocN(sizeof(short)*count, "snap to adjacent counts"); /* add all UV coords from visible, unselected UV coords as well as counting them to average later */ - for(efa= em->faces.first; efa; efa= efa->next) { - if((tface=(MTFace *)efa->tmp.p)) { - /* is this an unselected UV we can snap to? */ - if(efa->v1->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 0))) { - coords[efa->v1->tmp.l*2] += tface->uv[0][0]; - coords[(efa->v1->tmp.l*2)+1] += tface->uv[0][1]; - usercount[efa->v1->tmp.l]++; - change = 1; - } - if(efa->v2->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 1))) { - coords[efa->v2->tmp.l*2] += tface->uv[1][0]; - coords[(efa->v2->tmp.l*2)+1] += tface->uv[1][1]; - usercount[efa->v2->tmp.l]++; - change = 1; - } - if(efa->v3->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 2))) { - coords[efa->v3->tmp.l*2] += tface->uv[2][0]; - coords[(efa->v3->tmp.l*2)+1] += tface->uv[2][1]; - usercount[efa->v3->tmp.l]++; - change = 1; - } - - if(efa->v4) { - if(efa->v4->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 3))) { - coords[efa->v4->tmp.l*2] += tface->uv[3][0]; - coords[(efa->v4->tmp.l*2)+1] += tface->uv[3][1]; - usercount[efa->v4->tmp.l]++; - change = 1; - } + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) + continue; + + tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tface)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (BM_elem_index_get(l->v) >= 0 && + (!uvedit_uv_selected(em, scene, l))) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + add_v2_v2(&coords[BM_elem_index_get(l->v) * 2], luv->uv); + change = 1; } } } @@ -2521,46 +2818,23 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe if(!change) { MEM_freeN(coords); MEM_freeN(usercount); - BKE_mesh_end_editmesh(obedit->data, em); return change; } /* copy the averaged unselected UVs back to the selected UVs */ - for(efa= em->faces.first; efa; efa= efa->next) { - if((tface=(MTFace *)efa->tmp.p)) { - - if( uvedit_uv_selected(scene, efa, tface, 0) && - efa->v1->tmp.l >= 0 && - (users = usercount[efa->v1->tmp.l]) - ) { - tface->uv[0][0] = coords[efa->v1->tmp.l*2] / users; - tface->uv[0][1] = coords[(efa->v1->tmp.l*2)+1] / users; - } - - if( uvedit_uv_selected(scene, efa, tface, 1) && - efa->v2->tmp.l >= 0 && - (users = usercount[efa->v2->tmp.l]) - ) { - tface->uv[1][0] = coords[efa->v2->tmp.l*2] / users; - tface->uv[1][1] = coords[(efa->v2->tmp.l*2)+1] / users; - } - - if( uvedit_uv_selected(scene, efa, tface, 2) && - efa->v3->tmp.l >= 0 && - (users = usercount[efa->v3->tmp.l]) - ) { - tface->uv[2][0] = coords[efa->v3->tmp.l*2] / users; - tface->uv[2][1] = coords[(efa->v3->tmp.l*2)+1] / users; - } - - if(efa->v4) { - if( uvedit_uv_selected(scene, efa, tface, 3) && - efa->v4->tmp.l >= 0 && - (users = usercount[efa->v4->tmp.l]) - ) { - tface->uv[3][0] = coords[efa->v4->tmp.l*2] / users; - tface->uv[3][1] = coords[(efa->v4->tmp.l*2)+1] / users; - } + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) + continue; + + tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tface)) + continue; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l) && BM_elem_index_get(l->v) >= 0 + && (users = usercount[BM_elem_index_get(l->v)])) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(luv->uv, &coords[BM_elem_index_get(l->v) * 2]); } } } @@ -2568,43 +2842,41 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe MEM_freeN(coords); MEM_freeN(usercount); - BKE_mesh_end_editmesh(obedit->data, em); return change; } static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) { - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - Image *ima; - EditFace *efa; - MTFace *tface; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + Image *ima= sima->image; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tface; + MLoopUV *luv; int width= 0, height= 0; float w, h; short change = 0; - if(!sima) - return 0; - - ima= sima->image; - ED_space_image_size(sima, &width, &height); w = (float)width; h = (float)height; - for(efa= em->faces.first; efa; efa= efa->next) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(uvedit_face_visible(scene, ima, efa, tface)) { - if(uvedit_uv_selected(scene, efa, tface, 0)) snap_uv_to_pixel(tface->uv[0], w, h); - if(uvedit_uv_selected(scene, efa, tface, 1)) snap_uv_to_pixel(tface->uv[1], w, h); - if(uvedit_uv_selected(scene, efa, tface, 2)) snap_uv_to_pixel(tface->uv[2], w, h); - if(efa->v4) - if(uvedit_uv_selected(scene, efa, tface, 3)) snap_uv_to_pixel(tface->uv[3], w, h); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tface)) + continue; - change = 1; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + snap_uv_to_pixel(luv->uv, w, h); + } } + + change = 1; } - BKE_mesh_end_editmesh(obedit->data, em); return change; } @@ -2667,35 +2939,34 @@ static int pin_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tface; + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tface; + MLoopUV *luv; int clear= RNA_boolean_get(op->ptr, "clear"); - for(efa= em->faces.first; efa; efa= efa->next) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tface)) + continue; - if(uvedit_face_visible(scene, ima, efa, tface)) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + if(!clear) { - if(uvedit_uv_selected(scene, efa, tface, 0)) tface->unwrap |= TF_PIN1; - if(uvedit_uv_selected(scene, efa, tface, 1)) tface->unwrap |= TF_PIN2; - if(uvedit_uv_selected(scene, efa, tface, 2)) tface->unwrap |= TF_PIN3; - if(efa->v4) - if(uvedit_uv_selected(scene, efa, tface, 3)) tface->unwrap |= TF_PIN4; - } - else { - if(uvedit_uv_selected(scene, efa, tface, 0)) tface->unwrap &= ~TF_PIN1; - if(uvedit_uv_selected(scene, efa, tface, 1)) tface->unwrap &= ~TF_PIN2; - if(uvedit_uv_selected(scene, efa, tface, 2)) tface->unwrap &= ~TF_PIN3; - if(efa->v4) - if(uvedit_uv_selected(scene, efa, tface, 3)) tface->unwrap &= ~TF_PIN4; + if (uvedit_uv_selected(em, scene, l)) + luv->flag |= MLOOPUV_PINNED; + } else { + if (uvedit_uv_selected(em, scene, l)) + luv->flag &= ~MLOOPUV_PINNED; } } } WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -2722,26 +2993,28 @@ static int select_pinned_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tface; - - for(efa= em->faces.first; efa; efa= efa->next) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(uvedit_face_visible(scene, ima, efa, tface)) { - if(tface->unwrap & TF_PIN1) uvedit_uv_select(scene, efa, tface, 0); - if(tface->unwrap & TF_PIN2) uvedit_uv_select(scene, efa, tface, 1); - if(tface->unwrap & TF_PIN3) uvedit_uv_select(scene, efa, tface, 2); - if(efa->v4) { - if(tface->unwrap & TF_PIN4) uvedit_uv_select(scene, efa, tface, 3); - } + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tface; + MLoopUV *luv; + + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + if(!uvedit_face_visible(scene, ima, efa, tface)) + continue; + + 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->flag & MLOOPUV_PINNED) + uvedit_uv_select(em, scene, l); } } WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -2765,122 +3038,76 @@ static int hide_exec(bContext *C, wmOperator *op) SpaceImage *sima= CTX_wm_space_image(C); ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; + Scene *scene = CTX_data_scene(C); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; int swap= RNA_boolean_get(op->ptr, "unselected"); int facemode= sima ? sima->flag & SI_SELACTFACE : 0; if(ts->uv_flag & UV_SYNC_SELECTION) { - EM_hide_mesh(em, swap); + EDBM_hide_mesh(em, swap); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } - if(swap) { - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(facemode) { - /* Pretend face mode */ - if(( (efa->v4==NULL && - ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || - ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) == 0) { - - if(em->selectmode == SCE_SELECT_FACE) { - efa->f &= ~SELECT; - /* must re-select after */ - efa->e1->f &= ~SELECT; - efa->e2->f &= ~SELECT; - efa->e3->f &= ~SELECT; - if(efa->e4) efa->e4->f &= ~SELECT; - } - else - EM_select_face(efa, 0); - } - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } - else if(em->selectmode == SCE_SELECT_FACE) { - const char select_flag= efa->v4 ? (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) : (TF_SEL1|TF_SEL2|TF_SEL3); - if((tf->flag & select_flag)==0) { - EM_select_face(efa, 0); - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } - } - else { - /* EM_deselect_flush will deselect the face */ - if((tf->flag & TF_SEL1)==0) efa->v1->f &= ~SELECT; - if((tf->flag & TF_SEL2)==0) efa->v2->f &= ~SELECT; - if((tf->flag & TF_SEL3)==0) efa->v3->f &= ~SELECT; - if((efa->v4) && (tf->flag & TF_SEL4)==0) efa->v4->f &= ~SELECT; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + int hide = 0; - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } + 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->flag & MLOOPUV_VERTSEL) { + hide = 1; + break; } } - } - else { - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if(facemode) { - if( (efa->v4==NULL && - ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || - ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) { - - if(em->selectmode == SCE_SELECT_FACE) { - efa->f &= ~SELECT; - /* must re-select after */ - efa->e1->f &= ~SELECT; - efa->e2->f &= ~SELECT; - efa->e3->f &= ~SELECT; - if(efa->e4) efa->e4->f &= ~SELECT; - } - else - EM_select_face(efa, 0); - } - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + if (swap) + hide = !hide; + + if (hide) { + if (facemode) { + /*check that every UV is selected*/ + luv = NULL; + 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->flag & MLOOPUV_VERTSEL)) + break; } - else if(em->selectmode == SCE_SELECT_FACE) { - const char select_flag= efa->v4 ? (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) : (TF_SEL1|TF_SEL2|TF_SEL3); - if(tf->flag & select_flag) - EM_select_face(efa, 0); - - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + + if (!luv) { + BM_elem_select_set(em->bm, efa, FALSE); + uvedit_face_deselect(scene, em, efa); } - else { - /* EM_deselect_flush will deselect the face */ - if(tf->flag & TF_SEL1) efa->v1->f &= ~SELECT; - if(tf->flag & TF_SEL2) efa->v2->f &= ~SELECT; - if(tf->flag & TF_SEL3) efa->v3->f &= ~SELECT; - if((efa->v4) && tf->flag & TF_SEL4) efa->v4->f &= ~SELECT; - - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + } else if(em->selectmode == SCE_SELECT_FACE) { + /*check if a UV is selected*/ + 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->flag & MLOOPUV_VERTSEL) { + BM_elem_select_set(em->bm, efa, FALSE); + } + luv->flag &= ~MLOOPUV_VERTSEL; + } + } else { + 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->flag & MLOOPUV_VERTSEL) { + BM_elem_select_set(em->bm, l->v, FALSE); + luv->flag &= ~MLOOPUV_VERTSEL; + } } } } } - /*deselects too many but ok for now*/ - if(em->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_VERTEX)) - EM_deselect_flush(em); - - if(em->selectmode==SCE_SELECT_FACE) { - /* de-selected all edges from faces that were de-selected. - * now make sure all faces that are selected also have selected edges */ - for(efa= em->faces.first; efa; efa= efa->next) - if(efa->f & SELECT) - EM_select_face(efa, 1); - } - EM_validate_selections(em); + EDBM_validate_selections(em); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -2907,114 +3134,97 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) SpaceImage *sima= CTX_wm_space_image(C); ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); - EditFace *efa; - MTFace *tf; + /*Scene *scene = CTX_data_scene(C);*/ /*UNUSED*/ + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; int facemode= sima ? sima->flag & SI_SELACTFACE : 0; int stickymode= sima ? (sima->sticky != SI_STICKY_DISABLE) : 1; - + /* call the mesh function if we are in mesh sync sel */ if(ts->uv_flag & UV_SYNC_SELECTION) { - EM_reveal_mesh(em); + EDBM_reveal_mesh(em); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } - if(facemode) { if(em->selectmode == SCE_SELECT_FACE) { - for(efa= em->faces.first; efa; efa= efa->next) { - if(!(efa->h) && !(efa->f & SELECT)) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - EM_select_face(efa, 1); - tf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + BM_elem_select_set(em->bm, efa, TRUE); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag |= MLOOPUV_VERTSEL; + } } } } else { /* enable adjacent faces to have disconnected UV selections if sticky is disabled */ if(!stickymode) { - for(efa= em->faces.first; efa; efa= efa->next) { - if(!(efa->h) && !(efa->f & SELECT)) { - /* All verts must be unselected for the face to be selected in the UV view */ - if((efa->v1->f&SELECT)==0 && (efa->v2->f&SELECT)==0 && (efa->v3->f&SELECT)==0 && (efa->v4==NULL || (efa->v4->f&SELECT)==0)) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - tf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; - /* Cant use EM_select_face here because it unselects the verts - * and we cant tell if the face was totally unselected or not */ - /*EM_select_face(efa, 1); - * - * See Loop with EM_select_face() below... */ - efa->f |= SELECT; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + int totsel=0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + totsel += BM_elem_flag_test(l->v, BM_ELEM_SELECT); + } + + if (!totsel) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag |= MLOOPUV_VERTSEL; + } + + BM_elem_select_set(em->bm, efa, TRUE); } } } - } - else { - for(efa= em->faces.first; efa; efa= efa->next) { - if(!(efa->h) && !(efa->f & SELECT)) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if((efa->v1->f & SELECT)==0) {tf->flag |= TF_SEL1;} - if((efa->v2->f & SELECT)==0) {tf->flag |= TF_SEL2;} - if((efa->v3->f & SELECT)==0) {tf->flag |= TF_SEL3;} - if((efa->v4 && (efa->v4->f & SELECT)==0)) {tf->flag |= TF_SEL4;} - - efa->f |= SELECT; + } else { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)==0) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag |= MLOOPUV_VERTSEL; + } + } + + BM_elem_select_set(em->bm, efa, TRUE); } } } - - /* Select all edges and verts now */ - for(efa= em->faces.first; efa; efa= efa->next) - /* we only selected the face flags, and didnt changes edges or verts, fix this now */ - if(!(efa->h) && (efa->f & SELECT)) - EM_select_face(efa, 1); - - EM_select_flush(em); } - } - else if(em->selectmode == SCE_SELECT_FACE) { - for(efa= em->faces.first; efa; efa= efa->next) { - if(!(efa->h) && !(efa->f & SELECT)) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - efa->f |= SELECT; - tf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; + } else if(em->selectmode == SCE_SELECT_FACE) { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag |= MLOOPUV_VERTSEL; + } + + BM_elem_select_set(em->bm, efa, TRUE); } } - - /* Select all edges and verts now */ - for(efa= em->faces.first; efa; efa= efa->next) - /* we only selected the face flags, and didnt changes edges or verts, fix this now */ - if(!(efa->h) && (efa->f & SELECT)) - EM_select_face(efa, 1); - } - else { - for(efa= em->faces.first; efa; efa= efa->next) { - if(!(efa->h) && !(efa->f & SELECT)) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - if((efa->v1->f & SELECT)==0) {tf->flag |= TF_SEL1;} - if((efa->v2->f & SELECT)==0) {tf->flag |= TF_SEL2;} - if((efa->v3->f & SELECT)==0) {tf->flag |= TF_SEL3;} - if((efa->v4 && (efa->v4->f & SELECT)==0)) {tf->flag |= TF_SEL4;} - - efa->f |= SELECT; + } else { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)==0) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv->flag |= MLOOPUV_VERTSEL; + } + } + + BM_elem_select_set(em->bm, efa, TRUE); } } - - /* Select all edges and verts now */ - for(efa= em->faces.first; efa; efa= efa->next) - /* we only selected the face flags, and didnt changes edges or verts, fix this now */ - if(!(efa->h) && (efa->f & SELECT)) - EM_select_face(efa, 1); } - + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -3152,24 +3362,27 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) UvVertMap *vmap; Object *ob = CTX_data_edit_object(C); Mesh *me= (Mesh*)ob->data; - EditMesh *em; - EditEdge *editedge; + BMEditMesh *em; + BMEdge *editedge; float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; char mark_seams = RNA_boolean_get(op->ptr, "mark_seams"); char mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp"); - em = BKE_mesh_get_editmesh(me); + BMesh *bm; + BMIter iter; - if(!EM_texFaceCheck(em)) { - BKE_mesh_end_editmesh(ob->data, em); + em = me->edit_btmesh; + bm = em->bm; + + if(!EDBM_texFaceCheck(em)) { return OPERATOR_CANCELLED; } /* This code sets editvert->tmp.l to the index. This will be useful later on. */ - EM_init_index_arrays(em, 0, 0, 1); - vmap = EM_make_uv_vert_map(em, 0, 0, limit); + EDBM_init_index_arrays(em, 0, 0, 1); + vmap = EDBM_make_uv_vert_map(em, 0, 0, limit); - for(editedge = em->edges.first; editedge; editedge = editedge->next) { + BM_ITER(editedge, &iter, bm, BM_EDGES_OF_MESH, NULL) { /* flags to determine if we uv is separated from first editface match */ char separated1 = 0, separated2; /* set to denote edge must be flagged as seam */ @@ -3179,30 +3392,30 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) /* For use with v1coincident. v1coincident will change only if we've had commonFaces */ int commonFaces = 0; - EditFace *efa1, *efa2; + BMFace *efa1, *efa2; UvMapVert *mv1, *mvinit1, *mv2, *mvinit2, *mviter; /* mv2cache stores the first of the list of coincident uv's for later comparison * mv2sep holds the last separator and is copied to mv2cache when a hit is first found */ UvMapVert *mv2cache = NULL, *mv2sep = NULL; - mvinit1 = vmap->vert[editedge->v1->tmp.l]; + mvinit1 = vmap->vert[BM_elem_index_get(editedge->v1)]; if(mark_seams) - editedge->seam = 0; + BM_elem_flag_disable(editedge, BM_ELEM_SEAM); for(mv1 = mvinit1; mv1 && !faces_separated; mv1 = mv1->next) { if(mv1->separate && commonFaces) v1coincident = 0; separated2 = 0; - efa1 = EM_get_face_for_index(mv1->f); - mvinit2 = vmap->vert[editedge->v2->tmp.l]; + efa1 = EDBM_get_face_for_index(em, mv1->f); + mvinit2 = vmap->vert[BM_elem_index_get(editedge->v2)]; for(mv2 = mvinit2; mv2; mv2 = mv2->next) { if(mv2->separate) mv2sep = mv2; - efa2 = EM_get_face_for_index(mv2->f); + efa2 = EDBM_get_face_for_index(em, mv2->f); if(efa1 == efa2) { /* if v1 is not coincident no point in comparing */ if(v1coincident) { @@ -3237,17 +3450,16 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) if(faces_separated) { if(mark_seams) - editedge->seam = 1; + BM_elem_flag_enable(editedge, BM_ELEM_SEAM); if(mark_sharp) - editedge->sharp = 1; + BM_elem_flag_disable(editedge, BM_ELEM_SMOOTH); } } me->drawflag |= ME_DRAWSEAMS; - EM_free_uv_vert_map(vmap); - EM_free_index_arrays(); - BKE_mesh_end_editmesh(me, em); + EDBM_free_uv_vert_map(vmap); + EDBM_free_index_arrays(em); DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); @@ -3279,16 +3491,19 @@ static int mark_seam_exec(bContext *C, wmOperator *UNUSED(op)) Object *ob = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); Mesh *me= (Mesh*)ob->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - EditFace *efa; + BMEditMesh *em= me->edit_btmesh; + BMesh *bm = em->bm; + BMFace *efa; + BMLoop *loop; - for(efa = em->faces.first; efa; efa = efa->next) { - MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - int i, nverts = efa->v4? 4 : 3; + BMIter iter, liter; - for(i = 0; i < nverts; i++) - if(uvedit_edge_selected(scene, efa, mt, i)) - (*(&efa->e1 + i))->seam = 1; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + BM_ITER(loop, &liter, bm, BM_LOOPS_OF_FACE, efa) { + if(uvedit_edge_selected(em, scene, loop)) { + BM_elem_flag_enable(loop, BM_ELEM_SEAM); + } + } } me->drawflag |= ME_DRAWSEAMS; @@ -3296,8 +3511,6 @@ static int mark_seam_exec(bContext *C, wmOperator *UNUSED(op)) if(scene->toolsettings->edge_mode_live_unwrap) ED_unwrap_lscm(scene, ob, FALSE); - BKE_mesh_end_editmesh(me, em); - DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); @@ -3338,7 +3551,9 @@ void ED_operatortypes_uvedit(void) WM_operatortype_append(UV_OT_snap_selected); WM_operatortype_append(UV_OT_align); + WM_operatortype_append(UV_OT_stitch); + WM_operatortype_append(UV_OT_seams_from_islands); WM_operatortype_append(UV_OT_mark_seam); WM_operatortype_append(UV_OT_weld); |