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

483 lines
16 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.
*
***********************************************************************************************************************/
#define A3DAPI_DEPRECATED
#include <A3DSDKIncludes.h>
#include "drawing_parse.h"
#include "callback_opengl.h"
#include <math.h>
#include <vector>
//######################################################################################################################
typedef struct
{
std::vector<GLuint>* m_paSheetDL;
std::vector<A3DVector2dData>* m_paSheetSize;
bool m_bDrawMarkup;
} GLGlobalData;
//######################################################################################################################
static deprecated_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<uiNbMk; uiMk++)
{
A3DMkpMarkup* pCurMk = sBlkData.m_ppMarkups[uiMk];
if(pCurMk != NULL)
CHECK_RET(DrawMarkup(pCurMk, pAttr));
}
A3DDrawingBlockBasicGet(NULL, &sBlkData);
}
return iRet;
}
//######################################################################################################################
A3DStatus stPostDrawBlock(A3DEntity* /*psEntity*/, A3DMiscCascadedAttributes const* /*pAttr*/, A3DVoid* /*pGlobalData*/,
A3DVoid* pFunctionData, A3DUns32 /*uiBehavior*/)
{
// pop current transformation
if(pFunctionData != NULL)
{
A3D_DRAW_CALL0(PopMatrix);
}
return A3D_SUCCESS;
}
//######################################################################################################################
A3DStatus stTreatClipFrame(A3DDrawingClipFrame const* const pClipFrame)
{
A3DDrawingClipFrameData sClipData;
A3D_INITIALIZE_DATA(A3DDrawingClipFrameData, sClipData);
A3DStatus iRet = A3DDrawingClipFrameGet(pClipFrame, &sClipData);
if (iRet == A3D_SUCCESS)
{
if (sClipData.m_bDrawBound)
{
A3DDouble aPts[4 * 4];
aPts[0] = sClipData.m_sRectangularBox.m_sMin.m_dX;
aPts[1] = sClipData.m_sRectangularBox.m_sMin.m_dY;
aPts[2] = 0;
aPts[3] = sClipData.m_sRectangularBox.m_sMax.m_dX;
aPts[4] = sClipData.m_sRectangularBox.m_sMin.m_dY;
aPts[5] = 0;
aPts[6] = sClipData.m_sRectangularBox.m_sMax.m_dX;
aPts[7] = sClipData.m_sRectangularBox.m_sMax.m_dY;
aPts[8] = 0;
aPts[9] = sClipData.m_sRectangularBox.m_sMin.m_dX;
aPts[10] = sClipData.m_sRectangularBox.m_sMax.m_dY;
aPts[11] = 0;
aPts[9] = sClipData.m_sRectangularBox.m_sMin.m_dX;
aPts[10] = sClipData.m_sRectangularBox.m_sMin.m_dY;
aPts[11] = 0;
GLfloat afValues[3] = { 1, 1, 0 };
glColor3fv(afValues);
OpenGL_Polygon(aPts, 4);
}
A3DDrawingClipFrameGet(nullptr, &sClipData);
}
return iRet;
}
//######################################################################################################################
A3DStatus stPreDrawDrawingView(A3DEntity* psEntity, A3DMiscCascadedAttributes const* pAttr, A3DVoid* /*pGlobalData*/,
A3DVoid** pFunctionData, A3DUns32 /*uiBehavior*/)
{
*pFunctionData = NULL;
if(!stbGetVisibilityFromAttribute(pAttr))
return A3D_CALLBACK_CONTINUE;
A3DStatus iRet = A3D_SUCCESS;
// Get Data
A3DDrawingViewData sViewData;
A3D_INITIALIZE_DATA(A3DDrawingViewData, sViewData);
iRet = A3DDrawingViewGet(psEntity, &sViewData);
if(iRet == A3D_SUCCESS)
{
// Transformation matrix
A3DDouble adMatrix[16];
MAT_INIT_ANGLE(adMatrix, sViewData.m_dAngle);
MAT_TRANSLAT(adMatrix, sViewData.m_sOffsetLocation.m_dX, sViewData.m_sOffsetLocation.m_dY, 0);
MAT_SCALE(adMatrix, sViewData.m_dScale);
MAT_TRANSLAT(adMatrix, sViewData.m_sOriginOnSheet.m_dX, sViewData.m_sOriginOnSheet.m_dY, 0);
OpenGL_PushMatrix();
OpenGL_MultMatrix(adMatrix);
if(sViewData.m_pClipFrame)
{
// Clipping activation
stTreatClipFrame(sViewData.m_pClipFrame);
*pFunctionData = (void*) 1;
}
A3DDrawingViewGet(nullptr, &sViewData);
}
return A3D_SUCCESS;
}
//######################################################################################################################
A3DStatus stPostDrawDrawingView(A3DEntity* /*psEntity*/, A3DMiscCascadedAttributes const* /*pAttr*/, A3DVoid* /*pGlobalData*/,
A3DVoid* pFunctionData, A3DUns32 /*uiBehavior*/)
{
if(pFunctionData != NULL)
{
// Clipping desactivation
}
A3D_DRAW_CALL0(PopMatrix);
return A3D_SUCCESS;
}
//######################################################################################################################
A3DStatus stPreDrawDrawingSheet(A3DEntity* psEntity, A3DMiscCascadedAttributes const* pAttr, A3DVoid* pGlobalData,
A3DVoid** pFunctionData, A3DUns32 /*uiBehavior*/)
{
*pFunctionData = NULL;
if(!stbGetVisibilityFromAttribute(pAttr))
return A3D_CALLBACK_CONTINUE;
// each sheet are in a DisplayList
GLuint uiDisplayList = glGenLists(1);
if(uiDisplayList == 0)
return A3D_ERROR;
// memory DisplayList in global data
std::vector<GLuint>* paGLSheetDisplayList = ((GLGlobalData*) pGlobalData)->m_paSheetDL;
std::vector<A3DVector2dData> *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, deprecated_A3DDrawCallbacksData* psCallbacks,
std::vector<GLuint> &aGLSheetDisplayList, std::vector<A3DVector2dData>* 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;
}