BB: quick way to select/deselect all objects that have a IfcSweptAreaSolid class associated with it?

edited March 2022 in General

Is there a quick way to select/deselect all objects that have a IfcSweptAreaSolid class associated with it?

For example, we want to quickly assess which objects in this file are not IFC extrusions.

Comments

  • edited March 2022

    Don't know if it is the best way, but you can use this script in the Text Editor. For deselecting, just change "True" to "False" in the last line:

    import bpy
    import ifcopenshell
    import blenderbim.tool as tool
    from blenderbim.bim.ifc import IfcStore
    
    file = IfcStore.get_file()
    elements = file.by_type('IfcBuildingElementProxy')
    
    ifc_extrusions = []
    
    for e in elements:
        if e.Representation.Representations[0][2] == "SweptSolid":
            ifc_extrusions.append(e)
    
    objects = []
    
    for obj in ifc_extrusions:
        objects.append(tool.Ifc.get_object(obj))
    
    for obj in objects:
        obj.select_set(True)
    
    theoryshawDarth_BlenderbrunopostleAce
  • edited March 2022

    Very cool!
    As you see from this video it seems to only pick some of the extrusions.
    Any ideas why?

  • edited March 2022

    Per this video, even if it seems that it's an extrusion, if you 'Update Mesh as Arbitrary Extrusion', on the object, that the script works again. Strange.

  • @theoryshaw said:
    Very cool!
    As you see from this video it seems to only pick some of the extrusions.
    Any ideas why?

    The script assumes that all your elements are IfcBuildingElementProxy, so it won't pick up IfcCovering or similar. It also assumes that the Body representation is the first representation, but this is unlikely to be a problem unless you have multiple representations.

  • Thanks Bruno. With these large scale details, all the objects are classified as IfcBuildingElementProxy elements.
    But yeah, maybe it has something to do with Body representation... not sure.

  • Yeah, I made it too specific regarding the element type. Also, I don't fully understand Ifc Representation, I'll have to take a closer look at it. I'll try to write another version later.

  • This element:

    #144077=IFCBUILDINGELEMENTPROXY('15Furswqj9GxDI0ELt87JD',#144088,'Generic Models 841:Generic Models 1:245',$,$,#144137,#144102,$,$);
    

    ..has two representations:

    #144102=IFCPRODUCTDEFINITIONSHAPE($,$,(#144101,#144098));
    

    The first representation is BoundingBox:

    #144101=IFCSHAPEREPRESENTATION(#29,'Box','BoundingBox',(#144100));
    

    The second representation is the SweptSolid:

    #144098=IFCSHAPEREPRESENTATION(#28,'Body','SweptSolid',(#144097));
    

    The code should do something like this (untested):

    for e in elements:
        for representation in e.Representation.Representations:
            if representation.RepresentationIdentifier == "Body" and representation.RepresentationType == "SweptSolid":
                ifc_extrusions.append(e)
    
    theoryshaw
  • Thanks, @brunopostle! It's working better, but it still left a few objects that supposed to be extrusions. I checked one of them, and I got this value for its representation (#127142=IfcShapeRepresentation(#27,$,'SweptSolid',(#127141)),). I noticed that it doesn't have a Representation Identifier, and I guess that's why the script didn't work for it. It makes sense just to erase this condition and look just for the Representation Type?

  • Yes, the RepresentationIdentifier is unnecessary since a SweptSolid can only be Body anyway.

  • Here's the full script after the improvements:

    import bpy
    import ifcopenshell
    import blenderbim.tool as tool
    from blenderbim.bim.ifc import IfcStore
    
    file = IfcStore.get_file()
    elements = file.by_type('IfcElement')
    
    ifc_extrusions = []
    
    for e in elements:
       for representation in e.Representation.Representations:
            if representation.RepresentationType == "SweptSolid":
                ifc_extrusions.append(e)
    
    objects = []
    
    for obj in ifc_extrusions:
        objects.append(tool.Ifc.get_object(obj))
    
    for obj in objects:
        obj.select_set(True)
    
    theoryshawbrunopostleDarth_Blenderchunchk
  • I wonder if IFC should have something like an SQL query language for this sort of thing:

    SELECT * FROM IfcElement WHERE Representation.RepresentationType CONTAINS etc..
    

    Alternatively, blenderbim could have a function like autocad 'quick select', with a dynamic filter displaying available properties in context - but this wouldn't be as powerful

  • Was getting these errors

    File "c:\Users\Owner\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\blenderbim\extrusion_selection.py", line 12, in <module>
        for representation in e.Representation.Representations:
    AttributeError: 'NoneType' object has no attribute 'Representations'
    
    File "c:\Users\Owner\AppData\Roaming\Blender Foundation\Blender\3.5\scripts\addons\blenderbim\extrusion_selection.py", line 23, in <module>
        obj.select_set(True)
    AttributeError: 'NoneType' object has no attribute 'select_set'
    Location: c:\Program Files\Blender Foundation\Blender 3.5\3.5\scripts\modules\bpy\ops.py:111
    

    So added the following...

    import bpy
    import ifcopenshell
    import blenderbim.tool as tool
    from blenderbim.bim.ifc import IfcStore
    
    file = IfcStore.get_file()
    elements = file.by_type('IfcElement')
    
    ifc_extrusions = []
    
    for e in elements:
        if e.Representation is not None:
            for representation in e.Representation.Representations:
                    if representation.RepresentationType == "SweptSolid":
                        ifc_extrusions.append(e)
    
    objects = []
    
    for obj in ifc_extrusions:
        objects.append(tool.Ifc.get_object(obj))
    
    for obj in objects:
        if obj is not None:
            obj.select_set(True)
    
    bruno_perdigao
Sign In or Register to comment.