Files
Hoops_Exchange/exchange/exchangesource/DrawingViewer/drawing_main.cpp
2025-12-15 22:06:49 +08:00

869 lines
26 KiB
C++

/***********************************************************************************************************************
*
* Copyright (c) 2010 - 2022 by Tech Soft 3D, Inc.
* The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., and considered a trade secret
* as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event
* of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized
* employees of Tech Soft 3D, Inc. is granted only under a written non-disclosure agreement, expressly prescribing the
* scope and manner of such use.
*
***********************************************************************************************************************/
/**
\file drawing_main.cpp
This file demonstrates how to programmatically visualize a drawing PRC file
from a basic OpenGL program using HOOPS Exchange.
***********************************************************************************************************************/
#define INITIALIZE_A3D_API
#include <A3DSDKIncludes.h>
#include "../common.hpp"
#include "callback_opengl.h"
#include "drawing_main.h"
#include "trackball.h"
#include <stdarg.h>
#include <time.h>
#include <vector>
//######################################################################################################################
A3DStatus CollectDrawing(A3DAsmModelFile* pModelFile, std::vector<A3DDrawingModel*> &apDrawingModels);
//######################################################################################################################
A3DStatus A3DDrawDrawing(A3DDrawingModel* pDrawingModel, A3DDrawCallbacksData* psCallbacks,
std::vector<GLuint> &aGLSheetDisplayList, std::vector<A3DVector2dData>* paGLSheetSize,
bool bDrawMarkup);
//######################################################################################################################
static bool stbTrackBallAnimate = GL_FALSE;
//######################################################################################################################
static GLsizei stiXScreen = 0;
static GLsizei stiYScreen = 0;
static GLdouble stdXPan = 0.0;
static GLdouble stdYPan = 0.0;
static GLdouble stdZoom = 1.0;
static GLint staiViewport[4];
//######################################################################################################################
static bool stbLButtonDown = false;
static bool stbRButtonDown = false;
//######################################################################################################################
static GLuint stuiModelFileDisplayList = 0;
static GLuint stuiMarkupsDisplayList = 0;
static GLuint stuiTriedronDisplayList = 0;
//######################################################################################################################
static std::vector<GLuint> st_aGLSheetDisplayList;
static std::vector<A3DVector2dData> st_aGLSheetSize;
//######################################################################################################################
static std::vector<GLuint> st_aGLSheetMarkupDisplayList;
static GLuint st_CurrentSheetIndex = 0;
//######################################################################################################################
static GLfloat stafLightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
static GLfloat stafLightAmbient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
static GLfloat stafLightPosition[] = { 0.0f, 0.0f, 1.0f, 0.0f };
//######################################################################################################################
static GLfloat stafMaterialDiffuse[] = { 0.6f, 0.6f, 0.6f, 1.0f };
static GLfloat stafMaterialSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
static GLfloat stafMaterialShininess[] = { 100.0f };
//######################################################################################################################
static GLfloat stafTextColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
//######################################################################################################################
static unsigned int stuiClearColor = 0xB2B2B2;
//######################################################################################################################
static GLint staiWinSize[2];
static GLint staiWinPosition[2];
static bool stbFullScreen = false;
//######################################################################################################################
static clock_t stiStart, stiEnd;
static float stfElapsed;
static unsigned int stiNbFrames = 0;
static float stfFps = 0.0f;
//######################################################################################################################
static A3DUTF8Char stpcWinTitle[_MAX_PATH];
//######################################################################################################################
static bool stbDisplayHelp = false;
static bool stbDisplayInfos = false;
static bool stbDisplayMarkups = true;
//######################################################################################################################
#define TRIEDRON_SIZE 40.0
//######################################################################################################################
#define A3DGL_MIN(a,b) (((a)<(b)) ? (a) : (b))
#define A3DGL_MAX(a,b) (((a)>(b)) ? (a) : (b))
//######################################################################################################################
class A3DPRCViewerGLInfo
{
public:
A3DBoundingBoxData sBoundingBox;
double dBoundingBoxRadius;
A3DVector3dData sBoundingBoxCenter;
A3DVector2dData sDelta;
public:
//##################################################################################################################
A3DPRCViewerGLInfo() { Init(); }
//##################################################################################################################
void Init()
{
A3D_INITIALIZE_DATA(A3DBoundingBoxData, sBoundingBox);
A3D_INITIALIZE_DATA(A3DVector3dData, sBoundingBoxCenter);
dBoundingBoxRadius = 0.0;
}
//##################################################################################################################
void operator=(const A3DPRCViewerGLInfo& sOther)
{
sBoundingBox.m_sMin.m_dX = sOther.sBoundingBox.m_sMin.m_dX;
sBoundingBox.m_sMin.m_dY = sOther.sBoundingBox.m_sMin.m_dY;
sBoundingBox.m_sMin.m_dZ = sOther.sBoundingBox.m_sMin.m_dZ;
sBoundingBox.m_sMax.m_dX = sOther.sBoundingBox.m_sMax.m_dX;
sBoundingBox.m_sMax.m_dY = sOther.sBoundingBox.m_sMax.m_dY;
sBoundingBox.m_sMax.m_dZ = sOther.sBoundingBox.m_sMax.m_dZ;
dBoundingBoxRadius = sOther.dBoundingBoxRadius;
sBoundingBoxCenter.m_dX = sOther.sBoundingBoxCenter.m_dX;
sBoundingBoxCenter.m_dY = sOther.sBoundingBoxCenter.m_dY;
sBoundingBoxCenter.m_dZ = sOther.sBoundingBoxCenter.m_dZ;
}
//##################################################################################################################
void Calculate()
{
A3DVector3dData sMin;
A3DVector3dData sMax;
sMin.m_dX = sBoundingBox.m_sMin.m_dX;
sMin.m_dY = sBoundingBox.m_sMin.m_dY;
sMin.m_dZ = sBoundingBox.m_sMin.m_dZ;
sMax.m_dX = sBoundingBox.m_sMax.m_dX;
sMax.m_dY = sBoundingBox.m_sMax.m_dY;
sMax.m_dZ = sBoundingBox.m_sMax.m_dZ;
A3DDouble dBX = sMax.m_dX - sMin.m_dX;
A3DDouble dBY = sMax.m_dY - sMin.m_dY;
A3DDouble dBZ = sMax.m_dZ - sMin.m_dZ;
dBoundingBoxRadius = (float)sqrt(dBX*dBX + dBY*dBY + dBZ*dBZ) / 2.0f;
sBoundingBoxCenter.m_dX = (sMin.m_dX + sMax.m_dX) / 2.0;
sBoundingBoxCenter.m_dY = (sMin.m_dY + sMax.m_dY) / 2.0;
sBoundingBoxCenter.m_dZ = (sMin.m_dZ + sMax.m_dZ) / 2.0;
}
//##################################################################################################################
A3DPRCViewerGLInfo operator+(const A3DPRCViewerGLInfo& sOther)
{
A3DPRCViewerGLInfo sSum;
ExtentUnion(&sBoundingBox, &sOther.sBoundingBox, &sSum.sBoundingBox);
sSum.Calculate();
return sSum;
}
private:
//##################################################################################################################
void ExtentUnion(const A3DBoundingBoxData* e1, const A3DBoundingBoxData* e2, A3DBoundingBoxData* r)
{
r->m_sMin.m_dX = A3DGL_MIN(e1->m_sMin.m_dX, e2->m_sMin.m_dX);
r->m_sMax.m_dX = A3DGL_MAX(e1->m_sMax.m_dX, e2->m_sMax.m_dX);
r->m_sMin.m_dY = A3DGL_MIN(e1->m_sMin.m_dY, e2->m_sMin.m_dY);
r->m_sMax.m_dY = A3DGL_MAX(e1->m_sMax.m_dY, e2->m_sMax.m_dY);
r->m_sMin.m_dZ = A3DGL_MIN(e1->m_sMin.m_dZ, e2->m_sMin.m_dZ);
r->m_sMax.m_dZ = A3DGL_MAX(e1->m_sMax.m_dZ, e2->m_sMax.m_dZ);
}
};
//######################################################################################################################
static A3DDrawCallbacksData stsDrawCallbacksData;
static A3DSDKHOOPSExchangeLoader* stpHOOPSExchangeLoader = NULL;
//######################################################################################################################
static A3DPRCViewerGLInfo stsInfo;
static A3DPRCViewerGLInfo stsInfo3D;
static A3DPRCViewerGLInfo stsInfoMarkups;
//######################################################################################################################
#define HEX_TO_RED(hexcolor) ((GLclampf) ((hexcolor & 0xFF0000) >> 16) / 255.0f)
#define HEX_TO_GREEN(hexcolor) ((GLclampf) ((hexcolor & 0x00FF00) >> 8) / 255.0f)
#define HEX_TO_BLUE(hexcolor) ((GLclampf) (hexcolor & 0x0000FF) / 255.0f)
//######################################################################################################################
static enum
{
KE_NONE = 0,
KE_ZOOMING,
KE_PANNING
} eMotionType;
//######################################################################################################################
void Reshape(GLsizei w, GLsizei h)
{
tbReshape(w, h);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double dLengthX = stsInfo.sBoundingBox.m_sMax.m_dX - stsInfo.sBoundingBox.m_sMin.m_dX;
double dLengthY = stsInfo.sBoundingBox.m_sMax.m_dY - stsInfo.sBoundingBox.m_sMin.m_dY;
stsInfo.sDelta.m_dX = (dLengthY * w / h - dLengthX)/2.;
stsInfo.sDelta.m_dY = (dLengthX * h / w - dLengthY)/2.;
if(stsInfo.sDelta.m_dX > stsInfo.sDelta.m_dY)
stsInfo.sDelta.m_dY = 0;
else
stsInfo.sDelta.m_dX = 0;
glOrtho(stsInfo.sBoundingBox.m_sMin.m_dX - stsInfo.sDelta.m_dX,
stsInfo.sBoundingBox.m_sMax.m_dX + stsInfo.sDelta.m_dX,
stsInfo.sBoundingBox.m_sMin.m_dY - stsInfo.sDelta.m_dY,
stsInfo.sBoundingBox.m_sMax.m_dY + stsInfo.sDelta.m_dY,
-1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT, staiViewport);
if(!stbFullScreen)
{
staiWinSize[0] = w;
staiWinSize[1] = h;
}
}
//######################################################################################################################
void InitGL(void)
{
glClearColor(HEX_TO_RED(stuiClearColor), HEX_TO_GREEN(stuiClearColor), HEX_TO_BLUE(stuiClearColor), 1.0f);
glPointSize(5.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_NORMALIZE);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
stuiTriedronDisplayList = glGenLists(1);
glNewList(stuiTriedronDisplayList, GL_COMPILE);
{
glPushAttrib(GL_LIGHTING_BIT | GL_LINE_BIT);
glDisable(GL_LIGHTING);
glLineWidth(2.0);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(TRIEDRON_SIZE, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, TRIEDRON_SIZE, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, TRIEDRON_SIZE);
glEnd();
glPopAttrib();
}
glEndList();
stdZoom = 1.;
stdXPan = 0.0;
stdYPan = 0.0;
#ifdef _DEBUG
stiStart = clock();
#endif
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
//######################################################################################################################
static float stfX = 1.0f, stfY = 97.0f, stfLineH = 2.0f;
static char stpcMsg[2048];
//######################################################################################################################
void PrintString(const char* format, ...)
{
va_list args;
va_start(args, format);
vsprintf(stpcMsg, format, args);
va_end(args);
glRasterPos2f(stfX, stfY);
char* pcPos = &stpcMsg[0];
while(*pcPos)
{
if(*pcPos == '\n')
{
stfY -= stfLineH;
glRasterPos2f(stfX, stfY);
}
else
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *pcPos);
pcPos++;
}
}
//######################################################################################################################
void DrawStrings(void)
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, 100.0, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glColor3fv(stafTextColor);
if(stbDisplayInfos)
{
stfX = 1.0f;
stfY = 97.0f;
stiNbFrames++;
stiEnd = clock();
stfElapsed = (float)(stiEnd - stiStart) / CLOCKS_PER_SEC;
if(stfElapsed >= 1.0)
{
stfFps = stiNbFrames/stfElapsed;
stiStart = stiEnd;
stiNbFrames = 0;
}
PrintString("%.2f fps\n", stfFps);
PrintString("Bounding box\n");
A3DVector3dData& sMin = stsInfo.sBoundingBox.m_sMin;
A3DVector3dData& sMax = stsInfo.sBoundingBox.m_sMax;
PrintString(" Extent: [%.3f, %.3f, %.3f] -> [%.3f, %.3f, %.3f]\n", sMin.m_dX, sMin.m_dY, sMin.m_dZ,
sMax.m_dX, sMax.m_dY, sMax.m_dZ);
PrintString(" Radius: %.3f\n", stsInfo.dBoundingBoxRadius);
}
if(stbDisplayHelp)
{
stfX = 1.0f;
stfY = 70.0f;
PrintString("HELP\n");
PrintString(" MOUSE :\n");
PrintString(" Left button: panning\n");
PrintString(" Right button: zooming\n");
PrintString("\n");
PrintString(" KEYBOARD :\n");
PrintString(" F1: print this help\n");
PrintString(" F2: open a file (in the console)\n");
PrintString(" F3: save file as Prc\n");
PrintString(" F4: toggle display markups\n");
PrintString(" F5: toggle full screen\n");
PrintString(" F6: change background color\n");
PrintString(" F11: toggle display information\n");
PrintString(" PAGE_UP / PAGE_DOWN: change current sheet\n");
}
glPopAttrib();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
//######################################################################################################################
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
{
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, stafLightPosition);
double dOffsetX = (stsInfo.sBoundingBox.m_sMax.m_dX-stsInfo.sBoundingBox.m_sMin.m_dX)/2. + stsInfo.sDelta.m_dX;
double dOffsetY = (stsInfo.sBoundingBox.m_sMax.m_dY-stsInfo.sBoundingBox.m_sMin.m_dY)/2. + stsInfo.sDelta.m_dY;
glTranslated(dOffsetX, dOffsetY, 0.);
glScaled(stdZoom, stdZoom, 1.);
glTranslated(-dOffsetX, -dOffsetY, 0.);
glTranslated(-stsInfo.dBoundingBoxRadius*stdXPan, -stsInfo.dBoundingBoxRadius*stdYPan, 0);
//-stsInfo.dBoundingBoxRadius*stdZoom);
if (st_aGLSheetDisplayList.size() > 0)
{
GLfloat afValues[3] = { 1, 1, 1 };
glColor3fv(afValues);
glCallList(st_aGLSheetDisplayList.at(size_t(st_CurrentSheetIndex)));
}
if (stbDisplayMarkups && st_aGLSheetMarkupDisplayList.size() > 0)
{
glCallList(st_aGLSheetMarkupDisplayList.at(size_t(st_CurrentSheetIndex)));
}
}
glPopMatrix();
if(stbDisplayInfos || stbDisplayHelp)
DrawStrings();
glFlush();
glFinish();
glutSwapBuffers();
}
//######################################################################################################################
static bool stbTBRunning = false;
//######################################################################################################################
void MouseButton(int button, int state, GLsizei x, GLsizei y)
{
if(button == GLUT_LEFT_BUTTON)
{
if(state == GLUT_DOWN)
stbLButtonDown = true;
else if(state == GLUT_UP)
stbLButtonDown = false;
}
else if(button == GLUT_RIGHT_BUTTON)
{
if(state == GLUT_DOWN)
stbRButtonDown = true;
else if(state == GLUT_UP)
stbRButtonDown = false;
}
if(!stbLButtonDown && !stbRButtonDown)
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
eMotionType = KE_NONE;
if(stbLButtonDown)
{
if(stbTBRunning)
tbMouse(GLUT_LEFT_BUTTON, GLUT_UP, x, y);
eMotionType = KE_PANNING;
glutSetCursor(GLUT_CURSOR_SPRAY);
}
else
{
if(stbRButtonDown)
{
eMotionType = KE_ZOOMING;
glutSetCursor(GLUT_CURSOR_UP_DOWN);
}
else
{
tbMouse(button, state, x, y);
stbTBRunning = false;
}
}
stiXScreen = x;
stiYScreen = y;
glutPostRedisplay();
}
//######################################################################################################################
void Motion(GLsizei x, GLsizei y)
{
tbMotion(x, y);
switch(eMotionType)
{
case KE_PANNING :
{
stdXPan -= (GLdouble)(x - stiXScreen)/(GLdouble)staiViewport[2] * 2.0 / stdZoom;
stdYPan += (GLdouble)(y - stiYScreen)/(GLdouble)staiViewport[3] * 2.0 / stdZoom;
break;
}
case KE_ZOOMING :
{
stdZoom += (GLdouble)(y - stiYScreen)/(GLdouble)staiViewport[3] * 10.0;
if(stdZoom < 0.1)
stdZoom = 0.1;
break;
}
default:
break;
}
stiXScreen = x;
stiYScreen = y;
glutPostRedisplay();
}
//######################################################################################################################
A3DInt32 CloseFile()
{
A3DInt32 iRet = A3D_SUCCESS;
size_t uiList, uiNbList = st_aGLSheetDisplayList.size();
for(uiList = 0; uiList < uiNbList; ++uiList)
{
glDeleteLists(st_aGLSheetDisplayList.back(), 1);
st_aGLSheetDisplayList.pop_back();
glDeleteLists(st_aGLSheetMarkupDisplayList.back(), 1);
st_aGLSheetMarkupDisplayList.pop_back();
}
st_aGLSheetSize.clear();
glDeleteLists(stuiModelFileDisplayList, 1);
glDeleteLists(stuiMarkupsDisplayList, 1);
stuiModelFileDisplayList = stuiMarkupsDisplayList = 0;
return iRet;
}
//######################################################################################################################
A3DInt32 OpenFile(const A3DUTF8Char*pcCADFileName)
{
if(stpHOOPSExchangeLoader == NULL)
return A3D_ERROR;
A3DImport sImport(pcCADFileName);
sImport.m_sLoadData.m_sGeneral.m_eReadingMode2D3D = kA3DRead_Drawings;
A3DInt32 iRet = stpHOOPSExchangeLoader->Import(sImport);
printf("Done.\n");
return iRet;
}
//######################################################################################################################
A3DInt32 ProcessModelFile()
{
if(stpHOOPSExchangeLoader == NULL || stpHOOPSExchangeLoader->m_psModelFile == NULL)
return A3D_ERROR;
// Collect all DrawingModels
std::vector<A3DDrawingModel*> apDrawingModels;
A3DInt32 iRet = CollectDrawing(stpHOOPSExchangeLoader->m_psModelFile, apDrawingModels);
if(iRet != A3D_SUCCESS)
return iRet;
if(apDrawingModels.size() == 0)
return A3D_ERROR;
// Draws and stores all the sheets in list
st_aGLSheetDisplayList.clear();
size_t uiModel, uiNbModel = apDrawingModels.size();
for(uiModel = 0; uiModel < uiNbModel; ++uiModel)
{
iRet = A3DDrawDrawing(apDrawingModels.at(uiModel), &stsDrawCallbacksData, st_aGLSheetDisplayList,
&st_aGLSheetSize, false);
if(iRet != A3D_SUCCESS)
break;
iRet = A3DDrawDrawing(apDrawingModels.at(uiModel), &stsDrawCallbacksData, st_aGLSheetMarkupDisplayList,
NULL, true);
if(iRet != A3D_SUCCESS)
break;
}
if(iRet == A3D_SUCCESS && st_aGLSheetSize.size() > 0)
{
st_CurrentSheetIndex = 0;
stsInfo.sBoundingBox.m_sMin.m_dX = 0.;
stsInfo.sBoundingBox.m_sMin.m_dY = 0.;
stsInfo.sBoundingBox.m_sMax.m_dX = st_aGLSheetSize[st_CurrentSheetIndex].m_dX;
stsInfo.sBoundingBox.m_sMax.m_dY = st_aGLSheetSize[st_CurrentSheetIndex].m_dY;
stsInfo.Calculate();
}
stdZoom = 1.;
stdXPan = 0.0;
stdYPan = 0.0;
return iRet;
}
//######################################################################################################################
A3DInt32 SaveFileAsPrc()
{
A3DStatus iRet = A3D_SUCCESS;
if(stpHOOPSExchangeLoader->m_psModelFile != NULL)
{
PrintString("Enter file name in console\n");
printf("Enter file name:\n");
A3DUTF8Char pcPRCFileName[_MAX_PATH];
scanf("%s", pcPRCFileName);
A3DRWParamsExportPrcData sParamsExportData;
A3D_INITIALIZE_DATA(A3DRWParamsExportPrcData, sParamsExportData);
sParamsExportData.m_bCompressBrep = false;
sParamsExportData.m_bCompressTessellation = false;
CHECK_RET(A3DAsmModelFileExportToPrcFile(stpHOOPSExchangeLoader->m_psModelFile, &sParamsExportData, pcPRCFileName, NULL));
if(iRet == A3D_SUCCESS)
printf("Done.\n");
else
printf("failure [%d]\n", iRet);
}
return iRet;
}
//######################################################################################################################
void terminate2()
{
CloseFile();
delete stpHOOPSExchangeLoader;
stpHOOPSExchangeLoader = NULL;
ListLeaks();
}
//######################################################################################################################
void stChangeViewedSheet(bool bPrevious)
{
bool bChange = false;
if(bPrevious)
{
if(st_CurrentSheetIndex > 0)
{
st_CurrentSheetIndex--;
bChange = true;
}
}
else
{
if(st_CurrentSheetIndex + 1 < unsigned(st_aGLSheetDisplayList.size()))
{
st_CurrentSheetIndex++;
bChange = true;
}
}
if(bChange)
{
stsInfo.sBoundingBox.m_sMin.m_dX = 0.;
stsInfo.sBoundingBox.m_sMin.m_dY = 0.;
stsInfo.sBoundingBox.m_sMax.m_dX = st_aGLSheetSize[st_CurrentSheetIndex].m_dX;
stsInfo.sBoundingBox.m_sMax.m_dY = st_aGLSheetSize[st_CurrentSheetIndex].m_dY;
stsInfo.Calculate();
Reshape(staiWinSize[0], staiWinSize[1]);
glutPostRedisplay();
}
}
//######################################################################################################################
void Key(unsigned char key, int /* x */, int /* y */)
{
switch(key)
{
case 27 :
exit(0);
case GLUT_KEY_F1:
stbDisplayHelp = !stbDisplayHelp;
glutPostRedisplay();
break;
case GLUT_KEY_F2:
{
A3DUTF8Char pcFilePath[_MAX_PATH];
printf("\nFile path: ");
scanf("%s", pcFilePath);
CloseFile();
if (OpenFile(pcFilePath) == A3D_SUCCESS)
{
ProcessModelFile();
Reshape(staiWinSize[0], staiWinSize[1]);
}
Display();
}
break;
case GLUT_KEY_F3:
{
SaveFileAsPrc();
}
break;
case GLUT_KEY_F4:
stbDisplayMarkups = !stbDisplayMarkups;
Reshape(staiWinSize[0], staiWinSize[1]);
glutPostRedisplay();
break;
case GLUT_KEY_F5:
stbFullScreen = !stbFullScreen;
if(stbFullScreen)
glutFullScreen();
else
{
glutPositionWindow(staiWinPosition[0], staiWinPosition[1]);
glutReshapeWindow(staiWinSize[0], staiWinSize[1]);
}
break;
case GLUT_KEY_F6:
{
char pcNewColor[_MAX_PATH];
printf("\nNew color (0xHHHHHH) : ");
scanf("%s", pcNewColor);
sscanf(pcNewColor, "%x", &stuiClearColor);
glClearColor(HEX_TO_RED(stuiClearColor), HEX_TO_GREEN(stuiClearColor), HEX_TO_BLUE(stuiClearColor), 1.0f);
glutPostRedisplay();
}
break;
case GLUT_KEY_F11:
stbDisplayInfos = !stbDisplayInfos;
glutPostRedisplay();
break;
case GLUT_KEY_PAGE_UP:
stChangeViewedSheet(true);
break;
case GLUT_KEY_PAGE_DOWN:
stChangeViewedSheet(false);
break;
default:
break;
}
}
//######################################################################################################################
void SpecialKey(int k, int x, int y)
{
Key((unsigned char) k, x, y);
}
static MY_CHAR acSrcFileName[_MAX_PATH * 2];
static MY_CHAR acLogFileName[_MAX_PATH * 2];
//######################################################################################################################
// Main function
#ifdef _MSC_VER
int wmain(A3DInt32 iArgc, A3DUniChar** ppcArgv)
#else
int main(A3DInt32 iArgc, A3DUTF8Char** ppcArgv)
#endif
{
//
// ### COMMAND LINE ARGUMENTS
//
if (iArgc > 4)
{
MY_PRINTF2("Usage:\n %s [input CATDrawing file] [Clear color value] [output LOG file]\n", ppcArgv[0]);
MY_PRINTF(" Default output LOG file is [input CATDrawing file]_Log.txt\n\n");
}
if (iArgc > 1) MY_STRCPY(acSrcFileName, ppcArgv[1]);
else MY_STRCPY(acSrcFileName, DEFAULT_INPUT_DRAWING);
if (iArgc > 2) MY_SSCANF(ppcArgv[2], "%x", &stuiClearColor);
else stuiClearColor = 0xB2B2B2;
if (iArgc > 3) MY_STRCPY(acLogFileName, ppcArgv[3]);
else MY_SPRINTF(acLogFileName, "%s_Log.txt", acSrcFileName);
GetLogFile(acLogFileName); // Initialize log file
//
// ### INITIALIZE HOOPS EXCHANGE
//
stpHOOPSExchangeLoader = new A3DSDKHOOPSExchangeLoader(_T(HOOPS_BINARY_DIRECTORY));
if (stpHOOPSExchangeLoader->m_eSDKStatus != A3D_SUCCESS)
{
A3DStatus eSDKStatus = stpHOOPSExchangeLoader->m_eSDKStatus;
delete stpHOOPSExchangeLoader;
stpHOOPSExchangeLoader = NULL;
return eSDKStatus;
}
CHECK_RET(A3DDllSetCallbacksMemory(CheckMalloc, CheckFree));
CHECK_RET(A3DDllSetCallbacksReport(PrintLogMessage, PrintLogWarning, PrintLogError));
//
// ### PROCESS SAMPLE CODE
//
A3DInt32 iRet = A3D_SUCCESS;
glutInit((int*)(&iArgc), (char**)ppcArgv);
GLsizei iScreenW = glutGet(GLUT_SCREEN_WIDTH);
GLsizei iScreenH = glutGet(GLUT_SCREEN_HEIGHT);
staiWinSize[0] = (GLsizei)((double)iScreenW * 0.7);
staiWinSize[1] = (GLsizei)((double)iScreenH * 0.7);
staiWinPosition[0] = (iScreenW - staiWinSize[0]) / 2;
staiWinPosition[1] = (iScreenH - staiWinSize[1]) / 2;
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_STENCIL); // GLUT_DEPTH
glutInitWindowPosition(staiWinPosition[0], staiWinPosition[1]);
glutInitWindowSize(staiWinSize[0], staiWinSize[1]);
glutCreateWindow("A3DPRCDrawingViewerGL");
glViewport(0, 0, staiWinSize[0], staiWinSize[1]);
tbInit(GLUT_LEFT_BUTTON);
tbAnimate(stbTrackBallAnimate);
stsInfo.Init();
stsInfo3D.Init();
stsInfoMarkups.Init();
CHECK_RET(OpenGL_SetAndInitCallBack(stsDrawCallbacksData));
A3DUTF8Char sSrcFileNameUTF8[_MAX_PATH];
#ifdef _MSC_VER
A3DMiscUTF16ToUTF8(acSrcFileName, sSrcFileNameUTF8);
#else
MY_STRCPY(sSrcFileNameUTF8, acSrcFileName);
#endif
CHECK_RET_TERM(OpenFile(sSrcFileNameUTF8));
CHECK_RET_TERM(ProcessModelFile());
InitGL();
glutReshapeFunc(Reshape);
glutDisplayFunc(Display);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutMouseFunc(MouseButton);
glutMotionFunc(Motion);
glutIdleFunc(NULL);
printf("\nF1 for help\n");
// glut call exit(0) when closing windows, so set atexit to close properly dll
atexit(terminate2);
glutMainLoop();
return 0;
}