diff options
Diffstat (limited to 'source')
24 files changed, 1624 insertions, 1150 deletions
diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c index fa9747ec54f..bfea1600121 100644 --- a/source/blender/blenkernel/intern/editderivedbmesh.c +++ b/source/blender/blenkernel/intern/editderivedbmesh.c @@ -192,11 +192,11 @@ static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm) looptris[i*3+1] = efa->v2->tmp.p; looptris[i*3+2] = efa->v3->tmp.p; - if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2); + if (looptris[i*3]->head.eflag2 < looptris[i*3+1]->head.eflag2); SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]); - if (looptris[i*3+1]->head.eflag2 > looptris[i*3+2]->head.eflag2); + if (looptris[i*3+1]->head.eflag2 < looptris[i*3+2]->head.eflag2); SWAP(BMLoop*, looptris[i*3+1], looptris[i*3+2]); - if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2); + if (looptris[i*3]->head.eflag2 < looptris[i*3+1]->head.eflag2); SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]); i += 1; diff --git a/source/blender/bmesh/bmesh_queries.h b/source/blender/bmesh/bmesh_queries.h index ddcd67a3bab..dc38004929e 100644 --- a/source/blender/bmesh/bmesh_queries.h +++ b/source/blender/bmesh/bmesh_queries.h @@ -3,6 +3,10 @@ #include <stdio.h> /*Queries*/ + +/*get the area of face f*/ +float BM_face_area(BMFace *f); + /*counts number of elements of type type are in the mesh.*/ int BM_Count_Element(struct BMesh *bm, int type); diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 4339e22b45e..10aa4f2fdd4 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -164,6 +164,8 @@ void BM_Free_Mesh_Data(BMesh *bm) if (bm->vtar) MEM_freeN(bm->vtar); if (bm->plar) MEM_freeN(bm->plar); + BLI_freelistN(&bm->selected); + BMO_ClearStack(bm); } diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 9df2bb8c202..9d91a6d6d29 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -108,7 +108,7 @@ static void compute_poly_normal(float normal[3], float (*verts)[3], int nverts) Normalize_d(v2); l = INPR(v1, v2); - if (l < 0.01 && l > -0.01) + if (ABS(l) < 0.1) continue; /* newell's method @@ -189,6 +189,31 @@ static int compute_poly_center(float center[3], float *area, float (*verts)[3], return 0; } +float BM_face_area(BMFace *f) +{ + BMLoop *l; + BMIter iter; + float (*verts)[3], stackv[100][3]; + float area, center[3]; + int i; + + if (f->len <= 100) + verts = stackv; + else verts = MEM_callocN(sizeof(float)*f->len*3, "bm_face_area tmp"); + + i = 0; + BM_ITER(l, &iter, NULL, BM_LOOPS_OF_FACE, f) { + VECCOPY(verts[i], l->v->co); + i++; + } + + compute_poly_center(center, &area, verts, f->len); + + if (f->len > 100) + MEM_freeN(verts); + + return area; +} /* computes center of face in 3d. uses center of bounding box. */ diff --git a/source/blender/bmesh/operators/mesh_conv.c b/source/blender/bmesh/operators/mesh_conv.c index 9944c9b8d23..47173b356bf 100644 --- a/source/blender/bmesh/operators/mesh_conv.c +++ b/source/blender/bmesh/operators/mesh_conv.c @@ -244,6 +244,10 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { mvert->flag = BMFlags_To_MEFlags(v); BMINDEX_SET(v, i); + + /*copy over customdata*/ + CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i); + i++; mvert++; } @@ -262,6 +266,10 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { medge->flag = BMFlags_To_MEFlags(e); BMINDEX_SET(e, i); + + /*copy over customdata*/ + CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i); + i++; medge++; } @@ -308,10 +316,16 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { for ( ; l; l=BMIter_Step(&liter), j++, mloop++) { mloop->e = BMINDEX_GET(l->e); mloop->v = BMINDEX_GET(l->v); + + /*copy over customdata*/ + CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l->head.data, j); } if (f == bm->act_face) me->act_face = i; + /*copy over customdata*/ + CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i); + i++; mpoly++; } diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index dd29f270680..8a6bce21b44 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -53,6 +53,8 @@ struct BMesh; struct BMVert; struct BMEdge; struct BMFace; +struct UvVertMap; +struct UvMapVert; // edge and face flag both #define EM_FGON 2 @@ -78,23 +80,26 @@ struct BMFace; /* bmeshutils.c */ -/*this function is currently defunct, dead*/ -void EDBM_Tesselate(struct EditMesh *em); void EDBM_RecalcNormals(struct BMEditMesh *em); + void EDBM_MakeEditBMesh(struct Scene *scene, struct Object *ob); void EDBM_FreeEditBMesh(struct BMEditMesh *tm); void EDBM_LoadEditBMesh(struct Scene *scene, struct Object *ob); + void EDBM_init_index_arrays(struct BMEditMesh *tm, int forvert, int foredge, int forface); void EDBM_free_index_arrays(struct BMEditMesh *tm); struct BMVert *EDBM_get_vert_for_index(struct BMEditMesh *tm, int index); struct BMEdge *EDBM_get_edge_for_index(struct BMEditMesh *tm, int index); struct BMFace *EDBM_get_face_for_index(struct BMEditMesh *tm, int index); struct BMFace *EDBM_get_actFace(struct BMEditMesh *em, int sloppy); + void EDBM_selectmode_flush(struct BMEditMesh *em); int EDBM_get_actSelection(struct BMEditMesh *em, struct BMEditSelection *ese); + void EDBM_editselection_center(struct BMEditMesh *em, float *center, struct BMEditSelection *ese); void EDBM_editselection_plane(struct BMEditMesh *em, float *plane, struct BMEditSelection *ese); void EDBM_editselection_normal(float *normal, struct BMEditSelection *ese); + void EDBM_selectmode_set(struct BMEditMesh *em); void EDBM_convertsel(struct BMEditMesh *em, short oldmode, short selectmode); @@ -104,6 +109,19 @@ void EDBM_free_backbuf(void); int EDBM_init_backbuf_border(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); int EDBM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short rads); +void EDBM_select_swap(struct BMEditMesh *em); /* exported for UV */ +void EDBM_set_actFace(struct BMEditMesh *em, struct BMFace *efa); + +int EDBM_texFaceCheck(struct BMEditMesh *em); +struct MTexPoly *EDBM_get_active_mtexpoly(struct BMEditMesh *em, struct BMFace **act_efa, int sloppy); + +void EDBM_free_uv_vert_map(struct UvVertMap *vmap); +struct UvMapVert *EDBM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v); +struct UvVertMap *EDBM_make_uv_vert_map(struct BMEditMesh *em, int selected, int do_face_idx_array, float *limit); + +void EDBM_toggle_select_all(struct BMEditMesh *em); +void EDBM_set_flag_all(struct BMEditMesh *em, int flag); + /* meshtools.c */ intptr_t mesh_octree_table(struct Object *ob, struct BMEditMesh *em, float *co, char mode); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 74a9be75db6..e75eb751a0b 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -47,10 +47,10 @@ int ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obed int ED_uvedit_test_silent(struct Object *obedit); int ED_uvedit_test(struct Object *obedit); -int uvedit_face_visible(struct Scene *scene, struct Image *ima, struct EditFace *efa, struct MTFace *tf); -int uvedit_face_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf); -int uvedit_edge_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); -int uvedit_uv_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); +int uvedit_face_visible(struct Scene *scene, struct Image *ima, struct BMFace *efa, struct MTexPoly *tf); +int uvedit_face_selected(struct Scene *scene, struct BMEditMesh *em, struct BMFace *efa); +int uvedit_edge_selected(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l); +int uvedit_uv_selected(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l); int ED_uvedit_nearest_uv(struct Scene *scene, struct Object *obedit, struct Image *ima, float co[2], float uv[2]); diff --git a/source/blender/editors/mesh/bmesh_select.c b/source/blender/editors/mesh/bmesh_select.c index 760bb5b65e0..8dee58caddb 100644 --- a/source/blender/editors/mesh/bmesh_select.c +++ b/source/blender/editors/mesh/bmesh_select.c @@ -1422,3 +1422,62 @@ void EDBM_convertsel(BMEditMesh *em, short oldmode, short selectmode) } } } + + +void EDBM_select_swap(BMEditMesh *em) /* exported for UV */ +{ + BMIter iter; + BMVert *eve; + BMEdge *eed; + BMFace *efa; + + if(em->bm->selectmode & SCE_SELECT_VERTEX) { + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (BM_TestHFlag(eve, BM_HIDDEN)) + continue; + BM_Select(em->bm, eve, !BM_TestHFlag(eve, BM_SELECT)); + } + } + else if(em->selectmode & SCE_SELECT_EDGE) { + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { + if (BM_TestHFlag(eed, BM_HIDDEN)) + continue; + BM_Select(em->bm, eed, !BM_TestHFlag(eed, BM_SELECT)); + } + } + else { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (BM_TestHFlag(efa, BM_HIDDEN)) + continue; + BM_Select(em->bm, efa, !BM_TestHFlag(efa, BM_SELECT)); + } + + } +// if (EM_texFaceCheck()) +} + +static int select_inverse_mesh_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh; + + EDBM_select_swap(em); + + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void MESH_OT_select_inverse(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select Inverse"; + ot->idname= "MESH_OT_select_inverse"; + + /* api callbacks */ + ot->exec= select_inverse_mesh_exec; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 194a3ea9ebe..11049bc1210 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -1392,3 +1392,62 @@ void MESH_OT_edge_split(wmOperatorType *ot) RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, INT_MAX); } + +/****************** add duplicate operator ***************/ + +static int mesh_duplicate_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_edit_object(C); + BMEditMesh *em= ((Mesh*)ob->data)->edit_btmesh; + BMOperator bmop; + + EDBM_InitOpf(em, &bmop, op, "dupe geom=%hvef", BM_SELECT); + + BMO_Exec_Op(em->bm, &bmop); + EDBM_clear_flag_all(em, BM_SELECT); + + BMO_HeaderFlag_Buffer(em->bm, &bmop, "newout", BM_SELECT); + + if (!EDBM_FinishOp(em, &bmop, op, 1)) + return OPERATOR_CANCELLED; + + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); + + return OPERATOR_FINISHED; +} + +static int mesh_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + int ret; + + WM_cursor_wait(1); + ret = mesh_duplicate_exec(C, op); + WM_cursor_wait(0); + + if (ret == OPERATOR_CANCELLED) + return OPERATOR_CANCELLED; + + RNA_int_set(op->ptr, "mode", TFM_TRANSLATION); + WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); + + return OPERATOR_FINISHED; +} + +void MESH_OT_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Duplicate"; + ot->idname= "MESH_OT_duplicate"; + + /* api callbacks */ + ot->invoke= mesh_duplicate_invoke; + ot->exec= mesh_duplicate_exec; + + ot->poll= ED_operator_editmesh; + + /* to give to transform */ + RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); +} + diff --git a/source/blender/editors/mesh/bmeshutils.c b/source/blender/editors/mesh/bmeshutils.c index 5e8c295d7b8..71f79f7e944 100644 --- a/source/blender/editors/mesh/bmeshutils.c +++ b/source/blender/editors/mesh/bmeshutils.c @@ -521,3 +521,180 @@ void undo_push_mesh(bContext *C, char *name) { undo_editmode_push(C, name, getEditMesh, free_undo, undoMesh_to_editbtMesh, editbtMesh_to_undoMesh, NULL); } + +/*write comment here*/ +UvVertMap *EDBM_make_uv_vert_map(BMEditMesh *em, int selected, int do_face_idx_array, float *limit) +{ + BMVert *ev; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + /* vars from original func */ + UvVertMap *vmap; + UvMapVert *buf; + MTexPoly *tf; + MLoopUV *luv; + unsigned int a; + int totverts, i, totuv; + + if (do_face_idx_array) + EDBM_init_index_arrays(em, 0, 0, 1); + + /* we need the vert */ + totverts=0; + BM_ITER(ev, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BMINDEX_SET(ev, totverts); + totverts++; + } + + totuv = 0; + + /* generate UvMapVert array */ + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if(!selected || ((!BM_TestHFlag(efa, BM_HIDDEN)) && BM_TestHFlag(efa, BM_SELECT))) + totuv += efa->len; + } + + if(totuv==0) { + if (do_face_idx_array) + EDBM_free_index_arrays(em); + return NULL; + } + vmap= (UvVertMap*)MEM_callocN(sizeof(*vmap), "UvVertMap"); + if (!vmap) { + if (do_face_idx_array) + EDBM_free_index_arrays(em); + return NULL; + } + + vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totverts, "UvMapVert*"); + buf= vmap->buf= (UvMapVert*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvMapVert"); + + if (!vmap->vert || !vmap->buf) { + free_uv_vert_map(vmap); + if (do_face_idx_array) + EDBM_free_index_arrays(em); + return NULL; + } + + a = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if(!selected || ((!BM_TestHFlag(efa, BM_HIDDEN)) && BM_TestHFlag(efa, BM_SELECT))) { + i = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + buf->tfindex= i; + buf->f= a; + buf->separate = 0; + + buf->next= vmap->vert[BMINDEX_GET(((BMLoop*)l->head.next)->v)]; + vmap->vert[BMINDEX_GET(l->v)]= buf; + + buf++; + i++; + } + } + + a++; + } + + /* sort individual uvs for each vert */ + a = 0; + BM_ITER(ev, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + UvMapVert *newvlist= NULL, *vlist=vmap->vert[a]; + UvMapVert *iterv, *v, *lastv, *next; + float *uv, *uv2, uvdiff[2]; + + while(vlist) { + v= vlist; + vlist= vlist->next; + v->next= newvlist; + newvlist= v; + + efa = EDBM_get_face_for_index(em, v->f); + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + l = BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa, v->tfindex); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + uv = luv->uv; + + lastv= NULL; + iterv= vlist; + + while(iterv) { + next= iterv->next; + efa = EDBM_get_face_for_index(em, iterv->f); + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + l = BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + uv2 = luv->uv; + + Vec2Subf(uvdiff, uv2, uv); + + if(fabs(uv[0]-uv2[0]) < limit[0] && fabs(uv[1]-uv2[1]) < limit[1]) { + if(lastv) lastv->next= next; + else vlist= next; + iterv->next= newvlist; + newvlist= iterv; + } + else + lastv=iterv; + + iterv= next; + } + + newvlist->separate = 1; + } + + vmap->vert[a]= newvlist; + a++; + } + + if (do_face_idx_array) + EDBM_free_index_arrays(em); + + return vmap; +} + + +UvMapVert *EDBM_get_uv_map_vert(UvVertMap *vmap, unsigned int v) +{ + return vmap->vert[v]; +} + +void EDBM_free_uv_vert_map(UvVertMap *vmap) +{ + if (vmap) { + if (vmap->vert) MEM_freeN(vmap->vert); + if (vmap->buf) MEM_freeN(vmap->buf); + MEM_freeN(vmap); + } +} + + +/* last_sel, use em->act_face otherwise get the last selected face in the editselections + * at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */ +MTexPoly *EDBM_get_active_mtexpoly(BMEditMesh *em, BMFace **act_efa, int sloppy) +{ + BMFace *efa = NULL; + + if(!EDBM_texFaceCheck(em)) + return NULL; + + efa = EDBM_get_actFace(em, sloppy); + + if (efa) { + if (act_efa) *act_efa = efa; + return CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + } + + if (act_efa) *act_efa= NULL; + return NULL; +} + +/* can we edit UV's for this mesh?*/ +int EDBM_texFaceCheck(BMEditMesh *em) +{ + /* some of these checks could be a touch overkill */ + return em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY); +}
\ No newline at end of file diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 4b891843f5e..806ef4c299e 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -1557,50 +1557,3 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) RNA_def_int(ot->srna, "subdivisions", 2, 0, 6, "Subdivisions", "", 0, 8); RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00); } - -/****************** add duplicate operator ***************/ - -static int mesh_duplicate_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh(ob->data); - - adduplicateflag(em, SELECT); - - BKE_mesh_end_editmesh(ob->data, em); - - DAG_object_flush_update(scene, ob, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); - - return OPERATOR_FINISHED; -} - -static int mesh_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event) -{ - WM_cursor_wait(1); - mesh_duplicate_exec(C, op); - WM_cursor_wait(0); - - RNA_int_set(op->ptr, "mode", TFM_TRANSLATION); - WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); - - return OPERATOR_FINISHED; -} - -void MESH_OT_duplicate(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Duplicate"; - ot->idname= "MESH_OT_duplicate"; - - /* api callbacks */ - ot->invoke= mesh_duplicate_invoke; - ot->exec= mesh_duplicate_exec; - - ot->poll= ED_operator_editmesh; - - /* to give to transform */ - RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); -} - diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index aa7a5e6b292..1d92d93442d 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -2683,69 +2683,6 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -void EM_select_swap(EditMesh *em) /* exported for UV */ -{ - EditVert *eve; - EditEdge *eed; - EditFace *efa; - - if(em->selectmode & SCE_SELECT_VERTEX) { - - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->h==0) { - if(eve->f & SELECT) eve->f &= ~SELECT; - else eve->f|= SELECT; - } - } - } - else if(em->selectmode & SCE_SELECT_EDGE) { - for(eed= em->edges.first; eed; eed= eed->next) { - if(eed->h==0) { - EM_select_edge(eed, !(eed->f & SELECT)); - } - } - } - else { - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->h==0) { - EM_select_face(efa, !(efa->f & SELECT)); - } - } - } - - EM_selectmode_flush(em); - -// if (EM_texFaceCheck()) - -} - -static int select_inverse_mesh_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - - EM_select_swap(em); - - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - - BKE_mesh_end_editmesh(obedit->data, em); - return OPERATOR_FINISHED; -} - -void MESH_OT_select_inverse(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Select Inverse"; - ot->idname= "MESH_OT_select_inverse"; - - /* api callbacks */ - ot->exec= select_inverse_mesh_exec; - ot->poll= ED_operator_editmesh; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - static int bmesh_test_exec(bContext *C, wmOperator *op) { return OPERATOR_FINISHED; diff --git a/source/blender/editors/screen/Makefile b/source/blender/editors/screen/Makefile index 923a020afcf..ce6c59b69ed 100644 --- a/source/blender/editors/screen/Makefile +++ b/source/blender/editors/screen/Makefile @@ -42,6 +42,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I../../windowmanager CPPFLAGS += -I../../blenloader CPPFLAGS += -I../../blenkernel +CPPFLAGS += -I../../bmesh CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../makesdna CPPFLAGS += -I../../makesrna diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript index 3972efd8eed..affc6192290 100644 --- a/source/blender/editors/screen/SConscript +++ b/source/blender/editors/screen/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../blenfont ../../makesdna ../../imbuf' incs += ' ../../blenloader ../../windowmanager ../../python ../../makesrna' -incs += ' ../../render/extern/include' +incs += ' ../../render/extern/include ../../bmesh' incs += ' #/intern/guardedalloc #/extern/glew/include' defs = '' diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 19cbf93a83c..8f0a60359c2 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -53,6 +53,7 @@ #include "BKE_report.h" #include "BKE_screen.h" #include "BKE_utildefines.h" +#include "BKE_tessmesh.h" #include "WM_api.h" #include "WM_types.h" @@ -228,36 +229,27 @@ int ED_operator_posemode(bContext *C) int ED_operator_uvedit(bContext *C) { Object *obedit= CTX_data_edit_object(C); - EditMesh *em= NULL; + BMEditMesh *em= NULL; if(obedit && obedit->type==OB_MESH) - em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - - if(em && (em->faces.first) && (CustomData_has_layer(&em->fdata, CD_MTFACE))) { - BKE_mesh_end_editmesh(obedit->data, em); + em= ((Mesh *)obedit->data)->edit_btmesh; + if (em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) return 1; - } - if(obedit) - BKE_mesh_end_editmesh(obedit->data, em); return 0; } int ED_operator_uvmap(bContext *C) { Object *obedit= CTX_data_edit_object(C); - EditMesh *em= NULL; + BMEditMesh *em= NULL; if(obedit && obedit->type==OB_MESH) - em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + em= ((Mesh *)obedit->data)->edit_btmesh; - if(em && (em->faces.first)) { - BKE_mesh_end_editmesh(obedit->data, em); + if(em && (em->bm->totface)) return 1; - } - if(obedit) - BKE_mesh_end_editmesh(obedit->data, em); return 0; } diff --git a/source/blender/editors/space_image/Makefile b/source/blender/editors/space_image/Makefile index e7e9a9b5665..5a69cb7fc65 100644 --- a/source/blender/editors/space_image/Makefile +++ b/source/blender/editors/space_image/Makefile @@ -47,6 +47,7 @@ CPPFLAGS += -I../../makesrna CPPFLAGS += -I../../imbuf CPPFLAGS += -I../../python CPPFLAGS += -I../../render/extern/include +CPPFLAGS += -I../../bmesh CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include # own include diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript index e7041ef0458..5fa2509bf5f 100644 --- a/source/blender/editors/space_image/SConscript +++ b/source/blender/editors/space_image/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' -incs += ' ../../render/extern/include ../../makesrna' +incs += ' ../../render/extern/include ../../makesrna ../../bmesh' defs = [] diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 709fbb6299b..512053490f9 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -50,6 +50,7 @@ #include "BKE_mesh.h" #include "BKE_screen.h" #include "BKE_utildefines.h" +#include "BKE_tessmesh.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -256,13 +257,13 @@ static void image_refresh(const bContext *C, ScrArea *sa) if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin)); else if(obedit && obedit->type == OB_MESH) { Mesh *me= (Mesh*)obedit->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - MTFace *tf; + BMEditMesh *em= me->edit_btmesh; + MTexPoly *tf; - if(em && EM_texFaceCheck(em)) { + if(em && EDBM_texFaceCheck(em)) { sima->image= ima= NULL; - tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */ + tf = EDBM_get_active_mtexpoly(em, NULL, 1); /* partially selected face is ok */ if(tf && (tf->mode & TF_TEX)) { /* don't need to check for pin here, see above */ @@ -272,8 +273,6 @@ static void image_refresh(const bContext *C, ScrArea *sa) else sima->curtile= tf->tile; } } - - BKE_mesh_end_editmesh(obedit->data, em); } } @@ -748,13 +747,9 @@ int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit) return 0; if(obedit && obedit->type == OB_MESH) { - EditMesh *em = BKE_mesh_get_editmesh(obedit->data); - int ret; - - ret = EM_texFaceCheck(em); + BMEditMesh *em = ((Mesh*)obedit->data)->edit_btmesh; - BKE_mesh_end_editmesh(obedit->data, em); - return ret; + return EDBM_texFaceCheck(em); } return 0; @@ -767,13 +762,9 @@ int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit) if(ED_space_image_show_paint(sima)) if(obedit && obedit->type == OB_MESH) { - EditMesh *em = BKE_mesh_get_editmesh(obedit->data); - int ret; - - ret = EM_texFaceCheck(em); + BMEditMesh *em = ((Mesh*)obedit->data)->edit_btmesh; - BKE_mesh_end_editmesh(obedit->data, em); - return ret; + return EDBM_texFaceCheck(em); } return 0; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index f8b66dbca21..623c6bb24c3 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2451,36 +2451,38 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f static void createTransUVs(bContext *C, TransInfo *t) { -#if 0 SpaceImage *sima = (SpaceImage*)CTX_wm_space_data(C); Image *ima = CTX_data_edit_image(C); Scene *scene = CTX_data_scene(C); TransData *td = NULL; TransData2D *td2d = NULL; - MTFace *tf; + MTexPoly *tf; + MLoopUV *luv; + BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; int count=0, countsel=0; int propmode = t->flag & T_PROP_EDIT; - EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh; - EditFace *efa; - if(!ED_uvedit_test(t->obedit)) return; /* count */ - 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)) { - efa->tmp.p = tf; + if(!uvedit_face_visible(scene, ima, efa, tf)) { + BMINDEX_SET(efa, 0); + continue; + } + + BMINDEX_SET(efa, 1); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (uvedit_uv_selected(em, scene, l)) + countsel++; - if (uvedit_uv_selected(scene, efa, tf, 0)) countsel++; - if (uvedit_uv_selected(scene, efa, tf, 1)) countsel++; - if (uvedit_uv_selected(scene, efa, tf, 2)) countsel++; - if (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) countsel++; if(propmode) - count += (efa->v4)? 4: 3; - } else { - efa->tmp.p = NULL; + count += efa->len; } } @@ -2499,26 +2501,22 @@ static void createTransUVs(bContext *C, TransInfo *t) td= t->data; td2d= t->data2d; - for (efa= em->faces.first; efa; efa= efa->next) { - if ((tf=(MTFace *)efa->tmp.p)) { - if (propmode) { - UVsToTransData(sima, td++, td2d++, tf->uv[0], uvedit_uv_selected(scene, efa, tf, 0)); - UVsToTransData(sima, td++, td2d++, tf->uv[1], uvedit_uv_selected(scene, efa, tf, 1)); - UVsToTransData(sima, td++, td2d++, tf->uv[2], uvedit_uv_selected(scene, efa, tf, 2)); - if(efa->v4) - UVsToTransData(sima, td++, td2d++, tf->uv[3], uvedit_uv_selected(scene, efa, tf, 3)); - } else { - if(uvedit_uv_selected(scene, efa, tf, 0)) UVsToTransData(sima, td++, td2d++, tf->uv[0], 1); - if(uvedit_uv_selected(scene, efa, tf, 1)) UVsToTransData(sima, td++, td2d++, tf->uv[1], 1); - if(uvedit_uv_selected(scene, efa, tf, 2)) UVsToTransData(sima, td++, td2d++, tf->uv[2], 1); - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) UVsToTransData(sima, td++, td2d++, tf->uv[3], 1); - } + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; + + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (!propmode && !uvedit_uv_selected(em, scene, l)) + continue; + + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + UVsToTransData(sima, td++, td2d++, luv->uv, uvedit_uv_selected(em, scene, l)); } } if (sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_begin(t->scene, t->obedit); -#endif } void flushTransUVs(TransInfo *t) diff --git a/source/blender/editors/uvedit/SConscript b/source/blender/editors/uvedit/SConscript index b472b89d23d..9926eb0c7ea 100644 --- a/source/blender/editors/uvedit/SConscript +++ b/source/blender/editors/uvedit/SConscript @@ -5,6 +5,6 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' -incs += ' ../../makesrna #/intern/opennl/extern ../../gpu' +incs += ' ../../makesrna #/intern/opennl/extern ../../gpu ../../bmesh' env.BlenderLib ( 'bf_editors_uvedit', sources, Split(incs), [], libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 0a747c951f5..8ec87976064 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -28,6 +28,9 @@ #include <float.h> #include <math.h> #include <stdlib.h> +#include <string.h> + +#include "MEM_guardedalloc.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -41,7 +44,7 @@ #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_utildefines.h" -#include "BKE_mesh.h" +#include "BKE_tessmesh.h" #include "BLI_arithb.h" #include "BLI_editVert.h" @@ -120,34 +123,33 @@ static int draw_uvs_face_check(Scene *scene) static void draw_uvs_shadow(SpaceImage *sima, Object *obedit) { - EditMesh *em; - EditFace *efa; - MTFace *tf; + BMEditMesh *em; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MLoopUV *luv; - em= BKE_mesh_get_editmesh((Mesh*)obedit->data); + em= ((Mesh*)obedit->data)->edit_btmesh; /* draws the grey mesh when painting */ glColor3ub(112, 112, 112); - 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) { glBegin(GL_LINE_LOOP); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv= CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + glVertex2fv(luv->uv); + } glEnd(); } - - BKE_mesh_end_editmesh(obedit->data, em); } static int draw_uvs_dm_shadow(DerivedMesh *dm) { /* draw shadow mesh - this is the mesh with the modifier applied */ - if(dm && dm->drawUVEdges && CustomData_has_layer(&dm->faceData, CD_MTFACE)) { + if(dm && dm->drawUVEdges && CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { glColor3ub(112, 112, 112); dm->drawUVEdges(dm); return 1; @@ -156,13 +158,19 @@ static int draw_uvs_dm_shadow(DerivedMesh *dm) return 0; } -static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFace *activetf) +static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTexPoly *activetf) { - EditFace *efa; - MTFace *tf; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; Image *ima= sima->image; - float aspx, aspy, col[4], tf_uv[4][2]; - + V_DECLARE(tf_uv); + V_DECLARE(tf_uvorig); + float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL; + int i; + ED_space_image_uv_aspect(sima, &aspx, &aspy); switch(sima->dt_uvstretch) { @@ -170,21 +178,37 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac { float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area; - for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uv_copy_aspect(tf->uv, tf_uv, aspx, aspy); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + V_RESET(tf_uv); + V_RESET(tf_uvorig); + + 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); + V_GROW(tf_uv); + V_GROW(tf_uvorig); + + tf_uvorig[i][0] = luv->uv[0]; + tf_uvorig[i][1] = luv->uv[1]; - totarea += EM_face_area(efa); + i++; + } + + poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); + + totarea += BM_face_area(efa); //totuvarea += tf_area(tf, efa->v4!=0); - totuvarea += uv_area(tf_uv, efa->v4!=0); + totuvarea += poly_uv_area(tf_uv, efa->len); if(uvedit_face_visible(scene, ima, efa, tf)) { - efa->tmp.p = tf; + BMINDEX_SET(efa, 1); } else { if(tf == activetf) activetf= NULL; - efa->tmp.p = NULL; + BMINDEX_SET(efa, 0); } } @@ -192,24 +216,41 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac col[0] = 1.0; col[1] = col[2] = 0.0; glColor3fv(col); - for(efa= em->faces.first; efa; efa= efa->next) { - if((tf=(MTFace *)efa->tmp.p)) { - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if(BMINDEX_GET(efa)) { + glBegin(GL_POLYGON); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + } glEnd(); } } } else { - for(efa= em->faces.first; efa; efa= efa->next) { - if((tf=(MTFace *)efa->tmp.p)) { - area = EM_face_area(efa) / totarea; - uv_copy_aspect(tf->uv, tf_uv, aspx, aspy); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if(BMINDEX_GET(efa)) { + area = BM_face_area(efa) / totarea; + + V_RESET(tf_uv); + V_RESET(tf_uvorig); + + 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); + V_GROW(tf_uv); + V_GROW(tf_uvorig); + + tf_uvorig[i][0] = luv->uv[0]; + tf_uvorig[i][1] = luv->uv[1]; + + i++; + } + + poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); + //uvarea = tf_area(tf, efa->v4!=0) / totuvarea; - uvarea = uv_area(tf_uv, efa->v4!=0) / totuvarea; + uvarea = poly_uv_area(tf_uv, efa->len) / totuvarea; if(area < FLT_EPSILON || uvarea < FLT_EPSILON) areadiff = 1.0; @@ -221,11 +262,11 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac weight_to_rgb(areadiff, col, col+1, col+2); glColor3fv(col); - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); + glBegin(GL_POLYGON); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + } glEnd(); } } @@ -234,6 +275,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac } case SI_UVDT_STRETCH_ANGLE: { +#if 0 //BMESH_TODO float uvang1,uvang2,uvang3,uvang4; float ang1,ang2,ang3,ang4; float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d angle vectors */ @@ -244,7 +286,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac glShadeModel(GL_SMOOTH); for(efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + tf= CustomData_em_get(&em->fdata, efa->head.data, CD_MTFACE); if(uvedit_face_visible(scene, ima, efa, tf)) { efa->tmp.p = tf; @@ -375,11 +417,13 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac glShadeModel(GL_FLAT); break; + +#endif } } } -static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFace *activetf) +static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTexPoly *activetf) { Base *base; Image *curimage; @@ -399,17 +443,19 @@ static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFac Mesh *me= ob->data; if(me->mtface) { - MFace *mface= me->mface; - MTFace *tface= me->mtface; - int a; + MPoly *mface= me->mpoly; + MTexPoly *tface= me->mtpoly; + MLoopUV *mloopuv; + int a, b; - for(a=me->totface; a>0; a--, tface++, mface++) { + for(a=me->totpoly; a>0; a--, tface++, mface++) { if(tface->tpage == curimage) { glBegin(GL_LINE_LOOP); - glVertex2fv(tface->uv[0]); - glVertex2fv(tface->uv[1]); - glVertex2fv(tface->uv[2]); - if(mface->v4) glVertex2fv(tface->uv[3]); + + mloopuv = me->mloopuv + mface->loopstart; + for (b=0; b<mface->totloop; b++, mloopuv++) { + glVertex2fv(mloopuv->uv); + } glEnd(); } } @@ -423,18 +469,22 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) { ToolSettings *ts; Mesh *me= obedit->data; - EditMesh *em; - EditFace *efa, *efa_act; - MTFace *tf, *activetf = NULL; + BMEditMesh *em; + BMFace *efa, *efa_act, *activef; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf, *activetf = NULL; + MLoopUV *luv; DerivedMesh *finaldm, *cagedm; char col1[4], col2[4]; float pointsize; int drawfaces, interpedges, lastsel, sel; + int i; Image *ima= sima->image; - em= BKE_mesh_get_editmesh(me); - activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */ - + em= me->edit_btmesh; + activetf= EDBM_get_active_mtexpoly(em, &efa_act, 0); /* will be set to NULL if hidden */ + activef = EDBM_get_actFace(em, 0); ts= scene->toolsettings; drawfaces= draw_uvs_face_check(scene); @@ -478,45 +528,46 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); - 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)) { - efa->tmp.p = tf; - if(tf==activetf) continue; /* important the temp pointer is set above */ + BMINDEX_SET(efa, 1); + if(tf==activetf) continue; /* important the temp boolean is set above */ - if(uvedit_face_selected(scene, efa, tf)) + if(uvedit_face_selected(scene, em, efa)) glColor4ubv((GLubyte *)col2); else glColor4ubv((GLubyte *)col1); - - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); + + glBegin(GL_POLYGON); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + } glEnd(); } else { if(tf == activetf) activetf= NULL; - efa->tmp.p = NULL; + BMINDEX_SET(efa, 0); } } glDisable(GL_BLEND); } else { /* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */ - 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)) { - efa->tmp.p = tf; + BMINDEX_SET(efa, 1); } else { if(tf == activetf) activetf= NULL; - efa->tmp.p = NULL; + BMINDEX_SET(efa, 0); } } @@ -524,7 +575,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) /* 3. draw active face stippled */ - if(activetf) { + if(activef) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); UI_ThemeColor4(TH_EDITMESH_ACTIVE); @@ -532,11 +583,11 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(stipple_quarttone); - glBegin(efa_act->v4? GL_QUADS: GL_TRIANGLES); - glVertex2fv(activetf->uv[0]); - glVertex2fv(activetf->uv[1]); - glVertex2fv(activetf->uv[2]); - if(efa_act->v4) glVertex2fv(activetf->uv[3]); + glBegin(GL_POLYGON); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, activef) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + } glEnd(); glDisable(GL_POLYGON_STIPPLE); @@ -553,39 +604,38 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) switch(sima->dt_uv) { case SI_UVDT_DASH: - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); if(tf) { cpack(0x111111); glBegin(GL_LINE_LOOP); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + } glEnd(); - + setlinestyle(2); cpack(0x909090); - glBegin(GL_LINE_STRIP); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glEnd(); - - glBegin(GL_LINE_STRIP); - glVertex2fv(tf->uv[0]); - if(efa->v4) glVertex2fv(tf->uv[3]); - else glVertex2fv(tf->uv[2]); - glEnd(); - - glBegin(GL_LINE_STRIP); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); + glBegin(GL_LINE_LOOP); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + } glEnd(); + /*glBegin(GL_LINE_STRIP); + luv = CustomData_bmesh_get(&em->bm->ldata, efa->loopbase->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + luv = CustomData_bmesh_get(&em->bm->ldata, efa->loopbase->head.next->data, CD_MLOOPUV); + glVertex2fv(luv->uv); + glEnd();*/ + setlinestyle(0); } } @@ -595,34 +645,32 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) if(sima->dt_uv==SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(0.0f, 0.0f, 0.0f); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; - if(tf) { - glBegin(GL_LINE_LOOP); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); - glEnd(); + glBegin(GL_LINE_LOOP); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); } + glEnd(); } break; case SI_UVDT_OUTLINE: glLineWidth(3); cpack(0x0); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ - - if(tf) { - glBegin(GL_LINE_LOOP); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); - glEnd(); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; + + glBegin(GL_LINE_LOOP); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); } + glEnd(); } glLineWidth(1); @@ -636,83 +684,60 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) if(interpedges) { glShadeModel(GL_SMOOTH); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; - if(tf) { - glBegin(GL_LINE_LOOP); - sel = (uvedit_uv_selected(scene, efa, tf, 0)? 1 : 0); - if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[0]); - - sel = uvedit_uv_selected(scene, efa, tf, 1)? 1 : 0; - if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[1]); - - sel = uvedit_uv_selected(scene, efa, tf, 2)? 1 : 0; + glBegin(GL_LINE_LOOP); + i = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + sel = (uvedit_uv_selected(em, scene, l)? 1 : 0); if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[2]); - - if(efa->v4) { - sel = uvedit_uv_selected(scene, efa, tf, 3)? 1 : 0; - if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[3]); - } - - glEnd(); + + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.next->data, CD_MLOOPUV); + glVertex2fv(luv->uv); + i += 1; } + glEnd(); } glShadeModel(GL_FLAT); } else { - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; - if(tf) { - glBegin(GL_LINES); - sel = (uvedit_edge_selected(scene, efa, tf, 0)? 1 : 0); - if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - - sel = uvedit_edge_selected(scene, efa, tf, 1)? 1 : 0; - if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - - sel = uvedit_edge_selected(scene, efa, tf, 2)? 1 : 0; + glBegin(GL_LINE_LOOP); + i = 0; + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + sel = (uvedit_edge_selected(em, scene, l)? 1 : 0); if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[2]); - - if(efa->v4) { - glVertex2fv(tf->uv[3]); - - sel = uvedit_edge_selected(scene, efa, tf, 3)? 1 : 0; - if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; } - glVertex2fv(tf->uv[3]); - } - - glVertex2fv(tf->uv[0]); - - glEnd(); + + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.next->data, CD_MLOOPUV); + glVertex2fv(luv->uv); + i += 1; } + glEnd(); } } } else { /* no nice edges */ - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ - - if(tf) { - glBegin(GL_LINE_LOOP); - glVertex2fv(tf->uv[0]); - glVertex2fv(tf->uv[1]); - glVertex2fv(tf->uv[2]); - if(efa->v4) glVertex2fv(tf->uv[3]); - glEnd(); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; + + glBegin(GL_LINE_LOOP); + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + glVertex2fv(luv->uv); } + glEnd(); } } @@ -736,11 +761,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) UI_ThemeColor(TH_WIRE); bglBegin(GL_POINTS); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; - if(tf && !uvedit_face_selected(scene, efa, tf)) { - uv_center(tf->uv, cent, efa->v4 != NULL); + if(!uvedit_face_selected(scene, em, efa)) { + poly_uv_center(em, efa, cent); bglVertex2fv(cent); } } @@ -750,11 +776,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) UI_ThemeColor(TH_FACE_DOT); bglBegin(GL_POINTS); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + continue; - if(tf && uvedit_face_selected(scene, efa, tf)) { - uv_center(tf->uv, cent, efa->v4 != NULL); + if(uvedit_face_selected(scene, em, efa)) { + poly_uv_center(em, efa, cent); bglVertex2fv(cent); } } @@ -770,18 +797,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glPointSize(pointsize); bglBegin(GL_POINTS); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ - - if(tf) { - if(!uvedit_uv_selected(scene, efa, tf, 0)) - bglVertex2fv(tf->uv[0]); - if(!uvedit_uv_selected(scene, efa, tf, 1)) - bglVertex2fv(tf->uv[1]); - if(!uvedit_uv_selected(scene, efa, tf, 2)) - bglVertex2fv(tf->uv[2]); - if(efa->v4 && !uvedit_uv_selected(scene, efa, tf, 3)) - bglVertex2fv(tf->uv[3]); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + 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)) + bglVertex2fv(luv->uv); } } bglEnd(); @@ -792,46 +815,39 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) cpack(0xFF); bglBegin(GL_POINTS); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ - - if(tf) { - if(tf->unwrap & TF_PIN1) - bglVertex2fv(tf->uv[0]); - if(tf->unwrap & TF_PIN2) - bglVertex2fv(tf->uv[1]); - if(tf->unwrap & TF_PIN3) - bglVertex2fv(tf->uv[2]); - if(efa->v4 && (tf->unwrap & TF_PIN4)) - bglVertex2fv(tf->uv[3]); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + 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) + bglVertex2fv(luv->uv); } } bglEnd(); /* selected uvs */ UI_ThemeColor(TH_VERTEX_SELECT); - glPointSize(pointsize); + glPointSize(pointsize); bglBegin(GL_POINTS); - for(efa= em->faces.first; efa; efa= efa->next) { - tf= (MTFace *)efa->tmp.p; /* visible faces cached */ - - if(tf) { - if(uvedit_uv_selected(scene, efa, tf, 0)) - bglVertex2fv(tf->uv[0]); - if(uvedit_uv_selected(scene, efa, tf, 1)) - bglVertex2fv(tf->uv[1]); - if(uvedit_uv_selected(scene, efa, tf, 2)) - bglVertex2fv(tf->uv[2]); - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) - bglVertex2fv(tf->uv[3]); + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if (!BMINDEX_GET(efa)) + 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)) + bglVertex2fv(luv->uv); } } bglEnd(); } glPointSize(1.0); - BKE_mesh_end_editmesh(obedit->data, em); } void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit) diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index cca357c8685..a203fc9b55b 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -30,12 +30,16 @@ #define ED_UVEDIT_INTERN_H struct SpaceImage; -struct EditFace; -struct MTFace; +struct MTexPoly; struct Scene; struct Image; struct Object; struct wmOperatorType; +struct BMEditMesh; +struct BMFace; +struct BMLoop; +struct BMEdge; +struct BMVert; #define UV_SELECT_ALL 1 #define UV_SELECT_PINNED 2 @@ -45,26 +49,28 @@ struct wmOperatorType; #define TF_SEL_MASK(id) (TF_SEL1 << id) /* visibility and selection */ -int uvedit_face_visible_nolocal(struct Scene *scene, struct EditFace *efa); -int uvedit_face_visible(struct Scene *scene, struct Image *ima, struct EditFace *efa, struct MTFace *tf); +int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa); -int uvedit_face_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf); -void uvedit_face_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf); -void uvedit_face_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf); +/*all the uvedit_xxxx_[de]selected functions are + declared in ED_uvedit.h*/ +int uvedit_face_select(struct Scene *scene, struct BMEditMesh *em, struct BMFace *efa); +int uvedit_face_deselect(struct Scene *scene, struct BMEditMesh *em, struct BMFace *efa); -int uvedit_edge_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); -void uvedit_edge_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); -void uvedit_edge_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); +void uvedit_edge_select(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l); +void uvedit_edge_deselect(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l); -int uvedit_uv_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); -void uvedit_uv_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); -void uvedit_uv_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i); +void uvedit_uv_select(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l); +void uvedit_uv_deselect(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l); /* geometric utilities */ void uv_center(float uv[][2], float cent[2], int quad); float uv_area(float uv[][2], int quad); void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy); +float poly_uv_area(float uv[][2], int len); +void poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len); +void poly_uv_center(struct BMEditMesh *em, struct BMFace *f, float cent[2]); + /* operators */ void UV_OT_average_islands_scale(struct wmOperatorType *ot); void UV_OT_cube_project(struct wmOperatorType *ot); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 6f8d710ed3e..ddae9fc075b 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -30,12 +30,14 @@ #include <stdlib.h> #include <string.h> #include <math.h> +#include <string.h> #include "MEM_guardedalloc.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_image_types.h" #include "DNA_space_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -53,6 +55,7 @@ #include "BKE_mesh.h" #include "BKE_report.h" #include "BKE_utildefines.h" +#include "BKE_tessmesh.h" #include "ED_image.h" #include "ED_mesh.h" @@ -70,19 +73,20 @@ #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->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; } @@ -91,9 +95,10 @@ int ED_uvedit_test(Object *obedit) void ED_uvedit_assign_image(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... */ @@ -104,21 +109,20 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre 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; } /* ensure we have a uv layer */ - if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) { - EM_add_data_layer(em, &em->fdata, CD_MTFACE); + if(!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) { + BM_add_data_layer(em->bm, &em->bm->pdata, CD_MTFACE); 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) { @@ -140,17 +144,16 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre /* and update depdency graph */ if(update) DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - - 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. */ void ED_uvedit_set_tile(bContext *C, Scene *scene, 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)) @@ -160,18 +163,17 @@ void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, i if(ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE) return; - 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_TestHFlag(efa, BM_HIDDEN) && BM_TestHFlag(efa, BM_SELECT)) tf->tile= curtile; /* set tile index */ } DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - BKE_mesh_end_editmesh(obedit->data, em); } /*********************** space conversion *********************/ @@ -188,18 +190,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_TestHFlag(efa, BM_HIDDEN)==0); else - return (efa->h==0 && (efa->f & SELECT)); + return (BM_TestHFlag(efa, BM_HIDDEN)==0 && BM_TestHFlag(efa, BM_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) @@ -208,134 +209,216 @@ 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_TestHFlag(efa, BM_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_Select(em->bm, efa, 1); + 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); + BM_Select(em->bm, efa, 0); + 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)); + return BM_TestHFlag(l->f, BM_SELECT); + else if(ts->selectmode == SCE_SELECT_EDGE) { + return BM_TestHFlag(l->e, BM_SELECT); + } else + return BM_TestHFlag(l->v, BM_SELECT) && + BM_TestHFlag(((BMLoop*)l->head.next)->v, BM_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->head.next->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_Select(em->bm, l->f, 1); else if(ts->selectmode == SCE_SELECT_EDGE) - EM_select_edge((*(&efa->e1 + i)), 1); + BM_Select(em->bm, l->e, 1); else { - (efa->v1 + i)->f |= SELECT; - (efa->v1 + (i+1)%nvert)->f |= SELECT; + BM_Select(em->bm, l->e->v1, 1); + BM_Select(em->bm, l->e->v2, 1); } } - 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->head.next->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_Select(em->bm, l->f, 0); else if(ts->selectmode == SCE_SELECT_EDGE) - EM_select_edge((*(&efa->e1 + i)), 0); + BM_Select(em->bm, l->e, 0); else { - (efa->v1 + i)->f &= ~SELECT; - (efa->v1 + (i+1)%nvert)->f &= ~SELECT; + BM_Select(em->bm, l->e->v1, 0); + BM_Select(em->bm, l->e->v2, 0); } } - 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->head.next->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_TestHFlag(l->f, BM_SELECT); else - return (*(&efa->v1 + i))->f & SELECT; + return BM_TestHFlag(l, BM_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_Select(em->bm, l->f, 1); else - (*(&efa->v1 + i))->f |= SELECT; + BM_Select(em->bm, l->v, 1); + } + 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_Select(em->bm, l->f, 0); else - (*(&efa->v1 + i))->f &= ~SELECT; + BM_Select(em->bm, l->v, 0); + } + 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); } /*********************** geometric utilities ***********************/ +void poly_uv_center(BMEditMesh *em, BMFace *f, float cent[2]) +{ + BMLoop *l; + MLoopUV *luv; + BMIter liter; + + cent[0] = cent[1] = 0.0f; + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + cent[0] += luv->uv[0]; + cent[1] += luv->uv[1]; + } + + cent[0] /= (float) f->len; + cent[1] /= (float) f->len; +} + void uv_center(float uv[][2], float cent[2], int quad) { @@ -357,6 +440,28 @@ float uv_area(float uv[][2], int quad) return AreaF2Dfl(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 AreaF2Dfl(uv[0], uv[1], uv[2]) + AreaF2Dfl(uv[0], uv[2], uv[3]); + else + return AreaF2Dfl(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; @@ -374,33 +479,42 @@ 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; } -int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mode) +int uvedit_center(Scene *scene, Image *ima, Object *obedit, + float *cent, int mode) { - 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 min[2], max[2]; int change= 0; @@ -411,14 +525,18 @@ int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mod else if(mode==1) { INIT_MINMAX2(min, max); - 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); change= 1;} - if(uvedit_uv_selected(scene, efa, tf, 1)) { DO_MINMAX2(tf->uv[1], min, max); change= 1;} - if(uvedit_uv_selected(scene, efa, tf, 2)) { DO_MINMAX2(tf->uv[2], min, max); change= 1;} - if(efa->v4 && (uvedit_uv_selected(scene, efa, tf, 3))) { DO_MINMAX2(tf->uv[3], min, max); 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) { + 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); + change= 1; + } } } } @@ -427,108 +545,140 @@ int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mod cent[0]= (min[0]+max[0])/2.0; cent[1]= (min[1]+max[1])/2.0; - BKE_mesh_end_editmesh(obedit->data, em); return 1; } - BKE_mesh_end_editmesh(obedit->data, em); return 0; } /************************** find nearest ****************************/ typedef struct NearestHit { - EditFace *efa; - MTFace *tf; - - int vert, uv; - int edge, vert2; + BMFace *efa; + MTexPoly *tf; + BMLoop *l, *nextl; + MLoopUV *luv, *nextluv; + int lindex; //index of loop within face + int vert1, vert2; //index in mesh of edge vertices } NearestHit; -static void find_nearest_uv_edge(Scene *scene, Image *ima, EditMesh *em, float co[2], NearestHit *hit) +static void find_nearest_uv_edge(Scene *scene, Image *ima, BMEditMesh *em, float co[2], NearestHit *hit) { - MTFace *tf; - EditFace *efa; - EditVert *eve; + MTexPoly *tf; + BMFace *efa; + BMLoop *l; + BMVert *eve; + 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; + eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); + for (i=0; eve; eve=BMIter_Step(&iter), i++) { + BMINDEX_SET(eve, i); + } - 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= PdistVL2Dfl(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->head.next->data, CD_MLOOPUV); - if(dist < mindist) { - hit->tf= tf; - hit->efa= efa; - hit->edge= i; - mindist= dist; + dist= PdistVL2Dfl(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 = (BMLoop*)l->head.next; + hit->luv = luv; + hit->nextluv = nextluv; + hit->lindex = i; + hit->vert1 = BMINDEX_GET(hit->l->v); + hit->vert2 = BMINDEX_GET(((BMLoop*)hit->l->head.next)->v); } + + 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; + 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); - for(i=0; i<nverts; i++) { - cent[0] += tf->uv[i][0]; - cent[1] += tf->uv[i][1]; - } + cent[0] += luv->uv[0]; + cent[1] += luv->uv[1]; + } - cent[0] /= nverts; - cent[1] /= nverts; - dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]); + 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; - } + 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 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]; - Vec2Subf(v1, tf->uv[id1], tf->uv[id]); - Vec2Subf(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++; + } + + VecSubf(v1, uv1, uv); + VecSubf(v2, uv3, uv); /* m and v2 on same side of v-v1? */ c1= v1[0]*m[1] - v1[1]*m[0]; @@ -544,83 +694,98 @@ static int nearest_uv_between(MTFace *tf, int nverts, int id, float co[2], float return (c1*c2 >= 0.0f); } -static void find_nearest_uv_vert(Scene *scene, Image *ima, EditMesh *em, float co[2], float penalty[2], NearestHit *hit) +static void find_nearest_uv_vert(Scene *scene, Image *ima, BMEditMesh *em, + float co[2], float penalty[2], NearestHit *hit) { - EditFace *efa; - EditVert *eve; - MTFace *tf; + BMFace *efa; + BMVert *eve; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tf; + MLoopUV *luv; float mindist, dist; int i, nverts; 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); - - if(uvedit_face_visible(scene, ima, efa, tf)) { - nverts= efa->v4? 4: 3; + eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); + for (i=0; eve; eve=BMIter_Step(&iter), i++) { + BMINDEX_SET(eve, i); + } - for(i=0; i<nverts; i++) { - if(penalty && uvedit_uv_selected(scene, efa, tf, i)) - dist= fabs(co[0]-tf->uv[i][0])+penalty[0] + fabs(co[1]-tf->uv[i][1])+penalty[1]; - else - 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; + + 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 = (BMLoop*)l->head.next; + hit->luv = luv; + hit->nextluv = CustomData_bmesh_get(&em->bm->ldata, l->head.next->data, CD_MLOOPUV); + hit->tf= tf; + hit->efa= efa; + hit->lindex = i; + hit->vert1 = BMINDEX_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++) { - 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; } @@ -642,26 +807,28 @@ 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 = BMIter_AtIndex(NULL, BM_LOOPS_OF_FACE, efa, a); + first= EDBM_get_uv_map_vert(vmap, BMINDEX_GET(l->v)); for(iterv=first; iterv; iterv=iterv->next) { if(iterv->separate) first= iterv; - if(iterv->f == efa->tmp.l) + if(iterv->f == BMINDEX_GET(efa)) return first; } 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 */ @@ -675,8 +842,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_TestFlag(em->bm, efa, EFA_F1_FLAG)) return 0; tot++; @@ -700,8 +867,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_SetFlag(em->bm, efa, EFA_F1_FLAG); break; } } @@ -710,41 +877,47 @@ 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; + BMVert *eve; + 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; + count = 0; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BMINDEX_SET(eve, count); + count++; + } - 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); } - - efa->tmp.l= count; - efa->f1= 0; + + BMO_ClearFlag(em->bm, efa, EFA_F1_FLAG); + BMINDEX_SET(efa, count); + count++; } - + /* 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->vert1); + iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->vert1+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; @@ -755,11 +928,12 @@ 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_TestFlag(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); @@ -767,9 +941,9 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h /* 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_SetFlag(em->bm, efa, EFA_F1_FLAG); uv_vertex_loop_flag(iterv1); uv_vertex_loop_flag(iterv2); @@ -782,16 +956,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= efa->len; + iterv1= uv_vertex_map_get(vmap, hit->efa, hit->vert1); + iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->vert1+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) && uvedit_uv_selected(scene, hit->efa, tf, hit->edge)) + if(uvedit_uv_selected(em, scene, hit->l) && uvedit_uv_selected(em, scene, hit->l)) select= 0; else select= 1; @@ -799,66 +971,82 @@ 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_em_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 a, i, nverts, j, stacksize= 0, *stack; char *flag; - vmap= EM_make_uv_vert_map(em, 1, 1, limit); + vmap= EDBM_make_uv_vert_map(em, 1, 1, limit); if(vmap == NULL) return; - stack= MEM_mallocN(sizeof(*stack)* BLI_countlist(&em->faces), "UvLinkStack"); - flag= MEM_callocN(sizeof(*flag)*BLI_countlist(&em->faces), "UvLinkFlag"); + stack= MEM_mallocN(sizeof(*stack)*em->bm->totface, "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)) { - if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) { - 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++; } } @@ -866,15 +1054,21 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2] stacksize--; a= stack[stacksize]; - for(j=0, efa= em->faces.first; efa; efa= efa->next, j++) + j = 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { if(j==a) break; - nverts= efa->v4? 4: 3; + j++; + } + + nverts= efa->len; + + 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 indicies */ - vlist= EM_get_uv_map_vert(vmap, (*(&efa->v1 + i))->tmp.l); + vlist= EDBM_get_uv_map_vert(vmap, BMINDEX_GET(l->v)); startv= vlist; @@ -890,56 +1084,74 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2] break; else if(!flag[iterv->f]) { flag[iterv->f]= 1; - stack[stacksize]= iterv->f;; + stack[stacksize]= iterv->f; stacksize++; } } + + i++; } } - if(!extend || hit) { - 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 || hit) { + 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; + } } } else if(extend && hit) { - 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); - if(efa->v4) { - if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4))) - break; - } - else if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) + 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 (luv->flag & MLOOPUV_VERTSEL) 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]) 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]) 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); + EDBM_free_uv_vert_map(vmap); } /* ******************** mirror operator **************** */ @@ -993,31 +1205,33 @@ static void weld_align_uv(bContext *C, int tool) Scene *scene; Object *obedit; Image *ima; - EditMesh *em; - EditFace *efa; - MTFace *tf; + BMEditMesh *em; + BMFace *efa; + BMLoop *l; + 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); 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); + 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)) { - 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) + 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) + } } } @@ -1027,41 +1241,39 @@ 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]; + 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]; + 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]; + } + } } } DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - - BKE_mesh_end_editmesh(obedit->data, em); } static int align_exec(bContext *C, wmOperator *op) @@ -1126,16 +1338,19 @@ static int stitch_exec(bContext *C, wmOperator *op) SpaceImage *sima; Scene *scene; Object *obedit; - EditMesh *em; - EditFace *efa; - EditVert *eve; + BMEditMesh *em; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + BMVert *eve; Image *ima; - MTFace *tf; + MTexPoly *tf; + MLoopUV *luv; sima= (SpaceImage*)CTX_wm_space_data(C); 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); if(RNA_boolean_get(op->ptr, "use_limit")) { @@ -1147,15 +1362,15 @@ static int stitch_exec(bContext *C, wmOperator *op) pixels= RNA_float_get(op->ptr, "limit"); uvedit_pixel_to_float(sima, limit, pixels); - EM_init_index_arrays(em, 0, 0, 1); - vmap= EM_make_uv_vert_map(em, 1, 0, limit); + EDBM_init_index_arrays(em, 0, 0, 1); + vmap= EDBM_make_uv_vert_map(em, 1, 0, limit); if(vmap == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } - - for(a=0, eve= em->verts.first; eve; a++, eve= eve->next) { + + a = 0; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { vlist= EM_get_uv_map_vert(vmap, a); while(vlist) { @@ -1166,12 +1381,15 @@ static int stitch_exec(bContext *C, wmOperator *op) if((iterv != vlist) && iterv->separate) break; - efa = EM_get_face_for_index(iterv->f); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + efa = EDBM_get_face_for_index(em, iterv->f); + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if(uvedit_uv_selected(scene, efa, tf, iterv->tfindex)) { - newuv[0] += tf->uv[iterv->tfindex][0]; - newuv[1] += tf->uv[iterv->tfindex][1]; + l = BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex); + if (uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + + newuv[0] += luv->uv[0]; + newuv[1] += luv->uv[1]; vtot++; } } @@ -1183,95 +1401,72 @@ static int stitch_exec(bContext *C, wmOperator *op) if((iterv != vlist) && iterv->separate) break; - efa = EM_get_face_for_index(iterv->f); - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + efa = EDBM_get_face_for_index(em, iterv->f); + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + l = BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex); + if (uvedit_uv_selected(em, scene, l)) { + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - if(uvedit_uv_selected(scene, efa, tf, iterv->tfindex)) { - tf->uv[iterv->tfindex][0]= newuv[0]; - tf->uv[iterv->tfindex][1]= newuv[1]; + luv->uv[0] = newuv[0]; + luv->uv[1] = newuv[1]; + vtot++; } } } vlist= iterv; } + + a++; } - EM_free_uv_vert_map(vmap); - EM_free_index_arrays(); + EDBM_free_uv_vert_map(vmap); + EDBM_free_index_arrays(em); } else { UVVertAverage *uv_average, *uvav; int count; // index and count verts - for(count=0, eve=em->verts.first; eve; count++, eve= eve->next) - eve->tmp.l = count; + count=0; + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BMINDEX_SET(eve, count); + count++; + } uv_average= MEM_callocN(sizeof(UVVertAverage)*count, "Stitch"); // gather uv averages per 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)) { - if(uvedit_uv_selected(scene, efa, tf, 0)) { - uvav = uv_average + efa->v1->tmp.l; - uvav->count++; - uvav->uv[0] += tf->uv[0][0]; - uvav->uv[1] += tf->uv[0][1]; - } - - if(uvedit_uv_selected(scene, efa, tf, 1)) { - uvav = uv_average + efa->v2->tmp.l; - uvav->count++; - uvav->uv[0] += tf->uv[1][0]; - uvav->uv[1] += tf->uv[1][1]; - } - - if(uvedit_uv_selected(scene, efa, tf, 2)) { - uvav = uv_average + efa->v3->tmp.l; - uvav->count++; - uvav->uv[0] += tf->uv[2][0]; - uvav->uv[1] += tf->uv[2][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); + uvav = uv_average + BMINDEX_GET(l->v); - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) { - uvav = uv_average + efa->v4->tmp.l; uvav->count++; - uvav->uv[0] += tf->uv[3][0]; - uvav->uv[1] += tf->uv[3][1]; + uvav->uv[0] += luv->uv[0]; + uvav->uv[1] += luv->uv[1]; } } } // apply uv welding - 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)) { - uvav = uv_average + efa->v1->tmp.l; - tf->uv[0][0] = uvav->uv[0]/uvav->count; - tf->uv[0][1] = uvav->uv[1]/uvav->count; - } - - if(uvedit_uv_selected(scene, efa, tf, 1)) { - uvav = uv_average + efa->v2->tmp.l; - tf->uv[1][0] = uvav->uv[0]/uvav->count; - tf->uv[1][1] = uvav->uv[1]/uvav->count; - } - - if(uvedit_uv_selected(scene, efa, tf, 2)) { - uvav = uv_average + efa->v3->tmp.l; - tf->uv[2][0] = uvav->uv[0]/uvav->count; - tf->uv[2][1] = uvav->uv[1]/uvav->count; - } - - if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) { - uvav = uv_average + efa->v4->tmp.l; - tf->uv[3][0] = uvav->uv[0]/uvav->count; - tf->uv[3][1] = uvav->uv[1]/uvav->count; + 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); + uvav = uv_average + BMINDEX_GET(l->v); + luv->uv[0] = uvav->uv[0]/uvav->count; + luv->uv[1] = uvav->uv[1]/uvav->count; } } } @@ -1282,7 +1477,6 @@ static int stitch_exec(bContext *C, wmOperator *op) DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1309,36 +1503,39 @@ static int select_inverse_exec(bContext *C, wmOperator *op) 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) { - EM_select_swap(em); + EDBM_select_swap(em); } else { - 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_em_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - if(uvedit_face_visible(scene, ima, efa, tf)) { - tf->flag ^= TF_SEL1; - tf->flag ^= TF_SEL2; - tf->flag ^= TF_SEL3; - if(efa->v4) tf->flag ^= TF_SEL4; + 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); + luv->flag = luv->flag ^ MLOOPUV_VERTSEL; } } } WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1361,54 +1558,59 @@ static int de_select_all_exec(bContext *C, wmOperator *op) Scene *scene; ToolSettings *ts; Object *obedit; - EditMesh *em; - EditFace *efa; + BMEditMesh *em; + BMFace *efa; + BMLoop *l; + BMIter iter, liter; Image *ima; - MTFace *tf; - int sel; + MTexPoly *tf; + MLoopUV *luv; + int sel = 1; 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) { EDBM_toggle_select_all(((Mesh*)obedit->data)->edit_btmesh); } else { - sel= 0; + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); - 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)) + continue; - if(uvedit_face_visible(scene, ima, efa, tf)) { - if(tf->flag & (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4)) { - sel= 1; + 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) { + sel= 0; break; } } } - 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)) { - if(efa->v4) { - if(sel) tf->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4); - else tf->flag |= (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4); - } - else { - if(sel) tf->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4); - else tf->flag |= (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); + + if (sel) luv->flag |= MLOOPUV_VERTSEL; + else luv->flag &= ~MLOOPUV_VERTSEL; } } } WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1426,7 +1628,7 @@ void UV_OT_select_all_toggle(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; @@ -1435,7 +1637,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(fabs(hituv[i][0]-uv[0]) < limit[0] && fabs(hituv[i][1]-uv[1]) < limit[1]) @@ -1456,14 +1658,20 @@ 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 a, i, select = 1, selectmode, sticky, sync, *hitv=NULL, nvert; + V_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; + V_DECLARE(hituv); + float penalty[2]; + uvedit_pixel_to_float(sima, limit, 0.05f); uvedit_pixel_to_float(sima, penalty, 5.0f); @@ -1491,76 +1699,88 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) /* find edge */ find_nearest_uv_edge(scene, ima, em, co, &hit); if(hit.efa == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } + + hitlen = 0; } else if(selectmode == UV_SELECT_VERTEX) { /* find vertex */ find_nearest_uv_vert(scene, ima, em, co, penalty, &hit); if(hit.efa == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } /* mark 1 vertex as being hit */ - for(i=0; i<4; i++) + for(i=0; i<hit.efa->len; i++) { + V_GROW(hitv); + V_GROW(hituv); hitv[i]= 0xFFFFFFFF; + } + + hitv[hit.lindex]= hit.vert1; + hituv[hit.lindex]= hit.luv->uv; - hitv[hit.uv]= hit.vert; - hituv[hit.uv]= hit.tf->uv[hit.uv]; + hitlen = hit.efa->len; } else if(selectmode == UV_SELECT_EDGE) { /* find edge */ find_nearest_uv_edge(scene, ima, em, co, &hit); if(hit.efa == NULL) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } /* mark 2 edge vertices as being hit */ - for(i=0; i<4; i++) + for(i=0; i<hit.efa->len; i++) { + V_GROW(hitv); + V_GROW(hituv); 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); return OPERATOR_CANCELLED; } /* make active */ - EM_set_actFace(em, hit.efa); + EDBM_set_actFace(em, hit.efa); /* mark all face vertices as being hit */ - for(i=0; i<4; i++) - hituv[i]= hit.tf->uv[i]; + 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); - hitv[0]= hit.efa->v1->tmp.l; - hitv[1]= hit.efa->v2->tmp.l; - hitv[2]= hit.efa->v3->tmp.l; + V_GROW(hitv); + V_GROW(hituv); + hituv[i]= luv->uv; + hitv[i] = BMINDEX_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) { find_nearest_uv_vert(scene, ima, em, co, NULL, &hit); if(hit.efa==NULL) { - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } + + hitlen = 0; } else { - BKE_mesh_end_editmesh(obedit->data, em); + hitlen = 0; return OPERATOR_CANCELLED; } @@ -1574,36 +1794,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; @@ -1611,97 +1831,89 @@ 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; + BMVert *ev; + a = 0; + BM_ITER(ev, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + BMINDEX_SET(ev, a); + a++; + } + /* 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_em_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, BMINDEX_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, BMINDEX_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_em_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, BMINDEX_GET(l->v), hituv, luv->uv, sticky, hitlen)) + uvedit_uv_select(em, scene, l); flush= 1; } } } } - +#if 0 //bmesh does flushing through the BM_Select functions, so not sure + //what to do about this bit. if(sync) { /* flush for mesh selection */ if(ts->selectmode != SCE_SELECT_FACE) { @@ -1709,11 +1921,10 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop) else if(flush==-1) EM_deselect_flush(em); } } - +#endif DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED; } @@ -1820,13 +2031,12 @@ static int select_linked_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); + BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; float limit[2]; int extend; 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; } @@ -1837,7 +2047,6 @@ static int select_linked_exec(bContext *C, wmOperator *op) DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1865,27 +2074,38 @@ 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)) { - if(efa->v4) { - if(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + 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->pdata, l->head.data, CD_MLOOPUV); + + if (!(luv->flag & MLOOPUV_VERTSEL)) { + desel = 1; + break; } - else { - if(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) - tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3); + } + + if (desel) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + luv = CustomData_bmesh_get(&em->bm->pdata, l->head.data, CD_MLOOPUV); + luv->flag &= ~MLOOPUV_VERTSEL; } } } @@ -1893,7 +2113,6 @@ static int unlink_selection_exec(bContext *C, wmOperator *op) DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -1927,78 +2146,77 @@ 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) + BMINDEX_SET(eve, 0); - 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(BMINDEX_GET(efa)) { + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + BMINDEX_SET(l->v, 1); + } } } /* 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); + + BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) { + if (BMINDEX_GET(l->v)) { + 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; UvMapVert *start_vlist=NULL, *vlist_iter; struct UvVertMap *vmap; float limit[2]; 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 = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL); + for (efa_index=0; efa; efa=BMIter_Step(&iter), efa_index++) { + if(BMINDEX_GET(efa)) { + tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); + + 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, BMINDEX_GET(l->v)); while (vlist_iter) { if(vlist_iter->separate) @@ -2017,35 +2235,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); if(select) - uvedit_uv_select(scene, efa_vlist, tf_vlist, vlist_iter->tfindex); + uvedit_uv_select(em, scene, BMIter_AtIndex(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, BMIter_AtIndex(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(BMINDEX_GET(efa)) { 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) @@ -2056,9 +2272,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; @@ -2088,14 +2307,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); + BMINDEX_SET(efa, 0); + + 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; + BMINDEX_SET(efa, 1); + change = 1; } } } @@ -2107,51 +2328,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, 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(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((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); } } } @@ -2160,20 +2356,20 @@ static int border_select_exec(bContext *C, wmOperator *op) if(change) { /* make sure newly selected vert selection is updated*/ +#if 0 //ok, I think the BM_Select 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); } } +#endif WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_CANCELLED; } @@ -2204,20 +2400,23 @@ void UV_OT_select_border(wmOperatorType *ot) /* ******************** circle select operator **************** */ -static void select_uv_inside_ellipse(SpaceImage *sima, 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 *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.0) { - 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); } } @@ -2226,10 +2425,13 @@ int circle_select_exec(bContext *C, wmOperator *op) SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(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; + MTexPoly *tface; int x, y, radius, width, height, select; float zoomx, zoomy, offset[2], ellipse[2]; @@ -2250,21 +2452,19 @@ 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(sima, scene, select, efa, tface, 0, offset, ellipse, 0); - select_uv_inside_ellipse(sima, scene, select, efa, tface, 1, offset, ellipse, 1); - select_uv_inside_ellipse(sima, scene, select, efa, tface, 2, offset, ellipse, 2); - if(efa->v4) - select_uv_inside_ellipse(sima, 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_Select 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_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; } @@ -2362,30 +2562,34 @@ void UV_OT_snap_cursor(wmOperatorType *ot) static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, View2D *v2d) { - 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)) VECCOPY2D(tface->uv[0], v2d->cursor); - if(uvedit_uv_selected(scene, efa, tface, 1)) VECCOPY2D(tface->uv[1], v2d->cursor); - if(uvedit_uv_selected(scene, efa, tface, 2)) VECCOPY2D(tface->uv[2], v2d->cursor); - if(efa->v4) - if(uvedit_uv_selected(scene, efa, tface, 3)) VECCOPY2D(tface->uv[3], v2d->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); + VECCOPY2D(luv->uv, v2d->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) { +#if 0 EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); EditFace *efa; EditVert *eve; @@ -2405,11 +2609,11 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe 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(uvedit_uv_selected(em, scene, efa, tface, 0) && efa->v1->tmp.l==-1) efa->v1->tmp.l= count++; + if(uvedit_uv_selected(em, scene, efa, tface, 1) && efa->v2->tmp.l==-1) efa->v2->tmp.l= count++; + if(uvedit_uv_selected(em, 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++; + if(uvedit_uv_selected(em, scene, efa, tface, 3) && efa->v4->tmp.l==-1) efa->v4->tmp.l= count++; change = 1; @@ -2427,19 +2631,19 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe 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))) { + if(efa->v1->tmp.l >= 0 && (!uvedit_uv_selected(em, 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))) { + if(efa->v2->tmp.l >= 0 && (!uvedit_uv_selected(em, 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))) { + if(efa->v3->tmp.l >= 0 && (!uvedit_uv_selected(em, 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]++; @@ -2447,7 +2651,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe } if(efa->v4) { - if(efa->v4->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 3))) { + if(efa->v4->tmp.l >= 0 && (!uvedit_uv_selected(em, 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]++; @@ -2469,7 +2673,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe for(efa= em->faces.first; efa; efa= efa->next) { if((tface=(MTFace *)efa->tmp.p)) { - if( uvedit_uv_selected(scene, efa, tface, 0) && + if( uvedit_uv_selected(em, scene, efa, tface, 0) && efa->v1->tmp.l >= 0 && (users = usercount[efa->v1->tmp.l]) ) { @@ -2477,7 +2681,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe tface->uv[0][1] = coords[(efa->v1->tmp.l*2)+1] / users; } - if( uvedit_uv_selected(scene, efa, tface, 1) && + if( uvedit_uv_selected(em, scene, efa, tface, 1) && efa->v2->tmp.l >= 0 && (users = usercount[efa->v2->tmp.l]) ) { @@ -2485,7 +2689,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe tface->uv[1][1] = coords[(efa->v2->tmp.l*2)+1] / users; } - if( uvedit_uv_selected(scene, efa, tface, 2) && + if( uvedit_uv_selected(em, scene, efa, tface, 2) && efa->v3->tmp.l >= 0 && (users = usercount[efa->v3->tmp.l]) ) { @@ -2494,7 +2698,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe } if(efa->v4) { - if( uvedit_uv_selected(scene, efa, tface, 3) && + if( uvedit_uv_selected(em, scene, efa, tface, 3) && efa->v4->tmp.l >= 0 && (users = usercount[efa->v4->tmp.l]) ) { @@ -2510,10 +2714,12 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe BKE_mesh_end_editmesh(obedit->data, em); return change; +#endif } static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) { +#if 0 EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data); Image *ima= sima->image; EditFace *efa; @@ -2529,11 +2735,11 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) 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(uvedit_uv_selected(em, scene, efa, tface, 0)) snap_uv_to_pixel(tface->uv[0], w, h); + if(uvedit_uv_selected(em, scene, efa, tface, 1)) snap_uv_to_pixel(tface->uv[1], w, h); + if(uvedit_uv_selected(em, 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); + if(uvedit_uv_selected(em, scene, efa, tface, 3)) snap_uv_to_pixel(tface->uv[3], w, h); change = 1; } @@ -2541,6 +2747,7 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) BKE_mesh_end_editmesh(obedit->data, em); return change; +#endif } static int snap_selection_exec(bContext *C, wmOperator *op) @@ -2598,6 +2805,7 @@ void UV_OT_snap_selection(wmOperatorType *ot) static int pin_exec(bContext *C, wmOperator *op) { +#if 0 Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(C); @@ -2611,18 +2819,18 @@ static int pin_exec(bContext *C, wmOperator *op) if(uvedit_face_visible(scene, ima, efa, tface)) { 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(uvedit_uv_selected(em, scene, efa, tface, 0)) tface->unwrap |= TF_PIN1; + if(uvedit_uv_selected(em, scene, efa, tface, 1)) tface->unwrap |= TF_PIN2; + if(uvedit_uv_selected(em, 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, 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(uvedit_uv_selected(em, scene, efa, tface, 0)) tface->unwrap &= ~TF_PIN1; + if(uvedit_uv_selected(em, scene, efa, tface, 1)) tface->unwrap &= ~TF_PIN2; + if(uvedit_uv_selected(em, 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, efa, tface, 3)) tface->unwrap &= ~TF_PIN4; } } } @@ -2631,6 +2839,7 @@ static int pin_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; +#endif } void UV_OT_pin(wmOperatorType *ot) @@ -2652,6 +2861,7 @@ void UV_OT_pin(wmOperatorType *ot) static int select_pinned_exec(bContext *C, wmOperator *op) { +#if 0 Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); Image *ima= CTX_data_edit_image(C); @@ -2676,6 +2886,7 @@ static int select_pinned_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; +#endif } void UV_OT_select_pinned(wmOperatorType *ot) @@ -2694,6 +2905,7 @@ void UV_OT_select_pinned(wmOperatorType *ot) static int hide_exec(bContext *C, wmOperator *op) { +#if 0 SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); @@ -2817,6 +3029,7 @@ static int hide_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; +#endif } void UV_OT_hide(wmOperatorType *ot) @@ -2838,6 +3051,7 @@ void UV_OT_hide(wmOperatorType *ot) static int reveal_exec(bContext *C, wmOperator *op) { +#if 0 SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); ToolSettings *ts= CTX_data_tool_settings(C); Object *obedit= CTX_data_edit_object(C); @@ -2948,6 +3162,7 @@ static int reveal_exec(bContext *C, wmOperator *op) BKE_mesh_end_editmesh(obedit->data, em); return OPERATOR_FINISHED; +#endif } void UV_OT_reveal(wmOperatorType *ot) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 94713cf0d76..f54aee1dfc0 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -95,8 +95,14 @@ typedef struct MTexPoly{ typedef struct MLoopUV{ float uv[2]; + int flag; }MLoopUV; +/*mloopuv->flag*/ +#define MLOOPUV_EDGESEL 1 +#define MLOOPUV_VERTSEL 2 +#define MLOOPUV_PINNED 4 + typedef struct MLoopCol{ char a, r, g, b; int pad; /*waste!*/ |