482 lines
16 KiB
C++
482 lines
16 KiB
C++
/***********************************************************************************************************************
|
|
*
|
|
* 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 <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 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, 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;
|
|
}
|