Ejemplo n.º 1
0
static int object_hook_index_array(Object *obedit, int *tot, int **indexar, char *name, float *cent_r)
{
	*indexar= NULL;
	*tot= 0;
	name[0]= 0;
	
	switch(obedit->type) {
		case OB_MESH:
		{
			Mesh *me= obedit->data;
			EditMesh *em = BKE_mesh_get_editmesh(me);

			/* check selected vertices first */
			if( return_editmesh_indexar(em, tot, indexar, cent_r)) {
				BKE_mesh_end_editmesh(me, em);
				return 1;
			} else {
				int ret = return_editmesh_vgroup(obedit, em, name, cent_r);
				BKE_mesh_end_editmesh(me, em);
				return ret;
			}
		}
		case OB_CURVE:
		case OB_SURF:
			return return_editcurve_indexar(obedit, tot, indexar, cent_r);
		case OB_LATTICE:
		{
			Lattice *lt= obedit->data;
			return return_editlattice_indexar(lt->editlatt->latt, tot, indexar, cent_r);
		}
		default:
			return 0;
	}
}
Ejemplo n.º 2
0
/* return 1: success */
static int mesh_separate_loose(wmOperator *op, Main *bmain, Scene *scene, Base *editbase)
{
	Mesh *me;
	EditMesh *em;
	int doit= 1;
	
	me= editbase->object->data;
	em= BKE_mesh_get_editmesh(me);
	
	if(me->key) {
		error("Can't separate with vertex keys");
		BKE_mesh_end_editmesh(me, em);
		return 0;
	}
	
	EM_clear_flag_all(em, SELECT);

	while(doit) {
		/* Select a random vert to start with */
		EditVert *eve;
		int tot;

		/* check if all verts that are visible have been done */
		for(eve=em->verts.first; eve; eve= eve->next)
			if(!eve->h) break;
		if(eve==NULL) break; /* only hidden verts left, quit early */

		/* first non hidden vert */
		eve->f |= SELECT;
		
		selectconnected_mesh_all(em);
		
		/* don't separate the very last part */
		for(eve=em->verts.first; eve; eve= eve->next)
			if((eve->f & SELECT)==0) break;
		if(eve==NULL) break;

		tot= BLI_countlist(&em->verts);

		/* and now separate */
		doit= mesh_separate_selected(op, bmain, scene, editbase);

		/* with hidden verts this can happen */
		if(tot == BLI_countlist(&em->verts))
			break;
	}

	BKE_mesh_end_editmesh(me, em);
	return 1;
}
Ejemplo n.º 3
0
static int clear_fgon_exec(bContext *C, wmOperator *op)
{
	Object *obedit= CTX_data_edit_object(C);
	EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
	
	if( make_fgon(em, op, 0) ) {
		DAG_id_tag_update(obedit->data, 0);
		WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
		
		BKE_mesh_end_editmesh(obedit->data, em);
		return OPERATOR_FINISHED;
	}

	BKE_mesh_end_editmesh(obedit->data, em);
	return OPERATOR_CANCELLED;
}
Ejemplo n.º 4
0
static int navmesh_face_add_exec(bContext *C, wmOperator *UNUSED(op))
{
	Object *obedit= CTX_data_edit_object(C);
	EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
	EditFace *ef;

	if(CustomData_has_layer(&em->fdata, CD_RECAST)) {
		int targetPolyIdx= findFreeNavPolyIndex(em);

		if(targetPolyIdx>0) {
			/* set target poly idx to selected faces */
			ef= (EditFace*)em->faces.last;
			while(ef) {
				if(ef->f & SELECT) {
					int *recastDataBlock= (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST);
					*recastDataBlock= targetPolyIdx;
				}
				ef= ef->prev;
			}
		}
	}

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

	BKE_mesh_end_editmesh((Mesh*)obedit->data, em);
	return OPERATOR_FINISHED;
}
Ejemplo n.º 5
0
/* removes from active defgroup, if allverts==0 only selected vertices */
static void vgroup_active_remove_verts(Object *ob, int allverts)
{
	EditVert *eve;
	MDeformVert *dvert;
	MDeformWeight *newdw;
	bDeformGroup *dg, *eg;
	int	i;

	dg=BLI_findlink(&ob->defbase, ob->actdef-1);
	if(!dg)
		return;

	if(ob->type == OB_MESH) {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);

		for(eve=em->verts.first; eve; eve=eve->next){
			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
		
			if(dvert && dvert->dw && ((eve->f & 1) || allverts)){
				for(i=0; i<dvert->totweight; i++){
					/* Find group */
					eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr);
					if(eg == dg){
						dvert->totweight--;
						if(dvert->totweight){
							newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
							
							if(dvert->dw){
								memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i);
								memcpy(newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
								MEM_freeN(dvert->dw);
							}
							dvert->dw=newdw;
						}
						else{
							MEM_freeN(dvert->dw);
							dvert->dw=NULL;
							break;
						}
					}
				}
			}
		}
		BKE_mesh_end_editmesh(me, em);
	}
	else if(ob->type == OB_LATTICE) {
		Lattice *lt= vgroup_edit_lattice(ob);
		
		if(lt->dvert) {
			BPoint *bp;
			int a, tot= lt->pntsu*lt->pntsv*lt->pntsw;
				
			for(a=0, bp= lt->def; a<tot; a++, bp++) {
				if(allverts || (bp->f1 & SELECT))
					ED_vgroup_vert_remove(ob, dg, a);
			}
		}
	}
}
Ejemplo n.º 6
0
/* only in editmode */
static void vgroup_select_verts(Object *ob, int select)
{
	EditVert *eve;
	MDeformVert *dvert;
	int i;

	if(ob->type == OB_MESH) {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);

		for(eve=em->verts.first; eve; eve=eve->next){
			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);

			if(dvert && dvert->totweight){
				for(i=0; i<dvert->totweight; i++){
					if(dvert->dw[i].def_nr == (ob->actdef-1)){
						if(select) eve->f |= SELECT;
						else eve->f &= ~SELECT;
						
						break;
					}
				}
			}
		}
		/* this has to be called, because this function operates on vertices only */
		if(select) EM_select_flush(em);	// vertices to edges/faces
		else EM_deselect_flush(em);

		BKE_mesh_end_editmesh(me, em);
	}
	else if(ob->type == OB_LATTICE) {
		Lattice *lt= vgroup_edit_lattice(ob);
		
		if(lt->dvert) {
			BPoint *bp;
			int a, tot;
			
			dvert= lt->dvert;

			tot= lt->pntsu*lt->pntsv*lt->pntsw;
			for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) {
				for(i=0; i<dvert->totweight; i++){
					if(dvert->dw[i].def_nr == (ob->actdef-1)) {
						if(select) bp->f1 |= SELECT;
						else bp->f1 &= ~SELECT;
						
						break;
					}
				}
			}
		}
	}
}
Ejemplo n.º 7
0
static int addedgeface_mesh_exec(bContext *C, wmOperator *op)
{
	Object *obedit= CTX_data_edit_object(C);
	EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
	
	addedgeface_mesh(em, op);
	
	DAG_id_tag_update(obedit->data, 0);
	WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
	
	BKE_mesh_end_editmesh(obedit->data, em);
	return OPERATOR_FINISHED;
}
Ejemplo n.º 8
0
static int mesh_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
	Object *ob= CTX_data_edit_object(C);
	EditMesh *em= BKE_mesh_get_editmesh(ob->data);

	adduplicateflag(em, SELECT);

	BKE_mesh_end_editmesh(ob->data, em);

	DAG_id_tag_update(ob->data, 0);
	WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
	
	return OPERATOR_FINISHED;
}
Ejemplo n.º 9
0
static void act_vert_def(Object *ob, EditVert **eve, MDeformVert **dvert)
{
	if(ob && ob->mode & OB_MODE_EDIT && ob->type==OB_MESH && ob->defbase.first) {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);
		EditSelection *ese = ((EditSelection*)em->selected.last);

		if(ese && ese->type == EDITVERT) {
			*eve= (EditVert*)ese->data;
			*dvert= CustomData_em_get(&em->vdata, (*eve)->data, CD_MDEFORMVERT);
			return;
		}

		BKE_mesh_end_editmesh(me, em);
	}

	*eve= NULL;
	*dvert= NULL;
}
Ejemplo n.º 10
0
static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
{
	Mesh *me= ob->data;
	EditMesh *em= BKE_mesh_get_editmesh(me);
	EditVert *eve;
	int index=0, nr=0;
	
	if (hmd->indexar == NULL)
		return;
	
	for(eve= em->verts.first; eve; eve= eve->next, nr++) {
		if(nr==hmd->indexar[index]) {
			eve->f |= SELECT;
			if(index < hmd->totindex-1) index++;
		}
	}
	EM_select_flush(em);

	BKE_mesh_end_editmesh(me, em);
}
Ejemplo n.º 11
0
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
{
	Object *obedit = CTX_data_edit_object(C);
	uiBlock *block= uiLayoutGetBlock(layout);

	uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL);

	if(obedit && (obedit->type == OB_MESH)) {
		EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
		uiLayout *row;

		row= uiLayoutRow(layout, 1);
		block= uiLayoutGetBlock(row);
		uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
		uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
		uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode");

		BKE_mesh_end_editmesh(obedit->data, em);
	}
}
Ejemplo n.º 12
0
/* return 1: success */
static int mesh_separate_material(wmOperator *op, Main *bmain, Scene *scene, Base *editbase)
{
	Mesh *me= editbase->object->data;
	EditMesh *em= BKE_mesh_get_editmesh(me);
	unsigned char curr_mat;
	
	for (curr_mat = 1; curr_mat < editbase->object->totcol; ++curr_mat) {
		/* clear selection, we're going to use that to select material group */
		EM_clear_flag_all(em, SELECT);
		/* select the material */
		EM_select_by_material(em, curr_mat);
		/* and now separate */
		if(em->totfacesel > 0) {
			mesh_separate_selected(op, bmain, scene, editbase);
		}
	}

	BKE_mesh_end_editmesh(me, em);
	return 1;
}
Ejemplo n.º 13
0
static void draw_uvs_shadow(SpaceImage *sima, Object *obedit)
{
	EditMesh *em;
	EditFace *efa;
	MTFace *tf;
	
	em= BKE_mesh_get_editmesh((Mesh*)obedit->data);

	/* draws the grey mesh when painting */
	glColor3ub(112, 112, 112);

	for(efa= em->faces.first; efa; efa= efa->next) {
		tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);

		glBegin(GL_LINE_LOOP);
			glVertex2fv(tf->uv[0]);
			glVertex2fv(tf->uv[1]);
			glVertex2fv(tf->uv[2]);
			if(efa->v4) glVertex2fv(tf->uv[3]);
		glEnd();
	}

	BKE_mesh_end_editmesh(obedit->data, em);
}
Ejemplo n.º 14
0
static int navmesh_face_copy_exec(bContext *C, wmOperator *op)
{
	Object *obedit= CTX_data_edit_object(C);
	EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);

	/* do work here */
	EditFace *efa_act= EM_get_actFace(em, 0);

	if(efa_act) {
		if(CustomData_has_layer(&em->fdata, CD_RECAST)) {
			EditFace *efa;
			int targetPolyIdx= *(int*)CustomData_em_get(&em->fdata, efa_act->data, CD_RECAST);
			targetPolyIdx= targetPolyIdx>=0? targetPolyIdx : -targetPolyIdx;

			if(targetPolyIdx > 0) {
				/* set target poly idx to other selected faces */
				for (efa= (EditFace *)em->faces.first; efa; efa= efa->next) {
					if((efa->f & SELECT) && efa != efa_act)  {
						int* recastDataBlock= (int*)CustomData_em_get(&em->fdata, efa->data, CD_RECAST);
						*recastDataBlock= targetPolyIdx;
					}
				}
			}
			else {
				BKE_report(op->reports, RPT_ERROR, "Active face has no index set");
			}
		}
	}

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

	BKE_mesh_end_editmesh((Mesh*)obedit->data, em);

	return OPERATOR_FINISHED;
}
Ejemplo n.º 15
0
/* only in editmode */
static void vgroup_assign_verts(Object *ob, float weight)
{
	EditVert *eve;
	bDeformGroup *dg, *eg;
	MDeformWeight *newdw;
	MDeformVert *dvert;
	int	i, done;

	dg=BLI_findlink(&ob->defbase, ob->actdef-1);
	if(!dg)
		return;

	if(ob->type == OB_MESH) {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);

		if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
			EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT);

		/* Go through the list of editverts and assign them */
		for(eve=em->verts.first; eve; eve=eve->next){
			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);

			if(dvert && (eve->f & 1)){
				done=0;
				/* See if this vert already has a reference to this group */
				/*		If so: Change its weight */
				done=0;
				for(i=0; i<dvert->totweight; i++){
					eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr);
					/* Find the actual group */
					if(eg==dg){
						dvert->dw[i].weight= weight;
						done=1;
						break;
					}
			 	}
				/*		If not: Add the group and set its weight */
				if(!done){
					newdw = MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
					if(dvert->dw){
						memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
						MEM_freeN(dvert->dw);
					}
					dvert->dw=newdw;

					dvert->dw[dvert->totweight].weight= weight;
					dvert->dw[dvert->totweight].def_nr= ob->actdef-1;

					dvert->totweight++;

				}
			}
		}
		BKE_mesh_end_editmesh(me, em);
	}
	else if(ob->type == OB_LATTICE) {
		Lattice *lt= vgroup_edit_lattice(ob);
		BPoint *bp;
		int a, tot;
		
		if(lt->dvert==NULL)
			ED_vgroup_data_create(&lt->id);
		
		tot= lt->pntsu*lt->pntsv*lt->pntsw;
		for(a=0, bp= lt->def; a<tot; a++, bp++) {
			if(bp->f1 & SELECT)
				ED_vgroup_nr_vert_add(ob, ob->actdef-1, a, weight, WEIGHT_REPLACE);
		}
	}
}
Ejemplo n.º 16
0
static void vgroup_delete_edit_mode(Object *ob)
{
	bDeformGroup *defgroup;
	int i;

	if(!ob->actdef)
		return;

	defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
	if(!defgroup)
		return;

	/* Make sure that no verts are using this group */
	vgroup_active_remove_verts(ob, 1);

	/* Make sure that any verts with higher indices are adjusted accordingly */
	if(ob->type==OB_MESH) {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);
		EditVert *eve;
		MDeformVert *dvert;
		
		for(eve=em->verts.first; eve; eve=eve->next){
			dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);

			if(dvert)
				for(i=0; i<dvert->totweight; i++)
					if(dvert->dw[i].def_nr > (ob->actdef-1))
						dvert->dw[i].def_nr--;
		}
		BKE_mesh_end_editmesh(me, em);
	}
	else if(ob->type==OB_LATTICE) {
		Lattice *lt= vgroup_edit_lattice(ob);
		BPoint *bp;
		MDeformVert *dvert= lt->dvert;
		int a, tot;
		
		if(dvert) {
			tot= lt->pntsu*lt->pntsv*lt->pntsw;
			for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) {
				for(i=0; i<dvert->totweight; i++){
					if(dvert->dw[i].def_nr > (ob->actdef-1))
						dvert->dw[i].def_nr--;
				}
			}
		}
	}

	vgroup_delete_update_users(ob, ob->actdef);

	/* Update the active deform index if necessary */
	if(ob->actdef==BLI_countlist(&ob->defbase))
		ob->actdef--;
	
	/* Remove the group */
	BLI_freelinkN (&ob->defbase, defgroup);
	
	/* remove all dverts */
	if(ob->actdef==0) {
		if(ob->type==OB_MESH) {
			Mesh *me= ob->data;
			CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
			me->dvert= NULL;
		}
		else if(ob->type==OB_LATTICE) {
			Lattice *lt= vgroup_edit_lattice(ob);
			if(lt->dvert) {
				MEM_freeN(lt->dvert);
				lt->dvert= NULL;
			}
		}
	}
}
Ejemplo n.º 17
0
/* is used for both read and write... */
static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
{
	uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL;
	MDeformVert *dvert=NULL;
	TransformProperties *tfp;
	float median[6], ve_median[6];
	int tot, totw, totweight, totedge, totradius;
	char defstr[320];
	
	median[0]= median[1]= median[2]= median[3]= median[4]= median[5]= 0.0;
	tot= totw= totweight= totedge= totradius= 0;
	defstr[0]= 0;

	/* make sure we got storage */
	if(v3d->properties_storage==NULL)
		v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
	tfp= v3d->properties_storage;
	
	if(ob->type==OB_MESH) {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);
		EditVert *eve, *evedef=NULL;
		EditEdge *eed;
		
		eve= em->verts.first;
		while(eve) {
			if(eve->f & SELECT) {
				evedef= eve;
				tot++;
				add_v3_v3(median, eve->co);
			}
			eve= eve->next;
		}
		eed= em->edges.first;
		while(eed) {
			if((eed->f & SELECT)) {
				totedge++;
				median[3]+= eed->crease;
			}
			eed= eed->next;
		}

		/* check for defgroups */
		if(evedef)
			dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT);
		if(tot==1 && dvert && dvert->totweight) {
			bDeformGroup *dg;
			int i, max=1, init=1;
			char str[320];
			
			for (i=0; i<dvert->totweight; i++){
				dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
				if(dg) {
					max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); 
					if(max<320) strcat(defstr, str);
				}

				if(tfp->curdef==dvert->dw[i].def_nr) {
					init= 0;
					tfp->defweightp= &dvert->dw[i].weight;
				}
			}
			
			if(init) {	// needs new initialized 
				tfp->curdef= dvert->dw[0].def_nr;
				tfp->defweightp= &dvert->dw[0].weight;
			}
		}

		BKE_mesh_end_editmesh(me, em);
	}
	else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
		Curve *cu= ob->data;
		Nurb *nu;
		BPoint *bp;
		BezTriple *bezt;
		int a;
		ListBase *nurbs= ED_curve_editnurbs(cu);

		nu= nurbs->first;
		while(nu) {
			if(nu->type == CU_BEZIER) {
				bezt= nu->bezt;
				a= nu->pntsu;
				while(a--) {
					if(bezt->f2 & SELECT) {
						add_v3_v3(median, bezt->vec[1]);
						tot++;
						median[4]+= bezt->weight;
						totweight++;
						median[5]+= bezt->radius;
						totradius++;
					}
					else {
						if(bezt->f1 & SELECT) {
							add_v3_v3(median, bezt->vec[0]);
							tot++;
						}
						if(bezt->f3 & SELECT) {
							add_v3_v3(median, bezt->vec[2]);
							tot++;
						}
					}
					bezt++;
				}
			}
			else {
				bp= nu->bp;
				a= nu->pntsu*nu->pntsv;
				while(a--) {
					if(bp->f1 & SELECT) {
						add_v3_v3(median, bp->vec);
						median[3]+= bp->vec[3];
						totw++;
						tot++;
						median[4]+= bp->weight;
						totweight++;
						median[5]+= bp->radius;
						totradius++;
					}
					bp++;
				}
			}
			nu= nu->next;
		}
	}
	else if(ob->type==OB_LATTICE) {
		Lattice *lt= ob->data;
		BPoint *bp;
		int a;
		
		a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw;
		bp= lt->editlatt->latt->def;
		while(a--) {
			if(bp->f1 & SELECT) {
				add_v3_v3(median, bp->vec);
				tot++;
				median[4]+= bp->weight;
				totweight++;
			}
			bp++;
		}
	}
	
	if(tot==0) {
		uiDefBut(block, LABEL, 0, "Nothing selected",0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
		return;
	}
	median[0] /= (float)tot;
	median[1] /= (float)tot;
	median[2] /= (float)tot;
	if(totedge) median[3] /= (float)totedge;
	else if(totw) median[3] /= (float)totw;
	if(totweight) median[4] /= (float)totweight;
	if(totradius) median[5] /= (float)totradius;
	
	if(v3d->flag & V3D_GLOBAL_STATS)
		mul_m4_v3(ob->obmat, median);
	
	if(block) {	// buttons
		uiBut *but;

		memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
		
		uiBlockBeginAlign(block);
		if(tot==1) {
			uiDefBut(block, LABEL, 0, "Vertex:",					0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
			uiBlockBeginAlign(block);

			but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",		0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
			uiButSetUnitType(but, PROP_UNIT_LENGTH);
			but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",		0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
			uiButSetUnitType(but, PROP_UNIT_LENGTH);
			but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",		0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
			uiButSetUnitType(but, PROP_UNIT_LENGTH);

			if(totw==1) {
				uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",	0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, "");
				uiBlockBeginAlign(block);
				uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",		0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
				uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",		100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
				uiBlockEndAlign(block);
				if(totweight)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",	0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "");
				if(totradius)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",	0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs");
				}
			else {
				uiBlockBeginAlign(block);
				uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",		0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
				uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",		100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
				uiBlockEndAlign(block);
				if(totweight)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",	0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
				if(totradius)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",	0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs");
			}
		}
		else {
			uiDefBut(block, LABEL, 0, "Median:",					0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
			uiBlockBeginAlign(block);
			but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",		0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
			uiButSetUnitType(but, PROP_UNIT_LENGTH);
			but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",		0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
			uiButSetUnitType(but, PROP_UNIT_LENGTH);
			but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",		0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
			uiButSetUnitType(but, PROP_UNIT_LENGTH);
			if(totw==tot) {
				uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",	0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, "");
				uiBlockEndAlign(block);
				uiBlockBeginAlign(block);
				uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",		0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
				uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",		100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
				uiBlockEndAlign(block);
				if(totweight)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",	0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
				if(totradius)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",	0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs");
				uiBlockEndAlign(block);
			}
			else {
				uiBlockBeginAlign(block);
				uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",		0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
				uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",		100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
				uiBlockEndAlign(block);
				if(totweight)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",	0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "Weight is used for SoftBody Goal");
				if(totradius)
					uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",	0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs");
				uiBlockEndAlign(block);
			}
		}
				
		if(totedge==1)
			uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:",	0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, "");
		else if(totedge>1)
			uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Crease:",	0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, "");
		
	}
	else {	// apply
		memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
		
		if(v3d->flag & V3D_GLOBAL_STATS) {
			invert_m4_m4(ob->imat, ob->obmat);
			mul_m4_v3(ob->imat, median);
			mul_m4_v3(ob->imat, ve_median);
		}
		sub_v3_v3v3(median, ve_median, median);
		median[3]= ve_median[3]-median[3];
		median[4]= ve_median[4]-median[4];
		median[5]= ve_median[5]-median[5];
		
		if(ob->type==OB_MESH) {
			Mesh *me= ob->data;
			EditMesh *em = BKE_mesh_get_editmesh(me);

			/* allow for some rounding error becasue of matrix transform */
			if(len_v3(median) > 0.000001f) {
				EditVert *eve;

				for(eve= em->verts.first; eve; eve= eve->next) {
					if(eve->f & SELECT) {
						add_v3_v3(eve->co, median);
					}
				}

				recalc_editnormals(em);
			}

			if(median[3] != 0.0f) {
				EditEdge *eed;
				const float fixed_crease= (ve_median[3] <= 0.0f ? 0.0f : (ve_median[3] >= 1.0f ? 1.0f : FLT_MAX));
				
				if(fixed_crease != FLT_MAX) {
					/* simple case */

					for(eed= em->edges.first; eed; eed= eed->next) {
						if(eed->f & SELECT) {
							eed->crease= fixed_crease;
						}
					}
				}
				else {
					/* scale crease to target median */
					float median_new= ve_median[3];
					float median_orig= ve_median[3] - median[3]; /* previous median value */

					/* incase of floating point error */
					CLAMP(median_orig, 0.0f, 1.0f);
					CLAMP(median_new, 0.0f, 1.0f);

					if(median_new < median_orig) {
						/* scale down */
						const float sca= median_new / median_orig;
						
						for(eed= em->edges.first; eed; eed= eed->next) {
							if(eed->f & SELECT) {
								eed->crease *= sca;
								CLAMP(eed->crease, 0.0f, 1.0f);
							}
						}
					}
					else {
						/* scale up */
						const float sca= (1.0f - median_new) / (1.0f - median_orig);

						for(eed= em->edges.first; eed; eed= eed->next) {
							if(eed->f & SELECT) {
								eed->crease = 1.0f - ((1.0f - eed->crease) * sca);
								CLAMP(eed->crease, 0.0f, 1.0f);
							}
						}
					}
				}
			}

			BKE_mesh_end_editmesh(me, em);
		}
		else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
			Curve *cu= ob->data;
			Nurb *nu;
			BPoint *bp;
			BezTriple *bezt;
			int a;
			ListBase *nurbs= ED_curve_editnurbs(cu);

			nu= nurbs->first;
			while(nu) {
				if(nu->type == CU_BEZIER) {
					bezt= nu->bezt;
					a= nu->pntsu;
					while(a--) {
						if(bezt->f2 & SELECT) {
							add_v3_v3(bezt->vec[0], median);
							add_v3_v3(bezt->vec[1], median);
							add_v3_v3(bezt->vec[2], median);
							bezt->weight+= median[4];
							bezt->radius+= median[5];
						}
						else {
							if(bezt->f1 & SELECT) {
								add_v3_v3(bezt->vec[0], median);
							}
							if(bezt->f3 & SELECT) {
								add_v3_v3(bezt->vec[2], median);
							}
						}
						bezt++;
					}
				}
				else {
					bp= nu->bp;
					a= nu->pntsu*nu->pntsv;
					while(a--) {
						if(bp->f1 & SELECT) {
							add_v3_v3(bp->vec, median);
							bp->vec[3]+= median[3];
							bp->weight+= median[4];
							bp->radius+= median[5];
						}
						bp++;
					}
				}
				test2DNurb(nu);
				testhandlesNurb(nu); /* test for bezier too */

				nu= nu->next;
			}
		}
		else if(ob->type==OB_LATTICE) {
			Lattice *lt= ob->data;
			BPoint *bp;
			int a;
			
			a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw;
			bp= lt->editlatt->latt->def;
			while(a--) {
				if(bp->f1 & SELECT) {
					add_v3_v3(bp->vec, median);
					bp->weight+= median[4];
				}
				bp++;
			}
		}
		
//		ED_undo_push(C, "Transform properties");
	}
}
Ejemplo n.º 18
0
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
{
	wmWindow *win= CTX_wm_window(C);
	ToolSettings *ts= CTX_data_tool_settings(C);
	ScrArea *sa= CTX_wm_area(C);
	View3D *v3d= sa->spacedata.first;
	Object *obedit = CTX_data_edit_object(C);
	EditMesh *em= NULL;
	int ctrl= win->eventstate->ctrl, shift= win->eventstate->shift;
	PointerRNA props_ptr;
	
	if(obedit && obedit->type==OB_MESH) {
		em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
	}
	/* watch it: if sa->win does not exist, check that when calling direct drawing routines */

	switch(event) {
	case B_REDR:
		ED_area_tag_redraw(sa);
		break;
		
	case B_MODESELECT:
		WM_operator_properties_create(&props_ptr, "OBJECT_OT_mode_set");
		RNA_enum_set(&props_ptr, "mode", v3d->modeselect);
		WM_operator_name_call(C, "OBJECT_OT_mode_set", WM_OP_EXEC_REGION_WIN, &props_ptr);
		WM_operator_properties_free(&props_ptr);
		break;		
		
	case B_SEL_VERT:
		if(em) {
			if(shift==0 || em->selectmode==0)
				em->selectmode= SCE_SELECT_VERTEX;
			ts->selectmode= em->selectmode;
			EM_selectmode_set(em);
			WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
			ED_undo_push(C, "Selectmode Set: Vertex");
		}
		break;
	case B_SEL_EDGE:
		if(em) {
			if(shift==0 || em->selectmode==0){
				if( (em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX){
					if(ctrl) EM_convertsel(em, SCE_SELECT_VERTEX,SCE_SELECT_EDGE); 
				}
				em->selectmode = SCE_SELECT_EDGE;
			}
			ts->selectmode= em->selectmode;
			EM_selectmode_set(em);
			WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
			ED_undo_push(C, "Selectmode Set: Edge");
		}
		break;
	case B_SEL_FACE:
		if(em) {
			if( shift==0 || em->selectmode==0){
				if( ((em->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((em->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)){
					if(ctrl)
						EM_convertsel(em, (em->selectmode ^ SCE_SELECT_FACE),SCE_SELECT_FACE);
				}
				em->selectmode = SCE_SELECT_FACE;
			}
			ts->selectmode= em->selectmode;
			EM_selectmode_set(em);
			WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
			ED_undo_push(C, "Selectmode Set: Face");
		}
		break;	

	case B_MAN_TRANS:
		if( shift==0 || v3d->twtype==0) {
			v3d->twtype= V3D_MANIP_TRANSLATE;
		}
		ED_area_tag_redraw(sa);
		break;
	case B_MAN_ROT:
		if( shift==0 || v3d->twtype==0) {
			v3d->twtype= V3D_MANIP_ROTATE;
		}
		ED_area_tag_redraw(sa);
		break;
	case B_MAN_SCALE:
		if( shift==0 || v3d->twtype==0) {
			v3d->twtype= V3D_MANIP_SCALE;
		}
		ED_area_tag_redraw(sa);
		break;
	case B_NDOF:
		ED_area_tag_redraw(sa);
		break;
	case B_MAN_MODE:
		ED_area_tag_redraw(sa);
		break;
	default:
		break;
	}

	if(obedit && obedit->type==OB_MESH)
		BKE_mesh_end_editmesh(obedit->data, em);
}
Ejemplo n.º 19
0
Archivo: anim.c Proyecto: jinjoh/NOOR
static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
{
	Object *ob, *ob_iter;
	Mesh *me= par->data;
	Base *base = NULL;
	DerivedMesh *dm;
	struct vertexDupliData vdd;
	Scene *sce = NULL;
	Group *group = NULL;
	GroupObject * go = NULL;
	EditMesh *em;
	float vec[3], no[3], pmat[4][4];
	int lay, totvert, a, oblay;
	
	Mat4CpyMat4(pmat, par->obmat);
	
	/* simple preventing of too deep nested groups */
	if(level>MAX_DUPLI_RECUR) return;
	
	em = BKE_mesh_get_editmesh(me);
	
	if(em) {
		dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
		BKE_mesh_end_editmesh(me, em);
	} else
		dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
	
	if(G.rendering) {
		vdd.orco= (float(*)[3])get_mesh_orco_verts(par);
		transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0);
	}
	else
		vdd.orco= NULL;
	
	totvert = dm->getNumVerts(dm);

	/* having to loop on scene OR group objects is NOT FUN */
	if (GS(id->name) == ID_SCE) {
		sce = (Scene *)id;
		lay= sce->lay;
		base= sce->base.first;
	} else {
		group = (Group *)id;
		lay= group->layer;
		go = group->gobject.first;
	}
	
	/* Start looping on Scene OR Group objects */
	while (base || go) { 
		if (sce) {
			ob_iter= base->object;
			oblay = base->lay;
		} else {
			ob_iter= go->ob;
			oblay = ob_iter->lay;
		}
		
		if (lay & oblay && scene->obedit!=ob_iter) {
			ob=ob_iter->parent;
			while(ob) {
				if(ob==par) {
					ob = ob_iter;
	/* End Scene/Group object loop, below is generic */
					
					
					/* par_space_mat - only used for groups so we can modify the space dupli's are in
					   when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
					*/
					if(par_space_mat)
						Mat4MulMat4(vdd.obmat, ob->obmat, par_space_mat);
					else
						Mat4CpyMat4(vdd.obmat, ob->obmat);

					vdd.id= id;
					vdd.level= level;
					vdd.animated= animated;
					vdd.lb= lb;
					vdd.ob= ob;
					vdd.scene= scene;
					vdd.par= par;
					Mat4CpyMat4(vdd.pmat, pmat);
					
					/* mballs have a different dupli handling */
					if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;	/* doesnt render */

					if(par->mode & OB_MODE_EDIT) {
						dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd);
					}
					else {
						for(a=0; a<totvert; a++) {
							dm->getVertCo(dm, a, vec);
							dm->getVertNo(dm, a, no);
							
							vertex_dupli__mapFunc(&vdd, a, vec, no, NULL);
						}
					}
					
					break;
				}
				ob= ob->parent;
			}
		}
		if (sce)	base= base->next;	/* scene loop */
		else		go= go->next;		/* group loop */
	}

	if(vdd.orco)
		MEM_freeN(vdd.orco);
	dm->release(dm);
}
Ejemplo n.º 20
0
/* return 1: success */
static int mesh_separate_selected(wmOperator *op, Main *bmain, Scene *scene, Base *editbase)
{
	EditMesh *em, *emnew;
	EditVert *eve, *v1;
	EditEdge *eed, *e1;
	EditFace *efa, *f1;
	Object *obedit;
	Mesh *me, *menew;
	Base *basenew;
	
	if(editbase==NULL) return 0;
	
	obedit= editbase->object;
	me= obedit->data;
	em= BKE_mesh_get_editmesh(me);
	if(me->key) {
		BKE_report(op->reports, RPT_WARNING, "Can't separate mesh with shape keys");
		BKE_mesh_end_editmesh(me, em);
		return 0;
	}
	
	if(em->selected.first) 
		BLI_freelistN(&(em->selected)); /* clear the selection order */
		
	EM_selectmode_set(em);	// enforce full consistent selection flags 
	
	EM_stats_update(em);
	
	if(em->totvertsel==0) {
		BKE_mesh_end_editmesh(me, em);
		return 0;
	}
	
	/* we are going to work as follows:
	 * 1. add a linked duplicate object: this will be the new one, we remember old pointer
	 * 2. give new object empty mesh and put in editmode
	 * 3: do a split if needed on current editmesh.
	 * 4. copy over: all NOT selected verts, edges, faces
	 * 5. call load_editMesh() on the new object
	 */
	
	/* 1 */
	basenew= ED_object_add_duplicate(bmain, scene, editbase, 0);	/* 0 = fully linked */
	ED_base_object_select(basenew, BA_DESELECT);
	
	/* 2 */
	basenew->object->data= menew= add_mesh(me->id.name+2);	/* empty */
	assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
	me->id.us--;
	make_editMesh(scene, basenew->object);
	emnew= menew->edit_mesh;
	CustomData_copy(&em->vdata, &emnew->vdata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
	CustomData_copy(&em->edata, &emnew->edata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
	CustomData_copy(&em->fdata, &emnew->fdata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
	
	/* 3 */
	/* SPLIT: first make duplicate */
	adduplicateflag(em, SELECT);
	/* SPLIT: old faces have 3x flag 128 set, delete these ones */
	delfaceflag(em, 128);
	/* since we do tricky things with verts/edges/faces, this makes sure all is selected coherent */
	EM_selectmode_set(em);
	
	/* 4 */
	/* move over: everything that is selected */
	for(eve= em->verts.first; eve; eve= v1) {
		v1= eve->next;
		if(eve->f & SELECT) {
			BLI_remlink(&em->verts, eve);
			BLI_addtail(&emnew->verts, eve);
		}
	}
	
	for(eed= em->edges.first; eed; eed= e1) {
		e1= eed->next;
		if(eed->f & SELECT) {
			BLI_remlink(&em->edges, eed);
			BLI_addtail(&emnew->edges, eed);
		}
	}
	
	for(efa= em->faces.first; efa; efa= f1) {
		f1= efa->next;
		if (efa == em->act_face && (efa->f & SELECT)) {
			EM_set_actFace(em, NULL);
		}

		if(efa->f & SELECT) {
			BLI_remlink(&em->faces, efa);
			BLI_addtail(&emnew->faces, efa);
		}
	}

	/* 5 */
	load_editMesh(scene, basenew->object);
	free_editMesh(emnew);
	MEM_freeN(menew->edit_mesh);
	menew->edit_mesh= NULL;

	/* copy settings */
	menew->texflag= me->texflag;
	menew->drawflag= me->drawflag;
	menew->flag= me->flag;
	menew->editflag= me->editflag;
	menew->smoothresh= me->smoothresh;

	/* hashedges are invalid now, make new! */
	editMesh_set_hash(em);

	DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);	
	DAG_id_tag_update(&basenew->object->id, OB_RECALC_DATA);	

	BKE_mesh_end_editmesh(me, em);

	return 1;
}
Ejemplo n.º 21
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);
}
Ejemplo n.º 22
0
Archivo: anim.c Proyecto: jinjoh/NOOR
static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
{
	Object *ob, *ob_iter;
	Base *base = NULL;
	DupliObject *dob;
	DerivedMesh *dm;
	Mesh *me= par->data;
	MTFace *mtface;
	MFace *mface;
	MVert *mvert;
	float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w;
	int lay, oblay, totface, a;
	Scene *sce = NULL;
	Group *group = NULL;
	GroupObject *go = NULL;
	EditMesh *em;
	float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
	
	/* simple preventing of too deep nested groups */
	if(level>MAX_DUPLI_RECUR) return;
	
	Mat4CpyMat4(pmat, par->obmat);
	
	em = BKE_mesh_get_editmesh(me);
	if(em) {
		int totvert;
		
		dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
		
		totface= dm->getNumFaces(dm);
		mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp");
		dm->copyFaceArray(dm, mface);
		totvert= dm->getNumVerts(dm);
		mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp");
		dm->copyVertArray(dm, mvert);

		BKE_mesh_end_editmesh(me, em);
	}
	else {
		dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
		
		totface= dm->getNumFaces(dm);
		mface= dm->getFaceArray(dm);
		mvert= dm->getVertArray(dm);
	}

	if(G.rendering) {

		orco= (float(*)[3])get_mesh_orco_verts(par);
		transform_mesh_orco_verts(me, orco, me->totvert, 0);
		mtface= me->mtface;
	}
	else {
		orco= NULL;
		mtface= NULL;
	}
	
	/* having to loop on scene OR group objects is NOT FUN */
	if (GS(id->name) == ID_SCE) {
		sce = (Scene *)id;
		lay= sce->lay;
		base= sce->base.first;
	} else {
		group = (Group *)id;
		lay= group->layer;
		go = group->gobject.first;
	}
	
	/* Start looping on Scene OR Group objects */
	while (base || go) { 
		if (sce) {
			ob_iter= base->object;
			oblay = base->lay;
		} else {
			ob_iter= go->ob;
			oblay = ob_iter->lay;
		}
		
		if (lay & oblay && scene->obedit!=ob_iter) {
			ob=ob_iter->parent;
			while(ob) {
				if(ob==par) {
					ob = ob_iter;
	/* End Scene/Group object loop, below is generic */
					
					/* par_space_mat - only used for groups so we can modify the space dupli's are in
					   when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
					*/
					if(par_space_mat)
						Mat4MulMat4(ob__obmat, ob->obmat, par_space_mat);
					else
						Mat4CpyMat4(ob__obmat, ob->obmat);
					
					Mat3CpyMat4(imat, ob->parentinv);
						
					/* mballs have a different dupli handling */
					if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;	/* doesnt render */

					for(a=0; a<totface; a++) {
						int mv1 = mface[a].v1;
						int mv2 = mface[a].v2;
						int mv3 = mface[a].v3;
						int mv4 = mface[a].v4;
						float *v1= mvert[mv1].co;
						float *v2= mvert[mv2].co;
						float *v3= mvert[mv3].co;
						float *v4= (mv4)? mvert[mv4].co: NULL;
						float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];

						/* translation */
						if(v4)
							CalcCent4f(cent, v1, v2, v3, v4);
						else
							CalcCent3f(cent, v1, v2, v3);
						Mat4MulVecfl(pmat, cent);
						
						VecSubf(cent, cent, pmat[3]);
						VecAddf(cent, cent, ob__obmat[3]);
						
						Mat4CpyMat4(obmat, ob__obmat);
						
						VECCOPY(obmat[3], cent);
						
						/* rotation */
						triatoquat(v1, v2, v3, quat);
						QuatToMat3(quat, mat);
						
						/* scale */
						if(par->transflag & OB_DUPLIFACES_SCALE) {
							float size= v4?AreaQ3Dfl(v1, v2, v3, v4):AreaT3Dfl(v1, v2, v3);
							size= sqrt(size) * par->dupfacesca;
							Mat3MulFloat(mat[0], size);
						}
						
						Mat3CpyMat3(mat3, mat);
						Mat3MulMat3(mat, imat, mat3);
						
						Mat4CpyMat4(tmat, obmat);
						Mat4MulMat43(obmat, tmat, mat);
						
						dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES, animated);
						if(G.rendering) {
							w= (mv4)? 0.25f: 1.0f/3.0f;

							if(orco) {
								VECADDFAC(dob->orco, dob->orco, orco[mv1], w);
								VECADDFAC(dob->orco, dob->orco, orco[mv2], w);
								VECADDFAC(dob->orco, dob->orco, orco[mv3], w);
								if(mv4)
									VECADDFAC(dob->orco, dob->orco, orco[mv4], w);
							}

							if(mtface) {
								dob->uv[0] += w*mtface[a].uv[0][0];
								dob->uv[1] += w*mtface[a].uv[0][1];
								dob->uv[0] += w*mtface[a].uv[1][0];
								dob->uv[1] += w*mtface[a].uv[1][1];
								dob->uv[0] += w*mtface[a].uv[2][0];
								dob->uv[1] += w*mtface[a].uv[2][1];

								if(mv4) {
									dob->uv[0] += w*mtface[a].uv[3][0];
									dob->uv[1] += w*mtface[a].uv[3][1];
								}
							}
						}
						
						if(ob->transflag & OB_DUPLI) {
							float tmpmat[4][4];
							Mat4CpyMat4(tmpmat, ob->obmat);
							Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */
							object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, level+1, animated);
							Mat4CpyMat4(ob->obmat, tmpmat);
						}
					}
					
					break;
				}
				ob= ob->parent;
			}
		}
		if (sce)	base= base->next;	/* scene loop */
		else		go= go->next;		/* group loop */
	}
	
	if(par->mode & OB_MODE_EDIT) {
		MEM_freeN(mface);
		MEM_freeN(mvert);
	}

	if(orco)
		MEM_freeN(orco);
	
	dm->release(dm);
}
Ejemplo n.º 23
0
static void meshdeformModifier_do(
	  ModifierData *md, Object *ob, DerivedMesh *dm,
	  float (*vertexCos)[3], int numVerts)
{
	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
	struct Mesh *me= (mmd->object)? mmd->object->data: NULL;
	struct EditMesh *em = (me)? BKE_mesh_get_editmesh(me): NULL;
	DerivedMesh *tmpdm, *cagedm;
	MDeformVert *dvert = NULL;
	MDefInfluence *influences;
	int *offsets;
	float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
	float weight, totweight, fac, co[3], (*dco)[3], (*bindcagecos)[3];
	int a, b, totvert, totcagevert, defgrp_index;
	float (*cagecos)[3];

	if(!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc))
		return;
	
	/* get cage derivedmesh */
	if(em) {
		tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0);
		if(tmpdm)
			tmpdm->release(tmpdm);
		BKE_mesh_end_editmesh(me, em);
	}
	else
		cagedm= mmd->object->derivedFinal;

	/* if we don't have one computed, use derivedmesh from data
	 * without any modifiers */
	if(!cagedm) {
		cagedm= get_dm(mmd->object, NULL, NULL, NULL, 0);
		if(cagedm)
			cagedm->needsFree= 1;
	}
	
	if(!cagedm) {
		modifier_setError(md, "Can't get mesh from cage object.");
		return;
	}

	/* compute matrices to go in and out of cage object space */
	invert_m4_m4(imat, mmd->object->obmat);
	mult_m4_m4m4(cagemat, imat, ob->obmat);
	mult_m4_m4m4(cmat, mmd->bindmat, cagemat);
	invert_m4_m4(iobmat, cmat);
	copy_m3_m4(icagemat, iobmat);

	/* bind weights if needed */
	if(!mmd->bindcagecos) {
		static int recursive = 0;

		/* progress bar redraw can make this recursive .. */
		if(!recursive) {
			recursive = 1;
			mmd->bindfunc(md->scene, mmd, (float*)vertexCos, numVerts, cagemat);
			recursive = 0;
		}
	}

	/* verify we have compatible weights */
	totvert= numVerts;
	totcagevert= cagedm->getNumVerts(cagedm);

	if(mmd->totvert != totvert) {
		modifier_setError(md, "Verts changed from %d to %d.", mmd->totvert, totvert);
		cagedm->release(cagedm);
		return;
	}
	else if (mmd->totcagevert != totcagevert) {
		modifier_setError(md, "Cage verts changed from %d to %d.", mmd->totcagevert, totcagevert);
		cagedm->release(cagedm);
		return;
	} else if (mmd->bindcagecos == NULL) {
		modifier_setError(md, "Bind data missing.");
		cagedm->release(cagedm);
		return;
	}

	cagecos= MEM_callocN(sizeof(*cagecos)*totcagevert, "meshdeformModifier vertCos");

	/* setup deformation data */
	cagedm->getVertCos(cagedm, cagecos);
	influences= mmd->bindinfluences;
	offsets= mmd->bindoffsets;
	bindcagecos= (float(*)[3])mmd->bindcagecos;

	dco= MEM_callocN(sizeof(*dco)*totcagevert, "MDefDco");
	for(a=0; a<totcagevert; a++) {
		/* get cage vertex in world space with binding transform */
		copy_v3_v3(co, cagecos[a]);

		if(G.rt != 527) {
			mul_m4_v3(mmd->bindmat, co);
			/* compute difference with world space bind coord */
			sub_v3_v3v3(dco[a], co, bindcagecos[a]);
		}
		else
			copy_v3_v3(dco[a], co);
	}

	modifier_get_vgroup(ob, dm, mmd->defgrp_name, &dvert, &defgrp_index);

	/* do deformation */
	fac= 1.0f;

	for(b=0; b<totvert; b++) {
		if(mmd->flag & MOD_MDEF_DYNAMIC_BIND)
			if(!mmd->dynverts[b])
				continue;

		if(dvert) {
			fac= defvert_find_weight(&dvert[b], defgrp_index);

			if (mmd->flag & MOD_MDEF_INVERT_VGROUP) {
				fac= 1.0f - fac;
			}

			if (fac <= 0.0f) {
				continue;
			}
		}

		if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
			/* transform coordinate into cage's local space */
			mul_v3_m4v3(co, cagemat, vertexCos[b]);
			totweight= meshdeform_dynamic_bind(mmd, dco, co);
		}
		else {
			totweight= 0.0f;
			zero_v3(co);

			for(a=offsets[b]; a<offsets[b+1]; a++) {
				weight= influences[a].weight;
				madd_v3_v3fl(co, dco[influences[a].vertex], weight);
				totweight += weight;
			}
		}

		if(totweight > 0.0f) {
			mul_v3_fl(co, fac/totweight);
			mul_m3_v3(icagemat, co);
			if(G.rt != 527)
				add_v3_v3(vertexCos[b], co);
			else
				copy_v3_v3(vertexCos[b], co);
		}
	}

	/* release cage derivedmesh */
	MEM_freeN(dco);
	MEM_freeN(cagecos);
	cagedm->release(cagedm);
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
/* draws uv's in the image space */
static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
{
	ToolSettings *ts;
	Mesh *me= obedit->data;
	EditMesh *em;
	EditFace *efa, *efa_act;
	MTFace *tf, *activetf = NULL;
	DerivedMesh *finaldm, *cagedm;
	char col1[4], col2[4];
	float pointsize;
	int drawfaces, interpedges, lastsel, sel;
	Image *ima= sima->image;
 	
	em= BKE_mesh_get_editmesh(me);
	activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */

	ts= scene->toolsettings;

	drawfaces= draw_uvs_face_check(scene);
	if(ts->uv_flag & UV_SYNC_SELECTION)
		interpedges= (ts->selectmode & SCE_SELECT_VERTEX);
	else
		interpedges= (ts->uv_selectmode == UV_SELECT_VERTEX);
	
	/* draw other uvs */
	if(sima->flag & SI_DRAW_OTHER)
		draw_uvs_other(sima, scene, obedit, activetf);

	/* 1. draw shadow mesh */
	
	if(sima->flag & SI_DRAWSHADOW) {
		/* first try existing derivedmesh */
		if(!draw_uvs_dm_shadow(em->derivedFinal)) {
			/* create one if it does not exist */
			cagedm = editmesh_get_derived_cage_and_final(scene, obedit, em, &finaldm, CD_MASK_BAREMESH|CD_MASK_MTFACE);

			/* when sync selection is enabled, all faces are drawn (except for hidden)
			 * so if cage is the same as the final, theres no point in drawing this */
			if(!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
				draw_uvs_dm_shadow(finaldm);
			
			/* release derivedmesh again */
			if(cagedm != finaldm) cagedm->release(cagedm);
			finaldm->release(finaldm);
		}
	}
	
	/* 2. draw colored faces */
	
	if(sima->flag & SI_DRAW_STRETCH) {
		draw_uvs_stretch(sima, scene, em, activetf);
	}
	else if(me->drawflag & ME_DRAWFACES) {
		/* draw transparent faces */
		UI_GetThemeColor4ubv(TH_FACE, col1);
		UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);
		
		for(efa= em->faces.first; efa; efa= efa->next) {
			tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
			
			if(uvedit_face_visible(scene, ima, efa, tf)) {
				efa->tmp.p = tf;
				if(tf==activetf) continue; /* important the temp pointer is set above */

				if(uvedit_face_selected(scene, efa, tf))
					glColor4ubv((GLubyte *)col2);
				else
					glColor4ubv((GLubyte *)col1);
					
				glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
					glVertex2fv(tf->uv[0]);
					glVertex2fv(tf->uv[1]);
					glVertex2fv(tf->uv[2]);
					if(efa->v4) glVertex2fv(tf->uv[3]);
				glEnd();
			}
			else {
				if(tf == activetf)
					activetf= NULL;
				efa->tmp.p = NULL;
			}
		}
		glDisable(GL_BLEND);
	}
	else {
		/* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
		for(efa= em->faces.first; efa; efa= efa->next) {
			tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);

			if(uvedit_face_visible(scene, ima, efa, tf)) {		
				efa->tmp.p = tf;
			}
			else {
				if(tf == activetf)
					activetf= NULL;
				efa->tmp.p = NULL;
			}
		}
		
	}
	
	/* 3. draw active face stippled */

	if(activetf) {
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		UI_ThemeColor4(TH_EDITMESH_ACTIVE);

		glEnable(GL_POLYGON_STIPPLE);
		glPolygonStipple(stipple_quarttone);

		glBegin(efa_act->v4? GL_QUADS: GL_TRIANGLES);
			glVertex2fv(activetf->uv[0]);
			glVertex2fv(activetf->uv[1]);
			glVertex2fv(activetf->uv[2]);
			if(efa_act->v4) glVertex2fv(activetf->uv[3]);
		glEnd();

		glDisable(GL_POLYGON_STIPPLE);
		glDisable(GL_BLEND);
	}
	
	/* 4. draw edges */

	if(sima->flag & SI_SMOOTH_UV) {
		glEnable(GL_LINE_SMOOTH);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
	
	switch(sima->dt_uv) {
		case SI_UVDT_DASH:
			for(efa= em->faces.first; efa; efa= efa->next) {
				tf= (MTFace *)efa->tmp.p; /* visible faces cached */

				if(tf) {
					cpack(0x111111);

					glBegin(GL_LINE_LOOP);
						glVertex2fv(tf->uv[0]);
						glVertex2fv(tf->uv[1]);
						glVertex2fv(tf->uv[2]);
						if(efa->v4) glVertex2fv(tf->uv[3]);
					glEnd();
				
					setlinestyle(2);
					cpack(0x909090);

					glBegin(GL_LINE_STRIP);
						glVertex2fv(tf->uv[0]);
						glVertex2fv(tf->uv[1]);
					glEnd();
		
					glBegin(GL_LINE_STRIP);
						glVertex2fv(tf->uv[0]);
						if(efa->v4) glVertex2fv(tf->uv[3]);
						else glVertex2fv(tf->uv[2]);
					glEnd();
		
					glBegin(GL_LINE_STRIP);
						glVertex2fv(tf->uv[1]);
						glVertex2fv(tf->uv[2]);
						if(efa->v4) glVertex2fv(tf->uv[3]);
					glEnd();

					setlinestyle(0);
				}
			}
			break;
		case SI_UVDT_BLACK: /* black/white */
		case SI_UVDT_WHITE: 
			if(sima->dt_uv==SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f);
			else glColor3f(0.0f, 0.0f, 0.0f);

			for(efa= em->faces.first; efa; efa= efa->next) {
				tf= (MTFace *)efa->tmp.p; /* visible faces cached */

				if(tf) {
					glBegin(GL_LINE_LOOP);
						glVertex2fv(tf->uv[0]);
						glVertex2fv(tf->uv[1]);
						glVertex2fv(tf->uv[2]);
						if(efa->v4) glVertex2fv(tf->uv[3]);
					glEnd();
				}
			}
			break;
		case SI_UVDT_OUTLINE:
			glLineWidth(3);
			cpack(0x0);
			
			for(efa= em->faces.first; efa; efa= efa->next) {
				tf= (MTFace *)efa->tmp.p; /* visible faces cached */

				if(tf) {
					glBegin(GL_LINE_LOOP);
						glVertex2fv(tf->uv[0]);
						glVertex2fv(tf->uv[1]);
						glVertex2fv(tf->uv[2]);
						if(efa->v4) glVertex2fv(tf->uv[3]);
					glEnd();
				}
			}
			
			glLineWidth(1);
			col2[0] = col2[1] = col2[2] = 192; col2[3] = 255;
			glColor4ubv((unsigned char *)col2); 
			
			if(me->drawflag & ME_DRAWEDGES) {
				UI_GetThemeColor4ubv(TH_VERTEX_SELECT, col1);
				lastsel = sel = 0;

				if(interpedges) {
					glShadeModel(GL_SMOOTH);

					for(efa= em->faces.first; efa; efa= efa->next) {
						tf= (MTFace *)efa->tmp.p; /* visible faces cached */

						if(tf) {
							glBegin(GL_LINE_LOOP);
							sel = (uvedit_uv_selected(scene, efa, tf, 0)? 1 : 0);
							if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
							glVertex2fv(tf->uv[0]);
							
							sel = uvedit_uv_selected(scene, efa, tf, 1)? 1 : 0;
							if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
							glVertex2fv(tf->uv[1]);
							
							sel = uvedit_uv_selected(scene, efa, tf, 2)? 1 : 0;
							if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
							glVertex2fv(tf->uv[2]);
							
							if(efa->v4) {
								sel = uvedit_uv_selected(scene, efa, tf, 3)? 1 : 0;
								if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
								glVertex2fv(tf->uv[3]);
							}
							
							glEnd();
						}
					}

					glShadeModel(GL_FLAT);
				}
				else {
					for(efa= em->faces.first; efa; efa= efa->next) {
						tf= (MTFace *)efa->tmp.p; /* visible faces cached */

						if(tf) {
							glBegin(GL_LINES);
							sel = (uvedit_edge_selected(scene, efa, tf, 0)? 1 : 0);
							if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
							glVertex2fv(tf->uv[0]);
							glVertex2fv(tf->uv[1]);
							
							sel = uvedit_edge_selected(scene, efa, tf, 1)? 1 : 0;
							if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
							glVertex2fv(tf->uv[1]);
							glVertex2fv(tf->uv[2]);
							
							sel = uvedit_edge_selected(scene, efa, tf, 2)? 1 : 0;
							if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
							glVertex2fv(tf->uv[2]);
							
							if(efa->v4) {
								glVertex2fv(tf->uv[3]);

								sel = uvedit_edge_selected(scene, efa, tf, 3)? 1 : 0;
								if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
								glVertex2fv(tf->uv[3]);
							}

							glVertex2fv(tf->uv[0]);
							
							glEnd();
						}
					}
				}
			}
			else {
				/* no nice edges */
				for(efa= em->faces.first; efa; efa= efa->next) {
					tf= (MTFace *)efa->tmp.p; /* visible faces cached */

					if(tf) {
						glBegin(GL_LINE_LOOP);
							glVertex2fv(tf->uv[0]);
							glVertex2fv(tf->uv[1]);
							glVertex2fv(tf->uv[2]);
							if(efa->v4) glVertex2fv(tf->uv[3]);
						glEnd();
					}
				}
			}
			
			break;
	}

	if(sima->flag & SI_SMOOTH_UV) {
		glDisable(GL_LINE_SMOOTH);
		glDisable(GL_BLEND);
	}

	/* 5. draw face centers */

	if(drawfaces) {
		float cent[2];
		
		pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
		glPointSize(pointsize); // TODO - drawobject.c changes this value after - Investigate!
		
	    /* unselected faces */
		UI_ThemeColor(TH_WIRE);

		bglBegin(GL_POINTS);
		for(efa= em->faces.first; efa; efa= efa->next) {
			tf= (MTFace *)efa->tmp.p; /* visible faces cached */

			if(tf && !uvedit_face_selected(scene, efa, tf)) {
				uv_center(tf->uv, cent, efa->v4 != NULL);
				bglVertex2fv(cent);
			}
		}
		bglEnd();

		/* selected faces */
		UI_ThemeColor(TH_FACE_DOT);

		bglBegin(GL_POINTS);
		for(efa= em->faces.first; efa; efa= efa->next) {
			tf= (MTFace *)efa->tmp.p; /* visible faces cached */

			if(tf && uvedit_face_selected(scene, efa, tf)) {
				uv_center(tf->uv, cent, efa->v4 != NULL);
				bglVertex2fv(cent);
			}
		}
		bglEnd();
	}

	/* 6. draw uv vertices */
	
	if(drawfaces != 2) { /* 2 means Mesh Face Mode */
	    /* unselected uvs */
		UI_ThemeColor(TH_VERTEX);
		pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
		glPointSize(pointsize);
	
		bglBegin(GL_POINTS);
		for(efa= em->faces.first; efa; efa= efa->next) {
			tf= (MTFace *)efa->tmp.p; /* visible faces cached */

			if(tf) {
				if(!uvedit_uv_selected(scene, efa, tf, 0))
					bglVertex2fv(tf->uv[0]);
				if(!uvedit_uv_selected(scene, efa, tf, 1))
					bglVertex2fv(tf->uv[1]);
				if(!uvedit_uv_selected(scene, efa, tf, 2))
					bglVertex2fv(tf->uv[2]);
				if(efa->v4 && !uvedit_uv_selected(scene, efa, tf, 3))
					bglVertex2fv(tf->uv[3]);
			}
		}
		bglEnd();
	
		/* pinned uvs */
		/* give odd pointsizes odd pin pointsizes */
	    glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0));
		cpack(0xFF);
	
		bglBegin(GL_POINTS);
		for(efa= em->faces.first; efa; efa= efa->next) {
			tf= (MTFace *)efa->tmp.p; /* visible faces cached */

			if(tf) {
				if(tf->unwrap & TF_PIN1)
					bglVertex2fv(tf->uv[0]);
				if(tf->unwrap & TF_PIN2)
					bglVertex2fv(tf->uv[1]);
				if(tf->unwrap & TF_PIN3)
					bglVertex2fv(tf->uv[2]);
				if(efa->v4 && (tf->unwrap & TF_PIN4))
					bglVertex2fv(tf->uv[3]);
			}
		}
		bglEnd();
	
		/* selected uvs */
		UI_ThemeColor(TH_VERTEX_SELECT);
	    glPointSize(pointsize);
	
		bglBegin(GL_POINTS);
		for(efa= em->faces.first; efa; efa= efa->next) {
			tf= (MTFace *)efa->tmp.p; /* visible faces cached */

			if(tf) {
				if(uvedit_uv_selected(scene, efa, tf, 0))
					bglVertex2fv(tf->uv[0]);
				if(uvedit_uv_selected(scene, efa, tf, 1))
					bglVertex2fv(tf->uv[1]);
				if(uvedit_uv_selected(scene, efa, tf, 2))
					bglVertex2fv(tf->uv[2]);
				if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))
					bglVertex2fv(tf->uv[3]);
			}
		}
		bglEnd();	
	}

	glPointSize(1.0);
	BKE_mesh_end_editmesh(obedit->data, em);
}