How to extract Location data from IFC

Hi
I have a IFC file and I want to retrieve tuple in IfcCartesianPoint.
Please guide me through the relevant sources.

Comments

  • Have you read this crash course? https://wiki.osarch.org/index.php?title=IfcOpenShell_code_examples I think it will help answer a lot of questions.

  • edited July 2021

    Hi
    I read an IFC file and parsed it based on a condition.
    I want to extract IfcCartesianPoint for that extracted list.
    Below is my code and I get a error saying "list objects no attribute by_type"

    import multiprocessing
    import ifcopenshell
    import ifcopenshell.geom
    import ifcopenshell.util
    from ifcopenshell.util.selector import Selector
    
    ifc = ifcopenshell.open(r'Filename.ifc')
    
    settings = ifcopenshell.geom.settings()
    iterator = ifcopenshell.geom.iterator(settings, ifc, multiprocessing.cpu_count())
    if iterator.initialize():
        while iterator.next():
            selector = Selector()
            element = selector.parse(ifc, '.IfcBuildingElementProxy[Name="PUP Sewer Jnct"]')
            shape = iterator.get()
            coordinates = element.by_type("IfcCartesianPoint")
            print(coordinates)
    
  • In your code, element is a list, not a single element. The selector filters your file by your query and returns a list of elements. That is why you're getting your error.

    What exactly are you trying to achieve? Do you want to know the location of each object? Are you trying to convert element geometry into vertices and faces?

  • I want the location of each object in the list.

  • @Shilpa try this:

    elements = selector.parse(ifc, '.IfcBuildingElementProxy[Name="PUP Sewer Jnct"]')
    for element in elements:
        placement_matrix = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
        print(placement_matrix)
    
  • edited July 2021

    I tried that and below is the error message :

    AttributeError                            Traceback (most recent call last)
    <ipython-input-2-c5f678fd821d> in <module>
         14         elements = selector.parse(ifc, '.IfcBuildingElementProxy[Name="PUP Sewer Jnct"]')
         15         for element in elements:
    ---> 16             placement_matrix = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
         17             print(placement_matrix)
    
    AttributeError: module 'ifcopenshell.util' has no attribute 'placement'
    
  • You have an old IfcOpenShell. See this link for the latest util module: https://github.com/IfcOpenShell/IfcOpenShell/tree/v0.6.0/src/ifcopenshell-python/ifcopenshell

  • Can you please let me know how to update the util module in jupyter notebooks?

  • I have not used Jupyter before, unfortunately, so I don't know :(

  • I updated all the packages in my conda environment. ifcopenshell version is v0.6.0.
    Will the util module also gets updated automatically?

  • @Shilpa perhaps yes, perhaps no. The util module moves a bit faster than the conda builds I expect, so I'm not sure how recent the conda builds are.

  • edited July 2021

    Hi
    Below is my code

    import multiprocessing
    import ifcopenshell
    import ifcopenshell.geom
    from ifcopenshell.util.placement import get_local_placement
    from ifcopenshell.util.selector import Selector
    
    ifc = ifcopenshell.open(r'C:\12d\14.00\Metro Project\PUP Delivery\12dSewerService.ifc')
    
    settings = ifcopenshell.geom.settings()
    iterator = ifcopenshell.geom.iterator(settings, ifc, multiprocessing.cpu_count())
    if iterator.initialize():
        while iterator.next():
            selector = Selector()
            elements = selector.parse(ifc, '.IfcBuildingElementProxy[Name="PUP Sewer Jnct"]')      
            for element in elements:
                placement_matrix = get_local_placement(element.ObjectPlacement)
                print(placement_matrix)
    

    My Output is :

    [[1. 0. 0. 0.]
     [0. 1. 0. 0.]
     [0. 0. 1. 0.]
     [0. 0. 0. 1.]]
    [[1. 0. 0. 0.]
     [0. 1. 0. 0.]
     [0. 0. 1. 0.]
     [0. 0. 0. 1.]]
    

    But i want to retrieve the below from the ifc file

     IFCCARTESIANPOINT((51971.12751875, 158030.33677902, -1.494));
    #29 = IFCCARTESIANPOINT((51971.12751875, 158030.33677902, 4.598));
    #30 = IFCCARTESIANPOINT((51971.1328404, 158030.4631682, -1.494));
    #31 = IFCCARTESIANPOINT((51971.1328404, 158030.4631682, 4.598));
    

    Let me know how to retrieve these values from ifc file.

  • Given an element, you can retrieve all related cartesian points like this:

    points = [e for e in ifc.traverse(element) if e.is_a("IfcCartesianPoint")]
    print(points)
    
  • Hi Moult

    Attached is the image of an IFC file opened in BIM vision. Highlighted fields show Global X, Global Y and Global Z of the selected segment.
    I want to extract those fields using Ifcopenshell.
    I extracted IfcCartesianPoint , expecting that would be same as Global X, Global Y and Global Z. But they are not same. Below image shows the extracted cartesian points.

    My question is how can I extract the Global X, Global Y and Global Z fields which are visible in BIM Vision.

    Thanks
    Shilpa

  • @Shilpa
    I think you should go through the all hierarchy of Site/Building/Storey and assess all the local coordinates of them.

  • @Shilpa what's shown in your screenshot is not the coordinates of a vertex. It is the coordinates of the object placement. This can be done with one line of code using ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement). This will give you a matrix which includes that location in absolute coordinates.

    Note that these are global engineering coordinates. If your file contains georeferencing map conversions, you may want to then further apply the map conversion to get map grid coordinates. You can use ifcopenshell.util.geolocation.local2global or ifcopenshell.util.geolocation.xyz2enh for this.

    Then, should you wish to find the absolute coordinate of a local coordinate of a particular vertex within the shape, you may multiply the coordinate by the matrix.

    VDobranov
  • Hi Moult
    Attached is the IFC file I read.
    I tried the lines of code you mentioned. Attached is the output.

    My file does not have georeferencing map conversions. It does not have IfcMapConversion field.

  • @Shilpa correct, that matrix is what you need. Look at the numbers in the fourth (last) column of the matrix, and you will see the first three are the XYZ values you are looking for.

  • @Shilpa don't forget to say thank you

  • Hi Duncan
    Thanks for reminding me. I am still working on this . It is not resolved yet. The values retrieved were not same as the ones present in BIM vision screenshot (first image).
    But anyways a Big Thanks for all your suggestions so far.

  • @Shilpa can I help in any way? In your code screenshot on Sep 15, the values are indeed similar to the BIM vision screenshot. The discrepancy may be explained either by a bug in BIM vision, or that you have not truly selected the object origin (for example, if that value in BIM vision is invented or derived by BIM vision through some unofficial means, like a centroid of a bounding box).

  • Hi all. I am an engineer and very minimal background on coding. I tried the code but there is an error said "ModuleNotFoundError: No module named 'ifcopenshell.util.placement'". What should I do with this. Thanks for helping!

  • Hey @Qui it sounds like you have an outdated version of IfcOpenShell. Download the latest from here https://github.com/IfcOpenBot/IfcOpenShell/commit/05256fc0f43c418c5166c1d10eaeab212f398fea#commitcomment-59166428

  • Hi Moult. Thanks for super prompt response. Sorry for troubling you more. I am very new to all this python programming. I installed anaconda 3 (Spyder) with Python 3.8. Then I installed IfcOpenshell using anaconda prompt. So how can I update IfcOpenshell library now?
    Thanks a lot.

  • You can extract the ifcopenshell folder and replace your existing ifcopenshell folder that comes with conda. You can find it in your anaconda site packages folder. If you're not sure where this is, use import sys and print(sys.path) which will tell you.

  • Hi Qui
    Try giving the module explicitly as below.
    import ifcopenshell
    import ifcopenshell.util.placement

  • Thanks a lot Moult. Let me try it out.

Sign In or Register to comment.