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


// MeshProcessView.cpp : implementation of the CMeshProcessView class 
// 
 
#include "stdafx.h" 
#include "MeshProcess.h" 
 
#include "MainFrm.h" 
#include "MeshProcessDoc.h" 
#include "MeshProcessView.h" 
#include  
#include  
#include "gl/gl.h" 
#include "math.h" 
 
using namespace std; 
 
 
const int TIMER_ANIMATE = 1; 
const int TIMER_TOOLBAR = 2; 
const int ANIMATE_RATE	= 50; 
const int TOOLBAR_RATE  = 20; 
const float SCALE_RATE = 1.06f; 
const float ROTATE_ANLGE = 3.0f; 
 
const int MOUSE_DEFAULT = 0; 
const int MOUSE_SPIN = 1; 
const int MOUSE_TRANSLATE = 2; 
const int MOUSE_ZOOM = 3; 
const int MOUSE_PICKUP = 4; 
const int MOUSE_TOUCH = 5; 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CMeshProcessView 
 
IMPLEMENT_DYNCREATE(CMeshProcessView, CView) 
 
BEGIN_MESSAGE_MAP(CMeshProcessView, CView) 
	//{{AFX_MSG_MAP(CMeshProcessView) 
	ON_WM_CREATE() 
	ON_WM_SIZE() 
	ON_WM_ERASEBKGND() 
	ON_WM_DESTROY() 
	ON_COMMAND(ID_ZOOMIN, OnZoomin) 
	ON_COMMAND(ID_ZOOMOUT, OnZoomout) 
	ON_COMMAND(ID_zRotate, OnzRotate) 
	ON_COMMAND(ID_zRotatei, OnzRotatei) 
	ON_COMMAND(ID_xRotate, OnxRotate) 
	ON_COMMAND(ID_xRotatei, OnxRotatei) 
	ON_COMMAND(ID_yRotate, OnyRotate) 
	ON_COMMAND(ID_yRotatei, OnyRotatei) 
	ON_WM_TIMER() 
	ON_COMMAND(ID_SOLID, OnSolid) 
	ON_UPDATE_COMMAND_UI(ID_SOLID, OnUpdateSolid) 
	ON_COMMAND(ID_WIREFRAMES, OnWireframes) 
	ON_UPDATE_COMMAND_UI(ID_WIREFRAMES, OnUpdateWireframes) 
	ON_COMMAND(ID_SOLID_WIRE, OnSolidWire) 
	ON_UPDATE_COMMAND_UI(ID_SOLID_WIRE, OnUpdateSolidWire) 
	ON_COMMAND(ID_VERTICES, OnVertices) 
	ON_UPDATE_COMMAND_UI(ID_VERTICES, OnUpdateVertices) 
	ON_COMMAND(ID_FLAT_SOLID, OnFlatSolid) 
	ON_UPDATE_COMMAND_UI(ID_FLAT_SOLID, OnUpdateFlatSolid) 
	ON_COMMAND(ID_AXES, OnAxes) 
	ON_UPDATE_COMMAND_UI(ID_AXES, OnUpdateAxes) 
	ON_COMMAND(ID_BOUNDBOX, OnBoundbox) 
	ON_UPDATE_COMMAND_UI(ID_BOUNDBOX, OnUpdateBoundbox) 
	ON_COMMAND(ID_MOUSE_SPIN, OnMouseSpin) 
	ON_COMMAND(ID_MOUSE_TRANSLATE, OnMouseTranslate) 
	ON_COMMAND(ID_MOUSE_ZOOM, OnMouseZoom) 
	ON_UPDATE_COMMAND_UI(ID_MOUSE_SPIN, OnUpdateMouseSpin) 
	ON_UPDATE_COMMAND_UI(ID_MOUSE_TRANSLATE, OnUpdateMouseTranslate) 
	ON_UPDATE_COMMAND_UI(ID_MOUSE_ZOOM, OnUpdateMouseZoom) 
	ON_WM_SETCURSOR() 
	ON_COMMAND(ID_MOUSE_DEFAULT, OnMouseDefault) 
	ON_UPDATE_COMMAND_UI(ID_MOUSE_DEFAULT, OnUpdateMouseDefault) 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONDOWN() 
	ON_COMMAND(ID_MOUSE_PICKUP, OnMousePickup) 
	ON_UPDATE_COMMAND_UI(ID_MOUSE_PICKUP, OnUpdateMousePickup) 
	ON_COMMAND(ID_PICKUPVERTICES, OnPickupVertices) 
	ON_UPDATE_COMMAND_UI(ID_PICKUPVERTICES, OnUpdatePickupVertices) 
	ON_COMMAND(ID_SETUP_MESHCOLOR, OnSetupClearcolor) 
	ON_COMMAND(ID_SETUP_SOLIDCOLOR, OnSetupSolidcolor) 
	ON_COMMAND(ID_SETUP_LINECOLOR, OnSetupLinecolor) 
	ON_COMMAND(ID_OPEN_CORRESPOND, OnOpenCorrespond) 
	ON_COMMAND(ID_MESH_MORPH, OnMeshMorph) 
	ON_WM_PAINT() 
	//}}AFX_MSG_MAP 
	// Standard printing commands 
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMeshProcessView construction/destruction 
 
CMeshProcessView::CMeshProcessView() 
{ 
	// TODO: add construction code here 
 
	m_fScaling = 1.0 ; 
	m_nDisplaymode = 2 ; 
	m_bAxes = true ; 
	m_nMouseAct = MOUSE_DEFAULT ;  
	m_bLButtonDown = false; 
	m_bBox = true; 
	m_bPickup = true; 
	m_Correspond    = NULL; 
	m_vSTDifference = NULL; 
	m_vNormalDiffce = NULL; 
 
	m_sEye.origin.x = m_sEye.origin.y = m_sEye.origin.z = 0.0; 
	m_sEye.center.x = m_sEye.center.y = 0.0; m_sEye.center.z = -1.0; 
	m_sEye.up.x = m_sEye.up.z = 0.0; m_sEye.up.y = 1.0; 
	m_sEye.axisX.y = m_sEye.axisX.z = 0.0; m_sEye.axisX.x = 1.0; 
	m_sEye.axisY.x = m_sEye.axisY.z = 0.0; m_sEye.axisY.y = 1.0; 
	m_sEye.axisZ.x = m_sEye.axisZ.y = 0.0; m_sEye.axisZ.z = -1.0; 
 
	m_bAnimate  = false; 
	m_spinAngle = 0.0; 
	m_spinAxes[0] = m_spinAxes[2] = 0.0; m_spinAxes[1] = 1.0; 
	m_vProjectCenter[0] = 0.0f;  m_vProjectCenter[1] = 0.0f; m_vProjectCenter[2] = 0.0f; 
 
	 
	m_ClearColorRed = float(.9); m_ClearColorGreen = float(.9); m_ClearColorBlue= float(.9); 
 
	 
 
} 
 
CMeshProcessView::~CMeshProcessView() 
{ 
	if (m_Correspond) 
		delete []m_Correspond; 
	if (m_vSTDifference) 
		delete []m_vSTDifference; 
	if (m_vNormalDiffce) 
		delete []m_vNormalDiffce; 
	 
} 
 
BOOL CMeshProcessView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMeshProcessView drawing 
 
void CMeshProcessView::OnDraw(CDC* pDC) 
{ 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
//	RenderScene( m_mModel ); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMeshProcessView printing 
 
BOOL CMeshProcessView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CMeshProcessView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CMeshProcessView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMeshProcessView diagnostics 
 
#ifdef _DEBUG 
void CMeshProcessView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CMeshProcessView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CMeshProcessDoc* CMeshProcessView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMeshProcessDoc))); 
	return (CMeshProcessDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CMeshProcessView message handlers 
 
int CMeshProcessView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	GLInit(); 
	SetTimer( TIMER_TOOLBAR, TOOLBAR_RATE, NULL); 
	if (m_bAnimate) 
		SetTimer( TIMER_ANIMATE, ANIMATE_RATE, NULL ); 
 
	 
	return 0; 
} 
 
void CMeshProcessView::GLInit() 
{ 
	m_hDC = ::GetDC(m_hWnd); // Get the Device context 
 
	ASSERT(m_hDC); 
 
	static	PIXELFORMATDESCRIPTOR pfdWnd = 
	{ 
		sizeof(PIXELFORMATDESCRIPTOR), // Structure size. 
		1,                             // Structure version number. 
		PFD_DRAW_TO_WINDOW |           // Property flags. 
		PFD_SUPPORT_OPENGL | 
 		PFD_DOUBLEBUFFER, 
		PFD_TYPE_RGBA, 
		24,                            // 24-bit color. 
		0, 0, 0, 0, 0, 0,              // Not concerned with these. 
		0, 0, 0, 0, 0, 0, 0,           // No alpha or accum buffer. 
		32,                            // 32-bit depth buffer. 
		0, 0,                          // No stencil or aux buffer. 
		PFD_MAIN_PLANE,                // Main layer type. 
		0,                             // Reserved. 
		0, 0, 0                        // Unsupported. 
	}; 
 
	int pixelformat; 
    pixelformat = ChoosePixelFormat(m_hDC, &pfdWnd); 
 
    ASSERT(SetPixelFormat(m_hDC, pixelformat, &pfdWnd)); 
 
	m_hRC=wglCreateContext(m_hDC); 
 
	//make the rending context current, perform initialization, the 
	//deselect it 
	VERIFY(wglMakeCurrent(m_hDC,m_hRC)); 
	GLSetupRC(); 
//	VERIFY(wglMakeCurrent(NULL,NULL)); 
 
 
} 
 
 
void CMeshProcessView::GLRelease() 
{ 
 
	wglDeleteContext(m_hRC); 
	::ReleaseDC(m_hWnd,m_hDC); 
 
} 
 
 
void CMeshProcessView::GLResize(int cx, int cy) 
{ 
	double nRange = 2.0; 
 
	// Prevent a divide by zero 
	if(cy == 0) 
		cy = 1; 
 
	// Set Viewport to window dimensions 
    glViewport(0, 0, cx, cy); 
 
	glMatrixMode(GL_PROJECTION); 
 
	// Reset coordinate system 
	glLoadIdentity(); 
 
	// Establish clipping volume (left, right, bottom, top, near, far) 
	if(cx <= cy) 
		glOrtho( -(1/m_fScaling)*nRange, (1/m_fScaling)*nRange, -(1/m_fScaling)*nRange*cy/cx, (1/m_fScaling)*nRange*cy/cx, -nRange*5.0, nRange*5.0); 
	else 
		glOrtho( -(1/m_fScaling)*nRange*cx/cy, (1/m_fScaling)*nRange*cx/cy, -(1/m_fScaling)*nRange, (1/m_fScaling)*nRange, -nRange*5.0, nRange*5.0); 
 
 
	glMatrixMode( GL_MODELVIEW ); 
 
} 
 
void CMeshProcessView::GLSetupRC() 
{ 
	glEnable(GL_DEPTH_TEST);	// Hidden surface removal 
	glEnable(GL_COLOR_MATERIAL); 
 
	// Lighting components 
 
	GLfloat light[] = {1.0f,1.0f,1.0f,1.0f}; 
	GLfloat	 lightPos[] = { 1.0f, 1.0f, 1*3.0f, 1.0f}; 
 
	glLightfv(GL_LIGHT0,GL_SPECULAR,light); 
	glLightfv( GL_LIGHT0, GL_POSITION, lightPos); 
 
 
	float ambient[4] = {0.2f, 0.2f, 0.0f, 1.0f}; 
	float diffuse[4] = {0.95f, 0.95f, 0.0f, 1.0f}; 
	float specular[4] = {0.0f, 0.0f, 0.8f, 1.0f}; 
	float shininess[] = { 100.0f }; 
	glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient); 
	glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); 
	glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular); 
	glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shininess);	 
 
 
//	glEnable( GL_LIGHTING); 
//	glEnable( GL_LIGHT0); 
 
 
	glClearColor(m_ClearColorRed, m_ClearColorGreen, m_ClearColorBlue, 1.0 ); //background color 
 
} 
 
 
void CMeshProcessView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	// TODO: Add your message handler code here 
		 
	GLResize(cx,cy);	 
} 
 
BOOL CMeshProcessView::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	return FALSE; 
} 
 
void CMeshProcessView::OnDestroy()  
{ 
    GLRelease(); 
	CView::OnDestroy(); 
	 
} 
 
void CMeshProcessView::OnZoomin()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	 
	m_fScaling*= SCALE_RATE; 
 
	CRect rect; 
	GetClientRect(&rect); 
	GLResize( rect.right, rect.bottom);	 
	 
	RenderScene( pDoc->m_mSourceModel ); 
 
 
} 
 
void CMeshProcessView::OnZoomout()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
 
	m_fScaling/= SCALE_RATE; 
	 
	CRect rect; 
	GetClientRect(&rect); 
	GLResize( rect.right, rect.bottom); 
 
	 
	RenderScene( pDoc->m_mSourceModel ); 
 
 
} 
 
 
 
void CMeshProcessView::OnTimer(UINT nIDEvent)  
{ 
		// TODO: Add your message handler code here and/or call default 
	 
	if (nIDEvent == TIMER_ANIMATE) 
	{ 
		if (m_bAnimate && (m_spinAngle!=0.0) ) 
			SpinGlobal(m_spinAxes, m_spinAngle);		 
	} 
 
	else if (nIDEvent == TIMER_TOOLBAR) 
	{ 
		CMainFrame *pFrameWnd = (CMainFrame*)AfxGetMainWnd(); 
		int count = (pFrameWnd->m_leftToolBox).GetToolBarCtrl().GetButtonCount(); 
		int nIndex; 
	 
		for( nIndex = 4; nIndex < count; nIndex++) 
		{ 
			if( (pFrameWnd->m_leftToolBox).GetToolBarCtrl().IsButtonPressed( (pFrameWnd->m_leftToolBox).GetItemID( nIndex))) 
			{ 
				pFrameWnd->SendMessage( WM_COMMAND, (pFrameWnd->m_leftToolBox).GetItemID( nIndex), (LPARAM)m_hWnd); 
				break; 
			} 
		} 
	}	 
	 
	CView::OnTimer(nIDEvent); 
} 
 
void CMeshProcessView::DrawAxes() 
{ 
 
	glDisable(GL_LIGHTING); 
	glMatrixMode(GL_MODELVIEW); 
	glPushMatrix(); 
 
	glScalef(1.4f, 1.4f, 1.4f); 
 
	glLineWidth(3); 
	glBegin(GL_LINES);	 
	// x axis  
	glColor3f ( 1.0f, 0.0f, 0.0f); 
	glVertex3f( 0.0f, 0.0f, 0.0f); 
	glVertex3f( 1.0f, 0.0f, 0.0f); 
	 
	glVertex3f( 1.05f, 0.025f, 0.0f ); 
	glVertex3f( 1.1f, -0.025f, 0.0f ); 
	glVertex3f( 1.05f, -0.025f, 0.0f); 
	glVertex3f( 1.1f, 0.025f,  0.0f ); 
	 
 
	// y axis 
	glColor3f ( 0.0f, 1.0f, 0.0f); 
	glVertex3f( 0.0f, 0.0f, 0.0f); 
	glVertex3f( 0.0f, 1.0f, 0.0f); 
 
	glVertex3f( 0.0f, 1.1f,  0.0f); 
	glVertex3f(-.025f,1.15f, 0.0f); 
	glVertex3f( 0.0f, 1.1f,  0.0f); 
	glVertex3f(.025f, 1.15f, 0.0f); 
	glVertex3f( 0.0f, 1.1f,  0.0f); 
	glVertex3f( 0.0f, 1.05f, 0.0f); 
 
 
	// z axis 
	glColor3f ( 0.0f, 0.0f, 1.0f); 
	glVertex3f( 0.0f, 0.0f, 0.0f); 
	glVertex3f( 0.0f, 0.0f, 1.0f); 
 
	glVertex3f( 0.025f, 0.0f, 1.1f); 
	glVertex3f(-0.025f, 0.0f, 1.1f); 
	glVertex3f(-0.025f, 0.0f, 1.1f); 
	glVertex3f( 0.025f, 0.0f, 1.05f); 
	glVertex3f( 0.025f, 0.0f, 1.05f); 
	glVertex3f(-0.025f, 0.0f, 1.05f); 
 
	 
	glEnd();    
 
	glBegin(GL_TRIANGLES);	 
 
	// x axis arrow 
	glColor3f ( 1.0f, 0.0f,  0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    0.0f,    0.04f); 
	glVertex3f(0.9f,    0.028f,  0.028f); 
	glVertex3f(0.9f,    0.0f,    0.04f); 
	glVertex3f(0.9f,    0.028f,  0.028f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    0.028f,  0.028f); 
	glVertex3f(0.9f,    0.04f,   0.0f); 
	glVertex3f(0.9f,    0.028f,  0.028f); 
	glVertex3f(0.9f,    0.04f,   0.0f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    0.04f,   0.0f); 
	glVertex3f(0.9f,    0.028f,  -0.028f); 
	glVertex3f(0.9f,    0.04f,   0.0f); 
	glVertex3f(0.9f,    0.028f,  -0.028f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    0.028f,  -0.028f); 
	glVertex3f(0.9f,    0.0f,    -0.04f); 
	glVertex3f(0.9f,    0.028f,  -0.028f); 
	glVertex3f(0.9f,    0.0f,    -0.04f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    0.0f,    -0.04f); 
	glVertex3f(0.9f,    -0.028f, -0.028f); 
	glVertex3f(0.9f,    0.0f,    -0.04f); 
	glVertex3f(0.9f,    -0.028f, -0.028f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    -0.028f, -0.028f); 
	glVertex3f(0.9f,    -0.04f,  0.0f); 
	glVertex3f(0.9f,    -0.028f, -0.028f); 
	glVertex3f(0.9f,    -0.04f,  0.0f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    -0.04f,  0.0f); 
	glVertex3f(0.9f,    -0.028f, 0.028f); 
	glVertex3f(0.9f,    -0.04f,  0.0f); 
	glVertex3f(0.9f,    -0.028f, 0.028f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
	glVertex3f(1.0f,    0.0f,    0.0f); 
	glVertex3f(0.9f,    -0.028f, 0.028f); 
	glVertex3f(0.9f,    0.0f,    0.04f); 
	glVertex3f(0.9f,    -0.028f, 0.028f); 
	glVertex3f(0.9f,    0.0f,    0.04f); 
	glVertex3f(0.9f,    0.0f,    0.0f); 
 
	// y axis arrow 
	glColor3f ( 0.0f, 1.0f, 0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(0.0f,    0.9f,    0.04f); 
	glVertex3f(0.028f,  0.9f,    0.028f); 
	glVertex3f(0.0f,    0.9f,    0.04f); 
	glVertex3f(0.028f,  0.9f,    0.028f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(0.028f,  0.9f,    0.028f); 
	glVertex3f(0.04f,   0.9f,    0.0f); 
	glVertex3f(0.028f,  0.9f,    0.028f); 
	glVertex3f(0.04f,   0.9f,    0.0f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(0.04f,   0.9f,    0.0f); 
	glVertex3f(0.028f,  0.9f,    -0.028f); 
	glVertex3f(0.04f,   0.9f,    0.0f); 
	glVertex3f(0.028f,  0.9f,    -0.028f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(0.028f,  0.9f,    -0.028f); 
	glVertex3f(0.0f,    0.9f,    -0.04f); 
	glVertex3f(0.028f,  0.9f,    -0.028f); 
	glVertex3f(0.0f,    0.9f,    -0.04f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(0.0f,    0.9f,    -0.04f); 
	glVertex3f(-0.028f, 0.9f,    -0.028f); 
	glVertex3f(0.0f,    0.9f,    -0.04f); 
	glVertex3f(-0.028f, 0.9f,    -0.028f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(-0.028f, 0.9f,    -0.028f); 
	glVertex3f(-0.04f,  0.9f,    0.0f); 
	glVertex3f(-0.028f, 0.9f,    -0.028f); 
	glVertex3f(-0.04f,  0.9f,    0.0f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(-0.04f,  0.9f,    0.0f); 
	glVertex3f(-0.028f, 0.9f,    0.028f); 
	glVertex3f(-0.04f,  0.9f,    0.0f); 
	glVertex3f(-0.028f, 0.9f,    0.028f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
	glVertex3f(0.0f,    1.0f,    0.0f); 
	glVertex3f(-0.028f, 0.9f,    0.028f); 
	glVertex3f(0.0f,    0.9f,    0.04f); 
	glVertex3f(-0.028f, 0.9f,    0.028f); 
	glVertex3f(0.0f,    0.9f,    0.04f); 
	glVertex3f(0.0f,    0.9f,    0.0f); 
 
	// z axis arrow 
	glColor3f ( 0.0f, 0.0f, 1.0f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(0.0f,    0.04f,   0.9f); 
	glVertex3f(0.028f,  0.028f,  0.9f); 
	glVertex3f(0.0f,    0.04f,   0.9f); 
	glVertex3f(0.028f,  0.028f,  0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(0.028f,  0.028f,  0.9f); 
	glVertex3f(0.04f,   0.0f,    0.9f); 
	glVertex3f(0.028f,  0.028f,  0.9f); 
	glVertex3f(0.04f,   0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(0.04f,   0.0f,    0.9f); 
	glVertex3f(0.028f,  -0.028f, 0.9f); 
	glVertex3f(0.04f,   0.0f,    0.9f); 
	glVertex3f(0.028f,  -0.028f, 0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(0.028f,  -0.028f, 0.9f); 
	glVertex3f(0.0f,    -0.04f,  0.9f); 
	glVertex3f(0.028f,  -0.028f, 0.9f); 
	glVertex3f(0.0f,    -0.04f,  0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(0.0f,    -0.04f,  0.9f); 
	glVertex3f(-0.028f, -0.028f, 0.9f); 
	glVertex3f(0.0f,    -0.04f,  0.9f); 
	glVertex3f(-0.028f, -0.028f, 0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(-0.028f, -0.028f, 0.9f); 
	glVertex3f(-0.04f,  0.0f,    0.9f); 
	glVertex3f(-0.028f, -0.028f, 0.9f); 
	glVertex3f(-0.04f,  0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(-0.04f,  0.0f,    0.9f); 
	glVertex3f(-0.028f, 0.028f,  0.9f); 
	glVertex3f(-0.04f,  0.0f,    0.9f); 
	glVertex3f(-0.028f, 0.028f,  0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
	glVertex3f(0.0f,    0.0f,    1.0f); 
	glVertex3f(-0.028f, 0.028f,  0.9f); 
	glVertex3f(0.0f,    0.04f,   0.9f); 
	glVertex3f(-0.028f, 0.028f,  0.9f); 
	glVertex3f(0.0f,    0.04f,   0.9f); 
	glVertex3f(0.0f,    0.0f,    0.9f); 
 
	glEnd();    
	glPopMatrix(); 
	glEnable(GL_LIGHTING); 
	glColor3f ( 1.0f, 1.0f, 0.0f); 
 
} 
 
 
 
void CMeshProcessView::OnxRotate()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	glRotatef( ROTATE_ANLGE, 1.0, 0.0, 0.0 ); 
 
    RenderScene( pDoc->m_mSourceModel );	 
	 
} 
 
void CMeshProcessView::OnxRotatei()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
 
	glRotatef( -ROTATE_ANLGE , 1.0, 0.0, 0.0 ); 
 
    RenderScene( pDoc->m_mSourceModel );	 
 
} 
 
void CMeshProcessView::OnyRotate()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	glRotatef( ROTATE_ANLGE , 0.0, 1.0, 0.0 ); 
 
    RenderScene( pDoc->m_mSourceModel );	 
 
	 
} 
 
void CMeshProcessView::OnyRotatei()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	glRotatef( -ROTATE_ANLGE , 0.0, 1.0, 0.0 ); 
 
    RenderScene( pDoc->m_mSourceModel );	 
	 
} 
 
void CMeshProcessView::OnzRotate()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	glRotatef( ROTATE_ANLGE , 0.0, 0.0, 1.0 ); 
 
    RenderScene( pDoc->m_mSourceModel );	 
 
	 
} 
 
void CMeshProcessView::OnzRotatei()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	glRotatef( -ROTATE_ANLGE , 0.0, 0.0, 1.0 ); 
 
    RenderScene( pDoc->m_mSourceModel );	 
 
} 
 
 
void CMeshProcessView::OnSolid()  
{ 
	// TODO: Add your command handler code here 
	m_nDisplaymode = SOLIDMODE; 
	Invalidate( true ); 
	 
} 
 
void CMeshProcessView::OnUpdateSolid(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nDisplaymode == SOLIDMODE ); 
	 
} 
 
void CMeshProcessView::OnFlatSolid()  
{ 
	// TODO: Add your command handler code here 
	m_nDisplaymode = FLATSOLIDMODE ; 
	Invalidate( true ); 
 
	 
} 
 
void CMeshProcessView::OnUpdateFlatSolid(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nDisplaymode == FLATSOLIDMODE ); 
	 
} 
 
 
void CMeshProcessView::OnWireframes()  
{ 
	// TODO: Add your command handler code here 
	m_nDisplaymode = WIREFRAMEMODE ; 
	Invalidate( true ); 
	 
} 
 
void CMeshProcessView::OnUpdateWireframes(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here	 
	pCmdUI->SetCheck( m_nDisplaymode == WIREFRAMEMODE ); 
	 
} 
 
void CMeshProcessView::OnSolidWire()  
{ 
	// TODO: Add your command handler code here 
	m_nDisplaymode = SOLIDWIREMODE; 
	Invalidate( true ); 
	 
} 
 
void CMeshProcessView::OnUpdateSolidWire(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nDisplaymode == SOLIDWIREMODE ); 
	 
} 
 
void CMeshProcessView::OnVertices()  
{ 
	// TODO: Add your command handler code here 
	m_nDisplaymode = VERTEXMODE; 
	Invalidate( true );	 
} 
 
void CMeshProcessView::OnUpdateVertices(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nDisplaymode == VERTEXMODE ); 
 
} 
 
void CMeshProcessView::OnPickupVertices()  
{ 
	// TODO: Add your command handler code here 
	m_bPickup = !m_bPickup; 
	Invalidate( true ); 
	 
} 
 
void CMeshProcessView::OnUpdatePickupVertices(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_bPickup ); 
	 
} 
 
 
void CMeshProcessView::OnAxes()  
{ 
	// TODO: Add your command handler code here 
	m_bAxes = !m_bAxes;  
	Invalidate( true ); 
	 
} 
 
void CMeshProcessView::OnUpdateAxes(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_bAxes ); 
	 
} 
 
void CMeshProcessView::OnMouseDefault()  
{ 
	// TODO: Add your command handler code here 
	m_nMouseAct = MOUSE_DEFAULT; 
	 
} 
 
void CMeshProcessView::OnUpdateMouseDefault(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nMouseAct == MOUSE_DEFAULT ); 
	 
} 
 
void CMeshProcessView::OnMouseSpin()  
{ 
	// TODO: Add your command handler code here 
	m_nMouseAct = MOUSE_SPIN;	 
} 
 
void CMeshProcessView::OnUpdateMouseSpin(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nMouseAct == MOUSE_SPIN ); 
	 
} 
 
 
void CMeshProcessView::OnMouseTranslate()  
{ 
	// TODO: Add your command handler code here 
	m_nMouseAct = MOUSE_TRANSLATE; 
	 
} 
 
void CMeshProcessView::OnUpdateMouseTranslate(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nMouseAct == MOUSE_TRANSLATE ); 
	 
} 
 
 
void CMeshProcessView::OnMouseZoom()  
{ 
	// TODO: Add your command handler code here 
	m_nMouseAct = MOUSE_ZOOM; 
	 
} 
 
 
void CMeshProcessView::OnUpdateMouseZoom(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nMouseAct == MOUSE_ZOOM ); 
	 
} 
 
 
BOOL CMeshProcessView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)  
{ 
	// TODO: Add your message handler code here and/or call default 
 
	HCURSOR hCursor; 
	 
	switch(m_nMouseAct) { 
 
	case MOUSE_PICKUP: 
		hCursor = AfxGetApp()->LoadStandardCursor( IDC_CROSS ); 
		SetCursor( hCursor ); 
		break; 
	case MOUSE_TOUCH: 
		hCursor = AfxGetApp()->LoadCursor( IDC_TOUCH ); 
		SetCursor( hCursor ); 
		break;		 
	case MOUSE_SPIN: 
		hCursor = AfxGetApp()->LoadCursor( IDC_SPIN ); 
		SetCursor( hCursor ); 
		break; 
	case MOUSE_ZOOM: 
        hCursor = AfxGetApp()->LoadCursor( IDC_ZOOM ); 
		SetCursor( hCursor ); 
		break; 
	case MOUSE_TRANSLATE: 
		hCursor = AfxGetApp()->LoadCursor( IDC_TRANSLATE ); 
		SetCursor( hCursor ); 
		break; 
	case MOUSE_DEFAULT:		 
		hCursor = AfxGetApp()->LoadCursor( IDC_DEFAULT ); 
		SetCursor( hCursor ); 
		break;		 
	default: 
		hCursor = AfxGetApp()->LoadStandardCursor( IDC_ARROW  ); 
		SetCursor( hCursor ); 
		break;	 
		 
	} 
	 
 
	return TRUE; 
} 
 
void CMeshProcessView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	m_spinAngle = 0.0f; 
 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
	 
	switch( m_nMouseAct ) { 
	case MOUSE_TOUCH: 
		PickupVertex( pDoc->m_mSourceModel, point); 
		break; 
	case MOUSE_SPIN: 
		if (m_bAnimate) 
			SetTimer(TIMER_ANIMATE,ANIMATE_RATE,NULL); 
		MouseSpinGlobal( nFlags, point.x, point.y, 1 ); 
		break; 
	case MOUSE_ZOOM: 
		MouseZoom( nFlags, point.x, point.y ); 
		break; 
	case MOUSE_TRANSLATE: 
		MouseTranslate( nFlags, point.x, point.y ); 
		break; 
	default: 
		return; 
		 
	}	 
	 
	m_bLButtonDown = true; 
 
} 
 
void CMeshProcessView::SpinGlobal(float axes[], float angle) 
{	 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	EyeRotate(m_vProjectCenter, axes, angle, m_sEye ); 
	RenderScene( pDoc->m_mSourceModel );  
 
} 
 
void CMeshProcessView::MouseSpinGlobal(UINT nFlags, int x, int y, int init) 
{ 
	// use mouse to play 3D trackball transformation 
	// see also Intel 3DR 
 
	float centerX, centerY; 
	float radius; 
	float w, h;  // window 
 
    RECT rect; 
    GetClientRect( &rect); 
    w =(float)rect.right; 
	h =(float)rect.bottom; 
    h = (h == 0.0f) ? 1.0f : h; 
 
    centerX = w / 2.0f; 
	centerY = h / 2.0f; 
	radius  = (w > h) ? centerY : centerX ; 
 
	if (init) 
	{ 
		 //	And call Trackball() with current center, radius  
		 // and current cursor position (in client coordinates)  
		 // to initialize trackball internal parameters. 
		 //	Note that we must stop animation at that time. 
 
		Trackball( 0, radius, centerX, centerY, (float)x, (float)(h-y),  
		           m_spinAxes[0], m_spinAxes[1], m_spinAxes[2], m_spinAngle); 
	} 
	else if ( nFlags & MK_LBUTTON ) 
	{ 
	    Trackball(1, radius, centerX, centerY, (float)x, (float)(h-y),  
			      m_spinAxes[0], m_spinAxes[1], m_spinAxes[2], m_spinAngle); 
		SpinGlobal(m_spinAxes, m_spinAngle); 
	} 
 
 
} 
 
void CMeshProcessView::MouseZoom(UINT nFlags, int x, int y) 
{ 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	static float oldY, dy ; 
 
	RECT rect; 
	GetClientRect( &rect); 
    float w = (float)rect.right; 
	float h = (float)rect.bottom; 
	h = (h == 0.0f) ? 1.0f : h; 
 
	if( m_bLButtonDown && (nFlags & MK_LBUTTON)) 
	{ 
		dy=oldY-y; 
		m_fScaling+=dy/h; 
		GLResize( (int)w, (int)h);	 
		RenderScene( pDoc->m_mSourceModel );		 
		oldY=(float)y; 
	} 
	else 
	{ 
		oldY=(float)y; 
	} 
} 
 
void CMeshProcessView::MouseTranslate(UINT nFlags, int x, int y) 
{ 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	float w, h; 
	static float oldX, oldY, dx, dy, d[3] ; 
 
	RECT rect; 
	GetClientRect( &rect); 
	w =(float)rect.right; 
	h =(float)rect.bottom; 
	h = (h == 0.0f) ? 1.0f : h; 
 
	if( m_bLButtonDown && (nFlags & MK_LBUTTON)) 
	{ 
		dx=x-oldX; 
		dy=oldY-y; 
		d[0]=(float)2.0*dx/w*0.8f; 
		d[1]=(float)2.0*dy/h*0.8f;            
		d[2]=0.0f; 
		EyeTranslate(d, m_sEye);   
		RenderScene( pDoc->m_mSourceModel );		 
		oldX=(float)x; 
		oldY=(float)y; 
	} 
	else 
	{ 
		oldX=(float)x; 
		oldY=(float)y; 
	} 
 
 
} 
 
 
void CMeshProcessView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	switch( m_nMouseAct ) { 
 
	case MOUSE_PICKUP: 
		TouchVertex( pDoc->m_mSourceModel, point); 
		break; 
	case MOUSE_TOUCH: 
		TouchVertex( pDoc->m_mSourceModel, point); 
		break; 
	case MOUSE_SPIN: 
		MouseSpinGlobal(nFlags, point.x, point.y, 0); 
		break; 
	case MOUSE_ZOOM: 
		MouseZoom( nFlags, point.x, point.y ); 
		break; 
	case MOUSE_TRANSLATE: 
		MouseTranslate( nFlags, point.x, point.y ); 
		break; 
	default: 
		return; 
		 
	} 
	 
	 
	CView::OnMouseMove(nFlags, point); 
} 
 
void CMeshProcessView::OnBoundbox()  
{ 
	// TODO: Add your command handler code here 
	m_bBox = !m_bBox; 
	Invalidate( true ); 
} 
 
void CMeshProcessView::OnUpdateBoundbox(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_bBox ); 
	 
} 
 
void CMeshProcessView::OnMousePickup()  
{ 
	// TODO: Add your command handler code here 
	m_nMouseAct = MOUSE_PICKUP; 
	 
} 
 
void CMeshProcessView::OnUpdateMousePickup(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck( m_nMouseAct == MOUSE_PICKUP|| m_nMouseAct == MOUSE_TOUCH); 
	 
} 
 
int CMeshProcessView::PickupVertex(CMesh &mModel, CPoint point) 
{ 
	BYTE m_pixels[6*6*3]; 
	CRect Rect; 
    GetClientRect(&Rect); 
 	int width = (int)(Rect.right); 
    int height= (int)(Rect.bottom); 
 
	glDisable(GL_LIGHT0); 
	glDisable(GL_LIGHTING); 
 
 
	glDrawBuffer(GL_BACK); 
	{ 
		glClearColor(1.0, 1.0, 1.0, 1.0 );  
 
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
		glMatrixMode(GL_MODELVIEW); 
		glPushMatrix(); 
 
		mModel.DrawPickupTriVer();		 
 
		glMatrixMode(GL_MODELVIEW);	 
		glPopMatrix(); 
	} 
		 
	glFlush(); 
	glPixelStorei(GL_PACK_ALIGNMENT,1); 
 
	glReadBuffer(GL_BACK); 
	{ 
		glReadPixels( point.x+3, height-point.y-3, 6, 6, GL_RGB, GL_UNSIGNED_BYTE, m_pixels ); 
		bool BSEL = false; 
		for( int i = 0; i < 6*6; i++ ) 
		{ 
			if (m_pixels[i*3]!=255||m_pixels[i*3+1]!=255)//&& 
		//		(m_pixels[i*3]!=(int(m_ClearColorRed*255)||m_pixels[i*3+1]!=(int(m_ClearColorRed*255))))) 
			{ 
				int j = (m_pixels[i*3])*200+m_pixels[i*3+1]; 
				mModel.m_nSvertices[mModel.m_numS++] = j; 
				int k= mModel.m_nSvertices[mModel.m_numS]; 
				BSEL = true;  
				printf("The %d picked up vertex is %d.\n", mModel.m_numS-1, j); 
				break; 
			} 
		} 
		if(BSEL == false) 
			MessageBox("Pick up vertex failure!"); 
	} 
	glClearColor(m_ClearColorRed, m_ClearColorGreen, m_ClearColorBlue, 1.0 );  
 
	Invalidate( false ); 
 
 
	return true; 
 
} 
 
bool CMeshProcessView::TouchVertex(CMesh &mModel, CPoint point) 
{ 
	bool touch_vertex = false; 
    m_nMouseAct = MOUSE_PICKUP; 
 
	BYTE m_pixels[6*6*3]; 
	CRect Rect; 
    GetClientRect(&Rect); 
 	int width = (int)(Rect.right); 
    int height= (int)(Rect.bottom); 
 
	glDisable(GL_LIGHT0); 
	glDisable(GL_LIGHTING); 
 
 
	glDrawBuffer(GL_BACK); 
	{ 
		glClearColor(1.0, 1.0, 1.0, 1.0 );  
 
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
		glMatrixMode(GL_MODELVIEW); 
		glPushMatrix(); 
 
		mModel.DrawPickupTriVer();		 
 
		glMatrixMode(GL_MODELVIEW);	 
		glPopMatrix(); 
	} 
		 
	glFlush(); 
	glPixelStorei(GL_PACK_ALIGNMENT,1); 
 
	glReadBuffer(GL_BACK); 
	{ 
		glReadPixels( point.x+3, height-point.y-3, 6, 6, GL_RGB, GL_UNSIGNED_BYTE, m_pixels ); 
		bool BSEL = false; 
		for( int i = 0; i < 6*6; i++ ) 
		{ 
			if (m_pixels[i*3]!=255||m_pixels[i*3+1]!=255) 
			{ 
				touch_vertex = true; 
				m_nMouseAct = MOUSE_TOUCH; 
				break; 
			} 
		} 
	} 
	glClearColor(m_ClearColorRed, m_ClearColorGreen, m_ClearColorBlue, 1.0 );  
 
	Invalidate( false ); 
 
 
	return touch_vertex; 
 
 
 
} 
 
 
void CMeshProcessView::OnSetupClearcolor()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessApp *pApp = (CMeshProcessApp *)AfxGetApp(); 
	CColorDialog dlg(pApp->m_OptionColorGlBack); 
 
	if( dlg.DoModal() == IDOK) 
	{ 
		pApp->m_OptionColorGlBack = dlg.GetColor();	 
		m_ClearColorRed   = (float)GetRValue(pApp->m_OptionColorGlBack)/255 ; 
		m_ClearColorGreen = (float)GetGValue(pApp->m_OptionColorGlBack)/255 ; 
		m_ClearColorBlue  = (float)GetBValue(pApp->m_OptionColorGlBack)/255 ; 
		glClearColor(m_ClearColorRed, m_ClearColorGreen, m_ClearColorBlue, 1.0 );  
	} 
 
	Invalidate( true); 
	 
} 
 
 
void CMeshProcessView::OnSetupSolidcolor()  
{ 
	// TODO: Add your command handler code here 
 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	SetupSolidColor( pDoc->m_mSourceModel); 
 
	Invalidate( true);	 
} 
 
void CMeshProcessView::SetupSolidColor(CMesh &mModel) 
{ 
	CMeshProcessApp *pApp = (CMeshProcessApp *)AfxGetApp(); 
	CColorDialog dlg(pApp->m_OptionColorMesh); 
 
	if( dlg.DoModal() == IDOK) 
	{ 
		pApp->m_OptionColorMesh = dlg.GetColor();	 
		mModel.m_nMeshcolor[0] = (int)GetRValue(pApp->m_OptionColorMesh); 
		mModel.m_nMeshcolor[1] = (int)GetGValue(pApp->m_OptionColorMesh); 
		mModel.m_nMeshcolor[2] = (int)GetBValue(pApp->m_OptionColorMesh); 
	} 
 
} 
 
void CMeshProcessView::OnSetupLinecolor()  
{ 
	// TODO: Add your command handler code here 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	SetupLineColor( pDoc->m_mSourceModel); 
 
	Invalidate( true);	 
 
	 
} 
 
void CMeshProcessView::SetupLineColor(CMesh &mModel) 
{ 
	CMeshProcessApp *pApp = (CMeshProcessApp *)AfxGetApp(); 
	CColorDialog dlg(pApp->m_OptionColorLine); 
 
	if( dlg.DoModal() == IDOK) 
	{ 
		pApp->m_OptionColorLine = dlg.GetColor();	 
		mModel.m_nLinecolor[0] = (int)GetRValue(pApp->m_OptionColorLine); 
		mModel.m_nLinecolor[1] = (int)GetGValue(pApp->m_OptionColorLine); 
		mModel.m_nLinecolor[2] = (int)GetBValue(pApp->m_OptionColorLine); 
	} 
 
} 
 
 
 
 
 
 
void CMeshProcessView::RenderScene( CMesh& mModel) 
{ 
 
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
	glMatrixMode(GL_MODELVIEW); 
 
	glEnable( GL_COLOR_MATERIAL ); 
 
	glPushMatrix(); 
	 
	if( mModel.m_Vertices ) 
	{ 
		mModel.DisplayModel( m_nDisplaymode ); 
		if( m_bBox ) 
			mModel.DrawBoundingBox(); 
		if( m_bPickup ) 
			mModel.DrawSvertices( 8 , 255, 255, 0); 
	} 
	if( m_bAxes ) 
		DrawAxes(); 
	 
	glMatrixMode(GL_MODELVIEW);	 
	glPopMatrix(); 
 
	glDisable( GL_COLOR_MATERIAL ); 
 
 
	glFlush(); 
	SwapBuffers( m_hDC ); 
 
 
} 
 
void CMeshProcessView::OnOpenCorrespond()  
{ 
	// TODO: Add your command handler code here 
	static char BASED_CODE szFilter[] = "txt Files (*.txt)|*.txt|All Files (*.*)|*.*||"; 
	CFileDialog dlg( TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, szFilter ); 
	dlg.m_ofn.lpstrTitle = "Open Source/Target Correspondence"; 
 
	if( dlg.DoModal() == IDOK) 
	{ 
		CString pat = dlg.GetPathName(); 
		int   i = 0; 
		char *fl = pat.GetBuffer( 10 ); 
		char  linech[256]; 
		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); 
 
		lstream>>m_nCorrespond; 
		m_Correspond = new int[m_nCorrespond]; 
		while( !fin.eof() ) 
		{ 
			fin.clear(); 
			fin.getline(linech,256); 
			linestr=linech; 
 
			lstream.clear(); 
			lstream.str(linestr); 
			lstream>>m_Correspond[i ++];		 
		} 
 
	} 
 
	 
} 
 
void CMeshProcessView::MorphMesh(double t) 
{ 
 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	for (int i = 0; i < m_mModel.m_numT; i ++) 
	{ 
		m_mModel.m_Meshes[i].veridx[0] = pDoc->m_mSourceModel.m_Meshes[i].veridx[0]; 
		m_mModel.m_Meshes[i].veridx[1] = pDoc->m_mSourceModel.m_Meshes[i].veridx[1]; 
		m_mModel.m_Meshes[i].veridx[2] = pDoc->m_mSourceModel.m_Meshes[i].veridx[2]; 
	} 
 
	for (i = 0; i < m_mModel.m_numV; i ++) 
	{ 
		m_mModel.m_Vertices[i].x = pDoc->m_mSourceModel.m_Vertices[i].x + t * m_vSTDifference[i].x; 
		m_mModel.m_Vertices[i].y = pDoc->m_mSourceModel.m_Vertices[i].y + t * m_vSTDifference[i].y; 
	    m_mModel.m_Vertices[i].z = pDoc->m_mSourceModel.m_Vertices[i].z + t * m_vSTDifference[i].z; 
	} 
	for (i = 0; i < m_mModel.m_numV; i ++) 
	{ 
		m_mModel.m_Vertices[i].normale[0] = pDoc->m_mSourceModel.m_Vertices[i].normale[0] + t * m_vNormalDiffce[i].x;  
		m_mModel.m_Vertices[i].normale[1] = pDoc->m_mSourceModel.m_Vertices[i].normale[1] + t * m_vNormalDiffce[i].y; 
		m_mModel.m_Vertices[i].normale[2] = pDoc->m_mSourceModel.m_Vertices[i].normale[2] + t * m_vNormalDiffce[i].z; 
	} 
 
 
} 
 
 
 
void CMeshProcessView::OnMeshMorph()  
{ 
	// TODO: Add your command handler code here 
	int j = 0; 
	double t = .0; 
	while (j < 8) 
	{ 
		if (j%2 == 0) 
			t += 0.05; 
		else if (j%2 == 1) 
			t -= 0.05; 
		if (fabs(t - 1) <1e-5 || fabs(t) <1e-5) 
			j++; 
//		t = 0.5; 
		MorphMesh(t); 
		RenderScene(m_mModel); 
//		Invalidate(true); 
		Sleep(6); 
 
	} 
	 
} 
 
void CMeshProcessView::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	 
	// TODO: Add your message handler code here 
	 
	// Do not call CView::OnPaint() for painting messages 
	 
	CMeshProcessDoc* pDoc = (CMeshProcessDoc*)GetDocument(); 
 
	RenderScene(pDoc->m_mSourceModel); 
 
 
}