If you're reading this, we've just migrated servers! If anything looks broken please email dion@thinkmoult.com :)

Visualize IfcRelSpaceboundaries

I have a model with a number of IfcSpaces with Physical 2ndLevel IfcRelSpaceBoundaries and would like to visualize them in BlenderBIM as External or Internal with different color and wonder if anybody knows how to do this?

/Max

Comments

  • edited April 2023

    Chatgpt to the rescue... not vetted

    import bpy
    import ifcopenshell
    
    # Load the IFC file
    filename = "path/to/your/ifc/file.ifc"
    ifc_file = ifcopenshell.open(filename)
    
    # Get all IfcSpaces with Physical 2ndLevel IfcRelSpaceBoundaries
    spaces = ifc_file.by_type("IfcSpace")
    physical_spaces = []
    for space in spaces:
        if space.Representation:
            for rep in space.Representation.Representations:
                if rep.RepresentationIdentifier == "Body" and rep.RepresentationType == "SweptSolid":
                    if space.is_a("IfcSpace") and space.ElementType and space.ElementType.is_a("IfcSpaceType") and space.ElementType.PredefinedType == "INTERNAL":
                        physical_spaces.append(space)
                    elif space.is_a("IfcSpace") and space.ElementType and space.ElementType.is_a("IfcSpaceType") and space.ElementType.PredefinedType == "EXTERNAL":
                        physical_spaces.append(space)
    
    # Create two materials for internal and external spaces
    internal_material = bpy.data.materials.new("Internal")
    external_material = bpy.data.materials.new("External")
    
    # Set the diffuse colors for the materials
    internal_material.diffuse_color = (0.8, 0.8, 0.8)  # gray
    external_material.diffuse_color = (0.0, 0.0, 1.0)  # blue
    
    # Assign materials to IfcSpaces based on their InternalOrExternalBoundary property
    for space in physical_spaces:
        if space.InternalOrExternalBoundary == "INTERNAL":
            space_object = bpy.data.objects[space.GlobalId]
            space_object.data.materials.append(internal_material)
        elif space.InternalOrExternalBoundary == "EXTERNAL":
            space_object = bpy.data.objects[space.GlobalId]
            space_object.data.materials.append(external_material)
    
    
  • edited April 2023

    @theoryshaw
    Tried to run the script on the Schependomlaan converted to IFC4, because it has a lot of spaces.
    got this error.

    AttributeError: entity instance of type 'IFC4.IfcSpace' has no attribute 'ElementType'

    Looking at the code at first glance, it seems chatGPT does not understand what an IfcRelSpaceBoundary is.
    Documentation
    https://standards.buildingsmart.org/IFC/DEV/IFC4_2/FINAL/HTML/schema/ifcproductextension/lexical/ifcrelspaceboundary.htm


  • Would like to see an IFC which has IfcSpace boundaries, I don't think Schependomlaam.ifc has them?

  • I got the same error for an IFC2x3.
    AttributeError: entity instance of type 'IFC2X3.IfcSpace' has no attribute 'ElementType'

  • @Max
    Is it possible to share your IFC or maybe some similar example?

  • wow!, I just discovered you can select them with blenderBIM:

    Max
  • @Max I totally missed this topic… yes you can using IfcSelection


    Do not hesitate to tag me next time you have a question on this topic.

    Coen
  • I need to export the IfcSpaces as 3D CAD-objects (3DS) with unique colors for each face based upon IfcRelSpaceboundary (and if possible wall/slabtype) , prefarable using Python and wonder if anybody could point me in the right direction?

  • @Max have you looked at https://docs.blender.org/manual/en/dev/addons/import_export/scene_3ds.html ?

    I'd recommend looping through each IfcRelSpaceBoundary, finding its Blender object, then clearing its material slots, adding a new material with a random colour, then assigning it as the only material slot.

    f = blenderbim.tool.Ifc.get()
    boundaries = f.by_type("IfcRelSpaceBoundary")
    for boundary in boundaries:
        obj = blenderbim.tool.Ifc.get_object(boundary)
        if not obj:
            pass # load it in, or ignore? What's your usecase?
        while obj.material_slots:
            bpy.ops.object.material_slot_remove()
        mat = bpy.data.materials.new('Foo')
        mat.diffuse_color = (1,0,0,1) # Or random colour, or cycled colours, etc
        obj.data.materials.append(mat)
    
    Coentheoryshaw
  • Thanks a lot @Moult that helped a lot. I have a model ( the default Revit demo file) found at https://github.com/maxtillberg/ICEBridge/blob/main/RAC_basic_sample_project_spaces.ifc that contains boundaries but the objects contains "None" when I try the code and I wonder if this is due to this example? Also I would need to separate External and Internal boundaries with code.

    /Max

  • @Max the obj variable is probably none because it isn't loaded into Blender yet. By default space boundaries are not loaded and only loaded on demand.

    The loader is in a bit of a weird place (it should be moved to a tool function) so it's a bit awkward but you can do this to load in all space boundaries (alternatively you can choose which ones you're interested in):

    import blenderbim.bim.module.boundary.operator
    loader = blenderbim.bim.module.boundary.operator.Loader()
    for rel in tool.Ifc.get().by_type("IfcRelSpaceBoundary"):
        loader.load_boundary(rel, tool.Ifc.get_object(rel.RelatingSpace))
    
  • Thanks a lot @Moult , that explained a lot and now the code works perfectly. While I am at it I would like to add some more color features, preferable color IfcRelSpaceBoundaries according to InternalOrExternalBoundary, PhysicalOrVirtual, RelatingSpace and RelatedBuildingElement (IfcWindow, IfcWall, IfcSlab...) and wonder if you know how to do this.

  • @Max what's the issue? You can create your own colour map based on those properties via a dictionary and using a cycle to create the keys.

  • The main issue is that I am still trying to learn Python, Blender, BlenderBIM, IFC and IfcOpenShell.

Sign In or Register to comment.