/*********************************************************************************************************************** * * 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. * ***********************************************************************************************************************/ /** \file CascadedAttributes.cpp This file demonstrates how to programmatically set the mechanism of the cascaded attributes using HOOPS Exchange. ***********************************************************************************************************************/ #define INITIALIZE_A3D_API #include #include "../common.hpp" //###################################################################################################################### struct MiscCascadedAttributesGuard { A3DMiscCascadedAttributes* ptr_; MiscCascadedAttributesGuard(A3DMiscCascadedAttributes* ptr): ptr_(ptr) {} ~MiscCascadedAttributesGuard() { TEST_RET(A3DMiscCascadedAttributesDelete(ptr_)) ptr_ = NULL; } }; //###################################################################################################################### static A3DUTF8Char stpcWinTitle[_MAX_PATH]; //###################################################################################################################### /*! Given an A3DRootBaseWithGraphics*, will return the name of that entity in the out parameter m_ppcName. */ A3DStatus stGetName( const A3DRootBaseWithGraphics* pPartOrProduct, A3DUTF8Char** m_ppcName) { A3DRootBaseData sRootBaseData; A3D_INITIALIZE_DATA(A3DRootBaseData, sRootBaseData); CHECK_RET(A3DRootBaseGet(pPartOrProduct, &sRootBaseData)); const DATAGUARD(A3DRootBase) sGuard(sRootBaseData, A3DRootBaseGet); if (sRootBaseData.m_pcName != NULL) { *m_ppcName = static_cast(malloc(strlen(sRootBaseData.m_pcName) + 1)); strncpy(*m_ppcName, sRootBaseData.m_pcName, strlen(sRootBaseData.m_pcName)); (*m_ppcName)[strlen(sRootBaseData.m_pcName)] = '\0'; } return A3D_SUCCESS; } //###################################################################################################################### /*! Gets the color values for a A3DRootBaseWithGraphics, then prints it to the console. */ A3DStatus stExtractColorFromGraphicData( const A3DRootBaseWithGraphics* pRootBaseWithGraphics, const A3DGraphStyleData& sGraphStyleData) { // Get its name A3DUTF8Char* pcName = NULL; const A3DStatus iRet = stGetName(pRootBaseWithGraphics, &pcName); const MemoryGuard sGuard(pcName); CHECK_RET(iRet); // First get non-inherited color information A3DRootBaseWithGraphicsData rbwgData; A3D_INITIALIZE_DATA(A3DRootBaseWithGraphicsData, rbwgData); A3DRootBaseWithGraphicsGet(pRootBaseWithGraphics, &rbwgData); if (rbwgData.m_pGraphics != NULL) { // this entity has an attached graphics object A3DGraphicsData graphicsData; A3D_INITIALIZE_DATA(A3DGraphicsData, graphicsData); A3DGraphicsGet(rbwgData.m_pGraphics, &graphicsData); A3DGraphStyleData styleData; A3D_INITIALIZE_DATA(A3DGraphStyleData, styleData); A3DGlobalGetGraphStyleData(graphicsData.m_uiStyleIndex, &styleData); A3DGraphRgbColorData sColorData; A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sColorData); if (!sGraphStyleData.m_bMaterial) { if (A3DGlobalGetGraphRgbColorData(styleData.m_uiRgbColorIndex, &sColorData) == A3D_SUCCESS) { fprintf( GetLogFile(), "\tcolor without inheritance of %s: %f %f %f\n", pcName, sColorData.m_dRed, sColorData.m_dGreen, sColorData.m_dBlue); } A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sColorData); } else { fprintf( GetLogFile(), "\t local material of %s: %u\n", pcName, sGraphStyleData.m_uiRgbColorIndex ); } A3DGlobalGetGraphStyleData(A3D_DEFAULT_STYLE_INDEX, &styleData); A3DGraphicsGet(NULL, &graphicsData); } // Then get inherited color information if (!sGraphStyleData.m_bMaterial) { A3DGraphRgbColorData sColorData; A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sColorData); if (A3DGlobalGetGraphRgbColorData(sGraphStyleData.m_uiRgbColorIndex, &sColorData) == A3D_SUCCESS) { fprintf( GetLogFile(), "\tcolor with inheritance of %s: %f %f %f\n", pcName, sColorData.m_dRed, sColorData.m_dGreen, sColorData.m_dBlue); } A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sColorData); } else { fprintf( GetLogFile(), "\t inheritance material of %s: %u\n", pcName, sGraphStyleData.m_uiRgbColorIndex ); } return A3D_SUCCESS; } //###################################################################################################################### /*! Creates an A3DMiscCascadedAttributes structure and computes the attributes * based on the input A3DRootBaseWithGraphics structure pBase. */ static A3DStatus stCreateAndPushCascadedAttributes( const A3DRootBaseWithGraphics* pBase, const A3DMiscCascadedAttributes* pFatherAttr, A3DMiscCascadedAttributes** ppAttr, A3DMiscCascadedAttributesData* psAttrData) { CHECK_RET(A3DMiscCascadedAttributesCreate(ppAttr)); CHECK_RET(A3DMiscCascadedAttributesPush(*ppAttr, pBase, pFatherAttr)); A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, (*psAttrData)); CHECK_RET(A3DMiscCascadedAttributesGet(*ppAttr, psAttrData)); CHECK_RET(stExtractColorFromGraphicData(pBase, psAttrData->m_sStyle)); return A3D_SUCCESS; } //###################################################################################################################### /*! Parses a face, then computes cascaded attributes for that face. */ static A3DStatus stParseFace( const A3DTopoFace* pFace, const A3DMiscCascadedAttributes* pFatherAttr) { PrintLogMessage("Face level\n"); A3DMiscCascadedAttributes* pAttr; A3DMiscCascadedAttributesData sAttrData; CHECK_RET(stCreateAndPushCascadedAttributes(pFace, pFatherAttr, &pAttr, &sAttrData)); const MiscCascadedAttributesGuard sMCAttrGuard(pAttr); return A3D_SUCCESS; } //###################################################################################################################### /*! Parses a shell, then calls stParseFace for each face found in the shell. */ static A3DStatus stParseShell(const A3DTopoShell* pShell, const A3DMiscCascadedAttributes* pFatherAttr) { PrintLogMessage("Shell level\n"); A3DMiscCascadedAttributes* pAttr; A3DMiscCascadedAttributesData sAttrData; CHECK_RET(stCreateAndPushCascadedAttributes(pShell, pFatherAttr, &pAttr, &sAttrData)); const MiscCascadedAttributesGuard sMCAttrGuard(pAttr); A3DTopoShellData sTopoShellData; A3D_INITIALIZE_DATA(A3DTopoShellData, sTopoShellData); CHECK_RET(A3DTopoShellGet(pShell, &sTopoShellData)); const DATAGUARD(A3DTopoShell) sGuard(sTopoShellData, A3DTopoShellGet); for (unsigned int ui = 0; ui < sTopoShellData.m_uiFaceSize; ++ui) CHECK_RET(stParseFace(sTopoShellData.m_ppFaces[ui], pAttr)); return A3D_SUCCESS; } //###################################################################################################################### /*! Parses a connex, then calls stParseShell for each shell found in the connex. */ static A3DStatus stParseConnex( const A3DTopoConnex* pConnex, const A3DMiscCascadedAttributes* pFatherAttr) { PrintLogMessage("Connex level\n"); A3DMiscCascadedAttributes* pAttr; A3DMiscCascadedAttributesData sAttrData; CHECK_RET(stCreateAndPushCascadedAttributes(pConnex, pFatherAttr, &pAttr, &sAttrData)); const MiscCascadedAttributesGuard sMCAttrGuard(pAttr); A3DTopoConnexData sTopoConnexData; A3D_INITIALIZE_DATA(A3DTopoConnexData, sTopoConnexData); CHECK_RET(A3DTopoConnexGet(pConnex, &sTopoConnexData)); const DATAGUARD(A3DTopoConnex) sGuard(sTopoConnexData, A3DTopoConnexGet); for (unsigned int ui = 0; ui < sTopoConnexData.m_uiShellSize; ++ui) CHECK_RET(stParseShell(sTopoConnexData.m_ppShells[ui], pAttr)); return A3D_SUCCESS; } //###################################################################################################################### /*! Parses a representation item and computes cascaded attributes for it. * Calls stParseConnex for each connex in this representation item. */ static A3DStatus stParseRepresentationItem( const A3DRiRepresentationItem* pRepItem, const A3DMiscCascadedAttributes* pFatherAttr) { PrintLogMessage("Representation item level\n"); A3DMiscCascadedAttributes* pAttr; A3DMiscCascadedAttributesData sAttrData; // Compute the cascaded attributes for this representation item CHECK_RET(stCreateAndPushCascadedAttributes(pRepItem, pFatherAttr, &pAttr, &sAttrData)); const MiscCascadedAttributesGuard sMCAttrGuard(pAttr); A3DEEntityType eType = kA3DTypeUnknown; CHECK_RET(A3DEntityGetType(pRepItem, &eType)); if(eType == kA3DTypeRiBrepModel) { const A3DRiBrepModel* pBrepModel = static_cast(pRepItem); A3DRiBrepModelData sBrepModelData; A3D_INITIALIZE_DATA(A3DRiBrepModelData, sBrepModelData); CHECK_RET(A3DRiBrepModelGet(pBrepModel, &sBrepModelData)); const DATAGUARD(A3DRiBrepModel) sGuard1(sBrepModelData, A3DRiBrepModelGet); A3DTopoBrepDataData sTopoBrepDataData; A3D_INITIALIZE_DATA(A3DTopoBrepDataData, sTopoBrepDataData); CHECK_RET(A3DTopoBrepDataGet(sBrepModelData.m_pBrepData, &sTopoBrepDataData)); const DATAGUARD(A3DTopoBrepData) sGuard2(sTopoBrepDataData, A3DTopoBrepDataGet); for (unsigned int ui = 0; ui < sTopoBrepDataData.m_uiConnexSize; ++ui) CHECK_RET(stParseConnex(sTopoBrepDataData.m_ppConnexes[ui], pAttr)); } return A3D_SUCCESS; } //###################################################################################################################### /*! Iterates over all the representation items in the part pPart, and calls * stParseRepresentationItem on each one. */ static A3DStatus stParsePartDefinition( const A3DAsmPartDefinition* pPart, const A3DMiscCascadedAttributes* pFatherAttr) { PrintLogMessage("Part definition level\n"); A3DMiscCascadedAttributes* pAttr; A3DMiscCascadedAttributesData sAttrData; CHECK_RET(stCreateAndPushCascadedAttributes(pPart, pFatherAttr, &pAttr, &sAttrData)); const MiscCascadedAttributesGuard sMCAttrGuard(pAttr); A3DAsmPartDefinitionData sPartData; A3D_INITIALIZE_DATA(A3DAsmPartDefinitionData, sPartData); CHECK_RET(A3DAsmPartDefinitionGet(pPart, &sPartData)); const DATAGUARD(A3DAsmPartDefinition) sGuard(sPartData, A3DAsmPartDefinitionGet); for (unsigned int ui = 0; ui < sPartData.m_uiRepItemsSize; ++ui) CHECK_RET(stParseRepresentationItem(sPartData.m_ppRepItems[ui], pAttr)); return A3D_SUCCESS; } //###################################################################################################################### /*! Returns a part definition from a product occurrence. Part definition is returned as * the out parameter ppPart. */ static A3DStatus stProductOccurrenceGetPart( const A3DAsmProductOccurrenceData* psPOccData, A3DAsmPartDefinition** ppPart) { if(psPOccData == NULL) return A3D_ERROR; *ppPart = NULL; if(psPOccData->m_pPart != NULL) { *ppPart = psPOccData->m_pPart; return A3D_SUCCESS; } A3DAsmProductOccurrence* pProductPrototype = psPOccData->m_pPrototype; while(pProductPrototype != NULL) { A3DAsmProductOccurrenceData sProductPrototypeData; A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sProductPrototypeData); CHECK_RET(A3DAsmProductOccurrenceGet(pProductPrototype, &sProductPrototypeData)); const DATAGUARD(A3DAsmProductOccurrence) sGuard(sProductPrototypeData, A3DAsmProductOccurrenceGet); if(sProductPrototypeData.m_pPart != NULL) { *ppPart = sProductPrototypeData.m_pPart; return A3D_SUCCESS; } else pProductPrototype = sProductPrototypeData.m_pPrototype; } return A3D_SUCCESS; } //###################################################################################################################### /*! Parses a product occurrence recursively. When a part * definition is found, it is then passed to stParsePartDefinition. */ static A3DStatus stParseProductOccurrence( const A3DAsmProductOccurrence* pOccurrence, const A3DMiscCascadedAttributes* pFatherAttr) { PrintLogMessage("Product Occurrence level\n"); A3DMiscCascadedAttributes* pAttr; A3DMiscCascadedAttributesData sAttrData; CHECK_RET(stCreateAndPushCascadedAttributes(pOccurrence, pFatherAttr, &pAttr, &sAttrData)); const MiscCascadedAttributesGuard sMCAttrGuard(pAttr); A3DAsmProductOccurrenceData sData; A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sData); CHECK_RET(A3DAsmProductOccurrenceGet(pOccurrence, &sData)); const DATAGUARD(A3DAsmProductOccurrence) sGuard(sData, A3DAsmProductOccurrenceGet); A3DAsmPartDefinition* pPart = NULL; TEST_RET(stProductOccurrenceGetPart(&sData, &pPart)); if (pPart) CHECK_RET(stParsePartDefinition(pPart, pAttr)); if (sData.m_uiPOccurrencesSize > 0) { for (unsigned int ui = 0; ui < sData.m_uiPOccurrencesSize; ui++) { CHECK_RET(stParseProductOccurrence(sData.m_ppPOccurrences[ui], pAttr)); } } return A3D_SUCCESS; } //###################################################################################################################### /*! Calls stParseProductOccurrence for each product occurrence in the input parameter pModelFile. */ A3DStatus stParseCascadedAttributes(const A3DAsmModelFile* pModelFile) { // allocate model file structure A3DAsmModelFileData sData; A3D_INITIALIZE_DATA(A3DAsmModelFileData, sData); CHECK_RET(A3DAsmModelFileGet(pModelFile, &sData)); const DATAGUARD(A3DAsmModelFile) sGuard(sData, A3DAsmModelFileGet); // allocate cascaded attributes A3DMiscCascadedAttributes* pAttr; CHECK_RET(A3DMiscCascadedAttributesCreate(&pAttr)); const MiscCascadedAttributesGuard sMCAttrGuard(pAttr); for (A3DUns32 ui = 0; ui < sData.m_uiPOccurrencesSize; ++ui) // traverse the model tree CHECK_RET(stParseProductOccurrence(sData.m_ppPOccurrences[ui], pAttr)); return A3D_SUCCESS; } static MY_CHAR acSrcFileName[_MAX_PATH * 2]; static MY_CHAR acLogFileName[_MAX_PATH * 2]; //###################################################################################################################### // Main function #ifdef _MSC_VER int wmain(A3DInt32 iArgc, A3DUniChar** ppcArgv) #else int main(A3DInt32 iArgc, A3DUTF8Char** ppcArgv) #endif { // // ### COMMAND LINE ARGUMENTS // if (iArgc > 3) { MY_PRINTF2("Usage:\n %s [input CAD file] [output LOG file]\n", ppcArgv[0]); MY_PRINTF(" Default output LOG file is [input CAD file]_Log.txt\n\n"); return A3D_ERROR; } if (iArgc > 1) MY_STRCPY(acSrcFileName, ppcArgv[1]); else MY_STRCPY(acSrcFileName, DEFAULT_INPUT_CAD); if (iArgc > 2) MY_STRCPY(acLogFileName, ppcArgv[2]); else MY_SPRINTF(acLogFileName, "%s_Log.txt", acSrcFileName); GetLogFile(acLogFileName); // Initialize log file // // ### INITIALIZE HOOPS EXCHANGE // A3DSDKHOOPSExchangeLoader sHoopsExchangeLoader(_T(HOOPS_BINARY_DIRECTORY)); CHECK_RET(sHoopsExchangeLoader.m_eSDKStatus); CHECK_RET(A3DDllSetCallbacksMemory(CheckMalloc, CheckFree)); CHECK_RET(A3DDllSetCallbacksReport(PrintLogMessage, PrintLogWarning, PrintLogError)); // // ### PROCESS SAMPLE CODE // // Initialize importer A3DImport sImport(acSrcFileName); // see A3DSDKInternalConvert.hxx for import and export detailed parameters A3DStatus iRet = sHoopsExchangeLoader.Import(sImport); if (iRet != A3D_SUCCESS && iRet != A3D_LOAD_MISSING_COMPONENTS) CHECK_RET(iRet); // Parse model for cascaded attributes CHECK_RET(stParseCascadedAttributes(sHoopsExchangeLoader.m_psModelFile)); // // ### TERMINATE HOOPS EXCHANGE // // Check memory allocations // Check memory allocations return (int)ListLeaks(); }