Example #1
1
/* turns Mesh into editmesh */
void make_editMesh(Scene *scene, Object *ob)
{
	Mesh *me= ob->data;
	MFace *mface;
	MVert *mvert;
	MSelect *mselect;
	KeyBlock *actkey;
	EditMesh *em;
	EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
	EditFace *efa, *efa_last_sel= NULL;
	EditEdge *eed;
	EditSelection *ese;
	float *co, (*keyco)[3]= NULL;
	int tot, a, eekadoodle= 0;
	const short is_paint_face_sel=                             paint_facesel_test(ob);
	const short is_paint_vert_sel= is_paint_face_sel ? FALSE : paint_vertsel_test(ob);

	if(me->edit_mesh==NULL)
		me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh");
	else 
		/* because of reload */
		free_editMesh(me->edit_mesh);
	
	em= me->edit_mesh;
	
	em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced
	em->act_face = NULL;
	em->totvert= tot= me->totvert;
	em->totedge= me->totedge;
	em->totface= me->totface;
	
	if(tot==0) {
		return;
	}
	
	if(ob->actcol > 0)
		em->mat_nr= ob->actcol-1;

	/* initialize fastmalloc for editmesh */
	init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);

	actkey = ob_get_keyblock(ob);
	if(actkey) {
		/* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */
		undo_editmode_clear();
		keyco= actkey->data;
		em->shapenr= ob->shapenr;
	}

	/* make editverts */
	CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
	mvert= me->mvert;

	evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
	for(a=0; a<tot; a++, mvert++) {
		
		co= mvert->co;

		/* edit the shape key coordinate if available */
		if(keyco && a < actkey->totelem)
			co= keyco[a];

		eve= addvertlist(em, co, NULL);
		evlist[a]= eve;
		
		/* face select sets selection in next loop */
		if(!is_paint_face_sel)
			eve->f |= (mvert->flag & SELECT);
		
		if (mvert->flag & ME_HIDE) eve->h= 1;
		normal_short_to_float_v3(eve->no, mvert->no);

		eve->bweight= ((float)mvert->bweight)/255.0f;

		/* lets overwrite the keyindex of the editvert
		 * with the order it used to be in before
		 * editmode
		 */
		eve->keyindex = a;

		CustomData_to_em_block(&me->vdata, &em->vdata, a, &eve->data);
	}

	if(actkey && actkey->totelem!=me->totvert);
	else {
		MEdge *medge= me->medge;
		
		CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
		/* make edges */
		for(a=0; a<me->totedge; a++, medge++) {
			eed= addedgelist(em, evlist[medge->v1], evlist[medge->v2], NULL);
			/* eed can be zero when v1 and v2 are identical, dxf import does this... */
			if(eed) {
				int is_sel;
				if (is_paint_vert_sel) {
					/* when from vertex select, flush flags to edges,
					 * allow selection, code below handles editmode selection conversion */
					is_sel= (eed->v1->f & SELECT) && (eed->v2->f & SELECT);
				}
				else {
					is_sel= (medge->flag & SELECT);
				}

				eed->crease= ((float)medge->crease)/255.0f;
				eed->bweight= ((float)medge->bweight)/255.0f;
				
				if(medge->flag & ME_SEAM) eed->seam= 1;
				if(medge->flag & ME_SHARP) eed->sharp = 1;
				if(medge->flag & ME_FGON) eed->h= EM_FGON;	// 2 different defines!
				if(medge->flag & ME_HIDE) eed->h |= 1;
				if(is_sel) eed->f |= SELECT;
				if(em->selectmode==SCE_SELECT_EDGE)
					EM_select_edge(eed, eed->f & SELECT);		// force edge selection to vertices, seems to be needed ...
				CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data);
			}
		}
		
		CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);

		/* make faces */
		mface= me->mface;

		for(a=0; a<me->totface; a++, mface++) {
			eve1= evlist[mface->v1];
			eve2= evlist[mface->v2];
			if(!mface->v3) eekadoodle= 1;
			eve3= evlist[mface->v3];
			if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
			
			efa= addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);

			if(efa) {
				CustomData_to_em_block(&me->fdata, &em->fdata, a, &efa->data);

				efa->mat_nr= mface->mat_nr;
				efa->flag= mface->flag & ~ME_HIDE;
				
				/* select and hide face flag */
				if(mface->flag & ME_HIDE) {
					efa->h= 1;
				} else {
					int is_sel;

					if (!is_paint_vert_sel) {
						is_sel= (mface->flag & ME_FACE_SEL);
					}
					else {
						/* when from vertex select, flush flags to edges,
						 * allow selection, code below handles editmode selection conversion */
						is_sel= ( (efa->v1->f & SELECT) &&
						          (efa->v2->f & SELECT) &&
						          (efa->v3->f & SELECT) &&
						          (efa->v4 == NULL || efa->v4->f & SELECT)
						          );
					}

					if (a==me->act_face) {
						EM_set_actFace(em, efa);
					}
					
					/* dont allow hidden and selected */
					if(is_sel) {
						efa->f |= SELECT;
						
						if(is_paint_face_sel) {
							EM_select_face(efa, 1); /* flush down */
						}

						efa_last_sel= efa;
					}
				}
			}
		}
	}
	
	if(EM_get_actFace(em, 0)==NULL && efa_last_sel) {
		EM_set_actFace(em, efa_last_sel);
	}

	if(eekadoodle)
		error("This Mesh has old style edgecodes, please put it in the bugtracker!");
	
	MEM_freeN(evlist);

	end_editmesh_fastmalloc();	// resets global function pointers
	
	if(me->mselect){
		//restore editselections
		EM_init_index_arrays(em, 1,1,1);
		mselect = me->mselect;
		
		for(a=0; a<me->totselect; a++, mselect++){
			/*check if recorded selection is still valid, if so copy into editmesh*/
			if ( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) ||
			     (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) ||
			     (mselect->type == EDITFACE && me->mface[mselect->index].flag & ME_FACE_SEL) )
			{
				ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
				ese->type = mselect->type;	
				if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else
				if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else
				if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index);
				BLI_addtail(&(em->selected),ese);
			}
		}
		EM_free_index_arrays();
	}
	/* this creates coherent selections. also needed for older files */
	EM_selectmode_set(em);
	/* paranoia check to enforce hide rules */
	EM_hide_reset(em);
	/* sets helper flags which arent saved */
	EM_fgon_flags(em);
	
	if (EM_get_actFace(em, 0)==NULL) {
		EM_set_actFace(em, em->faces.first ); /* will use the first face, this is so we alwats have an active face */
	}
}
Example #2
1
static void undoMesh_to_editMesh(void *umv, void *emv)
{
	EditMesh *em= (EditMesh *)emv;
	UndoMesh *um= (UndoMesh *)umv;
	EditVert *eve, **evar=NULL;
	EditEdge *eed;
	EditFace *efa;
	EditSelection *ese;
	EditVertC *evec;
	EditEdgeC *eedc;
	EditFaceC *efac;
	EditSelectionC *esec;
	int a=0;

	free_editMesh(em);
	
	/* malloc blocks */
	memset(em, 0, sizeof(EditMesh));
		
	em->selectmode = um->selectmode;
	em->shapenr = um->shapenr;
	
	init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);

	CustomData_free(&em->vdata, 0);
	CustomData_free(&em->edata, 0);
	CustomData_free(&em->fdata, 0);

	CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
	CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
	CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);

	/* now copy vertices */

	if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
	for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
		eve= addvertlist(em, evec->co, NULL);
		evar[a]= eve;

		copy_v3_v3(eve->no, evec->no);
		eve->f= evec->f;
		eve->h= evec->h;
		eve->keyindex= evec->keyindex;
		eve->bweight= ((float)evec->bweight)/255.0f;

		CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data);
	}

	/* copy edges */
	for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
		eed= addedgelist(em, evar[eedc->v1], evar[eedc->v2], NULL);

		eed->f= eedc->f;
		eed->h= eedc->h;
		eed->seam= eedc->seam;
		eed->sharp= eedc->sharp;
		eed->fgoni= eedc->fgoni;
		eed->crease= ((float)eedc->crease)/255.0f;
		eed->bweight= ((float)eedc->bweight)/255.0f;
		CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data);
	}
	
	/* copy faces */
	for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
		if(efac->v4 != -1)
			efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
		else 
			efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);

		efa->mat_nr= efac->mat_nr;
		efa->flag= efac->flag;
		efa->f= efac->f;
		efa->h= efac->h;
		efa->fgonf= efac->fgonf;
		
		CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
	}
	
	end_editmesh_fastmalloc();
	if(evar) MEM_freeN(evar);
	
	em->totvert = um->totvert;
	em->totedge = um->totedge;
	em->totface = um->totface;
	/*restore stored editselections*/
	if(um->totsel){
		EM_init_index_arrays(em, 1,1,1);
		for(a=0, esec= um->selected; a<um->totsel; a++, esec++){
			ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
			ese->type = esec->type;
			if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else
			if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else
			if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index);
			BLI_addtail(&(em->selected),ese);
		}
		EM_free_index_arrays();
	}

	/* restore total selections */
	EM_nvertices_selected(em);
	EM_nedges_selected(em);
	EM_nfaces_selected(em);
}
Example #3
0
/* only adds quads or trias when there's edges already */
static void addfaces_from_edgenet(EditMesh *em)
{
	EditVert *eve1, *eve2, *eve3, *eve4;
	
	for(eve1= em->verts.first; eve1; eve1= eve1->next) {
		for(eve2= em->verts.first; (eve1->f & 1) && eve2; eve2= eve2->next) {
			if(findedgelist(em, eve1,eve2)) {
				for(eve3= em->verts.first; (eve2->f & 1) && eve3; eve3= eve3->next) {
					if((eve2!=eve3 && (eve3->f & 1) && findedgelist(em, eve1,eve3))) {
						EditEdge *sh_edge= NULL;
						EditVert *sh_vert= NULL;
						
						sh_edge= findedgelist(em, eve2,eve3);
						
						if(sh_edge) { /* Add a triangle */
							if(!exist_face_overlaps(em, eve1,eve2,eve3,NULL))
								fix_new_face(em, addfacelist(em, eve1,eve2,eve3,NULL,NULL,NULL));
						}
						else { /* Check for a shared vertex */
							for(eve4= em->verts.first; eve4; eve4= eve4->next) {
								if(eve4!=eve1 && eve4!=eve2 && eve4!=eve3 && (eve4->f & 1) &&
								   !findedgelist(em, eve1,eve4) && findedgelist(em, eve2,eve4) &&
								   findedgelist(em, eve3,eve4)) {
									sh_vert= eve4;
									break;
								}
							}
							
							if(sh_vert) {
								if(sh_vert) {
									if(!exist_face_overlaps(em, eve1,eve2,eve4,eve3))
										fix_new_face(em, addfacelist(em, eve1,eve2,eve4,eve3,NULL,NULL));
								}
							}
						}
					}
				}
			}
		}
	}

	EM_select_flush(em);
	
// XXX	DAG_id_tag_update(obedit->data, 0);
}
Example #4
0
void EditMeshAddFaces(int NumberFaces, Face* pFaces)
{
	for(int Index = 0; Index < NumberFaces; Index++)
	{
		int VertIndex0, VertIndex1, VertIndex2, VertIndex3;
		if(pFaces[Index].GetNumberOfVertices() > 4) return;

		VertIndex0 = pFaces[Index].GetVertexIndex(0);
		VertIndex1 = pFaces[Index].GetVertexIndex(1);
		VertIndex2 = pFaces[Index].GetVertexIndex(2);

		if(pFaces[Index].GetNumberOfVertices() == 4)
		{
			VertIndex3 = pFaces[Index].GetVertexIndex(3);
			addfacelist(VertsList[VertIndex0], VertsList[VertIndex1], VertsList[VertIndex2], VertsList[VertIndex3]);
		}
		else
		{
            addfacelist(VertsList[VertIndex0], VertsList[VertIndex1], VertsList[VertIndex2], NULL);
		}
	}
}
Example #5
0
/* precondition; 4 vertices selected, check for 4 edges and create face */
static EditFace *addface_from_edges(EditMesh *em)
{
	EditEdge *eed, *eedar[4]={NULL, NULL, NULL, NULL};
	EditVert *v1=NULL, *v2=NULL, *v3=NULL, *v4=NULL;
	int a;
	
	/* find the 4 edges */
	for(eed= em->edges.first; eed; eed= eed->next) {
		if( (eed->f & SELECT) || (eed->v1->f & eed->v2->f & SELECT) ) {
			if(eedar[0]==NULL) eedar[0]= eed;
			else if(eedar[1]==NULL) eedar[1]= eed;
			else if(eedar[2]==NULL) eedar[2]= eed;
			else eedar[3]= eed;
			
		}
	}
	
	
	if(eedar[3]) {
		/* first 2 points */
		v1= eedar[0]->v1;
		v2= eedar[0]->v2;
		
		/* find the 2 edges connected to first edge */
		for(a=1; a<4; a++) {
			if( eedar[a]->v1 == v2) v3= eedar[a]->v2;
			else if(eedar[a]->v2 == v2) v3= eedar[a]->v1;
			else if( eedar[a]->v1 == v1) v4= eedar[a]->v2;
			else if(eedar[a]->v2 == v1) v4= eedar[a]->v1;
		}
		
		/* verify if last edge exists */
		if(v3 && v4) {
			for(a=1; a<4; a++) {
				if( eedar[a]->v1==v3 && eedar[a]->v2==v4) break;
				if( eedar[a]->v2==v3 && eedar[a]->v1==v4) break;
			}
			if(a!=4) {
				return addfacelist(em, v1, v2, v3, v4, NULL, NULL);
			}
		}
	}
	return NULL;
}
Example #6
0
static void addedgeface_mesh(EditMesh *em, wmOperator *op)
{
	EditVert *eve, *neweve[4];
	EditEdge *eed;
	EditFace *efa;
	short amount=0;

	/* how many selected ? */
	if(em->selectmode & SCE_SELECT_EDGE) {
		/* in edge mode finding selected vertices means flushing down edge codes... */
		/* can't make face with only edge selection info... */
		EM_selectmode_set(em);
	}
	
	for(eve= em->verts.first; eve; eve= eve->next) {
		if(eve->f & SELECT) {
			amount++;
			if(amount>4) break;			
			neweve[amount-1]= eve;
		}
	}

	if(amount==2) {
		eed= addedgelist(em, neweve[0], neweve[1], NULL);
		EM_select_edge(eed, 1);

		// XXX		DAG_id_tag_update(obedit->data, 0);
		return;
	}
	else if(amount > 4) {
		addfaces_from_edgenet(em);
		return;
	}
	else if(amount<2) {
		BKE_report(op->reports, RPT_WARNING, "More vertices are needed to make an edge/face");
		return;
	}

	efa= NULL; // check later

	if(amount==3) {
		
		if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2], NULL)==0) {
			efa= addfacelist(em, neweve[0], neweve[1], neweve[2], 0, NULL, NULL);
			EM_select_face(efa, 1);
		}
		else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face");
	}
	else if(amount==4) {
		/* this test survives when theres 2 triangles */
		if(exist_face(em, neweve[0], neweve[1], neweve[2], neweve[3])==0) {
			int tria= 0;
			
			/* remove trias if they exist, 4 cases.... */
			if(exist_face(em, neweve[0], neweve[1], neweve[2], NULL)) tria++;
			if(exist_face(em, neweve[0], neweve[1], neweve[3], NULL)) tria++;
			if(exist_face(em, neweve[0], neweve[2], neweve[3], NULL)) tria++;
			if(exist_face(em, neweve[1], neweve[2], neweve[3], NULL)) tria++;
		
			if(tria==2) join_triangles(em);
			else if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2], neweve[3])==0) {
				 /* If there are 4 Verts, But more selected edges, we need to call addfaces_from_edgenet */
					EditEdge *eedcheck;
					int count;
					count = 0;
					for(eedcheck= em->edges.first; eedcheck; eedcheck= eedcheck->next) {
						if(eedcheck->f & SELECT) {
							count++;
						}
					}	
				
				if(count++ > 4){
					addfaces_from_edgenet(em);
					return;
				} else {
				/* if 4 edges exist, we just create the face, convex or not */
					efa= addface_from_edges(em);
					if(efa==NULL) {
						
						/* the order of vertices can be anything, 6 cases to check */
						if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co) ) {
							efa= addfacelist(em, neweve[0], neweve[1], neweve[2], neweve[3], NULL, NULL);
						}
						else if( convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co) ) {
							efa= addfacelist(em, neweve[0], neweve[2], neweve[3], neweve[1], NULL, NULL);
						}
						else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co, neweve[3]->co) ) {
							efa= addfacelist(em, neweve[0], neweve[2], neweve[1], neweve[3], NULL, NULL);
						}
						else if( convex(neweve[0]->co, neweve[1]->co, neweve[3]->co, neweve[2]->co) ) {
							efa= addfacelist(em, neweve[0], neweve[1], neweve[3], neweve[2], NULL, NULL);
						}
						else if( convex(neweve[0]->co, neweve[3]->co, neweve[2]->co, neweve[1]->co) ) {
							efa= addfacelist(em, neweve[0], neweve[3], neweve[2], neweve[1], NULL, NULL);
						}
						else if( convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co) ) {
							efa= addfacelist(em, neweve[0], neweve[3], neweve[1], neweve[2], NULL, NULL);
						}
						else BKE_report(op->reports, RPT_WARNING, "cannot find nice quad from concave set of vertices");

					}
				}
			}
			else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face");
		}
		else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face");
	}
	
	if(efa) {
		EM_select_face(efa, 1);

		fix_new_face(em, efa);
		
		recalc_editnormals(em);
	}
	}
Example #7
0
static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int seg,
		int subdiv, float dia, float depth, int ext, int fill)
{
	/*
	 * type - for the type of shape
	 * dia - the radius for cone,sphere cylinder etc.
	 * depth - 
	 * ext - extrude
	 * fill - end capping, and option to fill in circle
	 * cent[3] - center of the data. 
	 * */
	EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
	EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown;
	float phi, phid, vec[3];
	float q[4], cmat[3][3], nor[3]= {0.0, 0.0, 0.0};
	short a, b;
	
	EM_clear_flag_all(em, SELECT);

	phid= 2.0f*(float)M_PI/tot;
	phi= .25f*(float)M_PI;

	switch(type) {
	case PRIM_GRID: /*  grid */
		/* clear flags */
		eve= em->verts.first;
		while(eve) {
			eve->f= 0;
			eve= eve->next;
		}
		
		/* one segment first: the X axis */		
		phi = (2*dia)/(float)(tot-1);
		phid = (2*dia)/(float)(seg-1);
		for(a=tot-1;a>=0;a--) {
			vec[0] = (phi*a) - dia;
			vec[1]= - dia;
			vec[2]= 0.0f;
			eve= addvertlist(em, vec, NULL);
			eve->f= 1+2+4;
			if(a < tot -1) addedgelist(em, eve->prev, eve, NULL);
		}
		/* extrude and translate */
		vec[0]= vec[2]= 0.0;
		vec[1]= phid;
		
		for(a=0;a<seg-1;a++) {
			extrudeflag_vert(obedit, em, 2, nor, 0);	// nor unused
			translateflag(em, 2, vec);
		}
			
		/* and now do imat */
		eve= em->verts.first;
		while(eve) {
			if(eve->f & SELECT) {
				mul_m4_v3(mat,eve->co);
			}
			eve= eve->next;
		}
		recalc_editnormals(em);
		break;
			
	case PRIM_UVSPHERE: /*  UVsphere */
		
		/* clear all flags */
		eve= em->verts.first;
		while(eve) {
			eve->f= 0;
			eve= eve->next;
		}
		
		/* one segment first */
		phi= 0; 
		phid/=2;
		for(a=0; a<=tot; a++) {
			vec[0]= dia*sinf(phi);
			vec[1]= 0.0;
			vec[2]= dia*cosf(phi);
			eve= addvertlist(em, vec, NULL);
			eve->f= 1+2+4;
			if(a==0) v1= eve;
			else addedgelist(em, eve, eve->prev, NULL);
			phi+= phid;
		}
		
		/* extrude and rotate */
		phi= M_PI/seg;
		q[0]= cos(phi);
		q[3]= sin(phi);
		q[1]=q[2]= 0;
		quat_to_mat3( cmat,q);
		
		for(a=0; a<seg; a++) {
			extrudeflag_vert(obedit, em, 2, nor, 0); // nor unused
			rotateflag(em, 2, v1->co, cmat);
		}

		removedoublesflag(em, 4, 0, 0.0001);

		/* and now do imat */
		eve= em->verts.first;
		while(eve) {
			if(eve->f & SELECT) {
				mul_m4_v3(mat,eve->co);
			}
			eve= eve->next;
		}
		recalc_editnormals(em);
		break;
	case PRIM_ICOSPHERE: /* Icosphere */
		{
			EditVert *eva[12];
			EditEdge *eed;
			
			/* clear all flags */
			eve= em->verts.first;
			while(eve) {
				eve->f= 0;
				eve= eve->next;
			}
			dia/=200;
			for(a=0;a<12;a++) {
				vec[0]= dia*icovert[a][0];
				vec[1]= dia*icovert[a][1];
				vec[2]= dia*icovert[a][2];
				eva[a]= addvertlist(em, vec, NULL);
				eva[a]->f= 1+2;
			}
			for(a=0;a<20;a++) {
				EditFace *evtemp;
				v1= eva[ icoface[a][0] ];
				v2= eva[ icoface[a][1] ];
				v3= eva[ icoface[a][2] ];
				evtemp = addfacelist(em, v1, v2, v3, 0, NULL, NULL);
				evtemp->e1->f = 1+2;
				evtemp->e2->f = 1+2;
				evtemp->e3->f = 1+2;
			}

			dia*=200;
			for(a=1; a<subdiv; a++) esubdivideflag(obedit, em, 2, dia, 0, B_SPHERE,1, SUBDIV_CORNER_PATH, 0);
			/* and now do imat */
			eve= em->verts.first;
			while(eve) {
				if(eve->f & 2) {
					mul_m4_v3(mat,eve->co);
				}
				eve= eve->next;
			}
			
			// Clear the flag 2 from the edges
			for(eed=em->edges.first;eed;eed=eed->next){
				if(eed->f & 2){
					   eed->f &= !2;
				}   
			}
		}
		break;
	case PRIM_MONKEY: /* Monkey */
		{
			//extern int monkeyo, monkeynv, monkeynf;
			//extern signed char monkeyf[][4];
			//extern signed char monkeyv[][3];
			EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
			int i;

			for (i=0; i<monkeynv; i++) {
				float v[3];
				v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0;
				tv[i]= addvertlist(em, v, NULL);
				tv[i]->f |= SELECT;
				tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(em, v, NULL);
				tv[monkeynv+i]->f |= SELECT;
			}
			for (i=0; i<monkeynf; i++) {
				addfacelist(em, tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL);
				addfacelist(em, tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL);
			}

			MEM_freeN(tv);

			/* and now do imat */
			for(eve= em->verts.first; eve; eve= eve->next) {
				if(eve->f & SELECT) {
					mul_m4_v3(mat,eve->co);
				}
			}
			recalc_editnormals(em);
		}
		break;
	default: /* all types except grid, sphere... */
		if(type==PRIM_CONE);
		else if(ext==0) 
			depth= 0.0f;
	
		/* first vertex at 0° for circular objects */
		if( ELEM3(type, PRIM_CIRCLE,PRIM_CYLINDER,PRIM_CONE) )
			phi = 0.0f;
			
		vtop= vdown= v1= v2= 0;
		for(b=0; b<=ext; b++) {
			for(a=0; a<tot; a++) {
				
				vec[0]= dia*sinf(phi);
				vec[1]= dia*cosf(phi);
				vec[2]= b?depth:-depth;
				
				mul_m4_v3(mat, vec);
				eve= addvertlist(em, vec, NULL);
				eve->f= SELECT;
				if(a==0) {
					if(b==0) v1= eve;
					else v2= eve;
				}
				phi+=phid;
			}
		}
			
		/* center vertices */
		/* type PRIM_CONE can only have 1 one side filled
		 * if the cone has no capping, dont add vtop */
		if(type == PRIM_CONE || (fill && !ELEM(type, PRIM_PLANE, PRIM_CUBE))) {
			vec[0]= vec[1]= 0.0f;
			vec[2]= type==PRIM_CONE ? depth : -depth;
			mul_m4_v3(mat, vec);
			vdown= addvertlist(em, vec, NULL);
			if((ext || type==PRIM_CONE) && fill) {
				vec[0]= vec[1]= 0.0f;
				vec[2]= type==PRIM_CONE ? -depth : depth;
				mul_m4_v3(mat,vec);
				vtop= addvertlist(em, vec, NULL);
			}
		} else {
			vdown= v1;
			vtop= v2;
		}
		if(vtop) vtop->f= SELECT;
		if(vdown) vdown->f= SELECT;
	
		/* top and bottom face */
		if(fill || type==PRIM_CONE) {
			if(tot==4 && ELEM(type, PRIM_PLANE, PRIM_CUBE)) {
				v3= v1->next->next;
				if(ext) v4= v2->next->next;
				
				addfacelist(em, v3, v1->next, v1, v3->next, NULL, NULL);
				if(ext) addfacelist(em, v2, v2->next, v4, v4->next, NULL, NULL);
				
			}
			else {
				v3= v1;
				v4= v2;
				for(a=1; a<tot; a++) {
					addfacelist(em, vdown, v3, v3->next, 0, NULL, NULL);
					v3= v3->next;
					if(ext && fill) {
						addfacelist(em, vtop, v4, v4->next, 0, NULL, NULL);
						v4= v4->next;
					}
				}
				if(!ELEM(type, PRIM_PLANE, PRIM_CUBE)) {
					addfacelist(em, vdown, v3, v1, 0, NULL, NULL);
					if(ext) addfacelist(em, vtop, v4, v2, 0, NULL, NULL);
				}
			}
		}
		else if(type==PRIM_CIRCLE) {  /* we need edges for a circle */
			v3= v1;
			for(a=1;a<tot;a++) {
				addedgelist(em, v3, v3->next, NULL);
				v3= v3->next;
			}
			addedgelist(em, v3, v1, NULL);
		}
		/* side faces */
		if(ext) {
			v3= v1;
			v4= v2;
			for(a=1; a<tot; a++) {
				addfacelist(em, v3, v3->next, v4->next, v4, NULL, NULL);
				v3= v3->next;
				v4= v4->next;
			}
			addfacelist(em, v3, v1, v2, v4, NULL, NULL);
		}
		else if(fill && type==PRIM_CONE) {
			/* add the bottom flat area of the cone
			 * if capping is disabled dont bother */
			v3= v1;
			for(a=1; a<tot; a++) {
				addfacelist(em, vtop, v3->next, v3, 0, NULL, NULL);
				v3= v3->next;
			}
			addfacelist(em, vtop, v1, v3, 0, NULL, NULL);
		}
	}
	
	EM_stats_update(em);
	/* simple selection flush OK, based on fact it's a single model */
	EM_select_flush(em); /* flushes vertex -> edge -> face selection */

	if(!ELEM5(type, PRIM_GRID, PRIM_PLANE, PRIM_ICOSPHERE, PRIM_UVSPHERE, PRIM_MONKEY))
		EM_recalc_normal_direction(em, FALSE, TRUE);	/* otherwise monkey has eyes in wrong direction */

	BKE_mesh_end_editmesh(obedit->data, em);
}
Example #8
0
static Object* createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh, Base* base)
{
	float co[3], rot[3];
	EditMesh *em;
	int i,j, k;
	unsigned short* v;
	int face[3];
	Scene *scene= CTX_data_scene(C);
	Object* obedit;
	int createob= base==NULL;
	int nverts, nmeshes, nvp;
	unsigned short *verts, *polys;
	unsigned int *meshes;
	float bmin[3], cs, ch, *dverts;
	unsigned char *tris;

	zero_v3(co);
	zero_v3(rot);

	if(createob) {
		/* create new object */
		obedit= ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1);
	}
	else {
		obedit= base->object;
		scene_select_base(scene, base);
		copy_v3_v3(obedit->loc, co);
		copy_v3_v3(obedit->rot, rot);
	}

	ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER);
	em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));

	if(!createob) {
		/* clear */
		if(em->verts.first) free_vertlist(em, &em->verts);
		if(em->edges.first) free_edgelist(em, &em->edges);
		if(em->faces.first) free_facelist(em, &em->faces);
		if(em->selected.first) BLI_freelistN(&(em->selected));
	}

	/* create verts for polygon mesh */
	verts= recast_polyMeshGetVerts(pmesh, &nverts);
	recast_polyMeshGetBoundbox(pmesh, bmin, NULL);
	recast_polyMeshGetCell(pmesh, &cs, &ch);

	for(i= 0; i<nverts; i++) {
		v= &verts[3*i];
		co[0]= bmin[0] + v[0]*cs;
		co[1]= bmin[1] + v[1]*ch;
		co[2]= bmin[2] + v[2]*cs;
		SWAP(float, co[1], co[2]);
		addvertlist(em, co, NULL);
	}

	/* create custom data layer to save polygon idx */
	CustomData_add_layer_named(&em->fdata, CD_RECAST, CD_CALLOC, NULL, 0, "createRepresentation recastData");

	/* create verts and faces for detailed mesh */
	meshes= recast_polyMeshDetailGetMeshes(dmesh, &nmeshes);
	polys= recast_polyMeshGetPolys(pmesh, NULL, &nvp);
	dverts= recast_polyMeshDetailGetVerts(dmesh, NULL);
	tris= recast_polyMeshDetailGetTris(dmesh, NULL);

	for(i= 0; i<nmeshes; i++) {
		int uniquevbase= em->totvert;
		unsigned int vbase= meshes[4*i+0];
		unsigned short ndv= meshes[4*i+1];
		unsigned short tribase= meshes[4*i+2];
		unsigned short trinum= meshes[4*i+3];
		const unsigned short* p= &polys[i*nvp*2];
		int nv= 0;

		for(j= 0; j < nvp; ++j) {
			if(p[j]==0xffff) break;
			nv++;
		}

		/* create unique verts  */
		for(j= nv; j<ndv; j++) {
			copy_v3_v3(co, &dverts[3*(vbase + j)]);
			SWAP(float, co[1], co[2]);
			addvertlist(em, co, NULL);
		}

		EM_init_index_arrays(em, 1, 0, 0);

		/* create faces */
		for(j= 0; j<trinum; j++) {
			unsigned char* tri= &tris[4*(tribase+j)];
			EditFace* newFace;
			int* polygonIdx;

			for(k= 0; k<3; k++) {
				if(tri[k]<nv)
					face[k]= p[tri[k]]; /* shared vertex */
				else
					face[k]= uniquevbase+tri[k]-nv; /* unique vertex */
			}
			newFace= addfacelist(em, EM_get_vert_for_index(face[0]), EM_get_vert_for_index(face[2]),
									EM_get_vert_for_index(face[1]), NULL, NULL, NULL);

			/* set navigation polygon idx to the custom layer */
			polygonIdx= (int*)CustomData_em_get(&em->fdata, newFace->data, CD_RECAST);
			*polygonIdx= i+1; /* add 1 to avoid zero idx */
		}
		
		EM_free_index_arrays();
	}

	recast_destroyPolyMesh(pmesh);
	recast_destroyPolyMeshDetail(dmesh);

	BKE_mesh_end_editmesh((Mesh*)obedit->data, em);
	
	DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA);
	WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);


	ED_object_exit_editmode(C, EM_FREEDATA); 
	WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);

	if(createob) {
		obedit->gameflag&= ~OB_COLLISION;
		obedit->gameflag|= OB_NAVMESH;
		obedit->body_type= OB_BODY_TYPE_NAVMESH;
		rename_id((ID *)obedit, "Navmesh");
	}

	BKE_mesh_ensure_navmesh(obedit->data);

	return obedit;
}