Example #1
0
static void editvert_mirror_update(Object *ob, EditVert *eve, int def_nr, int index)
{
	Mesh *me= ob->data;
	EditMesh *em = BKE_mesh_get_editmesh(me);
	EditVert *eve_mirr;

	eve_mirr= editmesh_get_x_mirror_vert(ob, em, eve, eve->co, index);

	if(eve_mirr && eve_mirr != eve) {
		MDeformVert *dvert_src= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
		MDeformVert *dvert_dst= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT);
		if(dvert_dst) {
			if(def_nr == -1) {
				/* all vgroups, add groups where neded  */

				int *flip_map= defgroup_flip_map(ob, 1);
				defvert_sync_mapped(dvert_dst, dvert_src, flip_map, 1);
				MEM_freeN(flip_map);
			}
			else {
				/* single vgroup */
				MDeformWeight *dw= defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1));
				if(dw) {
					dw->weight= defvert_find_weight(dvert_src, def_nr);
				}
			}
		}
	}
}
Example #2
0
static void vgroup_copy_active_to_sel(Object *ob)
{
	EditVert *eve_act;
	MDeformVert *dvert_act;

	act_vert_def(ob, &eve_act, &dvert_act);

	if(dvert_act==NULL) {
		return;
	}
	else {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);
		EditVert *eve;
		MDeformVert *dvert;
		int index= 0;

		for(eve= em->verts.first; eve; eve= eve->next, index++) {
			if(eve->f & SELECT && eve != eve_act) {
				dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
				if(dvert) {
					defvert_copy(dvert, dvert_act);

					if(me->editflag & ME_EDIT_MIRROR_X)
						editvert_mirror_update(ob, eve, -1, index);

				}
			}
		}
	}
}
Example #3
0
static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, float *cent)
{
	MDeformVert *dvert;
	EditVert *eve;
	int i, totvert=0;
	
	cent[0]= cent[1]= cent[2]= 0.0;
	
	if(obedit->actdef) {
		
		/* find the vertices */
		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 == (obedit->actdef-1)) {
						totvert++;
						add_v3_v3(cent, eve->co);
					}
				}
			}
		}
		if(totvert) {
			bDeformGroup *defGroup = BLI_findlink(&obedit->defbase, obedit->actdef-1);
			strcpy(name, defGroup->name);
			mul_v3_fl(cent, 1.0f/(float)totvert);
			return 1;
		}
	}
	
	return 0;
}	
Example #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;
}
Example #5
0
static int findFreeNavPolyIndex(EditMesh* em)
{
	/* construct vector of indices */
	int numfaces= em->totface;
	int* indices= MEM_callocN(sizeof(int)*numfaces, "findFreeNavPolyIndex(indices)");
	EditFace* ef= (EditFace*)em->faces.last;
	int i, idx= 0, freeIdx= 1;

	while(ef) {
		int polyIdx= *(int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST);
		indices[idx]= polyIdx;
		idx++;
		ef= ef->prev;
	}

	qsort(indices, numfaces, sizeof(int), compare);

	/* search first free index */
	freeIdx= 1;
	for(i= 0; i<numfaces; i++) {
		if(indices[i]==freeIdx)
			freeIdx++;
		else if(indices[i]>freeIdx)
			break;
	}

	MEM_freeN(indices);

	return freeIdx;
}
Example #6
0
static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, float *cent)
{
	zero_v3(cent);

	if(obedit->actdef) {
		const int defgrp_index= obedit->actdef-1;
		int totvert=0;

		MDeformVert *dvert;
		EditVert *eve;

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

			if(dvert) {
				if(defvert_find_weight(dvert, defgrp_index) > 0.0f) {
					add_v3_v3(cent, eve->co);
					totvert++;
				}
			}
		}
		if(totvert) {
			bDeformGroup *dg = BLI_findlink(&obedit->defbase, defgrp_index);
			BLI_strncpy(name, dg->name, sizeof(dg->name));
			mul_v3_fl(cent, 1.0f/(float)totvert);
			return 1;
		}
	}
	
	return 0;
}	
Example #7
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);
			}
		}
	}
}
Example #8
0
static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr)
{
	EditVert *eve_act;
	MDeformVert *dvert_act;

	act_vert_def(ob, &eve_act, &dvert_act);

	if(dvert_act==NULL) {
		return;
	}
	else {
		Mesh *me= ob->data;
		EditMesh *em = BKE_mesh_get_editmesh(me);
		EditVert *eve;
		MDeformVert *dvert;
		MDeformWeight *dw;
		float act_weight = -1.0f;
		int i;
		int index= 0;

		for(i=0, dw=dvert_act->dw; i < dvert_act->totweight; i++, dw++) {
			if(def_nr == dw->def_nr) {
				act_weight= dw->weight;
				break;
			}
		}

		if(act_weight < -0.5f)
			return;

		for(eve= em->verts.first; eve; eve= eve->next, index++) {
			if(eve->f & SELECT && eve != eve_act) {
				dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
				if(dvert) {
					for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
						if(def_nr == dw->def_nr) {
							dw->weight= act_weight;

							if(me->editflag & ME_EDIT_MIRROR_X)
								editvert_mirror_update(ob, eve, -1, index);

							break;
						}
					}
				}
			}
		}

		if(me->editflag & ME_EDIT_MIRROR_X)
			editvert_mirror_update(ob, eve_act, -1, -1);

	}
}
Example #9
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;
					}
				}
			}
		}
	}
}
Example #10
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;
}
Example #11
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;
}
Example #12
0
static float get_vert_def_nr(Object *ob, int def_nr, int vertnum)
{
	MDeformVert *dvert= NULL;
	EditVert *eve;
	Mesh *me;
	int i;

	/* get the deform vertices corresponding to the vertnum */
	if(ob->type==OB_MESH) {
		me= ob->data;

		if(me->edit_mesh) {
			eve= BLI_findlink(&me->edit_mesh->verts, vertnum);
			if(!eve) return 0.0f;
			dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT);
			vertnum= 0;
		}
		else
			dvert = me->dvert;
	}
	else if(ob->type==OB_LATTICE) {
		Lattice *lt= vgroup_edit_lattice(ob);
		
		if(lt->dvert)
			dvert = lt->dvert;
	}
	
	if(dvert==NULL)
		return 0.0f;
	
	dvert += vertnum;
	
	for(i=dvert->totweight-1 ; i>=0 ; i--)
		if(dvert->dw[i].def_nr == def_nr)
			return dvert->dw[i].weight;

	return 0.0f;
}
Example #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);
}
Example #14
0
static void vgroup_blend(Object *ob)
{
	bDeformGroup *dg;
	MDeformWeight *dw;
	MDeformVert *dvert_array=NULL, *dvert;
	int i, def_nr, dvert_tot=0;

	EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)ob->data));
	// ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);

	if(em==NULL)
		return;

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

	if(dg) {
		int sel1, sel2;
		int i1, i2;

		EditEdge *eed;
		EditVert *eve;
		float *vg_weights;
		float *vg_users;

		def_nr= ob->actdef-1;

		i= 0;
		for(eve= em->verts.first; eve; eve= eve->next)
			eve->tmp.l= i++;

		dvert_tot= i;

		vg_weights= MEM_callocN(sizeof(float)*dvert_tot, "vgroup_blend_f");
		vg_users= MEM_callocN(sizeof(int)*dvert_tot, "vgroup_blend_i");

		for(eed= em->edges.first; eed; eed= eed->next) {
			sel1= eed->v1->f & SELECT;
			sel2= eed->v2->f & SELECT;

			if(sel1 != sel2) {
				/* i1 is always the selected one */
				if(sel1==TRUE && sel2==FALSE) {
					i1= eed->v1->tmp.l;
					i2= eed->v2->tmp.l;
					eve= eed->v2;
				}
				else {
					i2= eed->v1->tmp.l;
					i1= eed->v2->tmp.l;
					eve= eed->v1;
				}

				vg_users[i1]++;

				/* TODO, we may want object mode blending */
				if(em)	dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
				else	dvert= dvert_array+i2;

				dw= ED_vgroup_weight_get(dvert, def_nr);

				if(dw) {
					vg_weights[i1] += dw->weight;
				}
			}
		}

		i= 0;
		for(eve= em->verts.first; eve; eve= eve->next) {
			if(eve->f & SELECT && vg_users[i] > 0) {
				/* TODO, we may want object mode blending */
				if(em)	dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
				else	dvert= dvert_array+i;

				dw= ED_vgroup_weight_verify(dvert, def_nr);
				dw->weight= vg_weights[i] / (float)vg_users[i];
			}

			i++;
		}
		MEM_freeN(vg_weights);
		MEM_freeN(vg_users);
	}
}
Example #15
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;
}
Example #16
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");
	}
}
Example #17
0
static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFace *activetf)
{
	EditFace *efa;
	MTFace *tf;
	Image *ima= sima->image;
	float aspx, aspy, col[4], tf_uv[4][2];
	
	ED_space_image_uv_aspect(sima, &aspx, &aspy);
	
	switch(sima->dt_uvstretch) {
		case SI_UVDT_STRETCH_AREA:
		{
			float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area;
			
			for(efa= em->faces.first; efa; efa= efa->next) {
				tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
				uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);

				totarea += EM_face_area(efa);
				//totuvarea += tf_area(tf, efa->v4!=0);
				totuvarea += uv_area(tf_uv, efa->v4!=0);
				
				if(uvedit_face_visible(scene, ima, efa, tf)) {
					efa->tmp.p = tf;
				}
				else {
					if(tf == activetf)
						activetf= NULL;
					efa->tmp.p = NULL;
				}
			}
			
			if(totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
				col[0] = 1.0;
				col[1] = col[2] = 0.0;
				glColor3fv(col);
				for(efa= em->faces.first; efa; efa= efa->next) {
					if((tf=(MTFace *)efa->tmp.p)) {
						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 {
				for(efa= em->faces.first; efa; efa= efa->next) {
					if((tf=(MTFace *)efa->tmp.p)) {
						area = EM_face_area(efa) / totarea;
						uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
						//uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
						uvarea = uv_area(tf_uv, efa->v4!=0) / totuvarea;
						
						if(area < FLT_EPSILON || uvarea < FLT_EPSILON)
							areadiff = 1.0;
						else if(area>uvarea)
							areadiff = 1.0-(uvarea/area);
						else
							areadiff = 1.0-(area/uvarea);
						
						weight_to_rgb(areadiff, col, col+1, col+2);
						glColor3fv(col);
						
						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();
					}
				}
			}
			break;
		}
		case SI_UVDT_STRETCH_ANGLE:
		{
			float uvang1,uvang2,uvang3,uvang4;
			float ang1,ang2,ang3,ang4;
			float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d  angle vectors */
			float a;
			
			col[3] = 0.5; /* hard coded alpha, not that nice */
			
			glShadeModel(GL_SMOOTH);
			
			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;
					uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
					if(efa->v4) {
						
#if 0						/* Simple but slow, better reuse normalized vectors */
						uvang1 = RAD2DEG(Vec2Angle3(tf_uv[3], tf_uv[0], tf_uv[1]));
						ang1 = RAD2DEG(VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co));
						
						uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2]));
						ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co));
						
						uvang3 = RAD2DEG(Vec2Angle3(tf_uv[1], tf_uv[2], tf_uv[3]));
						ang3 = RAD2DEG(VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co));
						
						uvang4 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[3], tf_uv[0]));
						ang4 = RAD2DEG(VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co));
#endif
						
						/* uv angles */
						VECSUB2D(av1, tf_uv[3], tf_uv[0]); Normalize2(av1);
						VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2);
						VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3);
						VECSUB2D(av4, tf_uv[2], tf_uv[3]); Normalize2(av4);
						
						/* This is the correct angle however we are only comparing angles
						 * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90);*/
						uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
						uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
						uvang3 = NormalizedVecAngle2_2D(av3, av4)*180.0/M_PI;
						uvang4 = NormalizedVecAngle2_2D(av4, av1)*180.0/M_PI;
						
						/* 3d angles */
						VECSUB(av1, efa->v4->co, efa->v1->co); Normalize(av1);
						VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
						VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
						VECSUB(av4, efa->v3->co, efa->v4->co); Normalize(av4);
						
						/* This is the correct angle however we are only comparing angles
						 * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90);*/
						ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
						ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
						ang3 = NormalizedVecAngle2(av3, av4)*180.0/M_PI;
						ang4 = NormalizedVecAngle2(av4, av1)*180.0/M_PI;
						
						glBegin(GL_QUADS);
						
						/* This simple makes the angles display worse then they really are ;)
						 * 1.0-pow((1.0-a), 2) */
						
						a = fabs(uvang1-ang1)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[0]);
						a = fabs(uvang2-ang2)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[1]);
						a = fabs(uvang3-ang3)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[2]);
						a = fabs(uvang4-ang4)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[3]);
						
					}
					else {
#if 0						/* Simple but slow, better reuse normalized vectors */
						uvang1 = RAD2DEG(Vec2Angle3(tf_uv[2], tf_uv[0], tf_uv[1]));
						ang1 = RAD2DEG(VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co));
						
						uvang2 = RAD2DEG(Vec2Angle3(tf_uv[0], tf_uv[1], tf_uv[2]));
						ang2 = RAD2DEG(VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co));
						
						uvang3 = M_PI-(uvang1+uvang2);
						ang3 = M_PI-(ang1+ang2);
#endif						
						
						/* uv angles */
						VECSUB2D(av1, tf_uv[2], tf_uv[0]); Normalize2(av1);
						VECSUB2D(av2, tf_uv[0], tf_uv[1]); Normalize2(av2);
						VECSUB2D(av3, tf_uv[1], tf_uv[2]); Normalize2(av3);
						
						/* This is the correct angle however we are only comparing angles
						 * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90); */
						uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
						uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
						uvang3 = NormalizedVecAngle2_2D(av3, av1)*180.0/M_PI;
						
						/* 3d angles */
						VECSUB(av1, efa->v3->co, efa->v1->co); Normalize(av1);
						VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
						VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
						/* This is the correct angle however we are only comparing angles
						 * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90); */
						ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
						ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
						ang3 = NormalizedVecAngle2(av3, av1)*180.0/M_PI;
						
						/* This simple makes the angles display worse then they really are ;)
						 * 1.0-pow((1.0-a), 2) */
						
						glBegin(GL_TRIANGLES);
						a = fabs(uvang1-ang1)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[0]);
						a = fabs(uvang2-ang2)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[1]);
						a = fabs(uvang3-ang3)/180.0;
						weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
						glColor3fv(col);
						glVertex2fv(tf->uv[2]);
					}
					glEnd();
				}
				else {
					if(tf == activetf)
						activetf= NULL;
					efa->tmp.p = NULL;
				}
			}

			glShadeModel(GL_FLAT);
			break;
		}
	}
}
Example #18
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);
		}
	}
}
Example #19
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;
			}
		}
	}
}
Example #20
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);
}