Blender  V2.59
BME_conversions.c
Go to the documentation of this file.
00001 /*
00002  * BME_mesh.c    jan 2007
00003  *
00004  *      BMesh mesh level functions.
00005  *
00006  * $Id: BME_conversions.c 35247 2011-02-27 20:40:57Z jesterking $
00007  *
00008  * ***** BEGIN GPL LICENSE BLOCK *****
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU General Public License
00012  * as published by the Free Software Foundation; either version 2
00013  * of the License, or (at your option) any later version.
00014  * about this.  
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00024  *
00025  * The Original Code is Copyright (C) 2007 Blender Foundation.
00026  * All rights reserved.
00027  *
00028  * The Original Code is: all of this file.
00029  *
00030  * Contributor(s): Geoffrey Bantle, Levi Schooley.
00031  *
00032  * ***** END GPL LICENSE BLOCK *****
00033  */
00034 
00040 #include "MEM_guardedalloc.h"
00041 
00042 #include "DNA_meshdata_types.h"
00043 #include "DNA_object_types.h"
00044 #include "DNA_scene_types.h"
00045 
00046 #include "BLI_edgehash.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, **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];
00414                         eve3= evlist[f->loopbase->next->next->v->tflag1];
00415                         if (len == 4) {
00416                                 eve4= evlist[f->loopbase->prev->v->tflag1];
00417                         }
00418                         else {
00419                                 eve4= NULL;
00420                         }
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,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;
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 }