/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// #include #include "OdaCommon.h" #include "ExIfcTutorial_Ifc2MulObj.h" #include "ProjectSetup.h" #include "OdPlatformSettings.h" #include "ExSystemServices.h" #include "ExPrintConsole.h" #include "IfcCore.h" #include "IfcHostAppServices.h" #include "StaticRxObject.h" #ifdef OBJTOOLKIT_ENABLED #include "OBJToolkit.h" #endif using namespace OdIfc; Ifc2MulObjTutorial::Ifc2MulObjTutorial(const OdString& applicationName) : BaseIfcTutorial(applicationName) { m_tutorialArgsParser. add_param( std::make_shared>(m_ifcInputFileName, "input filename", "full path to the input .ifc file.")); m_tutorialArgsParser. add_param( std::make_shared>(m_objOutputFolder, "output folder", "full path to the folder for output .obj files.")); m_tutorialArgsParser. add_param( std::make_shared>(m_ifcType, "type", "optional parameter specifying instance typename.", true)); m_noWait = false; m_tutorialArgsParser .add_param( std::make_shared(m_noWait, "-NoWait", "disable \"press any key\" on finish.")); } #ifdef OBJTOOLKIT_ENABLED int Ifc2MulObjTutorial::run(const MyServices& svcs, const std::vector& argv, std::ostream& resultStream) { auto parseResult = BaseIfcTutorial::run(svcs, argv, resultStream); if (parseResult != 0) { return parseResult; } /**********************************************************************/ /* Load OBJ Toolkit module */ /**********************************************************************/ OBJToolkit::OdObjToolkitModulePtr pObjModule = odrxDynamicLinker()->loadApp(OdObjToolkitModuleName); if (pObjModule.isNull()) { odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: OBJToolkit module loading is failed.\n")); handleNoWait(); return -1; } odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: OBJToolkit module is successfully loaded.\n")); //Uninitialize to initialize with geometry calculation enabled odIfcUninitialize(); /**********************************************************************/ /* Initialize IfcCore */ /**********************************************************************/ odIfcInitialize(false /* No CDA */, true /* Geometry calculation needed */); // Return value for main int nRes = 0; try { OdIfcFilePtr pIfcFile = svcs.createDatabase(); OdResult res = pIfcFile->readFile(m_ifcInputFileName); if (res == eOk) { odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: reading file %s is successful.\n"), OdString(m_ifcInputFileName).c_str()); } else { odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: reading file %s is failed.\n"), OdString(m_ifcInputFileName).c_str()); handleNoWait(); return res; } /********************************************************************/ /* Get a representation context with geometric information */ /********************************************************************/ { OdDAIObjectIds contextsSelection = OdIfc::Utils::getDefaultRepresentationContextsSelection(pIfcFile, false); if (contextsSelection.isEmpty()) { contextsSelection = OdIfc::Utils::getAllRepresentationContexts(pIfcFile); } pIfcFile->setContextSelection(contextsSelection); odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: composing entities.\n")); pIfcFile->composeEntities(); } /********************************************************************/ /* Retrieve model from IFC file */ /********************************************************************/ OdIfcModelPtr pModel = pIfcFile->getModel(); /********************************************************************/ /* Retrieve all ifcproduct entities */ /********************************************************************/ const OdDAI::SetOfOdDAIObjectId* allIfcProducts = pModel->getEntityExtent("ifcproduct"); OdDAI::ConstIteratorPtr it = allIfcProducts->createConstIterator(); it->beginning(); OdUInt32 counter = 0; while (it->next()) { OdDAIObjectId id; it->getCurrentMember() >> id; OdDAI::ApplicationInstancePtr ifcInstance = id.openObject(); if (!ifcInstance.isNull()) { /****************************************************************/ /* Skip all instances of types different from specified type */ /****************************************************************/ const OdString typeName = ifcInstance->typeName(); if (!m_ifcType.isEmpty()) { if (typeName.find(m_ifcType) == -1) continue; } OdString fileName; fileName.format(OD_T("%sObject_%d.obj"), m_objOutputFolder.c_str(), counter); /****************************************************************/ /* Set options.m_bFillDb = true and fileName to be empty to */ /* export entity to run-time OBJ database */ /****************************************************************/ OBJToolkit::OdObjExportOptions options; options.m_applicationComment = OD_T("Export every IfcProduct into OBJ"); options.m_bFillDb = true; OdResult copyResult = pObjModule->exportObj(pIfcFile, ifcInstance, OD_T(""), &options); if (copyResult != eOk) { odPrintConsoleString(OdString(OD_T("\nIfc2MulObjTutorial: could not export IFC instance to run-time OBJ database."))); handleNoWait(); return copyResult; } OBJToolkit::OdObjDbPtr pObjDb = options.m_pObjDb; if (!pObjDb.isNull() && !pObjDb->isEmpty()) { /**************************************************************/ /* Copy texture files into output folder */ /**************************************************************/ OBJToolkit::OdMtlDbPtr pMtlDb = pObjDb->getMtlDb(); if (!pMtlDb.isNull() && pMtlDb->getMaterialsCount() > 0) { pObjModule->updateTexturesPaths(pMtlDb, pIfcFile, m_objOutputFolder, &options); } /**************************************************************/ /* Export converted database to OBJ file */ /**************************************************************/ OBJToolkit::OdObjExportPtr pObjExporter = OBJToolkit::createObjExporter(); pObjExporter->setObjDb(pObjDb); OdResult exportResult = pObjExporter->exportFile(fileName, options.m_applicationComment); if (exportResult != eOk) { odPrintConsoleString(OdString(OD_T("\nIfc2MulObjTutorial: export to ") + fileName + OdString(OD_T(" failed.")))); handleNoWait(); return exportResult; } else { odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: created ") + fileName); counter++; } } else { odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: this object of ") + typeName + OD_T(" type can't be exported to OBJ")); } } } /********************************************************************/ /* Unload the OBJ Toolkit module */ /********************************************************************/ pObjModule.release(); odrxDynamicLinker()->unloadModule(OdObjToolkitModuleName); } catch (OdError& e) { odPrintConsoleString(OD_T("\n\nIfc2MulObjTutorial: Error: %ls"), e.description().c_str()); nRes = -1; } catch (...) { odPrintConsoleString(OD_T("\n\nIfc2MulObjTutorial: Unexpected error.")); nRes = -1; } /**********************************************************************/ /* Uninitialize IfcCore */ /**********************************************************************/ odIfcUninitialize(); return nRes; } #else int Ifc2MulObjTutorial::run(const MyServices& svcs, const std::vector& argv, std::ostream& resultStream) { odPrintConsoleString(OD_T("\nIfc2MulObjTutorial: Components should be enabled for export into OBJ format.")); return -1; } #endif void Ifc2MulObjTutorial::handleNoWait() { if (m_noWait == false) { odPrintConsoleString(OD_T("\nPress any key to finish...")); (void)getchar(); } }