Last active
March 21, 2022 23:08
-
-
Save stefkeB/e2b308e13d299328ecd1dc8db2d20cc5 to your computer and use it in GitHub Desktop.
IFC Print Hierarchy using IfcOpenShell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <iostream> | |
#include <fstream> | |
// ifcOpenShell | |
#ifdef USE_IFC4 | |
#include <ifcparse/Ifc4.h> | |
#else | |
#include <ifcparse/Ifc2x3.h> | |
#endif | |
#include <ifcparse/IfcBaseClass.h> | |
#include <ifcparse/IfcHierarchyHelper.h> | |
using namespace IfcSchema; | |
// Recursive print function | |
void PrintEntity(IfcUtil::IfcBaseEntity * entity, int level = 0) { | |
// ------------------------------------------------ | |
// Print basic stuff | |
std::string spacer = ". "; | |
for (int i = 0; i < level; i++) | |
std::cout << spacer; | |
// #ID | |
std::cout << "#" << entity->id() << " = "; | |
// Classname | |
std::cout << IfcSchema::Type::ToString(entity->type()) << " "; | |
// if IfcRoot > name & guid | |
if (entity->is(IfcRoot::Class())) { | |
const IfcRoot* root = (IfcRoot*)entity; | |
if (root->hasName()) | |
std::cout << "'" << root->Name() << "' "; | |
std::cout << root->GlobalId(); | |
} | |
// Case - Entity is Property or PhysicalQuantity | |
if (entity->is(IfcSchema::IfcProperty::Class())) { | |
std::cout << entity->getArgument(0)->toString() << " "; | |
std::cout << "= " << entity->getArgument(2)->toString(); | |
} | |
if (entity->is(IfcSchema::IfcPhysicalQuantity::Class())) { | |
std::cout << entity->getArgument(0)->toString() << " "; | |
std::cout << "= " << entity->getArgument(3)->toString(); | |
} | |
std::cout << std::endl; | |
// ------------------------------------------------ | |
// Direct Attributes | |
bool loadAttributes = false; | |
std::vector<std::string> attNames = entity->getAttributeNames(); | |
for (int i = 0; loadAttributes && (i < (int)attNames.size()); i++) { | |
for (int i = 0; i < level+1; i++) std::cout << spacer; | |
std::cout << "'" << attNames[i] << "' = "; | |
std::cout << entity->getArgument(i)->toString(); | |
std::cout << std::endl; | |
} | |
// ------------------------------------------------ | |
// Recursively follow relations | |
// Case - Entity is SpatialStructureElement | |
if (entity->is(IfcSpatialStructureElement::Class())) { | |
const IfcSpatialStructureElement* spatial = (IfcSpatialStructureElement*)entity; | |
IfcTemplatedEntityList< IfcRelContainedInSpatialStructure >::ptr containsElements = spatial->ContainsElements(); | |
for (IfcTemplatedEntityList< IfcRelContainedInSpatialStructure >::it itContainsElements = containsElements->begin(); itContainsElements != containsElements->end(); ++itContainsElements) | |
{ | |
IfcRelContainedInSpatialStructure * relContainedInSpatialStructure = (IfcRelContainedInSpatialStructure*)*itContainsElements; | |
IfcTemplatedEntityList< IfcProduct >::ptr listRelatedElements = relContainedInSpatialStructure->RelatedElements(); | |
IfcTemplatedEntityList< IfcProduct >::it itListRelatedElements = listRelatedElements->begin(); | |
while (itListRelatedElements != listRelatedElements->end()) { | |
IfcUtil::IfcBaseEntity * item = (IfcUtil::IfcBaseEntity*)(*itListRelatedElements++); | |
if (item) { | |
PrintEntity(item, level + 1); | |
} | |
} | |
} | |
} // end if spatial structure element | |
// Case - Entity is ObjectDefinition | |
if (entity->is(IfcObjectDefinition::Class())) { | |
const IfcObjectDefinition* objDef = (IfcObjectDefinition*)entity; | |
// Follow Associates relation | |
IfcTemplatedEntityList<IfcRelAssociates>::ptr hasAssociation = objDef->HasAssociations(); | |
for (IfcTemplatedEntityList<IfcRelAssociates>::it itHasAssociation = hasAssociation->begin(); | |
itHasAssociation != hasAssociation->end(); ++itHasAssociation) { | |
IfcRelAssociates * relAssociates = (IfcRelAssociates*)*itHasAssociation; | |
// TODO: do something | |
} // end if hasAssociation | |
} | |
// Case - Entity is Object | |
if (entity->is(IfcObject::Class())) { | |
const IfcObject* object = (IfcObject*)entity; | |
// Follow DecomposedBy relation | |
IfcTemplatedEntityList< IfcRelDecomposes >::ptr isDecomposedBy = object->IsDecomposedBy(); | |
for (IfcTemplatedEntityList< IfcRelDecomposes >::it itDecomposedBy = isDecomposedBy->begin(); itDecomposedBy != isDecomposedBy->end(); ++itDecomposedBy) | |
{ | |
IfcRelAggregates * relDecomposedBy = (IfcRelAggregates*)*itDecomposedBy; | |
IfcTemplatedEntityList< IfcObjectDefinition >::ptr listRelated = relDecomposedBy->RelatedObjects(); | |
IfcTemplatedEntityList< IfcObjectDefinition >::it itListRelated = listRelated->begin(); | |
while (itListRelated != listRelated->end()) { | |
IfcUtil::IfcBaseEntity * item = (IfcUtil::IfcBaseEntity*)(*itListRelated++); | |
if (item) { | |
PrintEntity(item, level + 1); | |
} | |
} | |
} // end if decomposes | |
// Follow IsDefinedBy relation (PropertySets & Types) | |
IfcTemplatedEntityList< IfcRelDefines >::ptr isDefinedBy = object->IsDefinedBy(); | |
IfcTemplatedEntityList< IfcRelDefines >::it itIsDefinedBy = isDefinedBy->begin(); | |
while (itIsDefinedBy != isDefinedBy->end()) { | |
IfcRelDefines * relDefines = (IfcRelDefines*)(*itIsDefinedBy++); | |
// Type definition | |
if (relDefines->is(IfcRelDefinesByType::Class())) { | |
const IfcRelDefinesByType* definesByType = (IfcRelDefinesByType*)relDefines; | |
const IfcTypeObject * typeObject = definesByType->RelatingType(); | |
IfcUtil::IfcBaseEntity * item = (IfcUtil::IfcBaseEntity*)typeObject; | |
if (item) { | |
PrintEntity(item, level + 1); | |
} | |
} | |
// Property Definition | |
if (relDefines->is(IfcRelDefinesByProperties::Class())) { | |
const IfcRelDefinesByProperties* definesByProperties = (IfcRelDefinesByProperties*)relDefines; | |
const IfcPropertyDefinition * propDef = definesByProperties->RelatingPropertyDefinition(); | |
IfcUtil::IfcBaseEntity * item = (IfcUtil::IfcBaseEntity*)propDef; | |
if (item) { | |
PrintEntity(item, level + 1); | |
} | |
} | |
} // end IsDefinedBy | |
} // end if IfcObject | |
// Case - Entity is PropertySet or ElementQuantity | |
if (entity->is(IfcPropertyDefinition::Class())) { | |
// Check Property Definitions | |
if (entity->is(IfcPropertySet::Class())) { | |
const IfcPropertySet * propSet = (IfcPropertySet*)entity; | |
IfcTemplatedEntityList<IfcProperty>::ptr listProperties = propSet->HasProperties(); | |
IfcTemplatedEntityList<IfcProperty>::it itListProperties = listProperties->begin(); | |
while (itListProperties != listProperties->end()) { | |
IfcUtil::IfcBaseEntity * item = (IfcUtil::IfcBaseEntity*)*itListProperties++; | |
if (item) { | |
PrintEntity(item, level + 1); | |
} | |
} | |
} // end if Property Set | |
// Check Base Quantities | |
if (entity->is(IfcElementQuantity::Class())) { | |
const IfcElementQuantity * qSet = (IfcElementQuantity*)entity; | |
IfcTemplatedEntityList<IfcPhysicalQuantity>::ptr listQuantities = qSet->Quantities(); | |
IfcTemplatedEntityList<IfcPhysicalQuantity>::it itListQuantities = listQuantities->begin(); | |
while (itListQuantities != listQuantities->end()) { | |
IfcUtil::IfcBaseEntity * item = (IfcUtil::IfcBaseEntity*)*itListQuantities++; | |
if (item) { | |
PrintEntity(item, level + 1); | |
} | |
} | |
} // end if Element Quantity | |
} // end if property definition | |
} | |
int main(int argc, char** argv) { | |
// Read the file | |
IfcParse::IfcFile file; | |
if (argc < 1) return 0; | |
if ( ! file.Init(argv[1]) ) { | |
std::cout << "Unable to parse .ifc file" << std::endl; | |
return 1; | |
} | |
// Read a list of entities | |
IfcEntityList::ptr entities(new IfcEntityList()); | |
entities = file.entitiesByType("IfcProject"); | |
for (IfcEntityList::it it = entities->begin(); it != entities->end(); ++it) { | |
IfcUtil::IfcBaseEntity * entity = (IfcUtil::IfcBaseEntity*)*it; | |
// Display information about the entity | |
PrintEntity(entity); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
./PrintHierarchy ../Models/IfcOpenHouse.ifc | |
#12 = IfcProject 'IfcOpenHouse' 1h6kzgF2fA8BQ5niopb7zB | |
. #18 = IfcSite 0JA17OO9LAV9bo12Oa92B9 | |
. . #25 = IfcBuilding 15SI_NrofB1up99X9U7beo | |
. . . #32 = IfcBuildingStorey 1alUutlUH7lgQhe1Qj_tCw | |
. . . . #34 = IfcWallStandardCase 'South wall' 1YuHUfuqrE8wg5PsSQdDrl | |
. . . . #77 = IfcFooting 'Footing' 2i8H67IeD9IOU1gZO_ty_h | |
. . . . #187 = IfcRoof 'Roof' 36E1WAkln92OzjkUUsZ8jc | |
. . . . . #188 = IfcSlab 'South roof' 1MRdn1fY10jf_GACKdtpYF | |
. . . . . #189 = IfcSlab 'North roof' 3qwKFIswv1dPhYJKlAO2SN | |
. . . . #219 = IfcWallStandardCase 'North wall' 1KPqQr0Pb6qeClM$oN_Z3b | |
. . . . #292 = IfcWallStandardCase 'East wall' 3ZW12NntT7ivTZ$F5Qw5tW | |
. . . . #299 = IfcWallStandardCase 'West wall' 0NBI7eAdzDovnJGU_NnDOH | |
. . . . #2609 = IfcStairFlight 0gm$yeQRj1xxt0B_0lXzcM | |
. . . . #2687 = IfcDoor 3Ekq43r6bEoByFKAZ$aeyu | |
. . . . . #2697 = IfcDoorStyle 'Door type' 2Xk2fURwPBXAnV1gWjo9R6 | |
. . . . #2756 = IfcWindow 3vl_GRpqHA$x$W4D2406Cb | |
. . . . . #2787 = IfcMember 3v11_y5RfFGfsNCxxYjaJo | |
. . . . . #2793 = IfcMember 0NB_dqdAD5x9sBPo12CTYg | |
. . . . . #2804 = IfcMember 342x4ivin36vH6VlAbwStw | |
. . . . . #2810 = IfcMember 3W3DHl5554Iug8Vs3EMHT9 | |
. . . . . #2830 = IfcPlate 2vASEfqmr2jQRcyFzwSKDL | |
. . . . #2837 = IfcWindow 0XmWSDolr6jxgsOUPrD6cp | |
. . . . . #2863 = IfcMember 0Kmy_W8MTDYB0Or_Y1LirZ | |
. . . . . #2869 = IfcMember 3rzMkPWE9A2BQqA9RHhhDh | |
. . . . . #2875 = IfcMember 1S4j1NVdn5$Rgwmpq7OplQ | |
. . . . . #2881 = IfcMember 2MH68WATr9JQnd3o3ocGtQ | |
. . . . . #2901 = IfcPlate 0ePlx2tv12qPZHPPCZB7G4 | |
. . . . #2908 = IfcWindow 079RXBBfL8Ae1sDpdNHas4 | |
. . . . . #2934 = IfcMember 0zlM3W7qr5OOtGKvHpw5vi | |
. . . . . #2940 = IfcMember 1nkjoVu058kPUvoUhTi_6Z | |
. . . . . #2946 = IfcMember 27Ly7Y$GHD4f7Qyp9xnS3i | |
. . . . . #2952 = IfcMember 19DFw4For1vBB6ibn7IdNd | |
. . . . . #2972 = IfcPlate 0u12N$PF1EfftDWsWRIFCY | |
. . . . #2979 = IfcWindow 3$Xk82jXb6KeR0aYzIMPuV | |
. . . . . #3005 = IfcMember 3jgGlg3jbDdQ56XCrciMAN | |
. . . . . #3011 = IfcMember 32Myk4z9z6vvS$tcJPg3k8 | |
. . . . . #3017 = IfcMember 2bYkyT22DEFwZAX2K9Uky5 | |
. . . . . #3023 = IfcMember 1n1SamiGb3PORMo8xmdnlp | |
. . . . . #3043 = IfcPlate 31cdsB4nb4thXmRKmURy07 | |
. . . . #3050 = IfcWindow 0Pqx$ypVv3SxG$K80aN8S9 | |
. . . . . #3076 = IfcMember 3YW9$IZvj7lxRD8IfC3mEl | |
. . . . . #3082 = IfcMember 0pNcvVYkLCmub7vpcAR0JZ | |
. . . . . #3088 = IfcMember 1MWAO8n8nDxhKOF07_9oNa | |
. . . . . #3094 = IfcMember 2tTaYRsI15fejfAj_FQ$Yo | |
. . . . . #3114 = IfcPlate 3d5PIu9GnFcvO01eDR7s_I | |
. . #322 = IfcPropertySet 'Pset_SiteCommon' 1bEirXC2P98hf0CiUHc$ik | |
. . . #321 = IfcPropertySingleValue 'TotalArea' = IfcAreaMeasure(523.31397507897) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## ----------------------------------------------------------------- | |
## qmake project file | |
## | |
## Usage: qmake -spec macx-xcode (to generate XCode project) | |
## | |
## e.g. | |
## >> mkdir build && cd build | |
## >> qmake -spec macx-xcode ../XYZ.pro | |
## >> open XYZ.xcodeproj/ | |
## ----------------------------------------------------------------- | |
TEMPLATE = app | |
CONFIG += console | |
CONFIG -= app_bundle | |
OBJECTS_DIR = ./temp/obj | |
UI_DIR = ./temp/ui | |
MOC_DIR = ./temp/moc | |
## IFC 4 Support (instead of Ifc2x3) | |
# DEFINES += USE_IFC4 | |
INCLUDEPATH += /usr/local/include | |
LIBS += -L/usr/local/lib | |
## ----------------------------------------------------------------- | |
## Qt5 (GUI, Application, Integration) | |
## ----------------------------------------------------------------- | |
QT -= core gui widgets # no Qt Libraries to link | |
## Enforce debug modus (especially for XCode debug sessions!) | |
CONFIG += debug # debug_and_release | |
# This is an unsupported configuration. You may experience build issues, and by using | |
# the 10.13.4 SDK you are opting in to new features that Qt has not been prepared for. | |
# Please downgrade the SDK you use to build your app to version 10.13, or configure | |
# with CONFIG+=sdk_no_version_check when running qmake to silence this warning. | |
CONFIG+=sdk_no_version_check | |
# remove ld:warning ... was built for newer OSX version (10.13) than being linked (10.11) | |
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.13 | |
## ----------------------------------------------------------------- | |
## OpenCASCADE (3D Geometry Support) | |
## (Not required for this example - no geometry support) | |
## ----------------------------------------------------------------- | |
# DEFINES += USE_OCC | |
# INCLUDEPATH += /usr/local/include/oce /usr/local/include/opencascade | |
# LIBS += -lTKernel -lTKMath -lTKService -lTKV3d -lTKOpenGl \ | |
# -lTKBRep -lTKIGES -lTKSTL -lTKVRML -lTKSTEP -lTKSTEPAttr -lTKSTEP209 \ | |
# -lTKSTEPBase -lTKGeomBase -lTKGeomAlgo -lTKG3d -lTKG2d \ | |
# -lTKXSBase -lTKShHealing -lTKHLR -lTKTopAlgo -lTKMesh -lTKPrim \ | |
# -lTKCDF -lTKBool -lTKBO -lTKFillet -lTKOffset | |
## ----------------------------------------------------------------- | |
## IfcOpenShell (IFC File Support) | |
## ----------------------------------------------------------------- | |
LIBS += -lIfcParse # -lIfcGeom | |
# NEEDS ICU libraries for Unicode Support | |
LIBS += -L/usr/local/opt/icu4c/lib | |
LIBS += -licuuc -licudata #-licutu -licuio | |
INCLUDEPATH += /usr/local/opt/icu4c/include | |
## ----------------------------------------------------------------- | |
## Application | |
## ----------------------------------------------------------------- | |
SOURCES += main.cpp | |
##HEADERS += | |
## ----------------------------------------------------------------- | |
## Resources & Images & Icon | |
## ----------------------------------------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A minimal example, to show parsing of an IFC file from Project down to individual entities and attributes.