/////////////////////////////////////////////////////////////////////////////// // 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_IfcLayerAssignment.h" #include "OdPlatformSettings.h" #include "RxVariantValue.h" #include "IfcHostAppServices.h" #include "IfcGsManager.h" #include "IfcGiContext.h" #include "Entities/IfcPresentationLayerAssignment.h" #include "ColorMapping.h" #include "Gi/GiRasterImage.h" #include "Gs/Gs.h" #include "RxRasterServices.h" #include "AbstractViewPE.h" using namespace OdIfc; // params [input file] [output_dir] [products] IfcLayerAssignmentTutorial::IfcLayerAssignmentTutorial(const OdString& applicationName) : BaseIfcTutorial(applicationName) { m_tutorialArgsParser. add_param( std::make_shared>(m_ifcInputFileName, "inputFile", "full path to the input .ifc file.", false)); m_tutorialArgsParser. add_param( std::make_shared>(m_outputFilesFolder, "outputDir", "full path to the output .ifc folder.", false)); m_tutorialArgsParser. add_param( std::make_shared>(m_ifcProductItems, "products", "products that should be present in the layer of output file.", false)); m_noWait = false; m_tutorialArgsParser .add_param( std::make_shared(m_noWait, "-NoWait", "disable \"press any key\" on finish.")); // ExIfcTutorials.exe Number_Of_tutorial inputFile=C:\path\to_input_file.ifc outputDir=C:\path\to\dest_dir products=5868 products=5972 } int IfcLayerAssignmentTutorial::run(const MyServices& svcs, const std::vector& argv, std::ostream& resultStream) { auto parseResult = BaseIfcTutorial::run(svcs, argv, resultStream); if (parseResult != 0) { return parseResult; } // Return value for main int nRes = 0; if (m_ifcProductItems.size() == 0) { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: Error: %ls\n\n"), OdString("You should put layers items handles for new layer assignment").c_str()); nRes = -1; return nRes; } OdString sPath; bool isWin = true; #ifdef ODA_WINDOWS int slashPos = m_outputFilesFolder.reverseFind(L'\\') + 1; #else int slashPos = m_outputFilesFolder.reverseFind(L'/') + 1; isWin = false; #endif if (slashPos == m_outputFilesFolder.getLength()) { sPath = m_outputFilesFolder.mid(0, slashPos); } else { sPath = m_outputFilesFolder + (isWin ? "\\" : "/"); } //Uninitialize to initialize with geometry calculation enabled odIfcUninitialize(); /**********************************************************************/ /* Initialize IfcCore */ /**********************************************************************/ odIfcInitialize(false /* No CDA */, true /* Geometry calculation needed */); try { OdIfcFilePtr pIfcFile = svcs.createDatabase(); OdResult res = pIfcFile->readFile(m_ifcInputFileName); if (res == eOk) { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: reading file %s is successful.\n"), OdString(m_ifcInputFileName).c_str()); } else { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: reading file %s is failed.\n"), OdString(m_ifcInputFileName).c_str()); handleNoWait(); nRes = -1; return nRes; } /********************************************************************/ /* Retrieve model from IFC file */ /********************************************************************/ OdIfcModelPtr pModel = pIfcFile->getModel(sdaiRW); OdIfcPresentationLayerAssignmentPtr layerAssignment = OdIfc::OdIfcPresentationLayerAssignment::createObject(pIfcFile); OdDAIObjectIds layerProducts; for (auto& handle : m_ifcProductItems) { odPrintConsoleString(OD_T("\nProduct: %s"), OdString(std::to_string(handle).c_str()).c_str()); OdDAIObjectId productToAppend = pModel->getEntityInstance(handle); if (OdDAI::ApplicationInstancePtr pInstance = productToAppend.openObject()) { if (pInstance->isKindOf("ifcproduct")) { layerProducts.append(productToAppend); } else { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: Entity %s is not ifcproduct.\n"), OdString(std::to_string(handle).c_str()).c_str()); } } else { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: Entity %s is not valid.\n"), OdString(std::to_string(handle).c_str()).c_str()); } // avoid representation items sharing between layer assignments OdDAIObjectIds assignedLayers = OdIfc::Utils::getPresentationLayers(productToAppend); for (const auto& alreadyExistedLayer : assignedLayers) { pIfcFile->composeEntitiesbyIds(OdDAIObjectIds{ alreadyExistedLayer }); OdIfcPresentationLayerAssignmentPtr pLayerAssignment = (OdIfcInstance::asCompound(alreadyExistedLayer.openObject())); if (pLayerAssignment) { OdDAIObjectIds layerRepresentations = pLayerAssignment->getAssignedItems(); auto productRepresentations = OdIfc::Utils::getProductsRepresentations(OdDAIObjectIds{ productToAppend }); for (const auto & reprItem : productRepresentations) { if (layerRepresentations.contains(reprItem)) { layerRepresentations.remove(reprItem); } } pLayerAssignment->setLayerItems(layerRepresentations); } } } // set layer assignments parameters layerAssignment->setLayerName("NEW-LAYER"); layerAssignment->setLayerProducts(layerProducts); OdDbHandle layerId = OdDAIObjectId(layerAssignment->id()).getHandle(); odPrintConsoleString(OD_T("\nIfcLayer2BmpTutorial: New layer assignment %s was added.\n"), OdString(std::to_string(layerId).c_str()).c_str()); res = pIfcFile->writeFile(sPath + "output.ifc"); if (res == eOk) { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: writing result file %s is successful.\n"), OdString(sPath + "output.ifc").c_str()); OdString cmdString("ExIfcTutorials IfcLayer2BmpTutorial inputFile=" + sPath + "output.ifc outputDir=" + m_outputFilesFolder + " layers=" + std::to_string(layerId).c_str()); odPrintConsoleString(OD_T("\nTo render new layer assignment, run: %s\n"), cmdString.c_str()); } else { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: writing file %s is failed.\n"), OdString(sPath + "output.ifc").c_str()); handleNoWait(); nRes = -1; return nRes; } } catch (OdError& e) { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: Error: %ls"), e.description().c_str()); nRes = -1; } catch (...) { odPrintConsoleString(OD_T("\nIfcLayerAssignmentTutorial: Unexpected error.")); nRes = -1; } odIfcUninitialize(); return nRes; } void IfcLayerAssignmentTutorial::handleNoWait() { if (m_noWait == false) { odPrintConsoleString(OD_T("\nPress any key to finish...")); (void)getchar(); } }