Esempio n. 1
0
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);
			}
		}
	}
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/* 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);

}