869 lines
26 KiB
C++
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;
|
|
}
|