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

432 lines
14 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 <vector>
#include <A3DSDKIncludes.h>
#include "drawing_parse.h"
//######################################################################################################################
#define CHECK(FCT) \
if(!bExit) \
{ \
A3DStatus iLocRet = (FCT); \
if(iLocRet != A3D_SUCCESS) \
{ \
if(iLocRet == A3D_CALLBACK_CONTINUE) \
bExit = true; \
else \
{ \
iRet = iLocRet; \
bExit = (uiParseBehavior & A3D_PARSE_CONTINUE_EVEN_IF_ERROR) && (iLocRet != A3D_SUCCESS); \
} \
} \
}
//######################################################################################################################
#define A3DDRAWING_PARSE_SHEET 0x80000000 // 1000 0000 0000 0000
#define A3DDRAWING_PARSE_VIEW 0x40000000 // 0100 0000 0000 0000
#define A3DDRAWING_PARSE_BLOCK 0x20000000 // 0010 0000 0000 0000
#define A3DDRAWING_PARSE_BLOCKBASIC 0x10000000 // 0001 0000 0000 0000
#define A3DDRAWING_PARSE_BLOCKOPERATOR 0x08000000 // 0000 1000 0000 0000
#define A3DDRAWING_PARSE_ENTITY 0x00400000 // 0000 0100 0000 0000
//######################################################################################################################
#define A3DDRAWING_SET_PARSE_SHEET 0x80000000 // 1000 0000 0000 0000
#define A3DDRAWING_SET_PARSE_VIEW 0xC0000000 // 1100 0000 0000 0000
#define A3DDRAWING_SET_PARSE_BLOCK 0xE0000000 // 1110 0000 0000 0000
#define A3DDRAWING_SET_PARSE_BLOCKBASIC 0xF0000000 // 1111 0000 0000 0000
#define A3DDRAWING_SET_PARSE_BLOCKOPERATOR 0xE8000000 // 1110 1000 0000 0000
#define A3DDRAWING_SET_PARSE_ENTITY 0xF8000000 // 1111 1000 0000 0000
//######################################################################################################################
static A3DStatus stCreateAndPushCascadedAttributes(const A3DRootBaseWithGraphics* pBase,
const A3DMiscCascadedAttributes* pFatherAttr,
A3DMiscCascadedAttributes** ppAttr)
{
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(A3DMiscCascadedAttributesCreate(ppAttr));
CHECK_RET(A3DMiscCascadedAttributesPush(*ppAttr, pBase, pFatherAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stFreeCascadedAttributes(A3DMiscCascadedAttributes* ppAttr)
{
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(A3DMiscCascadedAttributesDelete(ppAttr));
return iRet;
}
//######################################################################################################################
#define CREATE_AUTOCLEAN_CLASS_DATA(TYPE) \
class AutoClean##TYPE##Data : public TYPE##Data\
{ \
public: \
AutoClean##TYPE##Data() { A3D_INITIALIZE_##TYPE##Data(*this)}; \
~AutoClean##TYPE##Data() { TYPE##Get(NULL, (TYPE##Data*)this);}; \
}
//######################################################################################################################
CREATE_AUTOCLEAN_CLASS_DATA(A3DDrawingBlockBasic);
//######################################################################################################################
static A3DStatus stA3DParse_Block(A3DParseDrawingModelData const* const pParseData, A3DUns32 uiParseBehavior,
A3DDrawingBlock* pBlock, A3DMiscCascadedAttributes const* pFatherAttr);
//######################################################################################################################
static A3DStatus stA3DParse_BlockBasic(A3DParseDrawingModelData const* const pParseData, A3DUns32 uiParseBehavior,
A3DDrawingBlockBasic* pBlock, A3DMiscCascadedAttributes const* pFatherAttr)
{
if((uiParseBehavior & A3DDRAWING_PARSE_BLOCKBASIC) == 0)
return A3D_SUCCESS;
A3DStatus iRet = A3D_SUCCESS;
A3DVoid* pFunctionData = NULL;
A3DUns32 uiFunctionBehavior = 0;
bool bExit = false;
// Compute CascadedAttributes ...
A3DMiscCascadedAttributes* pAttr = NULL;
CHECK(stCreateAndPushCascadedAttributes(pBlock, pFatherAttr, &pAttr));
if(pParseData->m_pfBlockBasic.m_pfPreProcess != NULL)
{
CHECK(pParseData->m_pfBlockBasic.m_pfPreProcess(pBlock, pAttr, pParseData->m_pGlobalData, &pFunctionData,
uiFunctionBehavior));
}
if(!bExit)
{
//A3DDrawingBlockBasicData sBlockData;
//A3D_INITIALIZE_DATA(A3DDrawingBlockBasicData, sBlockData);
AutoCleanA3DDrawingBlockBasicData sBlockData;
CHECK(A3DDrawingBlockBasicGet(pBlock,&sBlockData));
sBlockData.m_uiDrwEntitiesSize = 0;
if(bExit)
{
// No need to continue
stFreeCascadedAttributes(pAttr);
return iRet;
}
A3DUns32 uiIndex;
for(uiIndex = 0; uiIndex < sBlockData.m_uiDrwBlocksSize; uiIndex++)
{
CHECK(stA3DParse_Block(pParseData, uiParseBehavior, sBlockData.m_ppDrwBlocks[uiIndex], pAttr));
if(bExit)
break;
}
CHECK(A3DDrawingBlockBasicGet(NULL, &sBlockData));
}
if(pParseData->m_pfBlockBasic.m_pfPostProcess != NULL)
{
if(iRet != A3D_SUCCESS)
uiFunctionBehavior |= A3D_PARSE_ERROR;
CHECK(pParseData->m_pfBlockBasic.m_pfPostProcess(pBlock, pAttr, pParseData->m_pGlobalData, pFunctionData,
uiFunctionBehavior));
}
// Free local data
stFreeCascadedAttributes(pAttr);
return iRet;
}
//######################################################################################################################
static A3DStatus stA3DParse_BlockOperator(A3DParseDrawingModelData const* const pParseData, A3DUns32 uiParseBehavior,
A3DDrawingBlockOperator* pBlock, A3DMiscCascadedAttributes const* pFatherAttr)
{
if((uiParseBehavior & A3DDRAWING_PARSE_BLOCKBASIC)==0)
return A3D_SUCCESS;
A3DStatus iRet = A3D_SUCCESS;
A3DVoid *pFunctionData = NULL;
A3DUns32 uiFunctionBehavior = 0;
bool bExit = false;
// Compute CascadedAttributes ...
A3DMiscCascadedAttributes* pAttr = NULL;
CHECK(stCreateAndPushCascadedAttributes(pBlock, pFatherAttr, &pAttr));
if(pParseData->m_pfBlockOperator.m_pfPreProcess != NULL)
{
CHECK(pParseData->m_pfBlockOperator.m_pfPreProcess(pBlock, pAttr, pParseData->m_pGlobalData, &pFunctionData,
uiFunctionBehavior));
}
if(!bExit)
{
A3DDrawingBlockOperatorData sBlockData;
A3D_INITIALIZE_DATA(A3DDrawingBlockOperatorData, sBlockData);
CHECK(A3DDrawingBlockOperatorGet(pBlock,&sBlockData));
if(bExit)
{
// No need to continue
stFreeCascadedAttributes(pAttr);
return iRet;
}
A3DUns32 uiIndex;
for(uiIndex = 0; uiIndex < sBlockData.m_uiDrwBlocksSize; uiIndex++)
{
CHECK(stA3DParse_Block(pParseData, uiParseBehavior, sBlockData.m_ppDrwBlocks[uiIndex], pAttr));
if(bExit)
break;
}
CHECK(A3DDrawingBlockOperatorGet(NULL, &sBlockData));
}
if(pParseData->m_pfBlockOperator.m_pfPostProcess != NULL)
{
if(iRet != A3D_SUCCESS)
uiFunctionBehavior |= A3D_PARSE_ERROR;
CHECK(pParseData->m_pfBlockOperator.m_pfPostProcess(pBlock, pAttr, pParseData->m_pGlobalData, pFunctionData,
uiFunctionBehavior));
}
// Free local data
stFreeCascadedAttributes(pAttr);
return iRet;
}
//######################################################################################################################
static A3DStatus stA3DParse_Block(A3DParseDrawingModelData const* const pParseData, A3DUns32 uiParseBehavior,
A3DDrawingBlock* pBlock, A3DMiscCascadedAttributes const* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
bool bExit = false;
if((uiParseBehavior & A3DDRAWING_PARSE_BLOCK) != 0)
{
A3DEEntityType eType = kA3DTypeUnknown;
CHECK(A3DEntityGetType(pBlock, &eType));
switch(eType)
{
case kA3DTypeDrawingBlockBasic:
CHECK(stA3DParse_BlockBasic(pParseData, uiParseBehavior, (A3DDrawingBlockBasic*) pBlock, pFatherAttr));
break;
case kA3DTypeDrawingBlockOperator:
CHECK(stA3DParse_BlockOperator(pParseData, uiParseBehavior, (A3DDrawingBlockOperator*) pBlock, pFatherAttr));
break;
default:
return A3D_INVALID_ENTITY_TYPE;
}
}
return iRet;
}
//######################################################################################################################
static A3DStatus stA3DParse_View(A3DParseDrawingModelData const* const pParseData, A3DUns32 uiParseBehavior,
A3DDrawingView* pView, A3DMiscCascadedAttributes const* pFatherAttr)
{
if((uiParseBehavior & A3DDRAWING_PARSE_VIEW) == 0)
return A3D_SUCCESS;
A3DStatus iRet = A3D_SUCCESS;
A3DVoid* pFunctionData = NULL;
A3DUns32 uiFunctionBehavior = 0;
bool bExit = false;
// Compute CascadedAttributes ...
A3DMiscCascadedAttributes* pAttr = NULL;
CHECK(stCreateAndPushCascadedAttributes(pView, pFatherAttr, &pAttr));
if(pParseData->m_pfView.m_pfPreProcess != NULL)
{
CHECK(pParseData->m_pfView.m_pfPreProcess(pView, pAttr, pParseData->m_pGlobalData, &pFunctionData,
uiFunctionBehavior));
}
if(!bExit)
{
// Getting A3DDrawingView Data
A3DDrawingViewData sViewData;
A3D_INITIALIZE_DATA(A3DDrawingViewData, sViewData);
CHECK(A3DDrawingViewGet(pView, &sViewData));
if(bExit)
{
// No need to continue
stFreeCascadedAttributes(pAttr);
return iRet;
}
// Parse sub-entities
{
if(sViewData.m_pLocalBlocks != NULL)
{
CHECK(stA3DParse_Block(pParseData, uiParseBehavior, sViewData.m_pLocalBlocks, pAttr));
}
A3DUns32 uiIndex;
for(uiIndex = 0; uiIndex < sViewData.m_uiDrwBlocksSize; uiIndex++)
{
CHECK(stA3DParse_Block(pParseData, uiParseBehavior, sViewData.m_ppDrwBlocks[uiIndex], pAttr));
if(bExit)
break;
}
}
CHECK(A3DDrawingViewGet(NULL, &sViewData));
}
if(pParseData->m_pfView.m_pfPostProcess != NULL)
{
if(iRet != A3D_SUCCESS)
uiFunctionBehavior |= A3D_PARSE_ERROR;
CHECK(pParseData->m_pfView.m_pfPostProcess(pView, pAttr, pParseData->m_pGlobalData, pFunctionData,
uiFunctionBehavior));
}
// Free local data
stFreeCascadedAttributes(pAttr);
return iRet;
}
//######################################################################################################################
static A3DStatus stA3DParse_Sheet(A3DParseDrawingModelData const* const pParseData, A3DUns32 uiParseBehavior,
A3DDrawingSheet* pSheet, A3DMiscCascadedAttributes const* pFatherAttr)
{
if((uiParseBehavior & A3DDRAWING_PARSE_SHEET) == 0)
return A3D_SUCCESS;
A3DStatus iRet = A3D_SUCCESS;
A3DVoid* pFunctionData = NULL;
A3DUns32 uiFunctionBehavior = 0;
bool bExit = false;
// Compute CascadedAttributes ...
A3DMiscCascadedAttributes* pAttr = NULL;
CHECK(stCreateAndPushCascadedAttributes(pSheet, pFatherAttr, &pAttr));
if(pParseData->m_pfSheet.m_pfPreProcess != NULL)
{
CHECK(pParseData->m_pfSheet.m_pfPreProcess(pSheet, pAttr, pParseData->m_pGlobalData, &pFunctionData,
uiFunctionBehavior));
}
A3DDrawingSheetData sSheetData;
A3D_INITIALIZE_DATA(A3DDrawingSheetData, sSheetData);
CHECK(A3DDrawingSheetGet(pSheet, &sSheetData));
if(sSheetData.m_pBackgroundBlocks != NULL)
{
CHECK(stA3DParse_Block(pParseData, uiParseBehavior, sSheetData.m_pBackgroundBlocks, pAttr));
}
A3DUns32 uiIndex;
for(uiIndex = 0; uiIndex < sSheetData.m_uiDrwBlocksSize; uiIndex++)
{
CHECK(stA3DParse_Block(pParseData, uiParseBehavior, sSheetData.m_ppDrwBlocks[uiIndex], pAttr));
if(bExit)
break;
}
for(uiIndex=0; uiIndex<sSheetData.m_uiDrwViewsSize; uiIndex++)
{
CHECK(stA3DParse_View(pParseData, uiParseBehavior, sSheetData.m_ppDrwViews[uiIndex], pAttr));
if(bExit)
break;
}
if(pParseData->m_pfSheet.m_pfPostProcess != NULL)
{
if(iRet != A3D_SUCCESS)
uiFunctionBehavior |= A3D_PARSE_ERROR;
CHECK(pParseData->m_pfSheet.m_pfPostProcess(pSheet, pAttr, pParseData->m_pGlobalData, pFunctionData,
uiFunctionBehavior));
}
// Free local data
stFreeCascadedAttributes(pAttr);
CHECK(A3DDrawingSheetGet(nullptr, &sSheetData));
return iRet;
}
//######################################################################################################################
A3DStatus A3DParseDrawingModel(A3DParseDrawingModelData const* const pParseData)
{
if(pParseData == NULL ||pParseData->m_pDrawingModel == NULL)
return A3D_ERROR;
// Compute ParseBehavior
A3DUns32 uiLParseBehavior = pParseData->m_uiParseBehavior;
if(pParseData->m_pfSheet.m_pfPreProcess || pParseData->m_pfSheet.m_pfPostProcess)
uiLParseBehavior |= A3DDRAWING_SET_PARSE_VIEW;
if(pParseData->m_pfView.m_pfPreProcess || pParseData->m_pfView.m_pfPostProcess)
uiLParseBehavior |= A3DDRAWING_SET_PARSE_SHEET;
if(pParseData->m_pfBlockBasic.m_pfPreProcess || pParseData->m_pfBlockBasic.m_pfPostProcess)
uiLParseBehavior |= A3DDRAWING_SET_PARSE_BLOCKBASIC;
if(pParseData->m_pfBlockOperator.m_pfPreProcess || pParseData->m_pfBlockOperator.m_pfPostProcess)
uiLParseBehavior |= A3DDRAWING_SET_PARSE_BLOCKOPERATOR;
if(pParseData->m_pfEntity.m_pfPreProcess || pParseData->m_pfEntity.m_pfPostProcess)
uiLParseBehavior |= A3DDRAWING_SET_PARSE_ENTITY;
A3DStatus iRet;
A3DMiscCascadedAttributes* pCascadedAttr;
CHECK_RET(A3DMiscCascadedAttributesCreate(&pCascadedAttr));
A3DDrawingModelData sDrawingModelData;
A3D_INITIALIZE_DATA(A3DDrawingModelData, sDrawingModelData);
iRet = A3DDrawingModelGet(pParseData->m_pDrawingModel, &sDrawingModelData);
if(iRet == A3D_SUCCESS)
{
if((pParseData->m_uiParseBehavior & A3D_PARSE_DRAWING_ACTIVE_SHEET) != 0)
{
if(sDrawingModelData.m_uiActiveSheet < sDrawingModelData.m_uiDrwSheetsSize)
{
iRet = stA3DParse_Sheet(pParseData, uiLParseBehavior,
sDrawingModelData.m_ppDrwSheets[sDrawingModelData.m_uiActiveSheet], pCascadedAttr);
}
}
else
{
A3DUns32 uiSheet, uiNbSheet = sDrawingModelData.m_uiDrwSheetsSize;
for(uiSheet = 0; uiSheet < uiNbSheet; uiSheet++)
{
iRet = stA3DParse_Sheet(pParseData, uiLParseBehavior,
sDrawingModelData.m_ppDrwSheets[uiSheet], pCascadedAttr);
if((iRet != A3D_SUCCESS) && ((uiLParseBehavior & A3D_PARSE_CONTINUE_EVEN_IF_ERROR) == 0))
break;
}
}
A3DDrawingModelGet(nullptr, &sDrawingModelData);
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pCascadedAttr));
return iRet;
}