/*********************************************************************************************************************** * * 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. * ***********************************************************************************************************************/ #include #include "drawing_parse.h" #include "callback_opengl.h" #include #include //###################################################################################################################### typedef struct { std::vector* m_paSheetDL; std::vector* m_paSheetSize; bool m_bDrawMarkup; } GLGlobalData; //###################################################################################################################### static A3DDrawCallbacksData *st_psDrawCallBacks = NULL; #define A3D_DRAW_CALL0(name) { if(st_psDrawCallBacks) st_psDrawCallBacks->m_pfunc##name(); } #define A3D_DRAW_CALL1(name, p1) { if(st_psDrawCallBacks) st_psDrawCallBacks->m_pfunc##name(p1); } #define A3D_DRAW_CALL2(name, p1, p2) { if(st_psDrawCallBacks) st_psDrawCallBacks->m_pfunc##name(p1, p2); } #define A3D_DRAW_CALL3(name, p1, p2, p3) { if(st_psDrawCallBacks) st_psDrawCallBacks->m_pfunc##name(p1, p2, p3); } #define A3D_DRAW_CALL6(name, p1, p2, p3, p4, p5, p6) { if(st_psDrawCallBacks) st_psDrawCallBacks->m_pfunc##name(p1, p2, p3, p4, p5, p6); } //###################################################################################################################### #define MAT_INIT_ANGLE(mat, angle) \ memset(mat,0, sizeof(double)*16); \ mat[0] = +cos(angle);\ mat[1] = +sin(angle);\ mat[4] = -sin(angle);\ mat[5] = +cos(angle);\ mat[10] = 1.; \ mat[15] = 1 #define MAT_SCALE(mat, scale) \ for(int iInd = 0; iInd < 15; ++iInd) mat[iInd] *= scale #define MAT_TRANSLAT(mat, offsetX, offsetY, offsetZ) \ mat[12] += offsetX;\ mat[13] += offsetY;\ mat[14] += offsetZ //###################################################################################################################### A3DStatus DrawRepresentationItem(const A3DRiRepresentationItem* pRepItem, const A3DMiscCascadedAttributes* pFatherAttr); //###################################################################################################################### A3DStatus DrawMarkup(const A3DMkpMarkup* pMarkup, const A3DMiscCascadedAttributes* pFatherAttr); //###################################################################################################################### static void stVectoriel(const A3DVector3dData* X, const A3DVector3dData* Y, A3DVector3dData* Z) { Z->m_dX=X->m_dY*Y->m_dZ - X->m_dZ*Y->m_dY; Z->m_dY=X->m_dZ*Y->m_dX - X->m_dX*Y->m_dZ; Z->m_dZ=X->m_dX*Y->m_dY - X->m_dY*Y->m_dX; } //###################################################################################################################### static void stInitializeMatrix(A3DDouble adMatrix[16]) { adMatrix[0] = 1.; adMatrix[4] = 0.; adMatrix[8] = 0.; adMatrix[12] = 0.; adMatrix[1] = 0.; adMatrix[5] = 1.; adMatrix[9] = 0.; adMatrix[13] = 0.; adMatrix[2] = 0.; adMatrix[6] = 0.; adMatrix[10] = 1.; adMatrix[14] = 0.; adMatrix[3] = 0.; adMatrix[7] = 0.; adMatrix[11] = 0.; adMatrix[15] = 1.; } //###################################################################################################################### static bool stbGetVisibilityFromAttribute(A3DMiscCascadedAttributes const* pAttr) { bool bVibility = true; if(pAttr != NULL) { A3DMiscCascadedAttributesData sAttribData; A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, sAttribData); if(A3DMiscCascadedAttributesGet(pAttr, &sAttribData)==A3D_SUCCESS) { bVibility = (sAttribData.m_bShow && !sAttribData.m_bRemoved); A3DMiscCascadedAttributesGet(NULL, &sAttribData); } } return bVibility; } //###################################################################################################################### // Apply current transformation, to current matrix static A3DStatus stDrawTransformation(const A3DMiscTransformation* pTransfo3d) { if(pTransfo3d == NULL) return A3D_SUCCESS; A3DStatus iRet = A3D_SUCCESS; A3DEEntityType eType = kA3DTypeUnknown; A3DEntityGetType(pTransfo3d, &eType); switch(eType) { case kA3DTypeMiscCartesianTransformation : { A3DMiscCartesianTransformationData sData; A3D_INITIALIZE_DATA(A3DMiscCartesianTransformationData, sData); CHECK_RET(A3DMiscCartesianTransformationGet(pTransfo3d, &sData)); double adMatrix[16]; double dMirror = (sData.m_ucBehaviour & kA3DTransformationMirror) ? -1. : 1.; A3DVector3dData sZVector; memset(adMatrix, 0, 16*sizeof(double)); stVectoriel(&sData.m_sXVector, &sData.m_sYVector, &sZVector); adMatrix[12] = sData.m_sOrigin.m_dX; adMatrix[13] = sData.m_sOrigin.m_dY; adMatrix[14] = sData.m_sOrigin.m_dZ; adMatrix[0] = sData.m_sXVector.m_dX*sData.m_sScale.m_dX; adMatrix[1] = sData.m_sXVector.m_dY*sData.m_sScale.m_dX; adMatrix[2] = sData.m_sXVector.m_dZ*sData.m_sScale.m_dX; adMatrix[4] = sData.m_sYVector.m_dX*sData.m_sScale.m_dY; adMatrix[5] = sData.m_sYVector.m_dY*sData.m_sScale.m_dY; adMatrix[6] = sData.m_sYVector.m_dZ*sData.m_sScale.m_dY; adMatrix[8] = dMirror*sZVector.m_dX*sData.m_sScale.m_dZ; adMatrix[9] = dMirror*sZVector.m_dY*sData.m_sScale.m_dZ; adMatrix[10] = dMirror*sZVector.m_dZ*sData.m_sScale.m_dZ; adMatrix[15] = 1.; A3D_DRAW_CALL1(MultMatrix, adMatrix); CHECK_RET(A3DMiscCartesianTransformationGet(NULL, &sData)); } break; case kA3DTypeMiscGeneralTransformation : { A3DMiscGeneralTransformationData sData; A3D_INITIALIZE_DATA(A3DMiscGeneralTransformationData, sData); CHECK_RET(A3DMiscGeneralTransformationGet(pTransfo3d, &sData)); A3D_DRAW_CALL1(MultMatrix, sData.m_adCoeff); CHECK_RET(A3DMiscGeneralTransformationGet(NULL, &sData)); } break; default: iRet = A3D_INVALID_ENTITY_TYPE; } return iRet; } //###################################################################################################################### // DrawingBlockBasic and DrawingBlockOperator are A3DRiRepresentationItem: use the same function A3DStatus stPreDrawBlock(A3DEntity* psEntity, A3DMiscCascadedAttributes const* pAttr, A3DVoid* pGlobalData, A3DVoid** pFunctionData, A3DUns32 /*uiBehavior*/) { A3DStatus iRet = A3D_SUCCESS; *pFunctionData = NULL; if(!stbGetVisibilityFromAttribute(pAttr)) return A3D_CALLBACK_CONTINUE; // Get and apply local transformation A3DRiRepresentationItemData sData; A3D_INITIALIZE_DATA(A3DRiRepresentationItemData, sData); CHECK_RET(A3DRiRepresentationItemGet(psEntity, &sData)); const A3DRiCoordinateSystem* pCoordSys = sData.m_pCoordinateSystem; if(pCoordSys != NULL) { *pFunctionData = (void*) 1; A3D_DRAW_CALL0(PushMatrix); A3DRiCoordinateSystemData sCSysData; A3D_INITIALIZE_DATA(A3DRiCoordinateSystemData, sCSysData); CHECK_RET(A3DRiCoordinateSystemGet(sData.m_pCoordinateSystem, &sCSysData)); CHECK_RET(stDrawTransformation(sCSysData.m_pTransformation)); // free memory CHECK_RET(A3DRiCoordinateSystemGet(NULL, &sCSysData)); } bool bDrawMkupOnly = ((GLGlobalData*)pGlobalData)->m_bDrawMarkup; // Parse current tessellation if(!bDrawMkupOnly) CHECK_RET(DrawRepresentationItem(psEntity, pAttr)); // free memory CHECK_RET(A3DRiRepresentationItemGet(NULL, &sData)); // Parse markup if(bDrawMkupOnly) { A3DDrawingBlockBasicData sBlkData; A3D_INITIALIZE_DATA(A3DDrawingBlockBasicData, sBlkData); A3DDrawingBlockBasicGet(psEntity, &sBlkData); unsigned int uiMk, uiNbMk = sBlkData.m_uiMarkupsSize; for(uiMk=0; uiMk* paGLSheetDisplayList = ((GLGlobalData*) pGlobalData)->m_paSheetDL; std::vector *paGLSheetSize = ((GLGlobalData*) pGlobalData)->m_paSheetSize; bool bDrawMkupOnly = ((GLGlobalData*) pGlobalData)->m_bDrawMarkup; paGLSheetDisplayList->push_back(uiDisplayList); // activate DisplayList glNewList(uiDisplayList, GL_COMPILE_AND_EXECUTE); A3DUns32* puiInternalData = new A3DUns32; *pFunctionData = puiInternalData; *puiInternalData = 1; A3DStatus iRet = A3D_SUCCESS; A3DDrawingSheetData sSheetData; A3D_INITIALIZE_DATA(A3DDrawingSheetData, sSheetData); iRet = A3DDrawingSheetGet((A3DDrawingSheet*) psEntity, &sSheetData); if(iRet == A3D_SUCCESS) { if(sSheetData.m_pFormat != NULL) { A3DDrawingSheetFormatData sFormatData; A3D_INITIALIZE_DATA(A3DDrawingSheetFormatData, sFormatData); iRet = A3DDrawingSheetFormatGet(sSheetData.m_pFormat, &sFormatData); if (iRet==A3D_SUCCESS) { if (!bDrawMkupOnly) { A3DDouble aPts[5 * 3]; aPts[0] = 0; aPts[1] = 0; aPts[2] = 0; aPts[3] = sFormatData.m_sSize.m_dX; aPts[4] = 0; aPts[5] = 0; aPts[6] = sFormatData.m_sSize.m_dX; aPts[7] = sFormatData.m_sSize.m_dY; aPts[8] = 0; aPts[9] = 0; aPts[10] = sFormatData.m_sSize.m_dY; aPts[11] = 0; aPts[12] = 0; aPts[13] = 0; aPts[14] = 0; GLfloat afValues[3] = { 1, 1, 0 }; glColor3fv(afValues); OpenGL_PolyLine(aPts, 5); } iRet = A3DDrawingSheetFormatGet(NULL, &sFormatData); } if(paGLSheetSize != NULL) paGLSheetSize->push_back(sFormatData.m_sSize); } else { if(paGLSheetSize != NULL) paGLSheetSize->push_back(sSheetData.m_sSize); } *puiInternalData = 2; A3D_DRAW_CALL0(PushMatrix); // Transformation matrix A3DDouble adMatrix[16]; stInitializeMatrix(adMatrix); adMatrix[0] = sSheetData.m_dScale; adMatrix[5] = sSheetData.m_dScale; adMatrix[12] = sSheetData.m_sRefPoint.m_dX * sSheetData.m_dScale; adMatrix[13] = sSheetData.m_sRefPoint.m_dY * sSheetData.m_dScale; OpenGL_MultMatrix(adMatrix); A3DDrawingSheetGet(NULL, &sSheetData); } return iRet; } //###################################################################################################################### unsigned int OpenGL_GetPushLevel(); //###################################################################################################################### A3DStatus stPostDrawDrawingSheet(A3DEntity* /*psEntity*/, A3DMiscCascadedAttributes const* /*pAttr*/, A3DVoid* /*pGlobalData*/, A3DVoid* pFunctionData, A3DUns32 /*uiBehavior*/) { if(pFunctionData != NULL) { A3DUns32* puiInternalData = (A3DUns32*) pFunctionData; // pop current transformation if(*puiInternalData > 1) A3D_DRAW_CALL0(PopMatrix); // Close DisplayList glEndList(); delete puiInternalData; } return A3D_SUCCESS; } //###################################################################################################################### A3DStatus A3DDrawDrawing(A3DDrawingModel* pDrawingModel, A3DDrawCallbacksData* psCallbacks, std::vector &aGLSheetDisplayList, std::vector* paGLSheetSize, bool bDrawMarkup) { st_psDrawCallBacks = psCallbacks; A3DParseDrawingModelData sCallBackData; A3D_INITIALIZE_DATA_VAR(sCallBackData); sCallBackData.m_pfSheet.m_pfPreProcess = stPreDrawDrawingSheet; sCallBackData.m_pfSheet.m_pfPostProcess = stPostDrawDrawingSheet; sCallBackData.m_pfView.m_pfPreProcess = stPreDrawDrawingView; sCallBackData.m_pfView.m_pfPostProcess = stPostDrawDrawingView; sCallBackData.m_pfBlockBasic.m_pfPreProcess = stPreDrawBlock; sCallBackData.m_pfBlockBasic.m_pfPostProcess = stPostDrawBlock; sCallBackData.m_pfBlockOperator.m_pfPreProcess = stPreDrawBlock; sCallBackData.m_pfBlockOperator.m_pfPostProcess = stPostDrawBlock; GLGlobalData sGlobalData; sGlobalData.m_paSheetDL = &aGLSheetDisplayList; sGlobalData.m_paSheetSize = paGLSheetSize; sGlobalData.m_bDrawMarkup = bDrawMarkup; sCallBackData.m_pGlobalData = &sGlobalData; sCallBackData.m_pDrawingModel = pDrawingModel; A3DStatus iRet = A3DParseDrawingModel(&sCallBackData); st_psDrawCallBacks = NULL; return iRet; }