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