www.pudn.com > stlreader.rar > 3DModel.cpp


// 3DModel.cpp: implementation of the C3DModel class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "math.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
#include "3DModel.h" 
#define nCharBuffer 255 
const GLfloat white[]={ 1.0,1.0,1.0,1.0}; 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
C3DModel::C3DModel() 
{ 
 
} 
 
 
 
 
 
C3DModel::~C3DModel() 
{ 
} 
 
 
 
void C3DModel::NormalListData1(float pointa[3], float pointb[3], float pointc[3]) 
{ 
 
	double xac,xbc,x,yac,ybc,y,zac,zbc,z,sum; 
	float xa,xb,xc,ya,yb,yc,za,zb,zc; 
	float nx,ny,nz; 
	xa=pointa[0];		ya=pointa[1];		za=pointa[2]; 
	xb=pointb[0];		yb=pointb[1];		zb=pointb[2]; 
	xc=pointc[0];		yc=pointc[1];		zc=pointc[2]; 
	 
	xac=xa-xc;		yac=ya-yc;		zac=za-zc; 
	xbc=xb-xc;		ybc=yb-yc; 		zbc=zb-zc; 
	x=yac*zbc-ybc*zac;		y=xbc*zac-xac*zbc;		z=xac*ybc-xbc*yac;		 
	sum=sqrt(x*x+y*y+z*z); 
	nx=x/sum;		ny=y/sum;		nz=z/sum; 
	m_nNormal[0]=nx; 
	m_nNormal[1]=ny; 
	m_nNormal[2]=nz; 
} 
 
 
 
void C3DModel::Draw3DModel(int Showtype) 
{ 
	 
	//int i,j,l; 
	 
	//float a[3],b[3],c[3]; 
 
	int i,j,l; 
	GLUnurbsObj *theNurb1; 
	float a[3],b[3],c[3]; 
    GLfloat ctrlpoints[280][120][3]; 
 
	/*GLfloat ctrlpoints[5][5][3] = {{{-3,0.5,0},{-1,1.5,0},{-2,2,0},{1,-1,0},{-5,0,0}}, 
	{{-3,0.5,-1},{-1,1.5,-1},{-2,2,-1},{1,-1,-1},{-5,0,-1}}, 
	{{-3,0.5,-2},{-1,1.5,-2},{-2,2,-2},{1,-1,-2},{-5,0,-2}}, 
	{{-3,0.5,-3},{-1,1.5,-3},{-2,2,-3},{1,-1,-3},{-5,0,-3}}, 
	{{-3,0.5,-4},{-1,1.5,-4},{-2,2,-4},{1,-1,-4},{-5,0,-4}}};//控制点 
    */ 
 
	GLfloat mat_diffuse[] = {1.0,0.5,1,1.0}; 
	GLfloat mat_specular[] = {1.0,1.0,1.0,1.0}; 
	GLfloat mat_shininess[] = {100.0}; 
	GLfloat light_position0[] = {-5.0,10.0,0.0,1.0}; 
	GLfloat light_position1[] = {5.0,10.0,10.0,1.0}; 
	glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); 
	glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); 
	glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); 
	glLightfv(GL_FRONT,GL_POSITION,light_position0);//设置光源参数 
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//设置光照模型参数 
	//glEnable(GL_LIGHTING); 
	//glEnable(GL_LIGHT0); 
	//glLightf(GL_LIGHT1,GL_DIFFUSE,mat_diffuse); 
    //glLightf(GL_LIGHT1,GL_SPECULAR,mat_specular); 
	//glLightf(GL_LIGHT1,GL_SHININESS,mat_shininess[0]); 
	//glLightfv(GL_FRONT,GL_POSITION,light_position1); 
	//glEnable(GL_LIGHT1); 
	//glDepthFunc(GL_LEQUAL); 
	//glEnable(GL_DEPTH_TEST); 
	glEnable(GL_LEQUAL); 
	glEnable(GL_AUTO_NORMAL); 
	glEnable(GL_NORMALIZE); 
	glPolygonMode(GL_FRONT_AND_BACK ,GL_FILL ); 
	glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,white); 
	 
	glPushMatrix(); 
 
	glScalef(1.5,1.5,1.5); 
	 
	switch(Showtype) { 
	case 0: 
		for (i=0;i<10010;i++) 
			 
		{   //i=10; 
            /*glBegin(GL_POINTS); 
			//glColor3f (0.5,0.8,1.0); 
			//glVertex3f(m_nTrueList[i][0]-20,m_nTrueList[i][1]+80,m_nTrueList[i][2]-100); 
            glColor3f (0.5,0.5,1.0); 
			glVertex3f(m_orightTrueList[i][0]-20,m_orightTrueList[i][1]+80,m_orightTrueList[i][2]-100); 
			glVertex3f(m_orightTrueList[i][0]-20+1,m_orightTrueList[i][1]+80,m_orightTrueList[i][2]-100); 
			glVertex3f(m_orightTrueList[i][0]-20-1,m_orightTrueList[i][1]+80,m_orightTrueList[i][2]-100); 
			glVertex3f(m_orightTrueList[i][0]-20,m_orightTrueList[i][1]+80+1,m_orightTrueList[i][2]-100); 
			glVertex3f(m_orightTrueList[i][0]-20,m_orightTrueList[i][1]+80-1,m_orightTrueList[i][2]-100); 
			glVertex3f(m_orightTrueList[i][0]-20,m_orightTrueList[i][1]+80,m_orightTrueList[i][2]-100+1); 
			glVertex3f(m_orightTrueList[i][0]-20,m_orightTrueList[i][1]+80,m_orightTrueList[i][2]-100-1); 
			glVertex3f(m_orightTrueList[i][0]-20+1,m_orightTrueList[i][1]+80-1,m_orightTrueList[i][2]-100); 
			glVertex3f(m_orightTrueList[i][0]-20+1,m_orightTrueList[i][1]+80+1,m_orightTrueList[i][2]-100); 
			glVertex3f(m_orightTrueList[i][0]-20,m_orightTrueList[i][1]+80+1,m_orightTrueList[i][2]-100-1); 
			glVertex3f(m_orightTrueList[i][0]-20,m_orightTrueList[i][1]+80+1,m_orightTrueList[i][2]-100+1); 
			glVertex3f(m_orightTrueList[i][0]-20+1,m_orightTrueList[i][1]+80+1,m_orightTrueList[i][2]-100+1); 
			glVertex3f(m_orightTrueList[i][0]-20-1,m_orightTrueList[i][1]+80+1,m_orightTrueList[i][2]-100+1); 
			glVertex3f(m_orightTrueList[i][0]-20-1,m_orightTrueList[i][1]+80,m_orightTrueList[i][2]-100+1); 
			glVertex3f(m_orightTrueList[i][0]-20-1,m_orightTrueList[i][1]+80,m_orightTrueList[i][2]-100-1); 
			//glVertex3f(m_nTrueList[i][0],m_nTrueList[i][1]+25,m_nTrueList[i][2]-25); 
            glEnd(); 
            //glVertex3f(m_nTrueList[m_npointnum-i][0],m_nTrueList[m_npointnum-i][1],m_nTrueList[m_npointnum-i][2]); 
           //glVertex3f(m_nTrueList[m_npointnum/2-i][0],m_nTrueList[m_npointnum/2-i][1],m_nTrueList[m_npointnum/2-i][2]); 
			//glVertex3f(m_nTrueList[i+1][0],m_nTrueList[i+1][1],m_nTrueList[i+1][2]); 
			//glVertex3f(m_nTrueList[i+2][0],m_nTrueList[i+2][1],m_nTrueList[i+2][2]); 
			*/ 
		} 
		long surfacenum =VertexArray.GetSize(); 
		int i; 
		for(i=0;i20||fabs(VertexArray[i].x-VertexArray[i+2].x)>20||fabs(VertexArray[i+2].x-VertexArray[i+1].x)>20) 
				continue; 
			if(fabs(VertexArray[i].y-VertexArray[i+1].y)>20||fabs(VertexArray[i].y-VertexArray[i+2].y)>20||fabs(VertexArray[i+2].y-VertexArray[i+1].y)>20) 
				continue; 
			if(fabs(VertexArray[i].z-VertexArray[i+1].z)>20||fabs(VertexArray[i].z-VertexArray[i+2].z)>20||fabs(VertexArray[i+2].z-VertexArray[i+1].z)>20) 
				continue; 
			glBegin(GL_TRIANGLES); 
			glVertex3f(VertexArray[i].x,VertexArray[i].y,VertexArray[i].z); 
			glVertex3f(VertexArray[i+1].x,VertexArray[i+1].y,VertexArray[i+1].z); 
			glVertex3f(VertexArray[i+2].x,VertexArray[i+2].y,VertexArray[i+2].z); 
			glEnd(); 
			 
		} 
		break; 
		 
	/*case 0: 
		 
		glBegin(GL_TRIANGLES); 
		 
		for (l=0;l=array[i*2])		{x_min=array[i*2];} 
		if (y_max<=array[i*2+1])		{y_max=array[i*2+1];} 
		if (y_min>=array[i*2+1])		{y_min=array[i*2+1];} 
	} 
 
	x=x_max-x_min; 
	y=y_max-y_min; 
		//奇数存x的值,偶数存y的值 
	for (i=0;imaxx) 
		{ 
			orige11 = data[j]; 
            orige22 = data[j+1]; 
			orige33 = data[j+2]; 
			maxx = data[j+1]; 
		} 
		 
		if(data[j]maxy) 
		{ 
			orige11 = data[j]; 
            orige22 = data[j+1]; 
			orige33 = data[j+2]; 
			maxy= data[j]; 
		} 
		//orige22-orige2为脚长 
        //maxy-miny为脚宽  
		m_nVertextList[m][0]=(data[j]+20.8616)*0.1; 
		m_nVertextList[m][2]=-(data[j+1]+199.976)*0.1; 
		m_nVertextList[m][1]=(data[j+2]+150.859)*0.15; 
	    m_nTrueList[m][0] =data[j]+20.8616;   //y坐标 
		m_nTrueList[m][2] =data[j+1]+199.976; //x坐标 
		m_nTrueList[m][1] =data[j+2]+150.859; //z坐标 
		m_orightTrueList[m][0] =m_nTrueList[m][0]; 
		m_orightTrueList[m][2] =m_nTrueList[m][2]; 
		m_orightTrueList[m][1] =m_nTrueList[m][1]; 
        //m_trueListm_trueList[3*m] =data[j]; 
		m++; 
		//if(m>10000) 
			//AfxMessageBox(""); 
	}  
	//j =j+0; 
	m_npointnum=m; 
    //orige1 =orige1; 
 
} 
 
 
 
////////此函数计算切片里面的最大和最小坐标,得到每个切片里面的最大宽度和高度 
 
void C3DModel::ComputeScale() 
{ 
  float length =267; 
  float step =267/100; 
  int i,j,k; 
  for(i =0;i<100;i++) 
  { 
	  m_maxz[i] =0; 
	  m_minz[i] =500; 
	  m_maxy[i] =0; 
	  m_miny[i] =500; 
  } 
  for(i=0;i<10010;i++) 
  { 
      int index =findindex(length,step,m_nTrueList[i][2]); 
		   // AfxMessageBox(""); 
	  if(m_maxz[index] m_nTrueList[i][1]) 
		  m_minz[index] =m_nTrueList[i][1]; 
	   
	  if(m_maxy[index] <=m_nTrueList[i][0]) 
		  m_maxy[index] =m_nTrueList[i][0]; 
	  if(m_miny[index] >=m_nTrueList[i][0]) 
		  m_miny[index] =m_nTrueList[i][0]; 
	   
  } 
 
  for(i =0;i<100;i++) 
  { 
      m_yScale[i] =m_maxy[i]-m_miny[i]; 
	  m_zScale[i] =m_maxz[i]-m_minz[i]; 
  } 
   
} 
 
/////////此函数用来计算xvalue是第几个切片,返回0-99 
int C3DModel::findindex(float length, float step,float xvalue) 
{ 
     int m; 
	 m =(int)(xvalue/step); 
	 if(m<0) 
		 m =0; 
	 if(m>=100) 
		 m=99; 
	 return (m); 
} 
 
 
void C3DModel::ScaleFoot(float ZScale[], float YScale[],float xscale) 
{ 
	float length =267; 
	float step =267/100; 
	for(int i=0;i<10010;i++) 
	{ 
		int index =findindex(length,step,m_nTrueList[i][2]); 
        m_nTrueList[i][1] =m_nTrueList[i][1]*ZScale[index]/m_zScale[index]; 
		m_nTrueList[i][0] =m_nTrueList[i][0]*YScale[index]/m_yScale[index]; 
		m_nTrueList[i][2] =m_nTrueList[i][2]*xscale; 
         
	} 
} 
 
///////////初始化三维模型,先读出标准模型数据,再计算在每个切片里面的最宽和最高值 
void C3DModel::InitModel() 
{ 
	//初始化模型数据 
	 
	//细节调整时局部缩放参数 
	m_nscale=1.0; 
	//局部平移参数 
	m_ntranx=0.0; 
	m_ntrany=0.0; 
	 
	readdata(); 
	ReadStlFile("chouxi.stl"); 
    ComputeScale(); 
} 
 
 
////////画出Nurbs曲面//////////////// 
void C3DModel::DrawNurbs(int Showtype) 
{ 
    int i,j,l;	 
	float a[3],b[3],c[3]; 
    GLfloat ctrlpoints[5][5][3]; 
	GLfloat mat_diffuse[] = {1.0,0.5,0.1,1.0}; 
	GLfloat mat_specular[] = {1.0,1.0,1.0,1.0}; 
	GLfloat mat_shininess[] = {100.0}; 
	GLfloat light_position[] = {0.0,-10.0,0.0,1.0}; 
	glScalef(1,1,1); 
	glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); 
	glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); 
	glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); 
	glLightfv(GL_FRONT,GL_POSITION,light_position);//设置光源参数 
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//设置光照模型参数 
	glEnable(GL_LIGHTING); 
	glEnable(GL_LIGHT0); 
	glDepthFunc(GL_LEQUAL); 
	glEnable(GL_DEPTH_TEST); 
	glEnable(GL_LEQUAL); 
	glEnable(GL_AUTO_NORMAL); 
	glEnable(GL_NORMALIZE); 
	GLfloat knots[10] = {0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0}; 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
	glRotatef(50.0,1.0,1.0,0.0); 
//{-3,0.5,0} 
	/*GLfloat ctrlpoints[5][5][3] = {{{-3,0.5,0},{-1,1.5,0},{-2,2,0},{1,-1,0},{-5,0,0}}, 
	{{-3,0.5,-1},{-1,1.5,-1},{-2,2,-1},{1,-1,-1},{-5,0,-1}}, 
	{{-3,0.5,-2},{-1,1.5,-2},{-2,2,-2},{1,-1,-2},{-5,0,-2}}, 
	{{-3,0.5,-3},{-1,1.5,-3},{-2,2,-3},{1,-1,-3},{-5,0,-3}}, 
	{{-3,0.5,-4},{-1,1.5,-4},{-2,2,-4},{1,-1,-4},{-5,0,-4}}};//控制点 
    */ 
	 
	/*for(int thresh=0;thresh<10;thresh++) 
	{   GLUnurbsObj *theNurb1; 
		theNurb1 = gluNewNurbsRenderer();//创建NURBS对象theNurb1 
		gluNurbsProperty(theNurb1,GLU_SAMPLING_TOLERANCE,25.0); 
		gluNurbsProperty(theNurb1,GLU_DISPLAY_MODE,NULL); 
		for(i=0;i<5;i++) 
		for(j=0;j<5;j++) 
			for(int k=0;k<3;k++) 
		{ 
           ctrlpoints[i][j][k] =0; 
		} 
			{  int index1 =0; 
              for(int index =0;index<105;index++) 
				  if(thresh*20