www.pudn.com > MeshProcess.rar > Mesh.cpp


// Mesh.cpp: implementation of the CMesh class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "MeshProcess.h" 
#include "Mesh.h" 
#include "Math.h" 
#include  
#include  
#include "gl\gl.h" 
 
 
 
using namespace std; 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
//extern void gluCube(CVer3D mver3d, double r); 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CMesh::CMesh() 
{ 
	m_numS = 0; 
	m_numT = 0; 
	m_numV = 0; 
	m_nSvertices = new int[100]; 
	m_Meshes = NULL; 
	m_Vertices = NULL; 
 
	m_Box.X1 =  1e+6; 
	m_Box.X2 = -1e+6; 
	m_Box.Y1 =  1e+6; 
	m_Box.Y2 = -1e+6; 
	m_Box.Z1 =  1e+6; 
	m_Box.Z2 = -1e+6; 
 
	m_nMeshcolor[0] = 220; m_nMeshcolor[1] = 220; m_nMeshcolor[2] = 220;  
	m_nLinecolor[0] = 30 ; m_nLinecolor[1] =  32; m_nLinecolor[2] = 239; 
 
} 
 
 
CMesh::~CMesh() 
{ 
	if( m_Meshes ) 
		delete []m_Meshes; 
	if( m_Vertices) 
		delete []m_Vertices; 
	if( m_nSvertices) 
		delete []m_nSvertices; 
 
} 
 
 
bool CMesh::ImportMesh( char *fl, CString file_ext ) 
{ 
	bool cmesh = true; 
	int  i=0, j=0, k=0; 
	char linech[256]; 
	char * name; 
	string linestr,tag,str,temp; 
	ifstream fin; 
	basic_istringstream lstream,vstream; 
 
    fin.open(fl); 
	fin.clear(); 
	fin.getline(linech,256); 
	linestr=linech; 
	lstream.clear(); 
	lstream.str(linestr); 
 
    if( file_ext.Compare("obj") == 0 ) 
	{ 
	    lstream>>tag; 
		if( tag == "n" ) 
		{ 
			lstream>> m_numV>> m_numT; 
		} 
 
		m_Vertices = new CVer3D[m_numV];	 
		m_Meshes   = new CTri3D[m_numT]; 
	 
		while( !fin.eof() ) 
		{ 
			fin.clear(); 
			fin.getline(linech,256); 
			linestr=linech; 
 
			lstream.clear(); 
			lstream.str(linestr); 
			lstream>>tag; 
	   
 
			if( tag == "o" ) 
			{ 
				lstream.getline(linech,256); 
				name=linech; 
			} 
			if( tag == "v" ) 
			{    
				lstream>> (m_Vertices[i]).x>> (m_Vertices[i]).y >> (m_Vertices[i]).z; 
				i++; 
			} 
			if( tag == "f" ) 
			{ 
				int l=0; 
				while( lstream.good() ) 
				{    
					int n1; 
					lstream>>n1; 
					n1 = n1-1; 
					m_Meshes[k].veridx[l] = n1; 
					m_Vertices[n1].triidx[m_Vertices[n1].nfa++] = k; 
					l++;		       
				} 
				k++; 
			} 
		} 
 
	} 
	else if( file_ext.Compare("tm") == 0 ) 
	{ 
		lstream>> m_numV>> m_numT; 
		m_Vertices = new CVer3D[m_numV]; 
		m_Meshes   = new CTri3D[m_numT]; 
 
		i = 0; 
		int n1, n2, n3, k=0;  
		while( !fin.eof() ) 
		{ 
			fin.clear(); 
			fin.getline(linech,256); 
			linestr=linech; 
 
			lstream.clear(); 
			lstream.str(linestr); 
 
			if(i> m_Vertices[i].x>> m_Vertices[i].y>> m_Vertices[i].z; 
				i++; 
			} 
			else 
			{ 
				lstream>> n1>> n2>> n3; 
				m_Meshes[k].veridx[0] = n1; 
				m_Vertices[n1].triidx[m_Vertices[n1].nfa++] = k; 
				m_Meshes[k].veridx[1] = n2; 
				m_Vertices[n2].triidx[m_Vertices[n2].nfa++] = k; 
				m_Meshes[k].veridx[2] = n3; 
				m_Vertices[n3].triidx[m_Vertices[n3].nfa++] = k; 
				k++; 
			} 
		} 
		 
	 
	} 
	fin.close(); 
 
 
	if( i == 0) 
		cmesh = false; 
	else 
	{  
		// seek the Bounding m_Box 
		for( int i=0; i m_Box.X2 ) 
				m_Box.X2 = m_Vertices[i].x; 
			if( m_Vertices[i].y < m_Box.Y1 ) 
				m_Box.Y1 = m_Vertices[i].y; 
			if( m_Vertices[i].y > m_Box.Y2 ) 
				m_Box.Y2 = m_Vertices[i].y; 
			if( m_Vertices[i].z < m_Box.Z1 ) 
				m_Box.Z1 = m_Vertices[i].z; 
    		if( m_Vertices[i].z > m_Box.Z2 ) 
				m_Box.Z2 = m_Vertices[i].z; 
	 
		} 
	} 
	 
 
	return cmesh; 
 
} 
 
void CMesh::CoordianteTransform(BoundingBox winBox) 
{ 
	double mwid = m_Box.X2 - m_Box.X1; 
	double mhei = m_Box.Y2 - m_Box.Y1; 
	double cenx = (m_Box.X2 + m_Box.X1)/2; 
	double ceny = (m_Box.Y2 + m_Box.Y1)/2; 
	double cenz = (m_Box.Z2 + m_Box.Z1)/2; 
	double winx = winBox.X2 - winBox.X1; 
	double winy = winBox.Y2 - winBox.Y1; 
	double wid  = min(winx, winy)/max(mwid, mhei)*0.7; 
 
	for( int i=0; i1e-5) 
	for (int i = 0; i < m_numV; i++) 
	{ 
		y1              = m_Vertices[i].y*cos(xangle) - m_Vertices[i].z*sin(xangle); 
		m_Vertices[i].z = m_Vertices[i].y*sin(xangle) + m_Vertices[i].z*cos(xangle); 
		m_Vertices[i].y = y1; 
	} 
	if (fabs(yangle) > 1e-5) 
	for (int i = 0; i < m_numV; i++) 
	{ 
		x1              = m_Vertices[i].x * cos(yangle) + m_Vertices[i].z*sin(yangle); 
		m_Vertices[i].z = -m_Vertices[i].x* sin(yangle) + m_Vertices[i].z*cos(yangle); 
		m_Vertices[i].x = x1; 
	} 
	if (fabs(zangle) > 1e-5) 
	for (int i = 0; i < m_numV; i++) 
	{ 
		x1              = m_Vertices[i].x*cos(zangle) - m_Vertices[i].y*sin(zangle); 
		m_Vertices[i].y = m_Vertices[i].x*sin(zangle) + m_Vertices[i].y*cos(zangle); 
		m_Vertices[i].x = x1; 
 
	} 
		 
} 
 
void CMesh::CooridnateTranslate(double xtrans, double ytrans, double ztrans) 
{ 
	for (int i = 0; i < m_numV; i++) 
	{ 
		m_Vertices[i].x += xtrans; 
		m_Vertices[i].y += ytrans; 
		m_Vertices[i].z += ztrans; 
	}	 
 
} 
 
void CMesh::DisplayModel(int mode) 
{ 
 
	//Solid 
	if( mode == SOLIDMODE ) 
	{ 
		glEnable(GL_LIGHTING); 
		glEnable(GL_LIGHT0); 
		DrawTriangles(); 
		glDisable(GL_LIGHT0); 
		glDisable(GL_LIGHTING);	 
 
	} 
 
	if( mode == FLATSOLIDMODE ) 
	{ 
		glEnable(GL_LIGHTING); 
		glEnable(GL_LIGHT0); 
		 
		DrawFlatTriangles(); 
		glDisable(GL_LIGHT0); 
		glDisable(GL_LIGHTING);	 
 
	} 
 
 
	//Lines 
	if( mode == WIREFRAMEMODE ) 
	{ 
		glDisable(GL_LIGHT0); 
		glDisable(GL_LIGHTING);	 
	    DrawLines(); 
	} 
 
	//Solid with Lines 
	if( mode == SOLIDWIREMODE ) 
	{ 
		glEnable(GL_LIGHTING); 
		glEnable(GL_LIGHT0); 
		DrawTriangles(); 
		glDisable(GL_LIGHT0); 
		glDisable(GL_LIGHTING);	 
		DrawLines(); 
	} 
 
 
	//m_Vertices 
	if( mode == VERTEXMODE ) 
	{ 
		glEnable(GL_LIGHTING); 
		glEnable(GL_LIGHT0); 
		DrawVertices(); 
		glDisable(GL_LIGHT0); 
		glDisable(GL_LIGHTING);		 
	 
	} 
	 
 
} 
 
void CMesh::ComputeAttribute() 
{ 
	for( int i=0; i < m_numV; i++ )//Judge the inside node 
		m_Vertices[i].IntorOut( i, m_Meshes ); 
	for( i=0; i < m_numT; i++)//Compute the Edge Length and the Normale 
	{ 
		m_Meshes[i].CompCtgangle( m_Vertices ); 
		m_Meshes[i].CompEdgeLeng( m_Vertices ); 
		m_Meshes[i].CompNormale(  m_Vertices); 
		m_Meshes[i].CompArea();	 
	} 
	for( i=0; i < m_numV; i++)//Compute Gaussian Curvature 
	{ 
		m_Vertices[i].CompGaussianCurvature( i, m_Meshes ); 
		m_Vertices[i].CompMeanCurvature( i, m_Meshes ); 
	} 
 
} 
 
void CMesh::DrawTriangles() 
{ 
	for( int i=0; i < m_numT; i++ ) 
	{ 
		int j0 = m_Meshes[i].veridx[0]; 
		int j1 = m_Meshes[i].veridx[1]; 
		int j2 = m_Meshes[i].veridx[2]; 
		double xn = m_Meshes[i].normal[0]; 
		double yn = m_Meshes[i].normal[1]; 
		double zn = m_Meshes[i].normal[2]; 
 
		glColor3ub( m_nMeshcolor[0], m_nMeshcolor[1], m_nMeshcolor[2] ); 
		  
		glBegin( GL_TRIANGLES ); 
		   glNormal3f( xn, yn, zn); 
   		   glVertex3f( m_Vertices[j0].x, m_Vertices[j0].y, m_Vertices[j0].z ); 
		   glVertex3f( m_Vertices[j1].x, m_Vertices[j1].y, m_Vertices[j1].z ); 
		   glVertex3f( m_Vertices[j2].x, m_Vertices[j2].y, m_Vertices[j2].z ); 
	    glEnd();	 
	} 
 
} 
 
void CMesh::DrawFlatTriangles() 
{ 
	for( int i=0; i < m_numT; i++ ) 
	{ 
		int j0 = m_Meshes[i].veridx[0]; 
		int j1 = m_Meshes[i].veridx[1]; 
		int j2 = m_Meshes[i].veridx[2]; 
	 
		glColor3ub( m_nMeshcolor[0], m_nMeshcolor[1], m_nMeshcolor[2] ); 
	  
		glBegin( GL_TRIANGLES ); 
		   glNormal3f( m_Vertices[j0].normale[0], m_Vertices[j0].normale[1], m_Vertices[j0].normale[2] );	    
		   glVertex3f( m_Vertices[j0].x, m_Vertices[j0].y, m_Vertices[j0].z );		    
		   glNormal3f( m_Vertices[j1].normale[0], m_Vertices[j1].normale[1], m_Vertices[j1].normale[2] ); 
		   glVertex3f( m_Vertices[j1].x, m_Vertices[j1].y, m_Vertices[j1].z );		    
		   glNormal3f( m_Vertices[j2].normale[0], m_Vertices[j2].normale[1], m_Vertices[j2].normale[2] ); 
		   glVertex3f( m_Vertices[j2].x, m_Vertices[j2].y, m_Vertices[j2].z ); 
	    glEnd();	 
	} 
 
 
} 
 
void CMesh::DrawPickupTriVer() 
{ 
		for( int i=0; i < m_numT; i++) 
		{ 
			int j0 = m_Meshes[i].veridx[0]; 
			int j1 = m_Meshes[i].veridx[1]; 
			int j2 = m_Meshes[i].veridx[2]; 
			 
			glColor3ub( 255, 255, 255 );		  
			glBegin( GL_TRIANGLES ); 
				glVertex3f( m_Vertices[j0].x, m_Vertices[j0].y, m_Vertices[j0].z ); 
				glVertex3f( m_Vertices[j1].x, m_Vertices[j1].y, m_Vertices[j1].z ); 
				glVertex3f( m_Vertices[j2].x, m_Vertices[j2].y, m_Vertices[j2].z ); 
			glEnd();		 
		}    
 
 
		glPointSize(6); 
		glBegin(GL_POINTS); 
		GLfloat r = 0.03; 
 
		for( i=0; i < m_numV; i++) 
		{ 
			float x = m_Vertices[i].x + m_Vertices[i].normale[0]*0.02; 
			float y = m_Vertices[i].y + m_Vertices[i].normale[1]*0.02; 
			float z = m_Vertices[i].z + m_Vertices[i].normale[2]*0.02; 
			CVer3D ver3d; 
			ver3d.x=x; ver3d.y=y; ver3d.z=z; 
		 
			glColor3ub(i/200, i%200, 200); 
//			gluCube(ver3d, r);  
			glVertex3f( x, y, z ); 
		} 
	    glEnd(); 
 
 
} 
 
 
void CMesh::DrawLines() 
{	 
	float offset = 0.03; 
		// Antialiasing 
		glEnable(GL_LINE_SMOOTH);  
		glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
		glEnable(GL_BLEND); 
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
 
	for( int i=0; i < m_numT; i++ ) 
	{ 
		int j0 = m_Meshes[i].veridx[0]; 
		int j1 = m_Meshes[i].veridx[1]; 
		int j2 = m_Meshes[i].veridx[2]; 
		double xn = m_Meshes[i].normal[0]; 
		double yn = m_Meshes[i].normal[1]; 
		double zn = m_Meshes[i].normal[2]; 
		double nx = m_Meshes[i].normal[0]*0.008;  
		double ny = m_Meshes[i].normal[1]*0.008; 
		double nz = m_Meshes[i].normal[2]*0.008; 
		 
		glLineWidth(2); 
 
		glColor3ub(m_nLinecolor[0], m_nLinecolor[1], m_nLinecolor[2]); 
	 
 
		glBegin(GL_LINE_LOOP);	 
		glVertex3f(GLdouble(m_Vertices[j0].x + offset * m_Vertices[j0].normale[0]), GLdouble(m_Vertices[j0].y + offset * m_Vertices[j0].normale[1]), GLdouble(m_Vertices[j0].z + offset * m_Vertices[j0].normale[2]) ); 
		glVertex3f(GLdouble(m_Vertices[j1].x + offset * m_Vertices[j1].normale[0]), GLdouble(m_Vertices[j1].y + offset * m_Vertices[j1].normale[1]), GLdouble(m_Vertices[j1].z + offset * m_Vertices[j1].normale[2]) ); 
		glVertex3f(GLdouble(m_Vertices[j2].x + offset * m_Vertices[j2].normale[0]), GLdouble(m_Vertices[j2].y + offset * m_Vertices[j2].normale[1]), GLdouble(m_Vertices[j2].z + offset * m_Vertices[j2].normale[2]) );		 
		glEnd(); 
 
	 
		 
	} 
 
		glDisable(GL_LINE_SMOOTH); 
		glDisable(GL_BLEND); 
 
} 
 
void CMesh::DrawVertices() 
{ 
	double r=0.01; 
 
	glPointSize( 3.0f );	 
 
	glBegin( GL_POINTS ); 
	glColor3ub( 220, 220, 220 ); 
 
	for( int i=0; i < m_numV; i++ ) 
	{ 
	 
		glNormal3f( m_Vertices[i].normale[0], m_Vertices[i].normale[1], m_Vertices[i].normale[2] ); 
		 
		glColor3ub( 220, 220, 220 ); 
 
		glVertex3f( m_Vertices[i].x, m_Vertices[i].y, m_Vertices[i].z ); 
//		gluCube( m_Vertices[i],  r);		 
	} 
 
	glEnd();     
 
} 
 
 
void CMesh::DrawBoundingBox() 
{ 
	glDisable(GL_LIGHTING); 
	glMatrixMode(GL_MODELVIEW); 
	glPushMatrix(); 
	 
    glLineWidth(1); 
	glBegin(GL_LINE_LOOP); 
 
	glColor3f ( .0f, 1.0f, 0.0f);	 
    glVertex3f( m_Box.X1, m_Box.Y1, m_Box.Z2); 
	glVertex3f( m_Box.X1, m_Box.Y2, m_Box.Z2); 
	glVertex3f( m_Box.X2, m_Box.Y2, m_Box.Z2); 
	glVertex3f( m_Box.X2, m_Box.Y1, m_Box.Z2); 
 
	glEnd(); 
 
 
	glBegin(GL_LINE_LOOP); 
 
	glColor3f ( .0f, 1.0f, 0.0f);	 
    glVertex3f( m_Box.X1, m_Box.Y1, m_Box.Z1); 
	glVertex3f( m_Box.X1, m_Box.Y2, m_Box.Z1); 
	glVertex3f( m_Box.X2, m_Box.Y2, m_Box.Z1); 
	glVertex3f( m_Box.X2, m_Box.Y1, m_Box.Z1); 
 
	glEnd(); 
 
 
	glBegin(GL_LINES); 
 
	glColor3f ( .0f, 1.0f, 0.0f);	    
	glVertex3f( m_Box.X1, m_Box.Y1, m_Box.Z2); 
	glVertex3f( m_Box.X1, m_Box.Y1, m_Box.Z1);	 
	glVertex3f( m_Box.X1, m_Box.Y2, m_Box.Z2); 
	glVertex3f( m_Box.X1, m_Box.Y2, m_Box.Z1);	 
	glVertex3f( m_Box.X2, m_Box.Y2, m_Box.Z2); 
	glVertex3f( m_Box.X2, m_Box.Y2, m_Box.Z1);	 
	glVertex3f( m_Box.X2, m_Box.Y1, m_Box.Z2); 
	glVertex3f( m_Box.X2, m_Box.Y1, m_Box.Z1); 
 
	glEnd(); 
 
	glPopMatrix(); 
	glEnable(GL_LIGHTING); 
 
} 
 
void CMesh::DrawSvertices(int size, int cr, int cg, int cb) 
{ 
	if( m_numS > 0) 
	{ 
		glPointSize( size ); 
 
		glDisable( GL_LIGHT0 ); 
		glDisable( GL_LIGHTING ); 
		glBegin( GL_POINTS); 
 
		for( int i=0; i