Blender V2.61 - r43446
|
00001 /* 00002 * BME_mesh.c jan 2007 00003 * 00004 * BMesh mesh level functions. 00005 * 00006 * 00007 * ***** BEGIN GPL LICENSE BLOCK ***** 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License 00011 * as published by the Free Software Foundation; either version 2 00012 * of the License, or (at your option) any later version. 00013 * about this. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software Foundation, 00022 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00023 * 00024 * The Original Code is Copyright (C) 2007 Blender Foundation. 00025 * All rights reserved. 00026 * 00027 * The Original Code is: all of this file. 00028 * 00029 * Contributor(s): Geoffrey Bantle, Levi Schooley. 00030 * 00031 * ***** END GPL LICENSE BLOCK ***** 00032 */ 00033 00039 #include "MEM_guardedalloc.h" 00040 00041 #include "DNA_meshdata_types.h" 00042 #include "DNA_object_types.h" 00043 #include "DNA_scene_types.h" 00044 00045 #include "BLI_edgehash.h" 00046 #include "BLI_listbase.h" 00047 #include "BLI_utildefines.h" 00048 00049 #include "BKE_mesh.h" 00050 #include "BKE_cdderivedmesh.h" 00051 00052 //XXX #include "BIF_editmesh.h" 00053 //XXX #include "editmesh.h" 00054 #include "bmesh_private.h" 00055 00056 //XXX #include "BSE_edit.h" 00057 00058 /* XXX IMPORTANT: editmesh stuff doesn't belong in kernel! (ton) */ 00059 00060 /*merge these functions*/ 00061 static void BME_DMcorners_to_loops(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f, int numCol, int numTex){ 00062 int i, j; 00063 BME_Loop *l; 00064 MTFace *texface; 00065 MTexPoly *texpoly; 00066 MCol *mcol; 00067 MLoopCol *mloopcol; 00068 MLoopUV *mloopuv; 00069 00070 for(i=0; i< numTex; i++){ 00071 texface = CustomData_get_layer_n(facedata, CD_MTFACE, i); 00072 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); 00073 00074 texpoly->tpage = texface[index].tpage; 00075 texpoly->flag = texface[index].flag; 00076 texpoly->transp = texface[index].transp; 00077 texpoly->mode = texface[index].mode; 00078 texpoly->tile = texface[index].tile; 00079 texpoly->unwrap = texface[index].unwrap; 00080 00081 j = 0; 00082 l = f->loopbase; 00083 do{ 00084 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); 00085 mloopuv->uv[0] = texface[index].uv[j][0]; 00086 mloopuv->uv[1] = texface[index].uv[j][1]; 00087 j++; 00088 l = l->next; 00089 }while(l!=f->loopbase); 00090 } 00091 00092 for(i=0; i < numCol; i++){ 00093 mcol = CustomData_get_layer_n(facedata, CD_MCOL, i); 00094 j = 0; 00095 l = f->loopbase; 00096 do{ 00097 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); 00098 mloopcol->r = mcol[(index*4)+j].r; 00099 mloopcol->g = mcol[(index*4)+j].g; 00100 mloopcol->b = mcol[(index*4)+j].b; 00101 mloopcol->a = mcol[(index*4)+j].a; 00102 j++; 00103 l = l->next; 00104 }while(l!=f->loopbase); 00105 } 00106 } 00107 00108 static void BME_DMloops_to_corners(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f,int numCol, int numTex){ 00109 int i, j; 00110 BME_Loop *l; 00111 MTFace *texface; 00112 MTexPoly *texpoly; 00113 MCol *mcol; 00114 MLoopCol *mloopcol; 00115 MLoopUV *mloopuv; 00116 00117 for(i=0; i < numTex; i++){ 00118 texface = CustomData_get_layer_n(facedata, CD_MTFACE, i); 00119 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); 00120 00121 texface[index].tpage = texpoly->tpage; 00122 texface[index].flag = texpoly->flag; 00123 texface[index].transp = texpoly->transp; 00124 texface[index].mode = texpoly->mode; 00125 texface[index].tile = texpoly->tile; 00126 texface[index].unwrap = texpoly->unwrap; 00127 00128 j = 0; 00129 l = f->loopbase; 00130 do{ 00131 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); 00132 texface[index].uv[j][0] = mloopuv->uv[0]; 00133 texface[index].uv[j][1] = mloopuv->uv[1]; 00134 j++; 00135 l = l->next; 00136 }while(l!=f->loopbase); 00137 00138 } 00139 for(i=0; i < numCol; i++){ 00140 mcol = CustomData_get_layer_n(facedata,CD_MCOL, i); 00141 j = 0; 00142 l = f->loopbase; 00143 do{ 00144 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); 00145 mcol[(index*4) + j].r = mloopcol->r; 00146 mcol[(index*4) + j].g = mloopcol->g; 00147 mcol[(index*4) + j].b = mloopcol->b; 00148 mcol[(index*4) + j].a = mloopcol->a; 00149 j++; 00150 l = l->next; 00151 }while(l!=f->loopbase); 00152 } 00153 } 00154 00155 00156 static void BME_corners_to_loops(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){ 00157 int i, j; 00158 BME_Loop *l; 00159 MTFace *texface; 00160 MTexPoly *texpoly; 00161 MCol *mcol; 00162 MLoopCol *mloopcol; 00163 MLoopUV *mloopuv; 00164 00165 for(i=0; i < numTex; i++){ 00166 texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i); 00167 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); 00168 00169 texpoly->tpage = texface->tpage; 00170 texpoly->flag = texface->flag; 00171 texpoly->transp = texface->transp; 00172 texpoly->mode = texface->mode; 00173 texpoly->tile = texface->tile; 00174 texpoly->unwrap = texface->unwrap; 00175 00176 j = 0; 00177 l = f->loopbase; 00178 do{ 00179 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); 00180 mloopuv->uv[0] = texface->uv[j][0]; 00181 mloopuv->uv[1] = texface->uv[j][1]; 00182 j++; 00183 l = l->next; 00184 }while(l!=f->loopbase); 00185 00186 } 00187 for(i=0; i < numCol; i++){ 00188 mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i); 00189 j = 0; 00190 l = f->loopbase; 00191 do{ 00192 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); 00193 mloopcol->r = mcol[j].r; 00194 mloopcol->g = mcol[j].g; 00195 mloopcol->b = mcol[j].b; 00196 mloopcol->a = mcol[j].a; 00197 j++; 00198 l = l->next; 00199 }while(l!=f->loopbase); 00200 } 00201 } 00202 00203 static void BME_loops_to_corners(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){ 00204 int i, j; 00205 BME_Loop *l; 00206 MTFace *texface; 00207 MTexPoly *texpoly; 00208 MCol *mcol; 00209 MLoopCol *mloopcol; 00210 MLoopUV *mloopuv; 00211 00212 for(i=0; i < numTex; i++){ 00213 texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i); 00214 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i); 00215 00216 texface->tpage = texpoly->tpage; 00217 texface->flag = texpoly->flag; 00218 texface->transp = texpoly->transp; 00219 texface->mode = texpoly->mode; 00220 texface->tile = texpoly->tile; 00221 texface->unwrap = texpoly->unwrap; 00222 00223 j = 0; 00224 l = f->loopbase; 00225 do{ 00226 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i); 00227 texface->uv[j][0] = mloopuv->uv[0]; 00228 texface->uv[j][1] = mloopuv->uv[1]; 00229 j++; 00230 l = l->next; 00231 }while(l!=f->loopbase); 00232 00233 } 00234 for(i=0; i < numCol; i++){ 00235 mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i); 00236 j = 0; 00237 l = f->loopbase; 00238 do{ 00239 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i); 00240 mcol[j].r = mloopcol->r; 00241 mcol[j].g = mloopcol->g; 00242 mcol[j].b = mloopcol->b; 00243 mcol[j].a = mloopcol->a; 00244 j++; 00245 l = l->next; 00246 }while(l!=f->loopbase); 00247 } 00248 } 00249 /*move the EditMesh conversion functions to editmesh_tools.c*/ 00250 BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { 00251 BME_Mesh *bm; 00252 int allocsize[4] = {512,512,2048,512}, numTex, numCol; 00253 BME_Vert *v1, *v2; 00254 BME_Edge *e, *edar[4]; 00255 BME_Poly *f; 00256 00257 EditVert *eve; 00258 EditEdge *eed; 00259 EditFace *efa; 00260 00261 int len; 00262 bm = BME_make_mesh(allocsize); 00263 00264 /*copy custom data layout*/ 00265 CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); 00266 CustomData_copy(&em->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); 00267 CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0); 00268 00269 /*copy face corner data*/ 00270 CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata); 00271 /*initialize memory pools*/ 00272 CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]); 00273 CustomData_bmesh_init_pool(&bm->edata, allocsize[1]); 00274 CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]); 00275 CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]); 00276 /*needed later*/ 00277 numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); 00278 numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); 00279 00280 BME_model_begin(bm); 00281 /*add verts*/ 00282 eve= em->verts.first; 00283 while(eve) { 00284 v1 = BME_MV(bm,eve->co); 00285 VECCOPY(v1->no,eve->no); 00286 v1->flag = eve->f; 00287 v1->h = eve->h; 00288 v1->bweight = eve->bweight; 00289 /*Copy Custom Data*/ 00290 CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v1->data); 00291 eve->tmp.v = (EditVert*)v1; 00292 eve = eve->next; 00293 } 00294 00295 /*add edges*/ 00296 eed= em->edges.first; 00297 while(eed) { 00298 v1 = (BME_Vert*)eed->v1->tmp.v; 00299 v2 = (BME_Vert*)eed->v2->tmp.v; 00300 e = BME_ME(bm, v1, v2); 00301 e->crease = eed->crease; 00302 e->bweight = eed->bweight; 00303 e->flag = eed->f & SELECT; 00304 if(eed->sharp) e->flag |= ME_SHARP; 00305 if(eed->seam) e->flag |= ME_SEAM; 00306 //XXX if(eed->h & EM_FGON) e->flag |= ME_FGON; 00307 if(eed->h & 1) e->flag |= ME_HIDE; 00308 eed->tmp.e = (EditEdge*)e; 00309 CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->data); 00310 eed = eed->next; 00311 } 00312 /*add faces.*/ 00313 efa= em->faces.first; 00314 while(efa) { 00315 if(efa->v4) len = 4; 00316 else len = 3; 00317 00318 edar[0] = (BME_Edge*)efa->e1->tmp.e; 00319 edar[1] = (BME_Edge*)efa->e2->tmp.e; 00320 edar[2] = (BME_Edge*)efa->e3->tmp.e; 00321 if(len == 4){ 00322 edar[3] = (BME_Edge*)efa->e4->tmp.e; 00323 } 00324 00325 /*find v1 and v2*/ 00326 v1 = (BME_Vert*)efa->v1->tmp.v; 00327 v2 = (BME_Vert*)efa->v2->tmp.v; 00328 00329 f = BME_MF(bm,v1,v2,edar,len); 00330 f->mat_nr = efa->mat_nr; 00331 f->flag = efa->flag; 00332 if(efa->h) { 00333 f->flag |= ME_HIDE; 00334 f->flag &= ~ME_FACE_SEL; 00335 } 00336 else { 00337 if(efa->f & 1) f->flag |= ME_FACE_SEL; 00338 else f->flag &= ~ME_FACE_SEL; 00339 } 00340 CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data); 00341 BME_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex); 00342 efa = efa->next; 00343 } 00344 BME_model_end(bm); 00345 return bm; 00346 } 00347 /* adds the geometry in the bmesh to editMesh (does not free editMesh) 00348 * if td != NULL, the transdata will be mapped to the EditVert's co */ 00349 void BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td, EditMesh *em) { 00350 BME_Vert *v1; 00351 BME_Edge *e; 00352 BME_Poly *f; 00353 00354 BME_TransData *vtd; 00355 00356 EditVert *eve1, /* *eve2, *eve3, *eve4, */ /* UNUSED */ **evlist; 00357 EditEdge *eed; 00358 EditFace *efa; 00359 00360 int totvert, len, i, numTex, numCol; 00361 00362 if (em == NULL) return; 00363 00364 CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0); 00365 CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0); 00366 CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, CD_CALLOC, 0); 00367 CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata,0); 00368 numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); 00369 numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); 00370 00371 00372 /* convert to EditMesh */ 00373 /* make editverts */ 00374 totvert = BLI_countlist(&(bm->verts)); 00375 evlist= (EditVert **)MEM_mallocN(totvert*sizeof(void *),"evlist"); 00376 for (i=0,v1=bm->verts.first;v1;v1=v1->next,i++) { 00377 v1->tflag1 = i; 00378 eve1 = NULL; //XXX addvertlist(v1->co,NULL); 00379 if (td && (vtd = BME_get_transdata(td,v1))) { 00380 vtd->loc = eve1->co; 00381 } 00382 eve1->keyindex = i; 00383 evlist[i]= eve1; 00384 eve1->f = (unsigned char)v1->flag; 00385 eve1->h = (unsigned char)v1->h; 00386 eve1->bweight = v1->bweight; 00387 CustomData_em_copy_data(&bm->vdata, &em->vdata, v1->data, &eve1->data); 00388 } 00389 00390 /* make edges */ 00391 for (e=bm->edges.first;e;e=e->next) { 00392 if(0) { //XXX if(!(findedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1]))){ 00393 eed= NULL; //XXX addedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1], NULL); 00394 eed->crease = e->crease; 00395 eed->bweight = e->bweight; 00396 if(e->flag & ME_SEAM) eed->seam = 1; 00397 if(e->flag & ME_SHARP) eed->sharp = 1; 00398 if(e->flag & SELECT) eed->f |= SELECT; 00399 //XXX if(e->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines! 00400 if(e->flag & ME_HIDE) eed->h |= 1; 00401 if(em->selectmode==SCE_SELECT_EDGE) { 00402 ; //XXX EM_select_edge(eed, eed->f & SELECT); 00403 } 00404 CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data); 00405 } 00406 } 00407 00408 /* make faces */ 00409 for (f=bm->polys.first;f;f=f->next) { 00410 len = BME_cycle_length(f->loopbase); 00411 if (len==3 || len==4) { 00412 eve1= evlist[f->loopbase->v->tflag1]; 00413 /* eve2= evlist[f->loopbase->next->v->tflag1]; */ /* UNUSED */ 00414 /* eve3= evlist[f->loopbase->next->next->v->tflag1]; */ /* UNUSED */ 00415 /* if (len == 4) { 00416 eve4= evlist[f->loopbase->prev->v->tflag1]; 00417 } 00418 else { 00419 eve4= NULL; 00420 } */ /* UNUSED */ 00421 00422 efa = NULL; //XXX addfacelist(eve1, eve2, eve3, eve4, NULL, NULL); 00423 efa->mat_nr = (unsigned char)f->mat_nr; 00424 efa->flag= f->flag & ~ME_HIDE; 00425 if(f->flag & ME_FACE_SEL) { 00426 efa->f |= SELECT; 00427 } 00428 if(f->flag & ME_HIDE) efa->h= 1; 00429 // XXX flag depricated 00430 // if((G.f & G_FACESELECT) && (efa->f & SELECT)) 00431 //XXX EM_select_face(efa, 1); /* flush down */ 00432 CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data); 00433 BME_loops_to_corners(bm, &em->fdata, efa->data, f,numCol,numTex); 00434 } 00435 } 00436 00437 MEM_freeN(evlist); 00438 00439 } 00440 00441 /* Adds the geometry found in dm to bm 00442 */ 00443 BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm) 00444 { 00445 00446 BME_Mesh *bm; 00447 int allocsize[4] = {512,512,2048,512}; 00448 MVert *mvert, *mv; 00449 MEdge *medge, *me; 00450 MFace *mface, *mf; 00451 int totface,totedge,totvert,i,len, numTex, numCol; 00452 BME_Vert *v1=NULL,*v2=NULL, **vert_array; 00453 BME_Edge *e=NULL; 00454 BME_Poly *f=NULL; 00455 00456 EdgeHash *edge_hash = BLI_edgehash_new(); 00457 00458 bm = BME_make_mesh(allocsize); 00459 /*copy custom data layout*/ 00460 CustomData_copy(&dm->vertData, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); 00461 CustomData_copy(&dm->edgeData, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); 00462 CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0); 00463 00464 /*copy face corner data*/ 00465 CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata); 00466 /*initialize memory pools*/ 00467 CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]); 00468 CustomData_bmesh_init_pool(&bm->edata, allocsize[1]); 00469 CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]); 00470 CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]); 00471 /*needed later*/ 00472 numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); 00473 numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); 00474 00475 totvert = dm->getNumVerts(dm); 00476 totedge = dm->getNumEdges(dm); 00477 totface = dm->getNumFaces(dm); 00478 mvert = dm->getVertArray(dm); 00479 medge = dm->getEdgeArray(dm); 00480 mface = dm->getFaceArray(dm); 00481 00482 vert_array = MEM_mallocN(sizeof(*vert_array)*totvert,"BME_derivedmesh_to_bmesh BME_Vert* array"); 00483 00484 BME_model_begin(bm); 00485 /*add verts*/ 00486 for(i=0,mv = mvert; i < totvert;i++,mv++){ 00487 v1 = BME_MV(bm,mv->co); 00488 vert_array[i] = v1; 00489 v1->flag = mv->flag; 00490 v1->bweight = mv->bweight/255.0f; 00491 CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v1->data); 00492 } 00493 /*add edges*/ 00494 for(i=0,me = medge; i < totedge;i++,me++){ 00495 v1 = vert_array[me->v1]; 00496 v2 = vert_array[me->v2]; 00497 e = BME_ME(bm, v1, v2); 00498 e->crease = me->crease/255.0f; 00499 e->bweight = me->bweight/255.0f; 00500 e->flag = (unsigned char)me->flag; 00501 BLI_edgehash_insert(edge_hash,me->v1,me->v2,e); 00502 CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->data); 00503 } 00504 /*add faces.*/ 00505 for(i=0,mf = mface; i < totface;i++,mf++){ 00506 BME_Edge *edar[4]; 00507 if(mf->v4) len = 4; 00508 else len = 3; 00509 00510 edar[0] = BLI_edgehash_lookup(edge_hash,mf->v1,mf->v2); 00511 edar[1] = BLI_edgehash_lookup(edge_hash,mf->v2,mf->v3); 00512 if(len == 4){ 00513 edar[2] = BLI_edgehash_lookup(edge_hash,mf->v3,mf->v4); 00514 edar[3] = BLI_edgehash_lookup(edge_hash,mf->v4,mf->v1); 00515 } 00516 else 00517 edar[2] = BLI_edgehash_lookup(edge_hash,mf->v3,mf->v1); 00518 00519 /*find v1 and v2*/ 00520 v1 = vert_array[mf->v1]; 00521 v2 = vert_array[mf->v2]; 00522 00523 f = BME_MF(bm,v1,v2,edar,len); 00524 f->mat_nr = mf->mat_nr; 00525 f->flag = mf->flag; 00526 CustomData_to_bmesh_block(&dm->faceData,&bm->pdata,i,&f->data); 00527 BME_DMcorners_to_loops(bm, &dm->faceData,i,f, numCol,numTex); 00528 } 00529 00530 BME_model_end(bm); 00531 BLI_edgehash_free(edge_hash, NULL); 00532 MEM_freeN(vert_array); 00533 return bm; 00534 } 00535 00536 DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm) 00537 { 00538 MFace *mface, *mf; 00539 MEdge *medge, *me; 00540 MVert *mvert, *mv; 00541 int *origindex; 00542 int totface, totedge, totvert, i, /* bmeshok, */ /* UNUSED */ len, numTex, numCol; 00543 00544 BME_Vert *v1=NULL; 00545 BME_Edge *e=NULL, *oe=NULL; 00546 BME_Poly *f=NULL; 00547 00548 DerivedMesh *result; 00549 EdgeHash *edge_hash = BLI_edgehash_new(); 00550 00551 totvert = BLI_countlist(&(bm->verts)); 00552 totedge = 0; 00553 00554 /*we cannot have double edges in a derived mesh!*/ 00555 for(i=0, v1=bm->verts.first; v1; v1=v1->next, i++) v1->tflag1 = i; 00556 for(e=bm->edges.first; e; e=e->next){ 00557 oe = BLI_edgehash_lookup(edge_hash,e->v1->tflag1, e->v2->tflag1); 00558 if(!oe){ 00559 totedge++; 00560 BLI_edgehash_insert(edge_hash,e->v1->tflag1,e->v2->tflag1,e); 00561 e->tflag2 = 1; 00562 } 00563 else{ 00564 e->tflag2 = 0; 00565 } 00566 } 00567 00568 /*count quads and tris*/ 00569 totface = 0; 00570 /* bmeshok = 1; */ /* UNUSED */ 00571 for(f=bm->polys.first;f;f=f->next){ 00572 len = BME_cycle_length(f->loopbase); 00573 if(len == 3 || len == 4) totface++; 00574 } 00575 00576 /*convert back to mesh*/ 00577 result = CDDM_from_template(dm,totvert,totedge,totface); 00578 CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_BMESH, CD_CALLOC, totvert); 00579 CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_BMESH, CD_CALLOC, totedge); 00580 CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_BMESH, CD_CALLOC, totface); 00581 CustomData_from_bmeshpoly(&result->faceData, &bm->pdata, &bm->ldata,totface); 00582 numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); 00583 numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); 00584 00585 00586 /*Make Verts*/ 00587 mvert = CDDM_get_verts(result); 00588 origindex = result->getVertDataArray(result, CD_ORIGINDEX); 00589 for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){ 00590 VECCOPY(mv->co,v1->co); 00591 mv->flag = (unsigned char)v1->flag; 00592 mv->bweight = (char)(255.0*v1->bweight); 00593 CustomData_from_bmesh_block(&bm->vdata, &result->vertData, &v1->data, i); 00594 origindex[i] = ORIGINDEX_NONE; 00595 } 00596 medge = CDDM_get_edges(result); 00597 origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); 00598 i=0; 00599 for(e=bm->edges.first,me=medge;e;e=e->next){ 00600 if(e->tflag2){ 00601 if(e->v1->tflag1 < e->v2->tflag1){ 00602 me->v1 = e->v1->tflag1; 00603 me->v2 = e->v2->tflag1; 00604 } 00605 else{ 00606 me->v1 = e->v2->tflag1; 00607 me->v2 = e->v1->tflag1; 00608 } 00609 00610 me->crease = (char)(255.0*e->crease); 00611 me->bweight = (char)(255.0*e->bweight); 00612 me->flag = e->flag; 00613 CustomData_from_bmesh_block(&bm->edata, &result->edgeData, &e->data, i); 00614 origindex[i] = ORIGINDEX_NONE; 00615 me++; 00616 i++; 00617 } 00618 } 00619 if(totface){ 00620 mface = CDDM_get_faces(result); 00621 origindex = result->getFaceDataArray(result, CD_ORIGINDEX); 00622 /*make faces*/ 00623 for(i=0,f=bm->polys.first;f;f=f->next){ 00624 mf = &mface[i]; 00625 len = BME_cycle_length(f->loopbase); 00626 if(len==3 || len==4){ 00627 mf->v1 = f->loopbase->v->tflag1; 00628 mf->v2 = f->loopbase->next->v->tflag1; 00629 mf->v3 = f->loopbase->next->next->v->tflag1; 00630 if(len == 4){ 00631 mf->v4 = f->loopbase->prev->v->tflag1; 00632 } 00633 /* test and rotate indexes if necessary so that verts 3 and 4 aren't index 0 */ 00634 if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){ 00635 test_index_face(mf, NULL, i, len); 00636 } 00637 mf->mat_nr = (unsigned char)f->mat_nr; 00638 mf->flag = (unsigned char)f->flag; 00639 CustomData_from_bmesh_block(&bm->pdata, &result->faceData, &f->data, i); 00640 BME_DMloops_to_corners(bm, &result->faceData, i, f,numCol,numTex); 00641 origindex[i] = ORIGINDEX_NONE; 00642 i++; 00643 } 00644 } 00645 } 00646 BLI_edgehash_free(edge_hash, NULL); 00647 return result; 00648 }