/*********************************************************************************************************************** * * 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 #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; uiIndexm_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; }