/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// /************************************************************************/ /* This console application make dump of a IFC4 file */ /* */ /* Calling sequence: */ /* */ /* ExIfc4SpatialStructureDump []*/ /* */ /************************************************************************/ #include "ExIfc4SpatialStructureDump.h" #include "daiHeaderSection.h" #include "IfcExamplesCommon.h" #include "ExIfcHostAppServices.h" #include "RxDynamicModule.h" #include "DynamicLinker.h" #include "OdDbStub.h" #include #include "Ifc4/Ifc4Entities.h" #include "Common/examples/daiSimpleProgramOptions.h" #include "Common/examples/daiErrorEventListOutput.h" #define STL_USING_SET #define STL_USING_MAP #define STL_USING_IOSTREAM #include "OdaSTL.h" #define STD(a) std:: a const OdString preIndent = "| "; std::wofstream outFile; static void customAssertFunc(const char* expr, const char* fileName, int nLine) { printf( "Assertion has occurs:\n" " Expression: %s\n" " Filename: %s\n" " Line number: %d\n", expr, fileName, nLine); } #ifndef _TOOLKIT_IN_DLL_ using namespace OdIfc; \ ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdSDAIModule); \ ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfcCoreModule); \ ODRX_DECLARE_STATIC_MODULE_ENTRY_POINT(OdIfc4Module); \ ODRX_BEGIN_STATIC_MODULE_MAP() \ ODRX_DEFINE_STATIC_APPMODULE(OdSDAIModuleName, OdSDAIModule) \ ODRX_DEFINE_STATIC_APPMODULE(OdIfcCoreModuleName, OdIfcCoreModule) \ ODRX_DEFINE_STATIC_APPMODULE(OdIfc4ModuleName, OdIfc4Module) \ ODRX_END_STATIC_MODULE_MAP() #endif int nRes = EXIT_SUCCESS; // Return value for main void printString(const OdString& str) { odPrintConsoleString(str); if (outFile.is_open()) outFile << str.c_str(); } OdString getObject(const OdDAIObjectId& obj) { if (!obj) return OdString(OD_T("$")); OdString str = OdString().format(OD_T("#%lu"), (OdUInt64)obj->getHandle()); return str; } OdString getObjectsCollection(const OdDAIObjectIds& objects) { OdString str; for (const auto& it : objects) { str += OdString().format(OD_T("#%lu"), (OdUInt64)it.getHandle()); if (&it != &objects.last()) str += L","; } return str; } OdString getStringAttr(const OdAnsiString& attr) { if (OdDAI::Utils::isUnset(attr)) return OdString(OD_T("$")); OdString str; str.format(OD_T("\'%s\'"), OdString(attr).c_str()); return str; } void printIfcProduct(OdIfc4::IfcProduct* pInst, OdUInt64 handle, int indent) { OdString strData; for (int i = 0; i < indent; ++i) strData += preIndent; strData += OdString().format(OD_T("#%lu= %s(%s,%s,%s,%s,%s,%s,%s);\n"), handle, OdString(pInst->typeName().mid(0).makeUpper()).c_str(), getStringAttr(pInst->getGlobalId().c_str()).c_str(), getObject(pInst->getOwnerHistory()).c_str(), getStringAttr(pInst->getName()).c_str(), getStringAttr(pInst->getDescription()).c_str(), getStringAttr(pInst->getObjectType()).c_str(), getObject(pInst->getObjectPlacement()).c_str(), getObject(pInst->getRepresentation()).c_str()); printString(strData); } void printIfcProject(OdIfc4::IfcProject* pInst, OdUInt64 handle, int indent) { OdDAIObjectIds representationContexts; pInst->getRepresentationContexts(representationContexts); OdString strData; for (int i = 0; i < indent; ++i) strData += preIndent; strData += OdString().format(OD_T("#%lu= %s(%s,%s,%s,%s,%s,%s,%s,(%s),%s);\n"), handle, OdString(pInst->typeName().mid(0).makeUpper()).c_str(), getStringAttr(pInst->getGlobalId().c_str()).c_str(), getObject(pInst->getOwnerHistory()).c_str(), getStringAttr(pInst->getName()).c_str(), getStringAttr(pInst->getDescription()).c_str(), getStringAttr(pInst->getObjectType()).c_str(), getStringAttr(pInst->getLongName()).c_str(), getStringAttr(pInst->getPhase()).c_str(), getObjectsCollection(representationContexts).c_str(), getObject(pInst->getUnitsInContext()).c_str()); printString(strData); } void printIfcRelAggregatesData(OdIfc4::IfcRelAggregates* pInst, OdUInt64 handle, int indent) { OdDAIObjectIds relatedObjects; pInst->getRelatedObjects(relatedObjects); OdString strData; for (int i = 0; i < indent; ++i) strData += preIndent; strData += OdString().format(OD_T("#%lu= %s(%s,%s,%s,%s,%s,(%s));\n"), handle, OdString(pInst->typeName().mid(0).makeUpper()).c_str(), getStringAttr(pInst->getGlobalId().c_str()).c_str(), getObject(pInst->getOwnerHistory()).c_str(), getStringAttr(pInst->getName()).c_str(), getStringAttr(pInst->getDescription()).c_str(), getObject(pInst->getRelatingObject()).c_str(), getObjectsCollection(relatedObjects).c_str()); printString(strData); } void printIfcRelContainedInSpatialStructureData(OdIfc4::IfcRelContainedInSpatialStructure* pInst, OdUInt64 handle, int indent) { OdDAIObjectIds relatedObjects; pInst->getRelatedElements(relatedObjects); OdString strData; for (int i = 0; i < indent; ++i) strData += preIndent; strData += OdString().format(OD_T("#%lu= %s(%s,%s,%s,%s,(%s),%s);\n"), handle, OdString(pInst->typeName().mid(0).makeUpper()).c_str(), getStringAttr(pInst->getGlobalId().c_str()).c_str(), getObject(pInst->getOwnerHistory()).c_str(), getStringAttr(pInst->getName()).c_str(), getStringAttr(pInst->getDescription()).c_str(), getObjectsCollection(relatedObjects).c_str(), getObject(pInst->getRelatingStructure()).c_str()); printString(strData); } void printObjectData(OdIfcModel* pModel, OdDAIObjectId obj, int indent) { OdDAI::ApplicationInstancePtr pInst = obj.getNested(); OdDbHandle handle = obj.getHandle(); OdIfc4::IfcProductPtr ifcProduct = OdIfc4::IfcProduct::cast(pInst); if (!ifcProduct.isNull()) printIfcProduct(ifcProduct, handle, indent++); else { OdIfc4::IfcProjectPtr ifcProject = OdIfc4::IfcProject::cast(pInst); if (!ifcProject.isNull()) printIfcProject(ifcProject, handle, indent++); else { printString(OD_T("Reading data damper error\n")); nRes = EXIT_FAILURE; } } bool isFindRelAggregates = false; const OdDAI::SetOfOdDAIObjectId* entityExtent = pModel->getEntityExtent("IFCRELAGGREGATES"); auto it = entityExtent->createConstIterator(); for (it->beginning(); it->next();) { it->getCurrentMember() >> obj; pInst = obj.getNested(); OdIfc4::IfcRelAggregatesPtr rel = OdIfc4::IfcRelAggregates::cast(pInst); if (rel.isNull()) continue; if (rel->getRelatingObject()->getHandle() != OdUInt64(handle)) continue; printIfcRelAggregatesData(rel, obj.getHandle(), indent++); isFindRelAggregates = true; OdDAIObjectIds relatedObjects; rel->getRelatedObjects(relatedObjects); for (const auto& it : relatedObjects) printObjectData(pModel, pModel->getEntityInstance(it.getHandle()), indent); } if (!isFindRelAggregates) { entityExtent = pModel->getEntityExtent("IFCRELCONTAINEDINSPATIALSTRUCTURE"); auto it = entityExtent->createConstIterator(); for (it->beginning(); it->next();) { it->getCurrentMember() >> obj; pInst = obj.getNested(); OdIfc4::IfcRelContainedInSpatialStructurePtr rel = OdIfc4::IfcRelContainedInSpatialStructure::cast(pInst); if (rel.isNull()) continue; if (rel->getRelatingStructure().getHandle() != handle) continue; printIfcRelContainedInSpatialStructureData(rel, obj.getHandle(), indent++); OdDAIObjectIds relatedObjects; rel->getRelatedElements(relatedObjects); for (const auto& it : relatedObjects) { printObjectData(pModel, pModel->getEntityInstance(it.getHandle()), indent); } } } } void printEntityExtentData(OdIfcModel* pModel, const OdDAI::SetOfOdDAIObjectId* entityExtent, int indent) { OdDAIObjectId obj; for (auto it = entityExtent->createConstIterator(); it->next();) { it->getCurrentMember() >> obj; printObjectData(pModel, obj, indent); } } void DumpFile(OdIfcHostAppServices* pHostApp, const OdString& fileName) { // // Dump file // try { OdIfcFilePtr pIfcFile = pHostApp->readFile(fileName); if (pIfcFile.isNull()) { printString(OD_T("File open error: OdIfcFile wasn't created)\n")); nRes = EXIT_FAILURE; return; } OdIfcModelPtr pModel = pIfcFile->getModel(sdaiRO); if (!pModel.isNull()) { const OdDAI::SetOfOdDAIObjectId* entityExtent = pModel->getEntityExtent("IFCPROJECT"); printEntityExtentData(pModel, entityExtent, 0); } } catch (...) { nRes = EXIT_FAILURE; odPrintConsoleString(OD_T("Exception in file '%s'\n"), fileName.c_str()); } } void PrintExecutionStatus() { const OdChar* resultStatus = (nRes == EXIT_SUCCESS) ? L"Success" : L"Failure"; odPrintConsoleString(L"\nExecution status: %ls.", resultStatus); } #if defined(OD_USE_WMAIN) int wmain(int argc, wchar_t* argv[]) #else int main(int argc, char* argv[]) #endif { atexit(PrintExecutionStatus); ::odSetAssertFunc(customAssertFunc); /**********************************************************************/ /* Create a Services object */ /**********************************************************************/ OdStaticRxObject svcs; /**********************************************************************/ /* Display the Product and Version that created the executable */ /**********************************************************************/ odPrintConsoleString(OD_T("\nExIfc4SpatialStructureDump developed using %ls ver %ls\n"), svcs.product().c_str(), svcs.versionString().c_str()); OdString ifcInFileName; OdString dumpOutFileName; bool noProgress = false; using namespace OdDAI::utils; argv_parser commandLineParser(OD_T("ExIfc4SpatialStructureDump"), false); commandLineParser.add_param(std::make_shared>(ifcInFileName, "-inFile", "input .ifc or .ifczip file.", false)); commandLineParser.add_param(std::make_shared>(dumpOutFileName, "-outFile", "output dump file.")); commandLineParser.add_param(std::make_shared(noProgress, "-noProgress", "Disable progress meter output.")); std::vector argumentList(argv + 1, argv + argc); std::stringstream executionStream; if (commandLineParser.parse(argumentList, executionStream) != OdDAI::utils::ParseResult::succeed) { odPrintConsoleString(OD_T("\nExIfc4SpatialStructureDump sample program. Copyright (c) 2025, Open Design Alliance\n")); odPrintConsoleString(OdString(executionStream.str().c_str())); return ::Utils::res_INVALID_ARGUMENTS.first; } if (noProgress) { svcs.disableProgressMeterOutput(true); } if (!dumpOutFileName.isEmpty()) outFile.open(OdAnsiString(dumpOutFileName).c_str()); #ifndef _TOOLKIT_IN_DLL_ ODRX_INIT_STATIC_MODULE_MAP(); #endif /**********************************************************************/ /* Initialize Runtime Extension environment */ /**********************************************************************/ odrxInitialize(&svcs); /**********************************************************************/ /* Initialize IfcCore */ /**********************************************************************/ odIfcInitialize(false /* No CDA */, false /* No geometry calculation needed */); try { DumpFile(&svcs, ifcInFileName); } catch (...) { nRes = EXIT_FAILURE; ODA_ASSERT(0); } /**********************************************************************/ /* Uninitialize IfcCore */ /**********************************************************************/ odIfcUninitialize(); /**********************************************************************/ /* Uninitialize Runtime Extension environment */ /**********************************************************************/ ::odrxUninitialize(); return nRes; }