1 #include "MEM_guardedalloc.h"
2 #include "BKE_customdata.h"
3 #include "DNA_listBase.h"
4 #include "DNA_meshdata_types.h"
5 #include "DNA_object_types.h"
6 #include "DNA_scene_types.h"
8 #include "BKE_utildefines.h"
10 #include "BKE_global.h"
11 #include "BKE_DerivedMesh.h"
12 #include "BKE_cdderivedmesh.h"
14 #include "BLI_editVert.h"
15 #include "mesh_intern.h"
18 #include "BLI_blenlib.h"
19 #include "BLI_edgehash.h"
26 * This file contains functions for converting
27 * from a bmesh to an editmesh
32 * LOOPS TO EDITMESH CORNERS
34 * Converts N-Gon loop (face-edge)
35 * data (UVs, Verts Colors, ect) to
40 static void loops_to_editmesh_corners(BMesh *bm, CustomData *facedata, void *face_block, BMFace *f,int numCol, int numTex){
49 for(i=0; i < numTex; i++){
50 texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
51 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
53 texface->tpage = texpoly->tpage;
54 texface->flag = texpoly->flag;
55 texface->transp = texpoly->transp;
56 texface->mode = texpoly->mode;
57 texface->tile = texpoly->tile;
58 texface->unwrap = texpoly->unwrap;
63 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
64 texface->uv[j][0] = mloopuv->uv[0];
65 texface->uv[j][1] = mloopuv->uv[1];
67 l = ((BMLoop*)(l->head.next));
68 } while(l!=f->loopbase);
72 for(i=0; i < numCol; i++){
73 mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
77 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
78 mcol[j].r = mloopcol->r;
79 mcol[j].g = mloopcol->g;
80 mcol[j].b = mloopcol->b;
81 mcol[j].a = mloopcol->a;
83 l = ((BMLoop*)(l->head.next));
84 } while(l!=f->loopbase);
88 static EditVert *bmeshvert_to_editvert(BMesh *bm, EditMesh *em, BMVert *v, int index, EditVert **evlist)
92 v->head.eflag1 = index; /*abuse!*/
93 eve = addvertlist(em, v->co, NULL);
94 eve->keyindex = index;
98 if(v->head.flag & BM_HIDDEN) eve->h = 1;
99 if (v->head.flag & BM_SELECT) eve->f |= SELECT;
101 eve->bweight = v->bweight;
102 CustomData_em_copy_data(&bm->vdata, &em->vdata, v->data, &eve->data);
104 eve->no[0] = v->no[0];
105 eve->no[1] = v->no[1];
106 eve->no[2] = v->no[2];
111 static void bmeshedge_to_editedge_internal(BMesh *bm, EditMesh *em, BMEdge *e, EditEdge *eed)
113 eed->crease = e->crease;
114 eed->bweight = e->bweight;
116 //copy relavent flags
117 if (e->head.flag & BM_SELECT) eed->f |= SELECT;
118 if (e->head.flag & BM_SEAM) eed->seam = 1;
119 if (e->head.flag & BM_SHARP) eed->sharp = 1;
120 if (e->head.flag & BM_HIDDEN) eed->h = 1;
121 if (e->head.flag & BM_FGON) eed->h |= EM_FGON;
123 CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
126 static EditEdge *bmeshedge_to_editedge(BMesh *bm, EditMesh *em, BMEdge *e, EditVert **evlist)
128 EditEdge *eed = NULL;
130 if(!(findedgelist(em, evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1]))){
131 eed= addedgelist(em, evlist[e->v1->head.eflag1], evlist[e->v2->head.eflag1], NULL);
132 bmeshedge_to_editedge_internal(bm, em, e, eed);
138 static EditFace *bmeshface_to_editface(BMesh *bm, EditMesh *em, BMFace *f, EditVert **evlist, int numCol, int numTex)
140 EditVert *eve1, *eve2, *eve3, *eve4;
141 EditFace *efa = NULL;
146 eve1= evlist[f->loopbase->v->head.eflag1];
147 eve2= evlist[((BMLoop*)(f->loopbase->head.next))->v->head.eflag1];
148 eve3= evlist[((BMLoop*)(f->loopbase->head.next->next))->v->head.eflag1];
150 eve4= evlist[ ((BMLoop*)(f->loopbase->head.prev))->v->head.eflag1];
156 if (eve1==eve2 || eve1==eve3 || eve1==eve4 || eve2==eve3 || eve3==eve4
157 || eve2==eve4) return NULL;
159 efa = addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);
160 if (!efa) return NULL;
162 bmeshedge_to_editedge_internal(bm, em, f->loopbase->e, efa->e1);
163 bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->loopbase->head.next))->e, efa->e2);
164 bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->loopbase->head.next->next))->e, efa->e3);
166 bmeshedge_to_editedge_internal(bm, em, ((BMLoop*)(f->loopbase->head.prev))->e, efa->e4);
168 efa->mat_nr = (unsigned char)f->mat_nr;
171 efa->n[0] = f->no[0];
172 efa->n[1] = f->no[1];
173 efa->n[2] = f->no[2];
175 //copy relavent original flags
176 if (f->head.flag & BM_SELECT) efa->f |= SELECT;
177 if (f->head.flag & BM_HIDDEN) efa->h = 1;
178 if (f->head.flag & BM_SMOOTH) efa->flag |= ME_SMOOTH;
179 if (f->head.flag & BM_ACTIVE) EM_set_actFace(em, efa);
181 CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
182 loops_to_editmesh_corners(bm, &em->fdata, efa->data, f, numCol,numTex);
187 EditMesh *bmesh_to_editmesh_intern(BMesh *bm)
198 EditVert *eve, **evlist;
200 int totvert, i, numTex, numCol;
202 em = MEM_callocN(sizeof(EditMesh), "EditMesh from bmesh");
204 if(bm->selectmode & BM_VERT) em->selectmode |= SCE_SELECT_VERTEX;
205 if(bm->selectmode & BM_EDGE) em->selectmode |= SCE_SELECT_EDGE;
206 if(bm->selectmode & BM_FACE) em->selectmode |= SCE_SELECT_FACE;
208 CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
209 CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0);
210 CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, CD_CALLOC, 0);
211 CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata,0);
212 numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
213 numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
215 totvert = BM_Count_Element(bm, BM_VERT);
216 evlist= MEM_mallocN(totvert*sizeof(EditVert *),"evlist");
219 for(i=0, v = BMIter_New(&verts, bm, BM_VERTS, bm); v; v = BMIter_Step(&verts), i++)
220 eve = bmeshvert_to_editvert(bm, em, v, i, evlist);
223 for(e = BMIter_New(&edges, bm, BM_EDGES, bm); e; e = BMIter_Step(&edges))
224 bmeshedge_to_editedge(bm, em, e, evlist);
227 for(f = BMIter_New(&faces, bm, BM_FACES, bm); f; f = BMIter_Step(&faces))
228 bmeshface_to_editface(bm, em, f, evlist, numCol, numTex);
234 EM_nvertices_selected(em);
235 EM_nedges_selected(em);
236 EM_nfaces_selected(em);
241 void bmesh2edit_exec(BMesh *bmesh, BMOperator *op)
243 BMO_Set_Pnt(op, BMOP_TO_EDITMESH_EMOUT, bmesh_to_editmesh_intern(bmesh));
248 void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op)
257 BMO_Init_Op(&triop, BMOP_TRIANGULATE);
259 /*HACK: I don't know if this'll conflict with other flags at all!*/
260 for (face = BMIter_New(&iter, bmesh, BM_FACES, NULL); face; face=BMIter_Step(&iter)) {
262 BMO_SetFlag(bmesh, face, FACE_NGON);
266 BMO_Flag_To_Slot(bmesh, &triop, BMOP_TRIANG_FACEIN, FACE_NGON, BM_FACE);
267 BMO_Exec_Op(bmesh, &triop);
269 eout = BMO_GetSlot(&triop, BMOP_TRIANG_NEW_EDGES);
270 for (i=0; i<eout->len; i++) {
271 edge = ((BMEdge**)eout->data.buf)[i];
272 edge->head.flag |= BM_FGON;
275 BMO_Finish_Op(bmesh, &triop);
278 EditMesh *bmesh_to_editmesh(BMesh *bmesh)
280 BMOperator conv, makefgon;
283 /*first fgon-afy the mesh*/
284 BMO_Init_Op(&makefgon, BMOP_MAKE_FGONS);
285 BMO_Exec_Op(bmesh, &makefgon);
286 BMO_Finish_Op(bmesh, &makefgon);
288 BMO_Init_Op(&conv, BMOP_TO_EDITMESH);
289 BMO_Exec_Op(bmesh, &conv);
290 em = conv.slots[BMOP_TO_EDITMESH_EMOUT].data.p;
291 BMO_Finish_Op(bmesh, &conv);