/////////////////////////////////////////////////////////////////////////////// // 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 "IfcFile.h" #include "IfcModel.h" #include "ExIfcTutorial_ExtractGeometry.h" #include "Entities/IfcProduct.h" #include "Entities/IfcGeometricRepresentationItem.h" #include "Entities/IfcMappedItem.h" #include "Entities/IfcStyledItem.h" #include "Entities/IfcPresentationStyle.h" #include "Modeler/FMMdlBody.h" #include "Ge/GeTrMeshSimplification.h" #include "Ge/GePoint3d.h" Tutorial_ExtractGeometry::Tutorial_ExtractGeometry(const OdString& applicationName) : BaseIfcTutorial(applicationName) { m_tutorialArgsParser.add_param( std::make_shared>( m_ifcFileName, "inputFile", "Path to the input .ifc file.", true)); m_tutorialArgsParser.add_param( std::make_shared( m_noWait, "-NoWait", "Disable 'press any key' on finish.")); } void processGeomItem(OdIfc::OdIfcGeometricRepresentationItemPtr geomReprItem, const OdGeMatrix3d &transf) { OdDAIObjectId idGeomReprItem = geomReprItem->id(); OdUInt64 idHandle = idGeomReprItem.getHandle(); odPrintConsoleString(OD_T("\nExtracting geometry from #%lu.\n"), idHandle); // // Processing styles // OdDAIObjectIds idsStyledByItem; geomReprItem->getAttr("styledbyitem") >> idsStyledByItem; for (const auto& idStyledItem : idsStyledByItem) { OdIfc::OdIfcInstancePtr styledItem = idStyledItem.openObject(); OdDAIObjectIds idsStyles; styledItem->getAttr("styles") >> idsStyles; for (const auto& idPresentationStyle : idsStyles) { OdUInt64 presentationStyleHandle = idPresentationStyle.getHandle(); OdIfc::OdIfcInstancePtr presentationStyle = idPresentationStyle.openObject(); OdString presentationStyleName; presentationStyle->getAttr("name") >> presentationStyleName; odPrintConsoleString(OD_T("\nProcessing style #%lu = %hs, name &s.\n"), idHandle, presentationStyle->getInstanceType()->originalName().c_str(), presentationStyleName.c_str()); // ... } } // // Enhanced Processing styles using new implementation // odPrintConsoleString(OD_T("\n=== Enhanced Style Processing with New API ===\n")); OdIfc::OdIfcStyledItemPtrArray styledItemArray = geomReprItem->styledByItem(); odPrintConsoleString(OD_T("Found %d styled items for geometry #%lu.\n"), styledItemArray.size(), idHandle); if (styledItemArray.size()) { int bp = 1; } for (OdIfc::OdIfcStyledItemPtr pStyledItem : styledItemArray) { if (pStyledItem.isNull()) continue; OdUInt64 styledItemHandle = OdDAIObjectId(pStyledItem->id()).getHandle(); odPrintConsoleString(OD_T("\n=== Processing StyledItem #%lu ===\n"), styledItemHandle); // Dump OdIfcStyledItem properties OdString styledItemName = pStyledItem->name(); odPrintConsoleString(OD_T(" Name: %s\n"), styledItemName.c_str()); // Get referenced item OdIfc::OdIfcRepresentationItemPtr itemRef = pStyledItem->item(); if (!itemRef.isNull()) { odPrintConsoleString(OD_T(" Item: #%lu (%s)\n"), OdDAIObjectId(itemRef->id()).getHandle(), itemRef->isA()->name().c_str()); } // Get and dump all presentation styles OdArray styles = pStyledItem->styles(); odPrintConsoleString(OD_T(" Number of styles: %d\n"), styles.size()); for (const auto& pStyle : styles) { if (pStyle.isNull()) continue; OdUInt64 styleHandle = OdDAIObjectId(pStyle->id()).getHandle(); OdString styleType = pStyle->isA()->name().c_str(); odPrintConsoleString(OD_T("\n --- Style #%lu (%s) ---\n"), styleHandle, styleType.c_str()); // Base OdIfcPresentationStyle properties OdString styleName = pStyle->name(); odPrintConsoleString(OD_T(" Name: %s\n"), styleName.c_str()); // Check specific style types and dump their properties if (OdIfc::OdIfcCurveStylePtr pCurveStyle = OdIfc::OdIfcCurveStyle::cast(pStyle)) { odPrintConsoleString(OD_T(" === IfcCurveStyle Properties ===\n")); OdIfc::OdIfcInstancePtr curveFont = pCurveStyle->curveFont(); if (!curveFont.isNull()) { odPrintConsoleString(OD_T(" CurveFont: #%lu (%hs)\n"), OdDAIObjectId(curveFont->id()).getHandle(), curveFont->getInstanceType()->originalName().c_str()); } else { odPrintConsoleString(OD_T(" CurveFont: \n")); } OdIfc::OdIfcInstancePtr curveWidth = pCurveStyle->curveWidth(); if (!curveWidth.isNull()) { odPrintConsoleString(OD_T(" CurveWidth: #%lu (%hs)\n"), OdDAIObjectId(curveWidth->id()).getHandle(), curveWidth->getInstanceType()->originalName().c_str()); } else { odPrintConsoleString(OD_T(" CurveWidth: \n")); } OdIfc::OdIfcInstancePtr curveColour = pCurveStyle->curveColour(); if (!curveColour.isNull()) { odPrintConsoleString(OD_T(" CurveColour: #%lu (%hs)\n"), OdDAIObjectId(curveColour->id()).getHandle(), curveColour->getInstanceType()->originalName().c_str()); } else { odPrintConsoleString(OD_T(" CurveColour: \n")); } OdDAI::Boolean modelOrDraughting = pCurveStyle->modelOrDraughting(); odPrintConsoleString(OD_T(" ModelOrDraughting: %hs\n"), modelOrDraughting.exists() ? (modelOrDraughting ? "TRUE" : "FALSE") : ""); } else if (OdIfc::OdIfcSurfaceStylePtr pSurfaceStyle = OdIfc::OdIfcSurfaceStyle::cast(pStyle)) { odPrintConsoleString(OD_T(" === IfcSurfaceStyle Properties ===\n")); OdAnsiString side = pSurfaceStyle->side(); odPrintConsoleString(OD_T(" Side: %hs\n"), side.c_str()); OdArray surfaceStyles = pSurfaceStyle->styles(); odPrintConsoleString(OD_T(" Number of surface styles: %d\n"), surfaceStyles.size()); for (unsigned i = 0; i < surfaceStyles.size(); ++i) { const auto& surfaceStyleElem = surfaceStyles[i]; if (!surfaceStyleElem.isNull()) { odPrintConsoleString(OD_T(" Style[%d]: #%lu (%hs)\n"), i, OdDAIObjectId(surfaceStyleElem->id()).getHandle(), surfaceStyleElem->getInstanceType()->originalName().c_str()); } } } else if (OdIfc::OdIfcFillAreaStylePtr pFillAreaStyle = OdIfc::OdIfcFillAreaStyle::cast(pStyle)) { odPrintConsoleString(OD_T(" === IfcFillAreaStyle Properties ===\n")); OdArray fillStyles = pFillAreaStyle->fillStyles(); odPrintConsoleString(OD_T(" Number of fill styles: %d\n"), fillStyles.size()); for (unsigned i = 0; i < fillStyles.size(); ++i) { const auto& fillStyleElem = fillStyles[i]; if (!fillStyleElem.isNull()) { odPrintConsoleString(OD_T(" FillStyle[%d]: #%lu (%hs)\n"), i, OdDAIObjectId(fillStyleElem->id()).getHandle(), fillStyleElem->getInstanceType()->originalName().c_str()); } } OdDAI::Boolean modelOrDraughting = pFillAreaStyle->modelOrDraughting(); odPrintConsoleString(OD_T(" ModelOrDraughting: %hs\n"), modelOrDraughting.exists() ? (modelOrDraughting ? "TRUE" : "FALSE") : ""); } else if (OdIfc::OdIfcTextStylePtr pTextStyle = OdIfc::OdIfcTextStyle::cast(pStyle)) { odPrintConsoleString(OD_T(" === IfcTextStyle Properties ===\n")); OdIfc::OdIfcInstancePtr textCharacterAppearance = pTextStyle->textCharacterAppearance(); if (!textCharacterAppearance.isNull()) { odPrintConsoleString(OD_T(" TextCharacterAppearance: #%lu (%hs)\n"), OdDAIObjectId(textCharacterAppearance->id()).getHandle(), textCharacterAppearance->getInstanceType()->originalName().c_str()); } else { odPrintConsoleString(OD_T(" TextCharacterAppearance: \n")); } OdIfc::OdIfcInstancePtr textStyle = pTextStyle->textStyle(); if (!textStyle.isNull()) { odPrintConsoleString(OD_T(" TextStyle: #%lu (%hs)\n"), OdDAIObjectId(textStyle->id()).getHandle(), textStyle->getInstanceType()->originalName().c_str()); } else { odPrintConsoleString(OD_T(" TextStyle: \n")); } OdIfc::OdIfcInstancePtr textFontStyle = pTextStyle->textFontStyle(); if (!textFontStyle.isNull()) { odPrintConsoleString(OD_T(" TextFontStyle: #%lu (%hs)\n"), OdDAIObjectId(textFontStyle->id()).getHandle(), textFontStyle->getInstanceType()->originalName().c_str()); } else { odPrintConsoleString(OD_T(" TextFontStyle: \n")); } OdDAI::Boolean modelOrDraughting = pTextStyle->modelOrDraughting(); odPrintConsoleString(OD_T(" ModelOrDraughting: %hs\n"), modelOrDraughting.exists() ? (modelOrDraughting ? "TRUE" : "FALSE") : ""); } else { odPrintConsoleString(OD_T(" === Unknown Style Type ===\n")); } } } OdDAI::OdBodyVariant bodyContainer = geomReprItem->bodyContainer(); if (bodyContainer.kind() == OdDAI::OdBodyVariant::kFacetModelerBody) { const FacetModeler::Body* body = bodyContainer.facetModelerBody(); if (!body) return; GeMesh::OdGeTrMesh mesh; body->generateMesh(mesh); // ... } } int Tutorial_ExtractGeometry::run(const MyServices& svcs, const std::vector& argv, std::ostream& resultStream) { if (BaseIfcTutorial::run(svcs, argv, resultStream) != 0) { return 1; } OdIfcFilePtr pFile = svcs.createDatabase(); if (pFile->readFile(m_ifcFileName) != eOk) { odPrintConsoleString(OD_T("Error: Can't open input file %s\n"), m_ifcFileName.c_str()); return -1; } odPrintConsoleString(OD_T("Successfully opened IFC file: %s\n"), m_ifcFileName.c_str()); OdDAIObjectIds idsCtx = OdIfc::Utils::getAllRepresentationContexts(pFile); pFile->setContextSelection(idsCtx); odPrintConsoleString(OD_T("Composing geometry...\n")); if (pFile->composeEntities() != eOk) { odPrintConsoleString(OD_T("Error: Geometry compose failed.\n")); return -1; } odPrintConsoleString(OD_T("Geometry composed successfully.\n")); OdDAI::ModelPtr model = pFile->getModel(); const OdDAI::SetOfOdDAIObjectId* productIdSet = model->getEntityExtent("IfcProduct"); if (!productIdSet || productIdSet->isNil()) { odPrintConsoleString(OD_T("Warning: No IfcProduct instances found in the model.\n")); return 0; } OdDAIObjectIds productIds = productIdSet->getArray(); for (const OdDAIObjectId& id : productIds) { OdIfc::OdIfcInstancePtr inst = id.openObject(); OdIfc::OdIfcProductPtr product = OdIfc::OdIfcProduct::cast(OdIfc::OdIfcInstance::asCompound(inst)); if (product.isNull() || product->isKindOf(OdIfc::kIfcOpeningElement)) continue; OdGeMatrix3d productTransformation = product->getObjectPlacement(); OdIfc::OdIfcRepresentationItemPtrArray geomItems = product->getRepresentationItems(); for (unsigned i = 0; i < geomItems.size(); ++i) { OdIfc::OdIfcGeometricRepresentationItemPtr geomItem; OdIfc::OdIfcMappedItemPtr mappedItem = OdIfc::OdIfcMappedItem::cast(geomItems[i]); if (mappedItem) { OdDAIObjectId idMappingSource = mappedItem->mappingSource(); if (idMappingSource.isValid()) { const OdGeMatrix3d mappedTransformation = productTransformation * mappedItem->mappingTarget(); OdIfc::OdIfcInstancePtr instRepresentationMap = idMappingSource.openObject(); OdDAIObjectId idMappedRepresentation; instRepresentationMap->getAttr("mappedrepresentation") >> idMappedRepresentation; if (idMappedRepresentation.isValid()) { OdIfc::OdIfcInstancePtr mappedRepresentation = idMappedRepresentation.openObject(); OdDAIObjectIds items; mappedRepresentation->getAttr("items") >> items; for (unsigned j = 0; j < items.size(); ++j) { OdIfc::OdIfcInstancePtr item = items[j].openObject(); geomItem = OdIfc::OdIfcGeometricRepresentationItem::cast(OdIfc::OdIfcInstance::asCompound(item)); if (geomItem) { processGeomItem(geomItem, mappedTransformation); } } } } } else { geomItem = geomItems[i]; processGeomItem(geomItem, productTransformation); } } } odPrintConsoleString(OD_T("\nExtraction complete.\n")); return eOk; }