IfcOpenShell patch reset shared coordinates - possible to specify coordinates and rotation?

I have used ifcOpenShell patch tool to remove large coordinates from an IFC-file. Now I would like to specify the coordinates and rotation it should be moved by. See more details in this post on buildingsmart forums.

Is someone willing to give me a hint on how to accomplish this with python? Maybe even better if it woud be possible to copy the local coordinates from another IFC file.

Comments

  • Ok, so I figured out how the patch tool works, and it was surprisingly simple. I guess it will be more challenging to fix the rotation. Maybe some kind of matrix calculation?

    import ifcopenshell


    offset_x = 500

    offset_y = 1000

    offset_z = 0


    file = ifcopenshell.open("D:\import_global.ifc")


    points = file.by_type('IfcCartesianPoint')

    for point in points:

      if len(point.Coordinates) == 2:

        continue

      point.Coordinates = (

        point.Coordinates[0] - offset_x,

        point.Coordinates[1] - offset_y,

        point.Coordinates[2] - offset )


    file.write("D:\output_local.ifc")

    magicalcloud_75
  • OK, it did not work for all elements unfortunately. Some fire insulation and steel plates have jumped out of the bulding.


    magicalcloud_75
  • To displace all objects by a particular value, I would recommend only changing the coordinates of the world, which everything inherits from ... i.e. change the WorldCoordinateSystem attribute of the IfcGeometricRepresentation(Sub?)Context. Then it would affect everything without needing to change hundreds of thousands of coordinates.

    This documentation page may help:

    If it is confusing, let me know and I can build the patch recipe for you, otherwise, I think it is a good exercise for you to figure out and learn more about IFC and OpenBIM :)

  • Thanks @Moult ! There seem to be multiple ´IfcGeometricRepresentationContext´s, should I try to change all of them? I tried to move them like this, and it looks like the points are written to the IFC-file when I look at it in a text editor However in Solibri the old and new model stay in the same place.

    import ifcopenshell
    
    new_coordinate = (128930.387, 1532255.932, 3.32)
    
    file = ifcopenshell.open("D:\MTRE-NessetH.ifc")
    points = file.by_type('IfcCartesianPoint')
    print("random point:")
    print(points[8])
    
    print("Location of IfcGeometricRepresentationContext:")
    contexts = file.by_type('IfcGeometricRepresentationContext')
    for context in contexts:
      context.WorldCoordinateSystem.Location.Coordinates = new_coordinate
       
    print("Location of IfcGeometricRepresentationSubContext:")   
    subcontexts = file.by_type('IfcGeometricRepresentationSubContext')
    for subcontext in subcontexts:
      subcontext.WorldCoordinateSystem.Location.Coordinates = new_coordinate
       
    print(file.by_type('IfcGeometricRepresentationContext')[0].WorldCoordinateSystem.Location.Coordinates)
    file.write("D:\output.ifc")
    

    This is how I see this in my head: If I move the base point close to the geometry, the coordintes will be much closer to each other. Is this totally wrong?


  • Reading this informative post was very helpful to better understand what's going on: https://thinkmoult.com/ifc-coordinate-reference-systems-and-revit.html .

    It seems that in the file I'm testing, the coordinates are set absolute for each point in each object. That means the coordinates in the project/building/site are not inherited and are not used for anything.

    This made we monder if it was possible to set wall.ObjectPlacement.PlancementRelTo to inherit from site somehow. This is what I tried:

    ..and this is how it worked out:


  • @Einar - could you please send me your IFC file to dion@thinkmoult.com - you can use https://send.firefox.com to securely send it end-to-end-encrypted. I will only use your file for purposes of debugging your issue and will not reshare your file.

    Einar
  • @Einar - I thought that it would be able to be solved by merely changing the WorldCoordinateSystem attribute, but it seems I was wrong. I am not entirely sure if it is due to lack of implementations properly handling the attribute, or if my understanding of the IFC specification is incorrect there.

    In any case, I have written an IfcPatch recipe to achieve it:

    Hope it solves your issue. You can use it like so:

    ifcpatch -i foo.ifc -r OffsetObjectPlacements -a -128900 -1532260 0 90
    

    The first three arguments are the XYZ translation to apply, and the fourth argument is the angle to rotation anti-clockwise in degrees, around the global Z axis (I do not see a reason to implement arbitrary axis rotation).

    Einar
  • Nice @Moult! Seems like a better solution to move all IfcLocalPlacement than all IfcPoint.I will test it later to day.

    Did you think that the world coordinates should have been inherited automatically? Do you know how the PlancementRelTo attribute works? Maybe I should try to formulate a question over at the buldingSMART forums.

  • @Einar I believe when that world coordinates are inherited automatically, yes ... however, the documentation hints that it is only inherited in the case of world coordinates (i.e. when applying a map conversion). In that case, if the BIM authoring program does not perform the CRS transformation, it is also not required to apply the world coordinate system - which would explain the behaviour I see.

    I had hoped optimistically (but incorrectly) that BIM programs would have implemented the world coordinate system transformation.

    ReD_CoDE
  • It seems to work very well. Thank you very much again.

  • Not for all cases though, when I tried with the model in the other tread the result was more "interesting".


  • @Einar - my bad, I forgot that the coordinate or direction could be reused.

    Fixed, I think: https://github.com/IfcOpenShell/IfcOpenShell/commit/13d434c00fa77d5f399118008704a28db6883bdd

  • I can confirm that it is fixed! At least for the case above. You are amazing @Moult :)

    Moult
  • Hi @Moult, I'm pretty new to ifcopenshell and I'm wondering why ifcPatch is not included when installing ifcopenshell via conda or pip?
    Is there a tutorial on how to install/configure/run ifcpatch?
    I've got several ifc files with kinda random project base points. In order to move the whole building to the project basepoint, I was trying to move the project basepoint to the building. But I haven't figured out how to do this programmatically. Is there a workaround to change the world coordinate system? Would be happy for any help!

  • edited March 4

    I've figured it out. There is no need of installing, just clone the repo and direct to the ifcpatch path.
    My issue was a spelling error that I had taken from an official example: https://blenderbim.org/docs-python/ifcpatch.html
    Instead of using:
    ifcpatch -i input.ifc -o output.ifc -r ExtractElements -a "IfcWall"
    use:
    python -m ifcpatch -i input.ifc -o output.ifc -r ExtractElements -a "IfcWall"
    in the command line, where your input.ifc is located as well.

Sign In or Register to comment.