/////////////////////////////////////////////////////////////////////////////// // 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_IfcLayer2Bmp.h" #include "OdPlatformSettings.h" #include "RxVariantValue.h" #include "IfcHostAppServices.h" #include "IfcGsManager.h" #include "IfcGiContext.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] [layers] IfcLayer2BmpTutorial::IfcLayer2BmpTutorial(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_bmpOutputFilesFolder, "outputDir", "full path to the output .bmp folder.", false)); m_tutorialArgsParser. add_param( std::make_shared>(m_ifcLayers, "layers", "layer assignments that should be present in the 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 layers=6300 layers=6304 layers=6302 } int IfcLayer2BmpTutorial::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_ifcLayers.size() == 0) { odPrintConsoleString(OD_T("\n\nIfcLayer2BmpTutorial: Error: %ls\n\n"), OdString("You should put layers handles").c_str()); nRes = -1; return nRes; } //Uninitialize to initialize with geometry calculation enabled odIfcUninitialize(); /**********************************************************************/ /* Initialize IfcCore */ /**********************************************************************/ odIfcInitialize(false /* No CDA */, true /* Geometry calculation needed */); OdGsModulePtr pGsModule; OdString sPath; bool isWin = true; #ifdef ODA_WINDOWS int slashPos = m_bmpOutputFilesFolder.reverseFind(L'\\') + 1; #else int slashPos = m_bmpOutputFilesFolder.reverseFind(L'/') + 1; isWin = false; #endif if (slashPos == m_bmpOutputFilesFolder.getLength()) { sPath = m_bmpOutputFilesFolder.mid(0, slashPos); } else { sPath = m_bmpOutputFilesFolder + (isWin ? "\\" : "/"); } try { OdIfcFilePtr pIfcFile = svcs.createDatabase(); OdResult res = pIfcFile->readFile(m_ifcInputFileName); if (res == eOk) { odPrintConsoleString(OD_T("\nIfcLayer2BmpTutorial: reading file %s is successful.\n"), OdString(m_ifcInputFileName).c_str()); } else { odPrintConsoleString(OD_T("\nIfcLayer2BmpTutorial: reading file %s is failed.\n"), OdString(m_ifcInputFileName).c_str()); handleNoWait(); nRes = -1; } /********************************************************************/ /* Retrieve model from IFC file */ /********************************************************************/ OdIfcModelPtr pModel = pIfcFile->getModel(); OdDAIObjectIds presentationLayers; auto pExtent = pModel->getEntityExtent("ifcpresentationlayerassignment"); if (pExtent && pExtent->getMemberCount()) presentationLayers = pExtent->getArray(); if (nRes == 0 || presentationLayers.length()) { OdDAIObjectIds layersToDraw; for (auto layerHandle : m_ifcLayers) { odPrintConsoleString(OD_T("\nIfcLayer2BmpTutorial: Processing layer %s .\n"), OdString(std::to_string(layerHandle).c_str()).c_str()); if (OdDAIObjectId layerId = pModel->getEntityInstance(OdDbHandle(layerHandle))) { if (layerId.openObject()->isKindOf("ifcpresentationlayerassignment")) { layersToDraw.push_back(layerId); } else { odPrintConsoleString(OD_T("\nIfcLayer2BmpTutorial: Entity %s is not ifcpresentationlayerassignment.\n"), OdString(std::to_string(layerId.getHandle()).c_str()).c_str()); } } } /**********************************************************************/ /* Load GS module */ /**********************************************************************/ pGsModule = ::odrxDynamicLinker()->loadModule(OdWinBitmapModuleName); #ifdef _TOOLKIT_IN_DLL_ if (pGsModule.isNull()) { pGsModule = ::odrxDynamicLinker()->loadModule(OdWinGDIModuleName); } #endif if (pGsModule.isNull()) { odPrintConsoleString(OD_T("\nIfcLayer2BmpTutorial: GS module loading is failed.\n")); handleNoWait(); return -1; } odPrintConsoleString(OD_T("\nIfcLayer2BmpTutorial: GS module is successfully loaded.\n")); OdGsDevicePtr pBitmapDevice; if (pGsModule.get()) { pBitmapDevice = pGsModule->createBitmapDevice(); } if (pBitmapDevice.get()) { /********************************************************************/ /* 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("\nIfcLayer2BmpTutorial: composing entities.\n")); if (OdResult res = pIfcFile->composeEntities()) { if (res == eFileInternalErr) odPrintConsoleString(L"Geometry compose: internal file error!\n"); if (res == eNullPtr) odPrintConsoleString(L"Geometry compose: null model!\n"); if (res == eCreateFailed) odPrintConsoleString(L"Geometry compose: entity compose exception!\n"); else odPrintConsoleString(L"Geometry compose: unknown error!\n"); return res; } } OdGiContextForIfcDatabasePtr pIfcContext = OdGiContextForIfcDatabase::createObject(); pIfcContext->setDatabase(pIfcFile); pIfcContext->enableGsModel(true); OdGsDevicePtr pDevice = OdIfcGsManager::setupActiveLayoutViews(pBitmapDevice, pIfcContext); OdGsView* pView = pDevice->viewAt(0); OdRxRasterServicesPtr pRasSvcs = odrxDynamicLinker()->loadApp(RX_RASTER_SERVICES_APPNAME); ODA_ASSERT_ONCE(pRasSvcs.get()) if (pRasSvcs.isNull()) { throw OdError(eNotApplicable); } pView->setMode(OdGsView::kHiddenLine); pView->setView(OdGePoint3d(1, 1, 1), OdGePoint3d(0, 0, 0), OdGeVector3d::kZAxis, 1000, 1000); pIfcFile->setContextSelection(OdIfc::Utils::getDefaultRepresentationContextsSelection(pIfcFile, false)); const ODCOLORREF* palette = odcmAcadPalette(ODRGB(255, 255, 255)); OdArray > pPalCpy; ODCOLORREF background(ODRGB(192, 192, 192)); pDevice->setBackgroundColor(background); pIfcContext->setPaletteBackground(background); pPalCpy.insert(pPalCpy.begin(), palette, palette + 256); pDevice->setLogicalPalette(pPalCpy.asArrayPtr(), 256); OdGsDCRect screenRect(OdGsDCPoint(0, 768), OdGsDCPoint(1024, 0)); pDevice->onSize(screenRect); pDevice->properties()->putAt(OD_T("BitPerPixel"), OdRxVariantValue(OdUInt32(24))); OdAbstractViewPEPtr(pView)->zoomExtents(pView); for (auto activeLayer : layersToDraw) { for (const auto& layer : presentationLayers) { if (activeLayer != layer) { pView->freezeLayer(layer); } } pDevice->update(); OdGiRasterImagePtr ptrImage = pDevice->properties()->getAt(OD_T("RasterImage")); pRasSvcs->saveRasterImage(ptrImage, OdString(sPath + std::to_string(activeLayer.getHandle()).c_str()) + ".bmp"); pView->clearFrozenLayers(); } } else { odPrintConsoleString(OD_T("BMP skipped: inaccessible bitmap device.\n")); } } else { odPrintConsoleString(OD_T("\n\nIfcLayer2BmpTutorial: Error: %ls"), "No IfcPresentationLayerAssignments in file"); nRes = -1; } } catch (OdError& e) { odPrintConsoleString(OD_T("\n\nIfcLayer2BmpTutorial: Error: %ls"), e.description().c_str()); nRes = -1; } catch (...) { odPrintConsoleString(OD_T("\n\nIfcLayer2BmpTutorial: Unexpected error.")); nRes = -1; } /**********************************************************************/ /* Unload GS module */ /**********************************************************************/ if (pGsModule.get()) pGsModule.release(); odrxDynamicLinker()->unloadModule(OdWinBitmapModuleName); #ifdef _TOOLKIT_IN_DLL_ ::odrxDynamicLinker()->unloadModule(OdWinGDIModuleName); #endif /**********************************************************************/ /* Uninitialize IfcCore */ /**********************************************************************/ odIfcUninitialize(); return nRes; } void IfcLayer2BmpTutorial::handleNoWait() { if (m_noWait == false) { odPrintConsoleString(OD_T("\nPress any key to finish...")); (void)getchar(); } }