1417 lines
43 KiB
C++
1417 lines
43 KiB
C++
/***********************************************************************************************************************
|
|
*
|
|
* Copyright (c) 2010 - 2025 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 Viewer.cpp
|
|
|
|
This file demonstrates how to programmatically visualize a PRC file with a basic OpenGL program using HOOPS Exchange
|
|
and the connectors and visitors tools.
|
|
In the main function, we open the file.
|
|
Then we traverse once the model in order to retrieve the bounding box of the model.
|
|
Then we re-traverse the model to draw the different items.
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
//#define DIRECT_RENDERING
|
|
|
|
#define INITIALIZE_A3D_API
|
|
#include <A3DSDKIncludes.h>
|
|
#include <hoops_license.h>
|
|
|
|
#include "../common.hpp"
|
|
|
|
#define TF_A3DLIBS
|
|
|
|
#include <math.h>
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
#include <vector>
|
|
|
|
#include "callback_opengl.h"
|
|
#include "Matrix.h"
|
|
#include "trackball.h"
|
|
#include "TreeTraverse.h"
|
|
#include "VisitorContainer.h"
|
|
#include "VisitorTessellation.h"
|
|
#include "VisitorTransfo.h"
|
|
#include "VisitorTree.h"
|
|
#include "Viewer.h"
|
|
#include "VisitorCascadedAttribute.h"
|
|
|
|
//#####################################################################################################################
|
|
A3DUns32 mNumberOfViews;
|
|
A3DUns32 mCurrentViewIndex = ~0U;
|
|
bool stbDrawView = false;
|
|
|
|
//#####################################################################################################################
|
|
static A3DStatus DrawModel(const A3DAsmModelFile* pModelFile);
|
|
|
|
//######################################################################################################################
|
|
A3DStatus DrawGetBoundingBox(const A3DAsmModelFile* pModelFile, A3DBoundingBoxData* psBoundingBox,
|
|
const A3DBool bIncludeMarkups = false);
|
|
|
|
//######################################################################################################################
|
|
static A3DStatus Draw(const A3DAsmModelFile* pModelFile, const A3DBool bIncludeMarkups = false);
|
|
|
|
//######################################################################################################################
|
|
A3DAsmModelFile* ComputeSection(A3DAsmModelFile* pModelFile, A3DPlanarSectionData sSectionParametersData);
|
|
|
|
//######################################################################################################################
|
|
void ComputeHLR(
|
|
A3DAsmModelFile const * pModelFile,
|
|
A3DMkpView const *pActiveView,
|
|
A3DHLRViewPlaneData const &sHLRViewPlaneData,
|
|
GLuint &uiHLRDisplayList,
|
|
GLuint &uiHLRTanEdgeDisplayList,
|
|
GLuint &uiHLRHiddenDisplayList,
|
|
GLuint &uiHLRHiddenTanEdgeDisplayList,
|
|
GLuint &uiHLRSectionDisplayList);
|
|
|
|
//######################################################################################################################
|
|
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 GLdouble stdXPan_Save = 0.0;
|
|
static GLdouble stdYPan_Save = 0.0;
|
|
static GLdouble stdZoom_Save = 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 GLuint stuiHLRDisplayList = 0;
|
|
static GLuint stuiHLRTanEdgeDisplayList = 0;
|
|
static GLuint stuiHLRHiddenDisplayList = 0;
|
|
static GLuint stuiHLRHiddenTanEdgeDisplayList = 0;
|
|
static GLuint stuiHLRSectionDisplayList = 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 GLfloat stafErrorTextColor[] = { 1.0f, 0.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;
|
|
static bool stbDisplaySection = false;
|
|
static bool stbDisplayHLR = false;
|
|
static bool stbDisplayHLRHidden = true;
|
|
static bool stbDisplayHLRTanEdge = true;
|
|
static bool stbDisplayHLRSection = true;
|
|
static bool stbDoubleSideRendering = true;
|
|
static A3DVector3dData origin3d;
|
|
static A3DVector3dData direction3d;
|
|
static A3DVector3dData stHLROrigin;
|
|
|
|
|
|
|
|
//######################################################################################################################
|
|
#define TRIEDRON_SIZE 40.0
|
|
|
|
//######################################################################################################################
|
|
#define A3DGL_MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
#define A3DGL_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
|
|
|
static int stTraverseSet(A3DRiSet* pSet, A3DRiSet ** ppRISectionElements);
|
|
|
|
//######################################################################################################################
|
|
class A3DPRCViewerGLInfo
|
|
{
|
|
public:
|
|
A3DBoundingBoxData sBoundingBox;
|
|
double dBoundingBoxRadius;
|
|
A3DVector3dData sBoundingBoxCenter;
|
|
|
|
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 A3DSDKHOOPSExchangeLoader* stpHOOPSExchangeLoader = nullptr;
|
|
static A3DAsmModelFile* pSectionnedModelFile = nullptr;
|
|
|
|
//######################################################################################################################
|
|
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();
|
|
// gluPerspective(FOVY, (float)w / (h == 0.0 ? 1.0: (float)h), stsInfo.dBoundingBoxRadius * 0.1,
|
|
// stsInfo.dBoundingBoxRadius * 100.0);
|
|
// glOrtho(-w/2., w/2., -h/2., h/2., stsInfo.dBoundingBoxRadius * 0.1,stsInfo.dBoundingBoxRadius * 100.0);
|
|
glOrtho( -stsInfo.dBoundingBoxRadius * (float)w / (h == 0.0 ? 1.0: (float)h), stsInfo.dBoundingBoxRadius * (float)w / (h == 0.0 ? 1.0: (float)h),
|
|
-stsInfo.dBoundingBoxRadius, stsInfo.dBoundingBoxRadius,
|
|
-stsInfo.dBoundingBoxRadius-100,stsInfo.dBoundingBoxRadius * 100.0);
|
|
|
|
|
|
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);
|
|
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, stafLightDiffuse);
|
|
glLightfv(GL_LIGHT0, GL_AMBIENT, stafLightAmbient);
|
|
|
|
//glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, stafMaterialDiffuse);
|
|
//glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, stafMaterialSpecular);
|
|
//glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, stafMaterialShininess);
|
|
|
|
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.0;
|
|
stdXPan = 0.0;
|
|
stdYPan = 0.0;
|
|
|
|
#ifdef _DEBUG
|
|
stiStart = clock();
|
|
#endif
|
|
}
|
|
|
|
//######################################################################################################################
|
|
void DrawTriedron(void)
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
{
|
|
glLoadIdentity();
|
|
glOrtho(0.0, staiViewport[2], 0.0, staiViewport[3], -100.0, 100.0);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
{
|
|
glLoadIdentity();
|
|
glTranslated(TRIEDRON_SIZE*1.5, TRIEDRON_SIZE*1.5, 0.0);
|
|
tbMatrix();
|
|
glCallList(stuiTriedronDisplayList);
|
|
}
|
|
glPopMatrix();
|
|
}
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
}
|
|
|
|
//######################################################################################################################
|
|
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 DrawError(char const * acMessage, A3DStatus sStatus)
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
gluOrtho2D(0.0, 100.0, 0.0, 100.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glColor3fv(stafErrorTextColor);
|
|
|
|
stfX = 1.0f;
|
|
stfY = 85.0f;
|
|
if (acMessage)
|
|
PrintString("%s %d\n", acMessage, sStatus);
|
|
else
|
|
PrintString("ERROR %d\n", sStatus);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_LIGHTING);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
//#####################################################################################################################
|
|
void DrawStrings(void)
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
gluOrtho2D(0.0, 100.0, 0.0, 100.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glColor3fv(stafTextColor);
|
|
|
|
if (stbDrawView)
|
|
{
|
|
stfX = 1.0f;
|
|
stfY = 80.0f;
|
|
PrintString("VIEWS\n");
|
|
PrintString("Total of views: %d \n",mNumberOfViews);
|
|
PrintString(" View number: %d\n", mCurrentViewIndex);
|
|
|
|
}
|
|
|
|
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: rotating\n");
|
|
PrintString(" Right button: zooming\n");
|
|
PrintString(" Right+Left button: panning\n");
|
|
PrintString("\n");
|
|
PrintString(" KEYBOARD:\n");
|
|
PrintString(" F1: print this help\n");
|
|
PrintString(" F2: open a file (in the console)\n");
|
|
PrintString(" F3: toggle markup display\n");
|
|
PrintString(" F4: toggle full screen\n");
|
|
PrintString(" F5: change background color\n");
|
|
PrintString(" F6: toggle render mode %s\n", DisplayTriangles() == 1 ? "[SHADING]" :
|
|
DisplayTriangles() == 2 ? "[WIREFRAME]" :
|
|
DisplayTriangles() == 3 ? "[SHADING&WIREFRAME]":"NONE");
|
|
PrintString(" F7: toggle normals display %s\n", DisplayTriangleNormals() == 0 ? "[NONE]" :
|
|
DisplayTriangleNormals() == 1 ? "[TRIANGLE PLANE NORMALS (blue)]" :
|
|
DisplayTriangleNormals() == 2 ? "[NORMALS (green)]" :
|
|
DisplayTriangleNormals() == 3 ? "[TRIANGLE PLANE NORMALS (blue) & NORMALS (green)]" : "?");
|
|
PrintString(" (Up and down keys to change normals display length) %lf\n", DisplayTriangleNormalLength());
|
|
PrintString(" F8: toggle rotation animation\n");
|
|
PrintString(" F9: toggle double-side rendering %s\n", stbDoubleSideRendering ? "[ON]" : "[OFF]");
|
|
PrintString(" F10: compute a planar section. Use the page up and page down keys to change the origin coordinates of the section\n");
|
|
PrintString(" F11: toggle information display\n");
|
|
PrintString(" h: toggle computed HLR\n");
|
|
PrintString(" s: in HLR mode, hide/show section\n");
|
|
PrintString(" t: in HLR mode, hide/show tangent edge\n");
|
|
PrintString(" v: in HLR mode, hide/show hidden element\n");
|
|
PrintString(" Use the RIGHT and LEFT keys to toggle the views\n");
|
|
}
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_LIGHTING);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPopMatrix();
|
|
}
|
|
|
|
//######################################################################################################################
|
|
void DrawHLR()
|
|
{
|
|
glPushMatrix();
|
|
{
|
|
glLoadIdentity();
|
|
glTranslated(-stsInfo.dBoundingBoxRadius*stdXPan, -stsInfo.dBoundingBoxRadius*stdYPan, 0.);
|
|
glScalef(stdZoom, stdZoom, stdZoom);
|
|
if (stbDisplayHLRHidden)
|
|
glCallList(stuiHLRHiddenDisplayList);
|
|
if (stbDisplayHLRHidden && stbDisplayHLRTanEdge)
|
|
glCallList(stuiHLRHiddenTanEdgeDisplayList);
|
|
glCallList(stuiHLRDisplayList);
|
|
if (stbDisplayHLRTanEdge)
|
|
glCallList(stuiHLRTanEdgeDisplayList);
|
|
if (stbDisplayHLRSection)
|
|
glCallList(stuiHLRSectionDisplayList);
|
|
}
|
|
glPopMatrix();
|
|
}
|
|
|
|
//######################################################################################################################
|
|
void Display(void)
|
|
{
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
if (stbDisplayHLR)
|
|
{
|
|
DrawHLR();
|
|
}
|
|
else
|
|
{
|
|
glPushMatrix();
|
|
{
|
|
glLoadIdentity();
|
|
|
|
glLightfv(GL_LIGHT0, GL_POSITION, stafLightPosition);
|
|
|
|
glTranslated(0.0f, 0.0f, -3.0*stsInfo.dBoundingBoxRadius);
|
|
|
|
glTranslated(-stsInfo.dBoundingBoxRadius*stdXPan, -stsInfo.dBoundingBoxRadius*stdYPan,
|
|
0);
|
|
tbMatrix();
|
|
glTranslated(-stsInfo.sBoundingBoxCenter.m_dX, -stsInfo.sBoundingBoxCenter.m_dY,
|
|
0);
|
|
glScalef(stdZoom, stdZoom, stdZoom); // scale the matrix
|
|
|
|
#ifdef DIRECT_RENDERING
|
|
Draw(stpHOOPSExchangeLoader->m_psModelFile);
|
|
if (GetstbDrawMarkups())
|
|
{
|
|
constexpr bool bIncludeMarkups = true;
|
|
Draw(stpHOOPSExchangeLoader->m_psModelFile, bIncludeMarkups);
|
|
}
|
|
#else
|
|
glCallList(stuiModelFileDisplayList);
|
|
if(GetstbDrawMarkups())
|
|
glCallList(stuiMarkupsDisplayList);
|
|
#endif
|
|
}
|
|
glPopMatrix();
|
|
|
|
DrawTriedron();
|
|
}
|
|
|
|
if(stbDisplayInfos || stbDisplayHelp || stbDrawView)
|
|
DrawStrings();
|
|
|
|
glFlush();
|
|
glFinish();
|
|
glutSwapBuffers();
|
|
}
|
|
|
|
void GetOpenGLMatrix(A3DDouble adModelView[16], A3DDouble adProjectMatrix[16])
|
|
{
|
|
glPushMatrix();
|
|
{
|
|
glLoadIdentity();
|
|
|
|
glLightfv(GL_LIGHT0, GL_POSITION, stafLightPosition);
|
|
|
|
glTranslated(0.0f, 0.0f, -3.0*stsInfo.dBoundingBoxRadius);
|
|
|
|
glTranslated(-stsInfo.dBoundingBoxRadius*stdXPan, -stsInfo.dBoundingBoxRadius*stdYPan,
|
|
0.);
|
|
tbMatrix();
|
|
glTranslated(-stsInfo.sBoundingBoxCenter.m_dX, -stsInfo.sBoundingBoxCenter.m_dY,
|
|
0.);
|
|
glScalef(stdZoom, stdZoom, stdZoom); // scale the matrix
|
|
|
|
glGetDoublev(GL_MODELVIEW_MATRIX, adModelView);
|
|
glGetDoublev(GL_PROJECTION_MATRIX , adProjectMatrix);
|
|
}
|
|
glPopMatrix();
|
|
}
|
|
|
|
//######################################################################################################################
|
|
static bool stbTBRunning = false;
|
|
|
|
//######################################################################################################################
|
|
void MouseButton(int button, int state, GLsizei x, GLsizei y)
|
|
{
|
|
//GLboolean bActiveShift = glutGetModifiers() & GLUT_ACTIVE_SHIFT;
|
|
//GLboolean bActiveCtrl = glutGetModifiers() & GLUT_ACTIVE_CTRL;
|
|
//GLboolean bDownState = (state == GLUT_DOWN);
|
|
|
|
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(!stbRButtonDown)
|
|
{
|
|
tbMouse(button, state, x, y);
|
|
stbTBRunning = true;
|
|
}
|
|
else
|
|
{
|
|
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 MouseWheel(int /* number */, int direction, int /* x */, int /* y */)
|
|
//{
|
|
// // TODO
|
|
// stdZoom += stsReadModelResult.dBoundingBoxRadius * 0.001 * direction;
|
|
// glutPostRedisplay();
|
|
//}
|
|
|
|
//######################################################################################################################
|
|
void Motion(GLsizei x, GLsizei y)
|
|
{
|
|
tbMotion(x, y);
|
|
|
|
switch(eMotionType)
|
|
{
|
|
case KE_PANNING:
|
|
{
|
|
stdXPan -= (GLdouble)(x - stiXScreen)/(GLdouble)staiViewport[2] * 2.0;
|
|
stdYPan += (GLdouble)(y - stiYScreen)/(GLdouble)staiViewport[3] * 2.0;
|
|
break;
|
|
}
|
|
case KE_ZOOMING:
|
|
{
|
|
stdZoom -= (GLdouble)(y - stiYScreen)/(GLdouble)staiViewport[3] * 10.0;
|
|
if (stdZoom<0)
|
|
stdZoom = 0;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
stiXScreen = x;
|
|
stiYScreen = y;
|
|
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus OpenFile(const A3DUTF8Char* pcCADFile);
|
|
|
|
//######################################################################################################################
|
|
A3DStatus CloseFile();
|
|
|
|
//######################################################################################################################
|
|
static void stRebuildGenList()
|
|
{
|
|
glDeleteLists(stuiModelFileDisplayList, 1);
|
|
stuiModelFileDisplayList = glGenLists(1);
|
|
glNewList(stuiModelFileDisplayList, GL_COMPILE);
|
|
|
|
if(!stbDisplaySection)
|
|
Draw(stpHOOPSExchangeLoader->m_psModelFile);
|
|
|
|
else
|
|
Draw(pSectionnedModelFile);
|
|
|
|
glEndList();
|
|
|
|
Reshape(staiWinSize[0], staiWinSize[1]);
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
static void stRebuildGenListHLR()
|
|
{
|
|
// Get active View
|
|
A3DAsmModelFileData sData;
|
|
A3D_INITIALIZE_DATA(A3DAsmModelFileData, sData);
|
|
A3DAsmModelFileGet(stpHOOPSExchangeLoader->m_psModelFile, &sData);
|
|
A3DAsmProductOccurrenceData sPOData;
|
|
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sPOData);
|
|
A3DAsmProductOccurrenceGet(sData.m_ppPOccurrences[0], &sPOData);
|
|
|
|
A3DMkpView const *pActiveView = nullptr;
|
|
if (sPOData.m_uiViewsSize > 0)
|
|
{
|
|
mNumberOfViews = sPOData.m_uiViewsSize;
|
|
if (mCurrentViewIndex != -1)
|
|
{
|
|
pActiveView = sPOData.m_ppViews[mCurrentViewIndex];
|
|
}
|
|
}
|
|
else if (sPOData.m_pPart != nullptr)
|
|
{
|
|
A3DAsmPartDefinitionData sPartData;
|
|
A3D_INITIALIZE_DATA(A3DAsmPartDefinitionData, sPartData);
|
|
if (A3DAsmPartDefinitionGet(sPOData.m_pPart, &sPartData) == A3D_SUCCESS)
|
|
{
|
|
mNumberOfViews = sPartData.m_uiViewsSize;
|
|
if (mCurrentViewIndex != -1)
|
|
{
|
|
pActiveView = sPartData.m_ppViews[mCurrentViewIndex];
|
|
}
|
|
A3DAsmPartDefinitionGet(nullptr, &sPartData);
|
|
}
|
|
}
|
|
|
|
A3DDouble adModelView[16], adProjectMatrix[16];
|
|
GetOpenGLMatrix( adModelView, adProjectMatrix);
|
|
|
|
A3DMatrix4x4 sModelViewMat(adModelView), sCameraMat;
|
|
sModelViewMat.Invert(sCameraMat);
|
|
|
|
A3DHLRViewPlaneData sHLRViewPlaneData;
|
|
A3D_INITIALIZE_DATA(A3DHLRViewPlaneData,sHLRViewPlaneData);
|
|
sHLRViewPlaneData.m_adOrigin[0] = stHLROrigin.m_dX = sCameraMat[12];
|
|
sHLRViewPlaneData.m_adOrigin[1] = stHLROrigin.m_dY = sCameraMat[13];
|
|
sHLRViewPlaneData.m_adOrigin[2] = stHLROrigin.m_dZ = sCameraMat[14];
|
|
|
|
double dLength = stsInfo.dBoundingBoxRadius / 2.;
|
|
sHLRViewPlaneData.m_adAxis1[0] = sCameraMat[0] * dLength;
|
|
sHLRViewPlaneData.m_adAxis1[1] = sCameraMat[1] * dLength;
|
|
sHLRViewPlaneData.m_adAxis1[2] = sCameraMat[2] * dLength;
|
|
|
|
sHLRViewPlaneData.m_adAxis2[0] = sCameraMat[4] * dLength;
|
|
sHLRViewPlaneData.m_adAxis2[1] = sCameraMat[5] * dLength;
|
|
sHLRViewPlaneData.m_adAxis2[2] = sCameraMat[6] * dLength;
|
|
sHLRViewPlaneData.m_bUseClipBox = false;
|
|
|
|
ComputeHLR(stpHOOPSExchangeLoader->m_psModelFile, pActiveView, sHLRViewPlaneData,
|
|
stuiHLRDisplayList, stuiHLRTanEdgeDisplayList, stuiHLRHiddenDisplayList, stuiHLRHiddenTanEdgeDisplayList, stuiHLRSectionDisplayList);
|
|
|
|
stbDisplayHLR = true;
|
|
|
|
Reshape(staiWinSize[0], staiWinSize[1]);
|
|
|
|
A3DAsmModelFileGet(nullptr, &sData);
|
|
A3DAsmProductOccurrenceGet(nullptr, &sPOData);
|
|
}
|
|
|
|
//######################################################################################################################
|
|
void SpecialKey(int 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];
|
|
fprintf(stdout, "\nFile path: ");
|
|
scanf("%s", pcFilePath);
|
|
|
|
CloseFile();
|
|
if(OpenFile(pcFilePath) == A3D_SUCCESS)
|
|
{
|
|
mCurrentViewIndex=~0U;
|
|
stbDrawView = false;
|
|
Reshape(staiWinSize[0], staiWinSize[1]);
|
|
stdZoom = 1.;
|
|
|
|
stdYPan = 0.0;
|
|
}
|
|
Display();
|
|
}
|
|
break;
|
|
|
|
case GLUT_KEY_F3:
|
|
|
|
SetstbDrawMarkups(!GetstbDrawMarkups());
|
|
|
|
if(GetstbDrawMarkups())
|
|
stsInfo = stsInfo3D + stsInfoMarkups;
|
|
else
|
|
stsInfo = stsInfo3D;
|
|
Reshape(staiWinSize[0], staiWinSize[1]);
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case GLUT_KEY_F4:
|
|
stbFullScreen = !stbFullScreen;
|
|
if(stbFullScreen)
|
|
glutFullScreen();
|
|
else
|
|
{
|
|
glutPositionWindow(staiWinPosition[0], staiWinPosition[1]);
|
|
glutReshapeWindow(staiWinSize[0], staiWinSize[1]);
|
|
}
|
|
break;
|
|
|
|
case GLUT_KEY_F5:
|
|
{
|
|
char pcNewColor[_MAX_PATH];
|
|
fprintf(stdout, "\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_F6:
|
|
DisplayTriangles()++;
|
|
if(DisplayTriangles() > 3)
|
|
DisplayTriangles() = 1;
|
|
stRebuildGenList();
|
|
break;
|
|
|
|
case GLUT_KEY_F7:
|
|
DisplayTriangleNormals()++;
|
|
if(DisplayTriangleNormals() > 3)
|
|
DisplayTriangleNormals() = 0;
|
|
DisplayTriangleNormalLength() = stsInfo3D.dBoundingBoxRadius*2 / 100;
|
|
stRebuildGenList();
|
|
break;
|
|
|
|
case GLUT_KEY_F8:
|
|
tbMouse(GLUT_LEFT_BUTTON, GLUT_UP, 0, 0);
|
|
stbTBRunning = false;
|
|
stbTrackBallAnimate = !stbTrackBallAnimate;
|
|
tbAnimate(stbTrackBallAnimate);
|
|
break;
|
|
|
|
case GLUT_KEY_F9:
|
|
stbDoubleSideRendering = !stbDoubleSideRendering;
|
|
if(stbDoubleSideRendering)
|
|
{
|
|
glDisable(GL_CULL_FACE);
|
|
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
|
}
|
|
else
|
|
{
|
|
glEnable(GL_CULL_FACE);
|
|
glCullFace(GL_BACK);
|
|
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
|
|
}
|
|
stRebuildGenList();
|
|
break;
|
|
|
|
case GLUT_KEY_F10:
|
|
{
|
|
stbDisplaySection = !stbDisplaySection;
|
|
fprintf(stdout, "DisplaySection = %s\n", (stbDisplaySection) ? "true" : "false");
|
|
|
|
if(stbDisplaySection)
|
|
{
|
|
A3D_INITIALIZE_DATA(A3DVector3dData, origin3d);
|
|
|
|
origin3d.m_dX = stsInfo.sBoundingBoxCenter.m_dX;
|
|
origin3d.m_dY = stsInfo.sBoundingBoxCenter.m_dY;
|
|
origin3d.m_dZ = stsInfo.sBoundingBoxCenter.m_dZ;
|
|
|
|
A3D_INITIALIZE_DATA(A3DVector3dData, direction3d);
|
|
|
|
char Direction[20] = "Direction";
|
|
int nb1 = 0;
|
|
int nb2 = 0;
|
|
int nb3 = 0;
|
|
|
|
fprintf(stdout, "\nEnter the x direction of your section: \n");
|
|
scanf("%s", Direction);
|
|
sscanf(Direction, "%d", &nb1);
|
|
|
|
fprintf(stdout, "\nEnter the y direction of your section: \n");
|
|
scanf("%s", Direction);
|
|
sscanf(Direction, "%d", &nb2);
|
|
|
|
fprintf(stdout, "\nEnter the z direction of your section: \n");
|
|
scanf("%s", Direction);
|
|
sscanf(Direction, "%d", &nb3);
|
|
|
|
direction3d.m_dX = (A3DDouble) nb1;
|
|
direction3d.m_dY = (A3DDouble) nb2;
|
|
direction3d.m_dZ = (A3DDouble) nb3;
|
|
|
|
A3DPlanarSectionData sSectionParametersData;
|
|
A3D_INITIALIZE_DATA(A3DPlanarSectionData, sSectionParametersData);
|
|
|
|
sSectionParametersData.m_sOrigin = origin3d;
|
|
sSectionParametersData.m_sDirection = direction3d;
|
|
sSectionParametersData.m_bColor = true;
|
|
sSectionParametersData.m_bCreateFaces = true;
|
|
|
|
pSectionnedModelFile = ComputeSection(stpHOOPSExchangeLoader->m_psModelFile, sSectionParametersData);
|
|
stRebuildGenList();
|
|
}
|
|
else
|
|
stRebuildGenList();
|
|
}
|
|
break;
|
|
|
|
case GLUT_KEY_F11:
|
|
stbDisplayInfos = !stbDisplayInfos;
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case GLUT_KEY_UP:
|
|
DisplayTriangleNormalLength() *= 2;
|
|
stRebuildGenList();
|
|
break;
|
|
|
|
case GLUT_KEY_DOWN:
|
|
DisplayTriangleNormalLength() /= 2;
|
|
stRebuildGenList();
|
|
break;
|
|
|
|
case GLUT_KEY_RIGHT:
|
|
{
|
|
if (mCurrentViewIndex==mNumberOfViews-1)
|
|
mCurrentViewIndex = ~0U;
|
|
else
|
|
mCurrentViewIndex++;
|
|
|
|
stbDrawView = (mCurrentViewIndex != ~0U);
|
|
stRebuildGenList();
|
|
glutPostRedisplay();
|
|
}
|
|
break;
|
|
|
|
case GLUT_KEY_INSERT:
|
|
{
|
|
stRebuildGenList();
|
|
glutPostRedisplay();
|
|
}
|
|
break;
|
|
|
|
case GLUT_KEY_LEFT:
|
|
{
|
|
if (mCurrentViewIndex==~0U)
|
|
mCurrentViewIndex = mNumberOfViews-1;
|
|
else
|
|
mCurrentViewIndex--;
|
|
|
|
stbDrawView = (mCurrentViewIndex != ~0U);
|
|
stRebuildGenList();
|
|
glutPostRedisplay();
|
|
}
|
|
break;
|
|
|
|
case GLUT_KEY_PAGE_UP:
|
|
{
|
|
if(stbDisplaySection)
|
|
{
|
|
origin3d.m_dX = origin3d.m_dX+direction3d.m_dX*0.1;
|
|
origin3d.m_dY = origin3d.m_dY+direction3d.m_dY*0.1;
|
|
origin3d.m_dZ = origin3d.m_dZ+direction3d.m_dZ*0.1;
|
|
|
|
A3DPlanarSectionData sSectionParametersData;
|
|
A3D_INITIALIZE_DATA(A3DPlanarSectionData, sSectionParametersData);
|
|
|
|
sSectionParametersData.m_sOrigin = origin3d;
|
|
sSectionParametersData.m_sDirection = direction3d;
|
|
sSectionParametersData.m_bColor = true;
|
|
sSectionParametersData.m_bCreateFaces = true;
|
|
|
|
pSectionnedModelFile = ComputeSection(stpHOOPSExchangeLoader->m_psModelFile, sSectionParametersData);
|
|
stRebuildGenList();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case GLUT_KEY_PAGE_DOWN:
|
|
{
|
|
if(stbDisplaySection)
|
|
{
|
|
origin3d.m_dX = origin3d.m_dX-direction3d.m_dX*0.1;
|
|
origin3d.m_dY = origin3d.m_dY-direction3d.m_dY*0.1;
|
|
origin3d.m_dZ = origin3d.m_dZ-direction3d.m_dZ*0.1;
|
|
|
|
A3DPlanarSectionData sSectionParametersData;
|
|
A3D_INITIALIZE_DATA(A3DPlanarSectionData, sSectionParametersData);
|
|
|
|
sSectionParametersData.m_sOrigin = origin3d;
|
|
sSectionParametersData.m_sDirection = direction3d;
|
|
sSectionParametersData.m_bColor = true;
|
|
sSectionParametersData.m_bCreateFaces = true;
|
|
|
|
pSectionnedModelFile = ComputeSection(stpHOOPSExchangeLoader->m_psModelFile, sSectionParametersData);
|
|
stRebuildGenList();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus DrawGetBoundingBox(const A3DAsmModelFile* pModelFile, A3DBoundingBoxData* psBoundingBox, const A3DBool bIncludeMarkups)
|
|
{
|
|
A3DStatus iRet = A3D_SUCCESS;
|
|
|
|
if (pModelFile == nullptr)
|
|
return A3D_INVALID_ENTITY_NULL;
|
|
|
|
if (psBoundingBox == nullptr)
|
|
return A3D_INVALID_DATA_STRUCT_NULL;
|
|
|
|
stLoadIdentity();
|
|
stExtentInit(psBoundingBox);
|
|
SetstbDrawMarkups(bIncludeMarkups);
|
|
SetstpsBoundingBox(psBoundingBox);
|
|
SetstbUseCallbacks(false);
|
|
CHECK_RET(DrawModel(pModelFile));
|
|
|
|
return iRet;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
void Key( unsigned char key, int /*x*/, int /*y*/)
|
|
{
|
|
switch (key)
|
|
{
|
|
case 's':
|
|
stbDisplayHLRSection = !stbDisplayHLRSection;
|
|
glutPostRedisplay();
|
|
break;
|
|
case 't':
|
|
stbDisplayHLRTanEdge = !stbDisplayHLRTanEdge;
|
|
glutPostRedisplay();
|
|
break;
|
|
case 'v':
|
|
stbDisplayHLRHidden = !stbDisplayHLRHidden;
|
|
glutPostRedisplay();
|
|
break;
|
|
case 'h':
|
|
{
|
|
if( !stbDisplayHLR)
|
|
{
|
|
stRebuildGenListHLR();
|
|
stbDisplayHLR = true;
|
|
stdXPan_Save = stdXPan; stdXPan = 0.;
|
|
stdYPan_Save = stdYPan; stdYPan = 0.;
|
|
stdZoom_Save = stdZoom;
|
|
}
|
|
else
|
|
{
|
|
stbDisplayHLR = false;
|
|
stdXPan = stdXPan_Save;
|
|
stdYPan = stdYPan_Save;
|
|
stdZoom = stdZoom_Save;
|
|
}
|
|
}
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case 27:
|
|
exit(0);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//######################################################################################################################
|
|
static A3DStatus DrawModel(const A3DAsmModelFile* pModelFile)
|
|
{
|
|
A3DAsmModelFileData sData;
|
|
A3D_INITIALIZE_DATA(A3DAsmModelFileData, sData);
|
|
CHECK_RET(A3DAsmModelFileGet(pModelFile, &sData));
|
|
|
|
// Creation of the ModelFile Connector
|
|
A3DModelFileConnector sModelFileConnector(pModelFile);
|
|
A3DVisitorContainer sCadVisitorContainer(CONNECT_TRANSFO);
|
|
sCadVisitorContainer.SetTraverseInstance(true);
|
|
|
|
A3DAsmProductOccurrenceData sPOData;
|
|
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sPOData);
|
|
CHECK_RET(A3DAsmProductOccurrenceGet(sData.m_ppPOccurrences[0], &sPOData));
|
|
if (sPOData.m_uiViewsSize > 0)
|
|
{
|
|
mNumberOfViews = sPOData.m_uiViewsSize;
|
|
if (mCurrentViewIndex != -1 && mCurrentViewIndex<mNumberOfViews)
|
|
{
|
|
sCadVisitorContainer.SetActivateView(sPOData.m_ppViews[mCurrentViewIndex]);
|
|
}
|
|
}
|
|
else if (sPOData.m_pPart != nullptr)
|
|
{
|
|
A3DAsmPartDefinitionData sPartData;
|
|
A3D_INITIALIZE_DATA(A3DAsmPartDefinitionData, sPartData);
|
|
CHECK_RET(A3DAsmPartDefinitionGet(sPOData.m_pPart, &sPartData));
|
|
mNumberOfViews = sPartData.m_uiViewsSize;
|
|
if (mCurrentViewIndex != -1 && mCurrentViewIndex<mNumberOfViews)
|
|
{
|
|
sCadVisitorContainer.SetActivateView(sPartData.m_ppViews[mCurrentViewIndex]);
|
|
}
|
|
A3DAsmPartDefinitionGet(nullptr, &sPartData);
|
|
}
|
|
CHECK_RET(A3DAsmProductOccurrenceGet(nullptr, &sPOData));
|
|
CHECK_RET(A3DAsmModelFileGet(nullptr, &sData));
|
|
|
|
// Create the Visitor for the styles
|
|
A3DVisitorColorMaterials *psVisitorColorMaterial = new A3DVisitorColorMaterials(&sCadVisitorContainer);
|
|
sCadVisitorContainer.push(psVisitorColorMaterial);
|
|
|
|
A3DTreeVisitor *pA3DTreeVisitor = new A3DTreeVisitor(&sCadVisitorContainer);
|
|
sCadVisitorContainer.push(pA3DTreeVisitor);
|
|
|
|
// Create the Visitor for the tessellation
|
|
A3DVisitorTessellation *psVisitorTessellation = new A3DVisitorTessellation(&sCadVisitorContainer);
|
|
sCadVisitorContainer.push(psVisitorTessellation);
|
|
|
|
// Traverse the ModelFile Connector
|
|
sModelFileConnector.Traverse(&sCadVisitorContainer);
|
|
|
|
stsInfo3D.Calculate();
|
|
// TODO: Add the cameras
|
|
|
|
return A3D_SUCCESS;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus Draw(const A3DAsmModelFile* pModelFile, const A3DBool bIncludeMarkups)
|
|
{
|
|
if(pModelFile == nullptr)
|
|
return A3D_INVALID_ENTITY_NULL;
|
|
|
|
if(!GetstbCallbacksInitialized())
|
|
return A3D_ERROR;
|
|
|
|
stLoadIdentity();
|
|
|
|
SetstbDrawMarkups(bIncludeMarkups);
|
|
SetstbUseCallbacks(true);
|
|
|
|
CHECK_RET(DrawModel(pModelFile));
|
|
return A3D_SUCCESS;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus OpenFile(const A3DUTF8Char* pcCADFileName)
|
|
{
|
|
if(stpHOOPSExchangeLoader == nullptr)
|
|
return A3D_ERROR;
|
|
|
|
A3DImport sImport(pcCADFileName);
|
|
sImport.m_sLoadData.m_sSpecifics.m_sProE.m_bReadExplodeStateAsView = true;
|
|
sImport.m_sLoadData.m_sGeneral.m_bReadPmis = true;
|
|
sImport.m_sLoadData.m_sGeneral.m_bReadConstructionAndReferences = false;
|
|
sImport.m_sLoadData.m_sGeneral.m_bReadWireframes = false;
|
|
sImport.m_sLoadData.m_sTessellation.m_bAccurateTessellation = false;
|
|
|
|
A3DStatus iRet = stpHOOPSExchangeLoader->Import(sImport);
|
|
if(iRet != A3D_SUCCESS && iRet != A3D_LOAD_MULTI_MODELS_CADFILE && iRet != A3D_LOAD_MISSING_COMPONENTS)
|
|
return iRet;
|
|
|
|
// Traverse the model once to retrieve the bounding box
|
|
CHECK_RET(DrawGetBoundingBox(stpHOOPSExchangeLoader->m_psModelFile, &stsInfo3D.sBoundingBox));
|
|
stsInfo3D.Calculate();
|
|
|
|
#ifndef DIRECT_RENDERING
|
|
stuiModelFileDisplayList = glGenLists(1);
|
|
glNewList(stuiModelFileDisplayList, GL_COMPILE);
|
|
{
|
|
if(!stbDisplaySection)
|
|
{
|
|
// Traverse the model a second time to draw the items
|
|
CHECK_RET(Draw(stpHOOPSExchangeLoader->m_psModelFile));
|
|
}
|
|
else
|
|
{
|
|
// Draw the section
|
|
CHECK_RET(Draw(pSectionnedModelFile));
|
|
}
|
|
}
|
|
glEndList();
|
|
#endif
|
|
|
|
Reshape(staiWinSize[0], staiWinSize[1]);
|
|
|
|
// Traverse the model once to retrieve the bounding box with the markups
|
|
constexpr bool bIncludeMarkups = true;
|
|
CHECK_RET(DrawGetBoundingBox(stpHOOPSExchangeLoader->m_psModelFile, &stsInfoMarkups.sBoundingBox, bIncludeMarkups));
|
|
stsInfoMarkups.Calculate();
|
|
|
|
#ifndef DIRECT_RENDERING
|
|
stuiMarkupsDisplayList = glGenLists(1);
|
|
glNewList(stuiMarkupsDisplayList, GL_COMPILE_AND_EXECUTE);
|
|
{
|
|
if(!stbDisplaySection)
|
|
{
|
|
// Traverse the model a second time to draw the items (including the markups)
|
|
CHECK_RET(Draw(stpHOOPSExchangeLoader->m_psModelFile, bIncludeMarkups));
|
|
}
|
|
}
|
|
glEndList();
|
|
#endif
|
|
|
|
Reshape(staiWinSize[0], staiWinSize[1]);
|
|
|
|
fprintf(stdout, "Done.\n");
|
|
|
|
if(GetstbDrawMarkups())
|
|
stsInfo = stsInfo3D + stsInfoMarkups;
|
|
else
|
|
stsInfo = stsInfo3D;
|
|
|
|
sprintf(stpcWinTitle, "HOOPS Exchange Viewer - %s", pcCADFileName);
|
|
glutSetWindowTitle(stpcWinTitle);
|
|
|
|
return A3D_SUCCESS;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
A3DStatus CloseFile()
|
|
{
|
|
#ifndef DIRECT_RENDERING
|
|
glDeleteLists(stuiModelFileDisplayList, 1);
|
|
glDeleteLists(stuiMarkupsDisplayList, 1);
|
|
glDeleteLists(stuiHLRDisplayList, 1);
|
|
glDeleteLists(stuiHLRTanEdgeDisplayList, 1);
|
|
glDeleteLists(stuiHLRHiddenDisplayList,1);
|
|
glDeleteLists(stuiHLRHiddenTanEdgeDisplayList,1);
|
|
glDeleteLists(stuiHLRSectionDisplayList, 1);
|
|
|
|
//glDeleteLists(stuiTriedronDisplayList, 1);
|
|
stuiModelFileDisplayList = stuiMarkupsDisplayList = stuiHLRDisplayList = stuiHLRTanEdgeDisplayList = stuiHLRHiddenDisplayList = stuiHLRHiddenTanEdgeDisplayList = stuiHLRSectionDisplayList = 0;
|
|
#endif
|
|
return A3D_SUCCESS;
|
|
}
|
|
|
|
//######################################################################################################################
|
|
void terminate2()
|
|
{
|
|
CloseFile();
|
|
|
|
delete stpHOOPSExchangeLoader;
|
|
stpHOOPSExchangeLoader = nullptr;
|
|
ListLeaks();
|
|
}
|
|
|
|
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 CAD file] [Clear color value] [output LOG file]\n", ppcArgv[0]);
|
|
MY_PRINTF(" Default output LOG file is [input CAD file]_Log.txt\n\n");
|
|
return A3D_ERROR;
|
|
}
|
|
|
|
if (iArgc > 1) MY_STRCPY(acSrcFileName, ppcArgv[1]);
|
|
else MY_STRCPY(acSrcFileName, DEFAULT_INPUT_CAD);
|
|
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), HOOPS_LICENSE);
|
|
if (stpHOOPSExchangeLoader->m_eSDKStatus != A3D_SUCCESS)
|
|
{
|
|
A3DStatus eSDKStatus = stpHOOPSExchangeLoader->m_eSDKStatus;
|
|
delete stpHOOPSExchangeLoader;
|
|
stpHOOPSExchangeLoader = nullptr;
|
|
return eSDKStatus;
|
|
}
|
|
|
|
CHECK_RET(A3DDllSetCallbacksMemory(CheckMalloc, CheckFree));
|
|
CHECK_RET(A3DDllSetCallbacksReport(PrintLogMessage, PrintLogWarning, PrintLogError));
|
|
|
|
//
|
|
// ### PROCESS SAMPLE CODE
|
|
//
|
|
|
|
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_DEPTH);
|
|
glutInitWindowPosition(staiWinPosition[0], staiWinPosition[1]);
|
|
glutInitWindowSize(staiWinSize[0], staiWinSize[1]);
|
|
|
|
glutCreateWindow("A3DPRCViewerGL");
|
|
glViewport(0, 0, staiWinSize[0], staiWinSize[1]);
|
|
|
|
tbInit(GLUT_LEFT_BUTTON);
|
|
tbAnimate(stbTrackBallAnimate);
|
|
|
|
stsInfo.Init();
|
|
stsInfo3D.Init();
|
|
stsInfoMarkups.Init();
|
|
|
|
A3DUTF8Char sSrcFileNameUTF8[_MAX_PATH];
|
|
#ifdef _MSC_VER
|
|
A3DMiscUTF16ToUTF8(acSrcFileName, sSrcFileNameUTF8);
|
|
#else
|
|
MY_STRCPY(sSrcFileNameUTF8, acSrcFileName);
|
|
#endif
|
|
CHECK_RET_TERM(OpenFile(sSrcFileNameUTF8));
|
|
|
|
InitGL();
|
|
|
|
glutReshapeFunc(Reshape);
|
|
glutDisplayFunc(Display);
|
|
glutKeyboardFunc(Key);
|
|
glutSpecialFunc(SpecialKey);
|
|
glutMouseFunc(MouseButton);
|
|
//glutMouseWheelFunc(MouseWheel);
|
|
glutMotionFunc(Motion);
|
|
glutIdleFunc(nullptr);
|
|
|
|
fprintf(stdout, "\nF1 for help\n");
|
|
|
|
// glut call exit(0) when closing windows, so set atexit to properly close the DLL
|
|
atexit(terminate2);
|
|
|
|
glutMainLoop();
|
|
|
|
//
|
|
// ### TERMINATE HOOPS EXCHANGE
|
|
//
|
|
|
|
return 0;
|
|
}
|