Menu

IFC File in a 2D Plan (Or how do I get the start and end point of a wall)

Peter Top
2022-01-21
2022-06-18
  • Peter Top

    Peter Top - 2022-01-21

    Hello,

    I'm just starting to analyze IFC files using Python. For this I use IfcOpenShell for Python.

    I have already managed to determine the x,y,z position, the length and thickness of a wall. Unfortunately I fail because I know only one point where the wall starts. The point where the wall goes I just can not find or no way to calculate this.

    Can someone show me an example of how to do this?

    The goal would be that I can convert the data from the IFC at the end into a plot output (or other 2D information). Should this go quite simply, also please let me know.

    Here my code:

    ~~~

    import ifcopenshell
    import ifcopenshell.util
    import ifcopenshell.util.placement
    import ifcopenshell.util.element
    import ifcopenshell.geom
    
    import numpy as np
    import math as m
    
    
    with open ("./Desktop/Ausgabe.csv","w",encoding="cp1252") as Datei:
        Datei.write("Daten|Wert")
    
        ifc=ifcopenshell.open("./Desktop/Testraum.ifc")
    
        elements = ifc.by_type('IfcColumn')
        print ("Elemente",elements)
        settings = ifcopenshell.geom.settings()
        unit_scale = 0.001
    
        print ("Schema",ifc.schema)
        Datei.write("\r"+"Schema|"+ifc.schema)
    
    
        walls =ifc.by_type("IfcWall")
        print ("Anzahl der Wände",len(walls))
        Datei.write("\r"+"Anzahl der Wände|"+str(len(walls)))
    
    
        for durchlauf in range(len(walls)):
    
    
            Datei.write("\r"+"--------------------------------------------------------------------------------------------------------------")
            Datei.write("\r"+"--------------------------------------------------------------------------------------------------------------")
    
            wall=walls[durchlauf]
    
            daten= (ifcopenshell.util.element.get_psets(wall))
    
            location=ifcopenshell.util.placement.get_local_placement(wall.ObjectPlacement)
    
            Pos=location[0:3,3]
    
            print ("X",Pos[0])
            print ("Y",Pos[1])
            print ("Z",Pos[2])
    
            print (location[0:3,0])
            print (location[0:3,1])
            print (location[0:3,2])
            print (location[0:3,3])
    
    
            print ("----")
    
            for Bereich in daten:
    
                daten2=daten[Bereich]
    
                for f in daten2:
    
                    Datei.write("\r"+f+"|"+str(daten2[f]))
    
                Datei.write("\r"+"--------------------------------------------------------------------------------------------------------------")
    

    ~~~

    Thanks for any help

    Peter

     

    Last edit: Peter Top 2022-01-21
    • Thomas Krijnen

      Thomas Krijnen - 2022-01-22

      I would suggest to use PythonOCC for this and the ifcopenshell.geom module.

      Walls should typically have an Axis representation. A single polyline or arc segment that describes the start/end point and curve.

      So look in wall.Representation.Representations[...] to find that representation and then call ifcopenshell.geom.create_shape(wall, representation).

      You should have settings then with USE_PYTHON_OPENCASCADE=True and INCLUDE_CURVES=True.

      Use OCC.Core.TopExp.TopExp_Explorer to get a single edge of your wall axis representation (ideally there should only be one). OCC.Core.TopExp.topexp_Vertices to get its vertices. OCC.Core.BRep.Pnt to get the points associated to the vertices.

      This sounds overwhelming and will take some trial and error, but it's by the most robust way forward. Assuming your file has these axis representations.

       
      • Peter Top

        Peter Top - 2022-01-24

        Hello Thomas,

        do have a example code snipet for this?

        I don't think I understand what you're talking about. My hope was that you can (or must) simply calculate this out of the values.

        Thanks already so far for the first answer.

        Peter

         
  • Arcangelo Sergio-Böckle

    Hello everybody.
    I am really a beginner user of Python and IfcOpenshell
    Can someone help me in these questions?
    I have a achive witch 2 buildings ar listed (see code below):
    [In]

    import ifcopenshell.geom
    import ifcopenshell.util
    from ifcopenshell.util.selector import Selector
    selector = Selector()
    import ifcopenshell.util.element as util
    import pandas as pd
    import ifcopenshell
    ifc = ifcopenshell.open('FHZGR_PONTE DELL`ACCADEMIA_PH01_BEM.ifc')
    ifc
    

    [In]

    buildings = ifc.by_type('IfcBuilding')
    buildings
    

    [Out]

    [#164=IfcBuilding('2pHz_5mbKHwwFZeDF18Us0',#111,'Gebäude',$,$,#158,$,$,.ELEMENT.,$,$,#197063),#266=IfcBuilding('3XKt_rkWGHwwHrt4e_RK0V',#211,'Gebäude',$,$,#258,$,$,.ELEMENT.,$,$,#25030)]
    

    [In]

    GB01 = buildings[1]
    GB01
    

    [Out]

    #266=IfcBuilding('3XKt_rkWGHwwHrt4e_RK0V',#211,'Gebäude',$,$,#258,$,$,.ELEMENT.,$,$,#25030)
    

    [In]

    GB02 = buildings[0]
    GB02
    

    [Out]

    #164=IfcBuilding('2pHz_5mbKHwwFZeDF18Us0',#111,'Gebäude',$,$,#158,$,$,.ELEMENT.,$,$,#197063)
    

    Untill hier everything is ok:
    But my aim ist to extract all elements of the buildings.
    For this i used the code below:

    [In]

    typeObjects = ifc.by_type('IfcTypeObject')
    listTypes=[]
    
    for typeObject in typeObjects:
        relobjs = typeObject.ObjectTypeOf[0]
        if relobjs:
            for obj in relobjs.RelatedObjects:
                listObj = [obj.is_a(),
                            typeObject.Name,
                            obj.Name,
                            obj.GlobalId]
                listTypes.append(listObj)
    listTypes
    

    [Out]

    [['IfcDoor', 'D-1', 'TIW01', 'Innentür', '11u3SSoB0HwwFfeDF18Us0'],
     ['IfcDoor', 'D-1', 'TIW01', 'Innentür', '11u3Z3oB0HwwFfeDF18Us0'],
     ['IfcDoor', 'D-1', 'TIW01', 'Innentür', '11u3dAoB0HwwFfeDF18Us0'],
     ['IfcDoor', 'D-1', 'TIW01', 'Innentür', '11u3hHoB0HwwFfeDF18Us0'],
     ['IfcDoor', 'D-1', 'TIW01', 'Innentür', '11u3lOoB0HwwFfeDF18Us0'],
     ['IfcDoor', 'D-1', 'TIW01', 'Innentür', '11u3sToB0HwwFfeDF18Us0'],
     ['IfcDoor', 'D-1', 'TIW01', 'Innentür', '11u3_doB0HwwFfeDF18Us0'],
      ['IfcWallStandardCase','WAA_22', 'WAA_22',
      'Holzelementwand vorgefertigt',
      '3$JJG0mkGHwwHtt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_20', 'WAI_20', None, '0avSRmnsCHwwHzt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_30', 'WAI_30', None, '3aYimBkwCHwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAA_62', 'WAA_62', None, '3v$N4zkwGHwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_40', 'WAI_40', None, '3v$N54kwGHwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_25', 'WAI_25', None, '3v$N5GkwGHwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_15', 'WAI_15', None, '3v$N5ikwGHwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_8', 'WAI_8', None, '0hIitBkwKHwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAA_52', 'WAA_52', None, '1fFsNumKCHwwHtt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_5', 'WAI_5', None, '2csBuao7WHwwH_t4e_RK0V'],
     ['IfcDoor', 'D-1', 'TAW', 'Aussentür', '2mMWS$o4qHwwFeeDF18Us0'],
     ['IfcDoor', 'D-1', 'TAW', 'Aussentür', '2nbOFUo4qHwwFeeDF18Us0'],
     ['IfcDoor', 'D-1', 'Schiebetür', 'Aussentür', '2qRDDjo4qHwwFeeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster', None, '2vSrZWmbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster', None, '2vSruqmbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster 500.', None, '2rkDT7o4qHwwFeeDF18Us0'],
    
     ['IfcWallStandardCase', 'WAI_30', 'WAI_30', None, '3xwllnkluHwwHrt4e_RK0V'],
     ['IfcWallStandardCase',
      'WAI_12.5',
      'WAI_12.5',
      None,
      '0I$g0pklyHwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAA_62', 'WAA_62', None, '284uo0lI4HwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAA_52', 'WAA_52', None, '284uo1lI4HwwHrt4e_RK0V'],
     ['IfcWallStandardCase', 'WAI_40', 'WAI_40', None, '3jrZxcn40HwwHtt4e_RK0V'],
     ['IfcWindow', 'W-1', 'Abgehängte Fassade', None, '3GjyCLmbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Abgehängte Fassade', None, '3Gjxx8mbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster ', None, '1Un5jnsgeHwwFmeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster', None, '3D1DxfmbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster', None, '3D1EL6mbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster', None, '3D1EkZmbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster', None, '3D1F80mbKHwwFZeDF18Us0'],
     ['IfcWindow', 'W-1', 'Fenster', None, '3D1FXTmbKHwwFZeDF18Us0'],
     ````
    In other words only the following IFCs: Wall, Proxy, Door and Windows where exported.
    Other Elements like Slabs, Ramps, Columns and so on were not listed.
    I realised lather that the not listed objects have no  attribute 'TypeOfObject' 
    
    In this case i tried this code:
    
    [In]
    

    elements = selector.parse(ifc, '.IfcWall | .IfcSlab | .IfcWindow | .IfcDoor | .IfcRamp | .IfcColumn | .IfcBeam | .IfcStair')
    elements

    [Out]
    

    [#1539782=IfcWallStandardCase('3htFgQoBGHwwFfeDF18Us0',#111,'WAA_22','Holzelementwand vorgefertigt','WAA_22',#1539779,#1539780,$),
    #227652=IfcWallStandardCase('30$lAVkBuHwwFWeDF18Us0',#211,'WAA_52',$,'WAA_52',#227649,#227650,$),
    #11220749=IfcWallStandardCase('1QIOamkX0HwwHrt4e_RK0V',#111,'WAI_15',$,'WAI_15',#11220746,#11220747,$),
    #2481991=IfcDoor('11DmrBmneHwwFZeDF18Us0',#211,'TIW','Innentür',$,#2501178,#2482231,$,2100.,2280.),
    #2332896=IfcWallStandardCase('2QybFYfbuHwwHpt4e_RK0V',#211,'WAI_8',$,'WAI_8',#2332893,#2332894,$),
    #11224218=IfcBeam('0p54Jmu0qHwwFneDF18Us0',#111,'Träger',$,'Kehlbalken',#11224204,#11224216,'Kehlbalken'),
    #1477238=IfcColumn('0WxCkdrOmHwwI0t4e_RK0V',#111,'Column ',$,$,#1477219,#1477236,$),
    #2178642=IfcBeam('3iw2HCu0eHwwFneDF18Us0',#211,'IfcBeam',$,$,#2178647,#2178643,$),
    #194880=IfcBeam('23njxyrOaHwwFkeDF18Us0',#111,'Träger',$,'Kehlbalken',#194866,#194878,'Kehlbalken'),
    #11054027=IfcWallStandardCase('23ui3ckXaHwwHrt4e_RK0V',#111,'WAI_20',$,'WAI_20',#11054024,#11054025,$),
    #11047523=IfcDoor('1hiWcEoB0HwwFfeDF18Us0',#111,'TIW01','Innentür',$,#11073877,#11047763,$,2100.,1000.),
    #2209930=IfcWindow('3nbvLQoO0HwwFfeDF18Us0',#211,'Fenster',$,$,#2349661,#2211434,$,2650.,5300.),
    #2154548=IfcWallStandardCase('3edYbImluHwwFZeDF18Us0',#211,'WAI_20',$,'WAI_20',#2154545,#2154546,$),
    #2153157=IfcWallStandardCase('2zSZ$6kJCHwwHrt4e_RK0V',#211,'WAI_12.5',$,'WAI_12.5',#2153154,#2153155,$),
    #1721987=IfcWallStandardCase('0P_j1AlI4HwwHrt4e_RK0V',#111,'WAA_22','Holzelementwand vorgefertigt','WAA_22',#1721984,#1721985,$),
    #190579=IfcWallStandardCase('0hIitIkwKHwwHrt4e_RK0V',#111,'WAI_20',$,'WAI_20',#190576,#190577,$),
    #2337623=IfcDoor('0_UDKQmneHwwFZeDF18Us0',#211,'TIW','Innentür',$,#2355391,#2337863,$,2100.,940.),
    ````
    Actually the result that i wanted

    My wish is to convert this parse into a df to generate a list like this one:

        Clase   Tipo    Objecto     Descripcion     ID
    0   IfcDoor     D-1     TIW01   Innentür    11u3SSoB0HwwFfeDF18Us0
    1   IfcDoor     D-1     TIW01   Innentür    11u3Z3oB0HwwFfeDF18Us0
    2   IfcDoor     D-1     TIW01   Innentür    11u3dAoB0HwwFfeDF18Us0
    3   IfcDoor     D-1     TIW01   Innentür    11u3hHoB0HwwFfeDF18Us0
    4   IfcDoor     D-1     TIW01   Innentür    11u3lOoB0HwwFfeDF18Us0
    ...     ...     ...     ...     ...     ...
    937     IfcWallStandardCase     WAI_8   WAI_8   None    03nzs_irCHwwFVeDF18Us0
    938     IfcWallStandardCase     WAI_40  WAI_40  None    0YiO6ojEeHwwFVeDF18Us0
    939     IfcWallStandardCase     WAA_40  WAA_40  None    0cHZj3nT8HwwHwt4e_RK0V
    940     IfcBuildingElementProxy     WAA_22  WAA_22  None    1dbAzLnKqHwwHwt4e_RK0V
    941     IfcWallStandardCase     WAA_22  WAA_22  None    1dbAzMnKqHwwHwt4e_RK0V
    
    942 rows × 5 columns
    

    and export it like a csv.file

    Question 1: ist that possible?
    Question 2: how can i separate the elements according to their building?

    Thank you in advance

    Archie1969

     

    Last edit: Arcangelo Sergio-Böckle 2022-06-20

Log in to post a comment.