/*********************************************************************************************************************** * * 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 #include "Viewer.h" #include //###################################################################################################################### void DrawError(char const * acMessage, A3DStatus sStatus); //###################################################################################################################### void stCleanHLRResults(A3DHLRRepresentationItemData & sRIData) { unsigned int uiCrv, uiNbCrv = sRIData.m_uiNumberHLRCurves; for (uiCrv = 0; uiCrv #include #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 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 //###################################################################################################################### 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 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); }