/////////////////////////////////////////////////////////////////////////////// // 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 "ExIfcTutorial_ModelOpsSite.h" #include "daiApplicationInstance.h" #include "IfcModelOps.h" #include "IfcModelOpsFiller.h" #include "IfcModelProcessor.h" // try to append ifcbuildings to one output file // params [output_file] [source_file_1] [source_location_1] ... [source_file_N] [source_location_N] Tutorial_ModelOpsSite::Tutorial_ModelOpsSite(const OdString& applicationName) : BaseIfcTutorial(applicationName) { m_tutorialArgsParser .add_param( std::make_shared>(m_ifcDestFile, "outputFile", ".ifc file where we should insert IFC entities", false)); m_tutorialArgsParser .add_param( std::make_shared>(m_ifcSourceFiles, "sourceFiles", "the list of source entities files", false)); m_tutorialArgsParser .add_param( std::make_shared>(m_ifcDestPositions, "destPoints", "the list of points in destination model units", 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\dest_file.ifc sourceFiles=C:\path\to\source_file_1.ifc destPoints=-10.0,-10.0,-10.0 // sourceFiles=C:\path\to\source_file_2.ifc destPoints=20.0,20.0,20.0 } int Tutorial_ModelOpsSite::run(const MyServices& svcs, const std::vector& argumentList, std::ostream& resultStream) { auto parseResult = BaseIfcTutorial::run(svcs, argumentList, resultStream); if (parseResult != 0) { return parseResult; } OdIfcFilePtr pDestinationFile = svcs.createDatabase(); OdResult res = pDestinationFile->readFile(m_ifcDestFile); if (res == eOk) { odPrintConsoleString(OD_T("\nFile %ls opened successfully.\n"), OdString(m_ifcDestFile).c_str()); } else { odPrintConsoleString(OD_T("\nFile open error. Press any key to finish...")); if (m_noWait == false) { getchar(); } return res; } odPrintConsoleString(OD_T("\nAccessing target model...\n")); 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; } if (m_ifcSourceFiles.size() != m_ifcDestPositions.size()) { odPrintConsoleString(OD_T("\nInvalid arguments. Press any key to finish...\n")); if (m_noWait == false) { getchar(); } return -1; } for (auto& destString : m_ifcDestPositions) { OdArray doubleArray; unsigned int dimSize = 0; while (destString.find(OdChar(',')) != -1 && dimSize <= 3) { doubleArray.push_back(::atof(destString.left(destString.find(OdChar(','))))); destString.deleteChars(0, destString.find(OdChar(',')) + 1); dimSize++; } if (dimSize < 3 && !destString.isEmpty()) { doubleArray.push_back(::atof(destString)); destString.deleteChars(0, destString.getLength()); dimSize++; } if (dimSize == 2 && destString.isEmpty()) { doubleArray.push_back(0.0); } else if (dimSize < 2) { odPrintConsoleString(OD_T("\nInvalid position values. Press any key to finish...\n")); return -1; } OdGePoint3d point(doubleArray[0], doubleArray[1], doubleArray[2]); m_ifcDestPoints.push_back(point); } int stepCounter = 0; for (auto sourceFile : m_ifcSourceFiles) { OdIfcFilePtr pSourceFile = svcs.createDatabase(); OdResult res = pSourceFile->readFile(sourceFile); if (res == eOk) { odPrintConsoleString(OD_T("\nSource file %ls opened successfully.\n"), OdString(sourceFile).c_str()); } else { odPrintConsoleString(OD_T("\nFile open error. Press any key to finish...")); if (m_noWait == false) { getchar(); } return res; } odPrintConsoleString(OD_T("\nRetrieving source model information from %ls...\n"), OdString(sourceFile).c_str()); OdIfcModelPtr pSourceModel = pSourceFile->getModel(sdaiRW); OdIfc::ModelOps::IfcModelProcessor modelProcessor(pTargetModel); modelProcessor.setTargetOffset(m_ifcDestPoints[stepCounter++]); odPrintConsoleString(OD_T("\nMerging from %ls to %ls...\n"), OdString(sourceFile).c_str(), OdString(m_ifcDestFile).c_str()); OdDAIObjectId clonedItem = modelProcessor.ifcCombineWith(pSourceModel, OdIfc::ModelOps::MergeLevel::Site); try { pDestinationFile->writeFile(m_ifcDestFile); } catch (...) { return -1; } // update destination file and model if (stepCounter < m_ifcSourceFiles.size()) { pDestinationFile = svcs.createDatabase(); OdResult res = pDestinationFile->readFile(m_ifcDestFile); if (res == eOk) { odPrintConsoleString(OD_T("\nFile %ls opened successfully.\n"), OdString(m_ifcDestFile).c_str()); } else { odPrintConsoleString(OD_T("\nFile open error. Press any key to finish...")); if (m_noWait == false) { getchar(); } return res; } // updated target model pTargetModel = pDestinationFile->getModel(sdaiRW); odPrintConsoleString(OD_T("\nTarget model from %ls reopened successfully.\n"), OdString(m_ifcDestFile).c_str()); } } odPrintConsoleString(OD_T("\n\nProcess finished\n")); return 0; }