#if 0 #include "MEM_guardedalloc.h" #include "BKE_customdata.h" #include "DNA_listBase.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include #include "BKE_utildefines.h" #include "BKE_mesh.h" #include "BKE_global.h" #include "BKE_DerivedMesh.h" #include "BKE_cdderivedmesh.h" #include "BLI_editVert.h" #include "mesh_intern.h" #include "ED_mesh.h" #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_array.h" #include "BLI_array.h" #include "bmesh.h" /* * BMESH TO EDITMESH * * This file contains functions for converting * from a bmesh to an editmesh * */ /* * LOOPS TO EDITMESH CORNERS * * Converts N-Gon loop (face-edge) * data (UVs, Verts Colors, ect) to * face corner data. * */ static void loops_to_editmesh_corners(BMesh *bm, CustomData *facedata, void *face_block, BMFace *f,int numCol, int numTex){ int i, j; BMLoop *l; MTFace *texface; MTexPoly *texpoly; MCol *mcol; MLoopCol *mloopcol; MLoopUV *mloopuv; for(i=0; i < numTex; i++){ texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i); texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i); texface->tpage = texpoly->tpage; texface->flag = texpoly->flag; texface->transp = texpoly->transp; texface->mode = texpoly->mode; texface->tile = texpoly->tile; texface->unwrap = texpoly->unwrap; j = 0; l = f->loopbase; do { mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i); texface->uv[j][0] = mloopuv->uv[0]; texface->uv[j][1] = mloopuv->uv[1]; j++; l = ((BMLoop*)(l->next)); } while(l!=f->lbase); } for(i=0; i < numCol; i++){ mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i); j = 0; l = f->loopbase; do { mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i); mcol[j].r = mloopcol->r; mcol[j].g = mloopcol->g; mcol[j].b = mloopcol->b; mcol[j].a = mloopcol->a; j++; l = ((BMLoop*)(l->next)); } while(l!=f->lbase); } } static EditVert *bmeshvert_to_editvert(BMesh *bm, EditMesh *em, BMVert *v, int index, EditVert **evlist) { EditVert *eve = NULL; v->head.eflag1 = index; /*abuse!*/ eve = addvertlist(em, v->co, NULL); eve->keyindex = index; evlist[index]= eve; /*copy flags*/ if(v->head.flag & BM_HIDDEN) eve->h = 1; if (v->head.flag & BM_SELECT) eve->f |= SELECT; eve->bweight = v->bweight; CustomData_em_copy_data(&bm->vdata, &em->vdata, v->head.data, &eve->data); /*copy normal*/ eve->no[0] = v->no[0]; eve->no[1] = v->no[1]; eve->no[2] = v->no[2]; return eve; } static void bmeshedge_to_editedge_internal(BMesh *bm, EditMesh *em, BMEdge *e, EditEdge *eed) { eed->crease = e->crease; eed->bweight = e->bweight; //copy relavent flags if (e->head.flag & BM_SELECT) eed->f |= SELECT; if (e->head.flag & BM_SEAM) eed->seam = 1; if (e->head.flag & BM_SHARP) eed->sharp = 1; if (e->head.flag & BM_HIDDEN) eed->h = 1; if (e->head.flag & BM_FGON) eed->h |= EM_FGON; CustomData_em_copy_data(&bm->edata, &em->edata, e->head.data, &eed->data); } static EditEdge *bmeshedge_to_editedge(BMesh *bm, EditMesh *em, BMEdge *e, EditVert **evlist) { EditEdge *eed = NULL; if(!(findedgelist(em, evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1]))){ eed= addedgelist(em, evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1], NULL); bmeshedge_to_editedge_internal(bm, em, e, eed); } return eed; } static EditFace *bmeshface_to_editface(BMesh *bm, EditMesh *em, BMFace *f, EditVert **evlist, int numCol, int numTex) { EditVert *eve1, *eve2, *eve3, *eve4; EditFace *efa = NULL; int len; len = f->len; eve1= evlist[f->lbase->v->head.eflag1]; eve2= evlist[((BMLoop*)(f->lbase->next))->v->head.eflag1]; eve3= evlist[((BMLoop*)(f->lbase->next->next))->v->head.eflag1]; if (len == 4) { eve4= evlist[ ((BMLoop*)(f->lbase->prev))->v->head.eflag1]; } else { eve4= NULL; } if (eve1==eve2 || eve1==eve3 || eve1==eve4 || eve2==eve3 || eve3==eve4 || eve2==eve4) return NULL; efa = addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL); if (!efa) return NULL; bmeshedge_to_editedge_internal(bm, em, f->lbase->e, efa->e1); bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->lbase->next))->e, efa->e2); bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->lbase->next->next))->e, efa->e3); if(eve4) bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->lbase->prev))->e, efa->e4); efa->mat_nr = (unsigned char)f->mat_nr; /*Copy normal*/ efa->n[0] = f->no[0]; efa->n[1] = f->no[1]; efa->n[2] = f->no[2]; //copy relavent original flags if (f->head.flag & BM_SELECT) efa->f |= SELECT; if (f->head.flag & BM_HIDDEN) efa->h = 1; if (f->head.flag & BM_SMOOTH) efa->flag |= ME_SMOOTH; if (f->head.flag & BM_ACTIVE) EM_set_actFace(em, efa); CustomData_em_copy_data(&bm->pdata, &em->fdata, f->head.data, &efa->data); loops_to_editmesh_corners(bm, &em->fdata, efa->data, f, numCol,numTex); return efa; } EditMesh *bmesh_to_editmesh_intern(BMesh *bm) { BMVert *v; BMEdge *e; BMFace *f; BMIter verts; BMIter edges; BMIter faces; EditMesh *em; EditVert *eve, **evlist; int totvert, i, numTex, numCol, flag; em = MEM_callocN(sizeof(EditMesh), "EditMesh from bmesh"); em->selectmode = bm->selectmode; flag = CD_MASK_BMESH & ~CD_MASK_MTEXPOLY; CustomData_copy(&bm->vdata, &em->vdata, flag, CD_CALLOC, 0); CustomData_copy(&bm->edata, &em->edata, flag, CD_CALLOC, 0); CustomData_copy(&bm->pdata, &em->fdata, flag, CD_CALLOC, 0); CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata,0); numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); totvert = BM_Count_Element(bm, BM_VERT); evlist= MEM_mallocN(totvert*sizeof(EditVert *),"evlist"); /* make vertices */ for(i=0, v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm); v; v = BMIter_Step(&verts), i++) eve = bmeshvert_to_editvert(bm, em, v, i, evlist); /* make edges */ for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&edges)) bmeshedge_to_editedge(bm, em, e, evlist); /* make faces */ for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm); f; f = BMIter_Step(&faces)) bmeshface_to_editface(bm, em, f, evlist, numCol, numTex); MEM_freeN(evlist); EM_fgon_flags(em); EM_nvertices_selected(em); EM_nedges_selected(em); EM_nfaces_selected(em); return em; } void bmesh2edit_exec(BMesh *bmesh, BMOperator *op) { BMO_Set_Pnt(op, "emout", bmesh_to_editmesh_intern(bmesh)); } #define FACE_NGON 1 void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op) { BMOperator triop; BMFace *face; BMIter iter, liter; BMEdge *edge; BMLoop *l, *nl; BMOpSlot *eout; int i, trifan = BMO_Get_Int(op, "trifan"); if (!trifan) BMO_Init_Op(&triop, "triangulate"); /*instead of properly tesselate, just make a triangle fan, this should make bmesh -> editmesh -> bmesh conversions always properly work.*/ for (face = BMIter_New(&iter, bmesh, BM_FACES_OF_MESH, NULL); face; face=BMIter_Step(&iter)) { if (face->len > 4) { BMO_SetFlag(bmesh, face, FACE_NGON); if (trifan) { while (face->len > 4) { face = BM_Split_Face(bmesh, face, face->lbase->v, ((BMLoop*)face->lbase->next->next)->v, &nl, NULL); BM_SetHFlag(nl->e, BM_FGON); } } } } if (!trifan) { BMO_Flag_To_Slot(bmesh, &triop, "faces", FACE_NGON, BM_FACE); BMO_Exec_Op(bmesh, &triop); eout = BMO_GetSlot(&triop, "edgeout"); for (i=0; ilen; i++) { edge = ((BMEdge**)eout->data.buf)[i]; edge->head.flag |= BM_FGON; face = BMIter_New(&iter, bmesh, BM_FACES_OF_EDGE, edge); for (; face; face=BMIter_Step(&iter)) { face->head.flag |= BM_NONORMCALC; } } BMO_Finish_Op(bmesh, &triop); } } EditMesh *bmesh_to_editmesh(BMesh *bmesh) { BMOperator conv, makefgon; EditMesh *em; /*first fgon-afy the mesh*/ BMO_Init_Op(&makefgon, "makefgon"); BMO_Set_Int(&makefgon, "trifan", 1); BMO_Exec_Op(bmesh, &makefgon); BMO_Finish_Op(bmesh, &makefgon); BMO_Init_Op(&conv, "bmesh_to_editmesh"); BMO_Exec_Op(bmesh, &conv); em = BMO_Get_Pnt(&conv, "emout"); BMO_Finish_Op(bmesh, &conv); return em; } #endif