Files
2025-12-15 23:22:33 +08:00

300 lines
9.5 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.
*
***********************************************************************************************************************/
#include <Connector.h>
#include "Viewer.h"
#include <vector>
//######################################################################################################################
void DrawError(char const * acMessage, A3DStatus sStatus);
//######################################################################################################################
void stCleanHLRResults(A3DHLRRepresentationItemData & sRIData)
{
unsigned int uiCrv, uiNbCrv = sRIData.m_uiNumberHLRCurves;
for (uiCrv = 0; uiCrv<uiNbCrv; uiCrv++)
{
A3DHLRCurveData const & sCurveData = sRIData.m_pppHLRCurves[uiCrv];
A3DEntityDelete(sCurveData.m_pProjectedPolyLine);
}
}
//######################################################################################################################
// Call back function for gluTessBeginPolygon ...
#ifndef CALLBACK
#define CALLBACK
#endif
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include "GL/gl.h"
#include "GL/glu.h"
#endif
static void CALLBACK tessBegin(GLenum which)
{
glBegin(which);
}
static void CALLBACK tessEnd()
{
glEnd();
}
static void CALLBACK tessVertex(const GLvoid *data)
{
const GLdouble *ptr = (const GLdouble*)data;
glVertex3dv(ptr);
}
static void CALLBACK tessError(GLenum errorCode)
{
const GLubyte * errorStr = gluErrorString(errorCode);
DrawError( (char const *)errorStr, A3D_ERROR);
}
//######################################################################################################################
void stDrawPolyline(std::vector<A3DCrvPolyLine*> apPoly)
{
for (auto pPoly : apPoly)
{
A3DCrvPolyLineData sPolyData;
A3D_INITIALIZE_DATA(A3DCrvPolyLineData, sPolyData);
A3DCrvPolyLineGet(pPoly, &sPolyData);
glBegin(GL_LINE_STRIP);
A3DVector3dData const * pPt = sPolyData.m_pPts;
for (A3DUns32 uiPt = 0; uiPt < sPolyData.m_uiSize; uiPt++, pPt++)
{
glVertex3d(pPt->m_dX, pPt->m_dY, pPt->m_dZ);
}
glEnd();
A3DCrvPolyLineGet(nullptr, &sPolyData);
}
}
#include <ctime>
//######################################################################################################################
void ComputeHLR( A3DAsmModelFile const * pModelFile,
A3DMkpView const *pActiveView,
A3DHLRViewPlaneData const &sHLRViewPlaneData,
GLuint &uiHLRDisplayList,
GLuint &uiHLRTanEdgeDisplayList,
GLuint &uiHLRHiddenDisplayList,
GLuint &uiHLRHiddenTanEdgeDisplayList,
GLuint &uiHLRSectionDisplayList)
{
A3DHLROptionsData sHLROptionsData;
A3D_INITIALIZE_DATA(A3DHLROptionsData, sHLROptionsData);
sHLROptionsData.m_bTangentEdgeDetect = true;
sHLROptionsData.m_dTangentEdgeAngle = 0.0001*M_PI / 180.;
A3DUns32 uiNumberHLRRepItem = 0;
A3DHLRRepresentationItem **apHLRRepItem = nullptr;
A3DStatus iRet = A3DComputeOrthoHLROnModelFile3(pModelFile,
pActiveView,
&sHLRViewPlaneData,
&sHLROptionsData,
&uiNumberHLRRepItem,
&apHLRRepItem);
if (iRet != A3D_SUCCESS)
{
DrawError("A3DComputeOrthoHLROnModelFile3 return error", iRet);
return;
}
std::vector<A3DCrvPolyLine*> apVisible, apTanEdge, apHidden, apHiddenTanEdge;
// Section
glDeleteLists(uiHLRSectionDisplayList, 1);
uiHLRSectionDisplayList = glGenLists(1);
glNewList(uiHLRSectionDisplayList, GL_COMPILE);
glPushAttrib(GL_BLEND | GL_LINE_STIPPLE | GL_LIGHTING_BIT | GL_LINE_BIT | GL_TEXTURE_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE);
glDisable(GL_LIGHTING);
glShadeModel(GL_FLAT);
glColor4f(8., 0., 0., 0.5);
glLineWidth(2);
for (A3DUns32 uiResultRI = 0; uiResultRI < uiNumberHLRRepItem; uiResultRI++)
{
A3DHLRRepresentationItem const * pHLRRI = apHLRRepItem[uiResultRI];
A3DHLRRepresentationItemData sRIData;
A3D_INITIALIZE_DATA(A3DHLRRepresentationItemData, sRIData);
A3DHLRRepresentationItemGet(pHLRRI, &sRIData);
unsigned int uiCrv, uiNbCrv = sRIData.m_uiNumberHLRCurves;
for (uiCrv = 0; uiCrv < uiNbCrv; uiCrv++)
{
A3DHLRCurveData const & sCurveData = sRIData.m_pppHLRCurves[uiCrv];
if (sCurveData.m_bIsHidden)
{
if (sCurveData.m_bIsTanEdge && !sCurveData.m_bIsSilhouette)
apHiddenTanEdge.push_back(sCurveData.m_pProjectedPolyLine);
else
apHidden.push_back(sCurveData.m_pProjectedPolyLine);
}
else
{
if (sCurveData.m_bIsTanEdge && !sCurveData.m_bIsSilhouette)
apTanEdge.push_back(sCurveData.m_pProjectedPolyLine);
else
apVisible.push_back(sCurveData.m_pProjectedPolyLine);
}
}
// Section face treatment ...
A3DUns32 uiNbFace = sRIData.m_uiNumberSectionFace;
for (A3DUns32 uiFace = 0; uiFace < uiNbFace; ++uiFace)
{
A3DHLRSectionFaceData const & sFaceData = sRIData.m_pHLRSectionFaces[uiFace];
GLUtriangulatorObj *tess = gluNewTess();
gluTessCallback(tess, GLU_TESS_VERTEX, (GLvoid(CALLBACK *) ()) &tessVertex);
gluTessCallback(tess, GLU_TESS_BEGIN, (GLvoid(CALLBACK *) ()) &tessBegin);
gluTessCallback(tess, GLU_TESS_END, (GLvoid(CALLBACK *) ()) &tessEnd);
gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK *)())tessError);
std::vector< A3DCrvPolyLineData > asObjToDelete;
gluTessBeginPolygon(tess, nullptr);
for (A3DUns32 uiLoop = 0; uiLoop < sFaceData.m_uiNbLoop; ++uiLoop)
{
gluTessBeginContour(tess);
A3DUns32 uiNbLoopCrv = sFaceData.m_puiLoopSize[uiLoop];
for (A3DUns32 uiLoopCrv = 0; uiLoopCrv < uiNbLoopCrv; ++uiLoopCrv)
{
A3DUns32 uiCrvIndex = sFaceData.m_puiCurveIndex[uiLoop][uiLoopCrv];
A3DBool bCrvOrient = sFaceData.m_pbCurveOrientation[uiLoop][uiLoopCrv];
A3DHLRCurveData const & sCurveData = sRIData.m_pppHLRCurves[uiCrvIndex];
A3DCrvPolyLineData sPolyData;
A3D_INITIALIZE_DATA(A3DCrvPolyLineData, sPolyData);
A3DCrvPolyLineGet(sCurveData.m_pProjectedPolyLine, &sPolyData);
asObjToDelete.push_back(sPolyData);
if (bCrvOrient)
{
A3DVector3dData const *pPt = sPolyData.m_pPts;
for (A3DUns32 uiPt = 0; uiPt < sPolyData.m_uiSize; uiPt++, pPt++)
{
gluTessVertex(tess, (GLdouble*)&pPt->m_dX, (void*)&pPt->m_dX);
}
}
else
{
A3DVector3dData const *pPt = &sPolyData.m_pPts[sPolyData.m_uiSize - 1];
for (A3DUns32 uiPt = 0; uiPt < sPolyData.m_uiSize; uiPt++, pPt--)
{
gluTessVertex(tess, (GLdouble*)&pPt->m_dX, (void*)&pPt->m_dX);
}
}
}
gluTessEndContour(tess);
}
gluTessEndPolygon(tess);
gluDeleteTess(tess);
for (size_t i = 0; i < asObjToDelete.size(); ++i)
{
A3DCrvPolyLineGet(nullptr, &asObjToDelete[i]);
}
}
A3DHLRRepresentationItemGet(nullptr, &sRIData);
}
glPopAttrib();
glEndList();
// Visible ...
glDeleteLists(uiHLRDisplayList, 1);
uiHLRDisplayList = glGenLists(1);
glNewList(uiHLRDisplayList, GL_COMPILE);
glPushAttrib(GL_LINE_STIPPLE | GL_LIGHTING_BIT | GL_LINE_BIT | GL_TEXTURE_BIT);
glDisable(GL_TEXTURE);
glDisable(GL_LIGHTING);
glColor3f(1., 1., 1.); // white
glLineWidth(2);
stDrawPolyline(apVisible);
glPopAttrib();
glEndList();
// Visible TanEdge
glDeleteLists(uiHLRTanEdgeDisplayList, 1);
uiHLRTanEdgeDisplayList = glGenLists(1);
glNewList(uiHLRTanEdgeDisplayList, GL_COMPILE);
glPushAttrib(GL_LINE_STIPPLE | GL_LIGHTING_BIT | GL_LINE_BIT | GL_TEXTURE_BIT);
glDisable(GL_TEXTURE);
glDisable(GL_LIGHTING);
glColor3f(1., 1., 0.); // white
glLineWidth(2);
stDrawPolyline(apTanEdge);
glPopAttrib();
glEndList();
// Hidden
glDeleteLists(uiHLRHiddenDisplayList, 1);
uiHLRHiddenDisplayList = glGenLists(1);
glNewList(uiHLRHiddenDisplayList, GL_COMPILE);
glPushAttrib(GL_LINE_STIPPLE | GL_LIGHTING_BIT | GL_LINE_BIT | GL_TEXTURE_BIT);
glDisable(GL_TEXTURE);
glDisable(GL_LIGHTING);
glLineStipple(2, 0xAAAA);
glEnable(GL_LINE_STIPPLE);
glColor3f(0.0, 0.5, 0.7); // midnight blue
glLineWidth(1);
stDrawPolyline(apHidden);
glPopAttrib();
glEndList();
// Hidden Tan Edge
glDeleteLists(uiHLRHiddenTanEdgeDisplayList, 1);
uiHLRHiddenTanEdgeDisplayList = glGenLists(1);
glNewList(uiHLRHiddenTanEdgeDisplayList, GL_COMPILE);
glPushAttrib(GL_LINE_STIPPLE | GL_LIGHTING_BIT | GL_LINE_BIT | GL_TEXTURE_BIT);
glDisable(GL_TEXTURE);
glDisable(GL_LIGHTING);
glLineStipple(2, 0xAAAA);
glEnable(GL_LINE_STIPPLE);
//glColor3f(0.0, 0.5, 0.7); // midnight blue
glColor3f(1., 1., 0.); // white
glLineWidth(1);
stDrawPolyline(apHiddenTanEdge);
glPopAttrib();
glEndList();
// Delete geometry
for (A3DUns32 uiResultRI = 0; uiResultRI < uiNumberHLRRepItem; uiResultRI++)
{
A3DHLRRepresentationItem const * pHLRRI = apHLRRepItem[uiResultRI];
A3DHLRRepresentationItemData sRIData;
A3D_INITIALIZE_DATA(A3DHLRRepresentationItemData, sRIData);
A3DHLRRepresentationItemGet(pHLRRI, &sRIData);
stCleanHLRResults(sRIData);
A3DHLRRepresentationItemGet(nullptr, &sRIData);
}
// Delete HLRstructure
A3DComputeOrthoHLROnModelFile3(nullptr, nullptr, nullptr, nullptr, &uiNumberHLRRepItem, &apHLRRepItem);
}