Identify failed IFC surface (IDA ICE) and how to delete them

I have a general question, and if this is a bit to spesific for my main work software i can accept that, hower i do hope to get some help into this issue.

At times we receive non functional IFC files for use in IDA ICE. There will be some surfaces which can not be imported, like the image under suggest. This causes me to not be able to start my environmental modeling as i then need a DWG file instead to model the needed geometry for the building.

Whilst searching for the Brep number, blenderbim can not detect the surface. This led me to try the Debug "test all shapes" with a hope that if there are some mesh that is not valid, i could delete them and thus export a new IFC file for IDA ICE. This yields the following message after running BlenderBims "Test all shapes" :

"Info: Failed shapes: 170, check the system console for details."

Unfortunately it does not seems like i can select these 170 surfaces which causes my issue with import into IDA ICE. Would anyone have a suggestion into what more i can do to quickly find these meshes?

Max

Comments

  • Hi! You can check the system console for the list of failed elements and their ids. If you want to delete them all you can put their ids in the short script below.

    import blenderbim.tool as tool
    import bpy
    
    failed_elements = [1280, 1246, 1222]
    
    ifc_file = tool.Ifc.get()
    failed_elements = [ifc_file.by_id(i) for i in failed_elements]
    failed_objects = [tool.Ifc.get_object(element) for element in failed_elements]
    tool.Blender.set_objects_selection(bpy.context, None, failed_objects)
    bpy.ops.bim.override_object_delete(is_batch=True)
    
  • edited January 15

    Good afternoon.
    Would it be these numbers i would have to put in the "[ ]" notation? If so, there is a lot of manual work here. i can not copy paste the console text, and my suggested workflow was to take the text into excel and manipulate the infor there, and then copy it into the [ ] notation

  • No, you'll need ids of the elements (#33, #34, #35), not some of their attributes.
    Why cannot copy the text from console - what system you're using?

  • I am using windows 10.
    As i have 170 elements, i have to then write [1, 2, 3 .... 170] ?
    Is python the same as octave when it comes to selecting numbers from/to by the operator ":".

    Would it then work by [1:170] ?

  • edited January 16

    Tried to modify your script by adding failed_elements = [list(range(33, 92))] and it unforitonaly is not returning with any promessing result with some error codes.
    However when i study the objects which is in the list there is some xx numbers, xxx, xxxxx and xxxxxx numbers, meaning i can not generate with ease any list taking # 33, # 481, #98887 and #190505 as an example. Is there ny way to modify the script to just auto decide what numbers the failed elements are and place them in the [] list for failed_elements?
    attaching the IFC file i am exploring the work flow with.

  • I am using windows 10.

    It is possible to copy the text from the cmd on windows, there probably some option in the settings. Though I'm using Windows 11 and settings for cmd are a bit different here, so can't show you the exact setting. Then you'd be able to get ids from the beginning of each string either in excel or some text editor to create an arbitrary list like [33, 481, 98887].
    Creating list with failed_elements = list(range(33, 92)) will work if you're sure affected elements are all elements in the range 33-91.

    Is there ny way to modify the script to just auto decide what numbers the failed elements are and place them in the [] list for failed_elements?

    Sure, you reuse bim.create_all_shapes operator execute code from here and combine it with the script above. After the opeartor's code executed, variable failures is a list of entities that have issues with the representation and it can be used as failed_elements in the previous script.

  • Thank you for your feedback. It sounds really promessing that it can be done, however i do feel embarrassed as i do need more assistance. I am not familiar with programing at all beside making one mathematical script in Octave. The way i read your suggestion is to simply copy the entire section where this bim.create_all_shapes is used, and combine the first set of code. I can only imagine that

    failed_elements = failures = []

    I am confident i have done this inaccurately, may i ask for more help?

    import blenderbim.tool as tool
    import bpy

    class CreateAllShapes(bpy.types.Operator):
    bl_idname = "bim.create_all_shapes"
    bl_label = "Test All Shapes"
    bl_description = "Look for errors in all the shapes contained in the file"

    @classmethod
    def poll(cls, context):
        return IfcStore.get_file()
    
    def execute(self, context):
        self.file = IfcStore.get_file()
        elements = self.file.by_type("IfcElement") + self.file.by_type("IfcSpace")
    
        total = len(elements)
        settings = ifcopenshell.geom.settings()
        settings_2d = ifcopenshell.geom.settings()
        settings_2d.set(settings_2d.INCLUDE_CURVES, True)
        failures = []
        excludes = ()  # For the developer to debug with
        for i, element in enumerate(elements, 1):
            if element.GlobalId in excludes:
                continue
            print(f"{i}/{total}:", element)
            start = time.time()
            shape = None
            try:
                shape = ifcopenshell.geom.create_shape(settings, element)
            except:
                try:
                    shape = ifcopenshell.geom.create_shape(settings_2d, element)
                except:
                    failures.append(element)
                    print("***** FAILURE *****")
            if shape:
                print(
                    "Success",
                    time.time() - start,
                    len(shape.geometry.verts),
                    len(shape.geometry.edges),
                    len(shape.geometry.faces),
                )
        self.report({"INFO"}, f"Failed shapes: {len(failures)}, check the system console for details.")
        for failure in failures:
            print(failure)
        return {"FINISHED"}
    

    failed_elements = failures = []
    ifc_file = tool.Ifc.get()
    failed_elements = [ifc_file.by_id(i) for i in failed_elements]
    failed_objects = [tool.Ifc.get_object(element) for element in failed_elements]
    tool.Blender.set_objects_selection(bpy.context, None, failed_objects)
    bpy.ops.bim.override_object_delete(is_batch=True)

  • By some help from ayex in the chat yesterday i had assistance to where the missing copy function for the toggle system control was hiding. After some math magic in excel + notepad i got finaly the number sequens in the script provided by Andrej730. I am happy to share i succeeded deleting the inaccurate surface, made new IFC and had a successful import of the IFC into IDA ICE.

    Even if the window shape in the image underneath is not accurate, working in floor plan 2D mode i can still make the geometry for my needs, and also see where i can place out IDA ICE Windows. I hope this tread can be useful for more people, or with simelar needs when it comes to IFC Debug -> Test all shapes. :)

    Nigel
Sign In or Register to comment.