static void mesh_ensure_tessellation_customdata(Mesh *me) { if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) { /* Pass, otherwise this function clears 'mface' before * versioning 'mface -> mpoly' code kicks in [#30583] * * Callers could also check but safer to do here - campbell */ } else { const int tottex_original = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY); const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE); const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL); if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) { BKE_mesh_tessface_clear(me); CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface); /* TODO - add some --debug-mesh option */ if (G.debug & G_DEBUG) { /* note: this warning may be un-called for if we are initializing the mesh for the * first time from bmesh, rather then giving a warning about this we could be smarter * and check if there was any data to begin with, for now just print the warning with * some info to help troubleshoot whats going on - campbell */ printf("%s: warning! Tessellation uvs or vcol data got out of sync, " "had to reset!\n CD_MTFACE: %d != CD_MTEXPOLY: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n", __func__, tottex_tessface, tottex_original, totcol_tessface, totcol_original); } } } }
DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm) { MFace *mface, *mf; MEdge *medge, *me; MVert *mvert, *mv; int *origindex; int totface,totedge,totvert,i,bmeshok,len, numTex, numCol; BME_Vert *v1=NULL; BME_Edge *e=NULL, *oe=NULL; BME_Poly *f=NULL; DerivedMesh *result; EdgeHash *edge_hash = BLI_edgehash_new(); totvert = BLI_countlist(&(bm->verts)); totedge = 0; /*we cannot have double edges in a derived mesh!*/ for(i=0, v1=bm->verts.first; v1; v1=v1->next, i++) v1->tflag1 = i; for(e=bm->edges.first; e; e=e->next){ oe = BLI_edgehash_lookup(edge_hash,e->v1->tflag1, e->v2->tflag1); if(!oe){ totedge++; BLI_edgehash_insert(edge_hash,e->v1->tflag1,e->v2->tflag1,e); e->tflag2 = 1; } else{ e->tflag2 = 0; } } /*count quads and tris*/ totface = 0; bmeshok = 1; for(f=bm->polys.first;f;f=f->next){ len = BME_cycle_length(f->loopbase); if(len == 3 || len == 4) totface++; } /*convert back to mesh*/ result = CDDM_from_template(dm,totvert,totedge,totface); CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_BMESH, CD_CALLOC, totvert); CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_BMESH, CD_CALLOC, totedge); CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_BMESH, CD_CALLOC, totface); CustomData_from_bmeshpoly(&result->faceData, &bm->pdata, &bm->ldata,totface); numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); /*Make Verts*/ mvert = CDDM_get_verts(result); origindex = result->getVertDataArray(result, CD_ORIGINDEX); for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){ VECCOPY(mv->co,v1->co); mv->flag = (unsigned char)v1->flag; mv->bweight = (char)(255.0*v1->bweight); CustomData_from_bmesh_block(&bm->vdata, &result->vertData, &v1->data, i); origindex[i] = ORIGINDEX_NONE; } medge = CDDM_get_edges(result); origindex = result->getEdgeDataArray(result, CD_ORIGINDEX); i=0; for(e=bm->edges.first,me=medge;e;e=e->next){ if(e->tflag2){ if(e->v1->tflag1 < e->v2->tflag1){ me->v1 = e->v1->tflag1; me->v2 = e->v2->tflag1; } else{ me->v1 = e->v2->tflag1; me->v2 = e->v1->tflag1; } me->crease = (char)(255.0*e->crease); me->bweight = (char)(255.0*e->bweight); me->flag = e->flag; CustomData_from_bmesh_block(&bm->edata, &result->edgeData, &e->data, i); origindex[i] = ORIGINDEX_NONE; me++; i++; } } if(totface){ mface = CDDM_get_faces(result); origindex = result->getFaceDataArray(result, CD_ORIGINDEX); /*make faces*/ for(i=0,f=bm->polys.first;f;f=f->next){ mf = &mface[i]; len = BME_cycle_length(f->loopbase); if(len==3 || len==4){ mf->v1 = f->loopbase->v->tflag1; mf->v2 = f->loopbase->next->v->tflag1; mf->v3 = f->loopbase->next->next->v->tflag1; if(len == 4){ mf->v4 = f->loopbase->prev->v->tflag1; } /* test and rotate indexes if necessary so that verts 3 and 4 aren't index 0 */ if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){ test_index_face(mf, NULL, i, len); } mf->mat_nr = (unsigned char)f->mat_nr; mf->flag = (unsigned char)f->flag; CustomData_from_bmesh_block(&bm->pdata, &result->faceData, &f->data, i); BME_DMloops_to_corners(bm, &result->faceData, i, f,numCol,numTex); origindex[i] = ORIGINDEX_NONE; i++; } } } BLI_edgehash_free(edge_hash, NULL); return result; }
/* adds the geometry in the bmesh to editMesh (does not free editMesh) * if td != NULL, the transdata will be mapped to the EditVert's co */ void BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td, EditMesh *em) { BME_Vert *v1; BME_Edge *e; BME_Poly *f; BME_TransData *vtd; EditVert *eve1, *eve2, *eve3, *eve4, **evlist; EditEdge *eed; EditFace *efa; int totvert, len, i, numTex, numCol; if (em == NULL) return; CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0); CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0); CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, 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); /* convert to EditMesh */ /* make editverts */ totvert = BLI_countlist(&(bm->verts)); evlist= (EditVert **)MEM_mallocN(totvert*sizeof(void *),"evlist"); for (i=0,v1=bm->verts.first;v1;v1=v1->next,i++) { v1->tflag1 = i; eve1 = NULL; //XXX addvertlist(v1->co,NULL); if (td && (vtd = BME_get_transdata(td,v1))) { vtd->loc = eve1->co; } eve1->keyindex = i; evlist[i]= eve1; eve1->f = (unsigned char)v1->flag; eve1->h = (unsigned char)v1->h; eve1->bweight = v1->bweight; CustomData_em_copy_data(&bm->vdata, &em->vdata, v1->data, &eve1->data); } /* make edges */ for (e=bm->edges.first;e;e=e->next) { if(0) { //XXX if(!(findedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1]))){ eed= NULL; //XXX addedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1], NULL); eed->crease = e->crease; eed->bweight = e->bweight; if(e->flag & ME_SEAM) eed->seam = 1; if(e->flag & ME_SHARP) eed->sharp = 1; if(e->flag & SELECT) eed->f |= SELECT; //XXX if(e->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines! if(e->flag & ME_HIDE) eed->h |= 1; if(em->selectmode==SCE_SELECT_EDGE) { ; //XXX EM_select_edge(eed, eed->f & SELECT); } CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data); } } /* make faces */ for (f=bm->polys.first;f;f=f->next) { len = BME_cycle_length(f->loopbase); if (len==3 || len==4) { eve1= evlist[f->loopbase->v->tflag1]; eve2= evlist[f->loopbase->next->v->tflag1]; eve3= evlist[f->loopbase->next->next->v->tflag1]; if (len == 4) { eve4= evlist[f->loopbase->prev->v->tflag1]; } else { eve4= NULL; } efa = NULL; //XXX addfacelist(eve1, eve2, eve3, eve4, NULL, NULL); efa->mat_nr = (unsigned char)f->mat_nr; efa->flag= f->flag & ~ME_HIDE; if(f->flag & ME_FACE_SEL) { efa->f |= SELECT; } if(f->flag & ME_HIDE) efa->h= 1; // XXX flag depricated // if((G.f & G_FACESELECT) && (efa->f & SELECT)) //XXX EM_select_face(efa, 1); /* flush down */ CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data); BME_loops_to_corners(bm, &em->fdata, efa->data, f,numCol,numTex); } } MEM_freeN(evlist); }