/////////////////////////////////////////////////////////////////////////////// // 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 "OdaCommon.h" #include "OdPerfTimer.h" #include "ExIfcTutorial_ModelOpsCombine.h" #include "daiApplicationInstance.h" #include "IfcModelOpsFiller.h" #include "IfcModelProcessor.h" // combine models with different merge levels to the one new output file // params [output_file] [source_file_1] ... [source_file_N] // source_files: 1 2 3 // 1st step : 1 -> 3 // 2nd step : 2 -> [1 + 3] // result : [1 + 2 + 3] -> output_file Tutorial_ModelOpsCombine::Tutorial_ModelOpsCombine(const OdString& applicationName) : BaseIfcTutorial(applicationName) { m_tutorialArgsParser .add_param( std::make_shared>(m_ifcOutputFile, "outputFile", ".ifc file that will be created for new combined model", false)); m_tutorialArgsParser .add_param( std::make_shared>(m_ifcSourceFiles, "sourceFiles", "the list of source entities files [ at least 2 items ], the last one is target for merge", false)); m_tutorialArgsParser .add_param( std::make_shared>(m_mergeLevelString, "mergeLevel", "level of entities processing < site | building | storey >)", false)); m_tutorialArgsParser .add_param( std::make_shared(m_noWait, "-NoWait", "disable \"press any key\" on finish.")); //ExIfcTutorials.exe Number_Of_tutorial outputFile=C:\path\to\output_file.ifc mergeLevel=building sourceFiles=C:\path\to\source_file_1.ifc sourceFiles=C:\path\to\source_file_2.ifc } int Tutorial_ModelOpsCombine::run(const MyServices& svcs, const std::vector& argumentList, std::ostream& resultStream) { auto parseResult = BaseIfcTutorial::run(svcs, argumentList, resultStream); if (parseResult != 0) { return parseResult; } if (m_ifcSourceFiles.size() < 2) { odPrintConsoleString(OD_T("\nInvalid arguments. Specify at least 2 source files. Press any key to finish...\n")); if (m_noWait == false) { getchar(); } return -1; } if (m_mergeLevelString.iCompare(OD_T("site")) == 0) { m_mergeLevel = OdIfc::ModelOps::MergeLevel::Site; } else if (m_mergeLevelString.iCompare(OD_T("building")) == 0) { m_mergeLevel = OdIfc::ModelOps::MergeLevel::Building; } else if (m_mergeLevelString.iCompare(OD_T("storey")) == 0) { m_mergeLevel = OdIfc::ModelOps::MergeLevel::Storey; } else { m_mergeLevel = OdIfc::ModelOps::MergeLevel::Building; } OdPerfTimerWrapper timerWrapper; timerWrapper.getTimer()->start(); // the last model in the source sequence become target OdIfcFilePtr pDestinationFile = svcs.createDatabase(); OdString stepDestinationFile = m_ifcSourceFiles[m_ifcSourceFiles.size() - 1]; OdResult res = pDestinationFile->readFile(stepDestinationFile); stepDestinationFile = pDestinationFile->getShortFileName(); if (res == eOk) { odPrintConsoleString(OD_T("\nFile %ls opened successfully.\n"), OdString(stepDestinationFile).c_str()); odPrintConsoleString(OD_T("\nOpening time: %d msec\n"), timerWrapper.getTimer()->countedMSec()); } else { odPrintConsoleString(OD_T("\nFile %ls had open error. Press any key to finish...\n"), OdString(stepDestinationFile).c_str()); if (m_noWait == false) { getchar(); } return res; } OdIfcModelPtr pTargetModel = pDestinationFile->getModel(sdaiRW); if (pTargetModel.isNull()) { odPrintConsoleString(OD_T("\nDestination model is not valid. Press any key to finish...\n")); if (m_noWait == false) { getchar(); } return -1; } // merge one source file per step to the target model which is extended with new entities for (size_t stepCounter = 0; stepCounter < m_ifcSourceFiles.size() - 1; ++stepCounter) { timerWrapper.getTimer()->start(); OdIfcFilePtr pSourceFile = svcs.createDatabase(); OdResult res = pSourceFile->readFile(m_ifcSourceFiles[stepCounter]); timerWrapper.getTimer()->stop(); if (res == eOk) { odPrintConsoleString(OD_T("\nSource file %ls opened successfully.\n"), OdString(m_ifcSourceFiles[stepCounter]).c_str()); odPrintConsoleString(OD_T("\nOpening time: %d msec\n"), timerWrapper.getTimer()->countedMSec()); } else { odPrintConsoleString(OD_T("\nFile %ls had open error. Press any key to finish..."), OdString(m_ifcSourceFiles[stepCounter]).c_str()); if (m_noWait == false) { getchar(); } return res; } OdIfcModelPtr pSourceModel = pSourceFile->getModel(sdaiRW); timerWrapper.getTimer()->start(); OdIfc::ModelOps::IfcModelProcessor modelProcessor(pTargetModel); odPrintConsoleString(OD_T("\nMerging from %ls to [ %ls ] ...\n"), OdString(pSourceFile->getShortFileName()).c_str(), OdString(stepDestinationFile).c_str()); modelProcessor.ifcCombineWith(pSourceModel, m_mergeLevel); timerWrapper.getTimer()->stop(); odPrintConsoleString(OD_T("\nProcessing time: %d msec\n"), timerWrapper.getTimer()->countedMSec()); stepDestinationFile.insert(0, " + "); stepDestinationFile.insert(0, pSourceFile->getShortFileName()); } try { pDestinationFile->writeFile(m_ifcOutputFile); } catch (...) { return -1; } odPrintConsoleString(OD_T("\n\nProcess finished\n")); return 0; }