OSArch Community

Crash course on learning to manipulate IFCs with IfcOpenShell and Python

  1. M
  1. C

    @Moult said:

    The wiki has a crash course :)

    YESSSS! many thanks :)

  1. M

    The page now has some samples of the elusive "IFC selector / query syntax".

    Especially this solves the problem of "how do you efficiently query a subset of IFC elements from a file". The results of this query can be fed into many things, such as:

    • Importing or exporting only portions of a file the BlenderBIM Add-on

    • Doing a diff check on a portion of a file in IFCDiff

    • Doing clash detection on a portion of a file in IfcClash

    • Exporting a portion of a file to a CSV, or really any generation of any schedules, used in IFCCSV

    • Auditing a portion of a file in BIMTester

    @yorik - I hope it is interesting to you and maybe it can be used in FreeCAD too?

  1. B

    Very good for someone to get started and very good reference. Some hint: if a ifc is taken (uploaded with webget or even parsed directly from web) from a github account a new user even has a example to directly work with and exaclty see the same output as on the tutorial.

    Furthermore a good reference. Sometimes I do not do any Python and ifc for a few weeks and thus some commands are just gone.

  1. B
    print(ifcopenshell.util.get_psets(wall))

    compiled latest 0.6 ifcopenshell but there is no ifcopenshell.util ? Do I need to compile 0.7 branch for this ?

  1. C

    @bernd said:

    compiled latest 0.6 ifcopenshell but there is no ifcopenshell.util ? Do I need to compile 0.7 branch for this ?

    Here

    You need to compile it from git source or to download it from IfcOpenBot.

  1. B
    $ python3
    
    Python 3.7.3 (default, Dec 20 2019, 18:57:59) 
    
    [GCC 8.3.0] on linux
    
    Type "help", "copyright", "credits" or "license" for more information.
    
    >>> 
    
    >>> import ifcopenshell
    
    >>> ifcopenshell.version
    
    '0.6.0b0'
    
    >>> 
    
    >>> from ifcopenshell.util import get_psets
    
    Traceback (most recent call last):
    
      File "<stdin>", line 1, in <module>
    
    ImportError: cannot import name 'get_psets' from 'ifcopenshell.util' (/usr/lib/python3/dist-packages/ifcopenshell/util/__init__.py)
    
    >>> 
    
    $ git log -1
    
    commit a337c480a99a9c5f199a360b684f08aa36548af8 (HEAD, origin/v0.6.0)
    
    Author: Dion Moult <dion@thinkmoult.com>
    
    Date:   Wed Jul 29 21:46:16 2020 +1000
    
        Support exporting IfcSweptDiskSolid for curves with no bevel profile
  1. C
    print(ifcopenshell.util.get_psets(wall))

    compiled latest 0.6 ifcopenshell but there is no ifcopenshell.util ? Do I need to compile 0.7 branch for this ?

    Just a mistake on wiki. get_psets is in element module not util directly :

    
    import ifcopenshell.util
    
    ifcopenshell.util.element.get_psets(wall)
    
  1. B
    $ python3
    
    Python 3.7.3 (default, Dec 20 2019, 18:57:59) 
    
    [GCC 8.3.0] on linux
    
    Type "help", "copyright", "credits" or "license" for more information.
    
    >>> 
    
    >>> import ifcopenshell
    
    >>> ifcopenshell.version
    
    '0.6.0b0'
    
    >>> from ifcopenshell.util.element import get_psets
    
    >>> 

    :-)

  1. S

    Very useful information!

    I still remember that I knew @Moult because I was learning ifcopenshell-Python, and I contacted him by email to ask if he has more examples. He said that I could come to OSArch to communicate, so I came here.

  1. B
  1. B

    file from here ... https://forum.freecadweb.org/viewtopic.php?t=14059&start=20#p123072

    >>> import ifcopenshell
    
    >>> ifc = ifcopenshell.open("C:/Users/BHA/Downloads/simple-building.ifc")
    
    >>> 
    
    >>> get_psets(ifc[354])
    
    failed to load properties: entity instance of type 'IfcQuantityLength' has no attribute 'IsDefinedBy'
    
    {}
    
    Traceback (most recent call last):
    
      File "C:\0_BHA_privat\progr\FreeCAD_0.19.xxxxx_Py3Qt5\bin\lib\site-packages\ifcopenshell\util\element.py", line 9, in get_psets
    
        for relationship in element.IsDefinedBy:
    
      File "C:\0_BHA_privat\progr\FreeCAD_0.19.xxxxx_Py3Qt5\bin\lib\site-packages\ifcopenshell\entity_instance.py", line 65, in __getattr__
    
        "entity instance of type '%s' has no attribute '%s'" % (self.wrapped_data.is_a(), name))
    
    AttributeError: entity instance of type 'IfcQuantityLength' has no attribute 'IsDefinedBy'
    
    >>> 
  1. M
  1. B

    @Moult said:

    @bernd added support: https://github.com/IfcOpenShell/IfcOpenShell/commit/2a22acfdc936bc9ed6d2ff0ec36e76287da08d56

    By the way, it's ifc[345] not ifc[354].

    :-)

    >>> 
    
    >>> from ifcopenshell.util.element import get_psets
    
    >>> for ps, p in get_psets(ifc[345]).items():
    
    ...     print("{} --> {}".format(ps, p))
    
    ... 
    
    WallQuantities --> {'GrossVolume': 6.0, 'NetVolume': 6.0, 'GrossSideArea': 24.0, 'NetSideArea': 24.0, 'NominalLength': 8.0, 'NominalWidth': 0.25, 'GrossFootprintArea': 2.0, 'NominalHeight': 3.0}
    
    Allplan Attributes --> {'Allright_Bauteil_ID': IfcDescriptiveMeasure('1007HWa0000000011'), 'Einheit': IfcDescriptiveMeasure('St'), 'Objektname': IfcDescriptiveMeasure('Mehrsch-Wand'), 'NOI_UUID': IfcDescriptiveMeasure('5a6837a3-f217-44ed-997f-04834a2db582--11'), 'IFC-Objekttyp': IfcLabel('IfcWallStandardCase')}
    
    >>> 
  1. B

    but if there are really some layers it misses some properties ...

    >>> 
    
    >>> for ps, p in get_psets(ifc[437]).items():
    
    ...    print("{} --> {}".format(ps, p))
    
    ...    
    
    ... 
    
    Pset_WallCommon --> {'LoadBearing': IfcBoolean(.T.)}
    
    AllplanAttributes --> {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033HWa0000000022'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('St'), 'Objektname': IfcDescriptiveMeasure('Mehrsch-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--22'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}
    
    >>> 

    !

  1. B

    up ... @Moult have you noticed the problem ?

  1. M

    @bernd it works for me, are you sure you have the latest file?

    See my results:

    
    >>> for ps, p in ifcopenshell.util.element.get_psets(f[437]).items():
    
    ...     print("{} --> {}".format(ps, p))
    
    ... 
    
    Pset_WallCommon --> {'LoadBearing': IfcBoolean(.T.)}
    
    AllplanAttributes --> {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033HWa0000000022'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('St'), 'Objektname': IfcDescriptiveMeasure('Mehrsch-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--22'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall'), 'Object Layer Attributes #1': {'id': 467, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #1', 'Description': 'Layer #1', 'UsageName': 'Layer #1', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000026'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('St'), 'Gewerk': IfcDescriptiveMeasure('Betonarbeiten'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Fertigelement Beton'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--26'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}, 'Object Layer Attributes #2': {'id': 491, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #2', 'Description': 'Layer #2', 'UsageName': 'Layer #2', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000025'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('m³'), 'Gewerk': IfcDescriptiveMeasure('Betonarbeiten'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Ortbeton'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--25'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}, 'Object Layer Attributes #3': {'id': 515, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #3', 'Description': 'Layer #3', 'UsageName': 'Layer #3', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000024'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('St'), 'Gewerk': IfcDescriptiveMeasure('Betonarbeiten'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Daemmung'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--24'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}, 'Object Layer Attributes #4': {'id': 538, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #4', 'Description': 'Layer #4', 'UsageName': 'Layer #4', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000023'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('m²'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Fertigelement Beton'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--23'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}}
    
  1. B

    Dion I musst somehow have been overwritten the file on FreeCAD (if I am at my computer at work I only use downloadable FreeCAD version which includes ifcopenshell) update ... works great here too.

    >>> 
    
    >>> f=ifc
    
    >>> from ifcopenshell.util.element import get_psets
    
    >>> for ps, p in ifcopenshell.util.element.get_psets(f[437]).items():
    
    ...     print("{} --> {}".format(ps, p))
    
    ... 
    
    Pset_WallCommon --> {'LoadBearing': IfcBoolean(.T.)}
    
    AllplanAttributes --> {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033HWa0000000022'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('St'), 'Objektname': IfcDescriptiveMeasure('Mehrsch-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--22'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall'), 'Object Layer Attributes #1': {'id': 467, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #1', 'Description': 'Layer #1', 'UsageName': 'Layer #1', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000026'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('St'), 'Gewerk': IfcDescriptiveMeasure('Betonarbeiten'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Fertigelement Beton'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--26'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}, 'Object Layer Attributes #2': {'id': 491, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #2', 'Description': 'Layer #2', 'UsageName': 'Layer #2', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000025'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('m³'), 'Gewerk': IfcDescriptiveMeasure('Betonarbeiten'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Ortbeton'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--25'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}, 'Object Layer Attributes #3': {'id': 515, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #3', 'Description': 'Layer #3', 'UsageName': 'Layer #3', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000024'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('St'), 'Gewerk': IfcDescriptiveMeasure('Betonarbeiten'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Daemmung'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--24'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}, 'Object Layer Attributes #4': {'id': 538, 'type': 'IfcComplexProperty', 'Name': 'Object Layer Attributes #4', 'Description': 'Layer #4', 'UsageName': 'Layer #4', 'properties': {'Allright_Bauteil_ID': IfcDescriptiveMeasure('0033Wa 0000000023'), 'Umbaukategorie': IfcLabel('Neubau'), 'Einheit': IfcDescriptiveMeasure('m²'), 'Objektname': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Bezeichnung': IfcDescriptiveMeasure('Mehrschichten-Wand'), 'Material': IfcDescriptiveMeasure('Fertigelement Beton'), 'statisch_tragend': IfcBoolean(.T.), 'Außenbauteil': IfcBoolean(.F.), 'NOI_UUID': IfcDescriptiveMeasure('2c3f7016-d5f2-4b9b-9ea7-6de7b5e546cf--23'), 'IFC-Objekttyp': IfcDescriptiveMeasure('IfcWall')}}}
    
    >>> 
  1. B

    Is there a special reason why you did not make it work this way?

    f[437].get_psets()

  1. M

    @bernd I guess we just started collecting functions and haven't yet started to organise them better.

    But for this one, I agree it totally makes sense :) Perhaps post a comment in the Github issue and ask @aothms what his thoughts are?

  1. B

Login or Register to reply.