OSArch Community

Updating/inserting new parameters inside IFC files using belnderBIM

  1. F

    I have started using BlenderBIM Bonsai since a week ago. I wanted to update IFC files data parameters. I have succeeded in updating the parameters inside the IFC file and then save the IFC file with the new parameters using python scripts. That process will take between 10 seconds and a couple of minutes based on the file size. I found that the more objects are available, the longer it will take to complete the task ( the time of competition of each object will elongate with the increase in object quantity).

    Ex :

    1. File with 100 objects, then each object to be updated will require something around 0.02 seconds.

    2: File with 2000 objects, then each object to be updated will require something around 1.3 seconds.

    However, when I tried to do so with files that contain huge number of objects ( more than 10 k) , each object will require more than 5 seconds. For a file the contains 23 k objects each object will require around 14.6 seconds, so that to update the file I do need 4.2 days :).

    If someone can support/advise me about the optimum way to update the data using BlenderBIM/Bonsai regardless of the file size or number of objects.

    Below is the code I am using:

    Get all the from the SQL Server

    query = ("""SELECT '0, ' + LEFT([filename],23) + '.dgn, Design Model:' + cast(cast([Id] as bigint) as varchar(100)) as FileID,

    [Trade],[Sub Trade],[Construction Zone Number],[Room Number],[Level 1],[Level 2],[Level 3],[Level 4],[Level 6],[BIM Code],

    [BIM Description],[CSI Code],[Unit],cast(cast([Quantity] as bigint) as varchar(100)) as Quantity,[Electrical Zone],[HVAC Zone],[Fire Fighting Zone],[Fire Evacuation Zone],[Nominal Size],

    [Asset Code],[Function],[Circuit Number],[Equipment Mechanical Interface],[Equipment Electrical Interface],[Equipment Parent],[Fire Resistance Rating],

    [Control Circuit Number],[Asset Code 2],[Asset Code 3] FROM [Tandem].[dbo].[myTable] where [filename] like '%"""+ Modlenamex + "%'")

    df = pd.read_sql(query, cnxn)

    if df.empty:

    print('The selected file has no records in the MTO database table or you have not selected all items!')
    
    bpy.ops.bim.save_project(filepath="C:\\Users\\far\\Desktop\\BIM\\Blender IFC\\" +  Modlenamex + ".ifc", should_save_as=True, save_as_invoked=True)
    
    print ('Finiiiiiiiiished Running the Code')

    else:

    for obj in selection:
    
        obj.select_set(True)
    
        # some exporters only use the active object
    
        view_layer.objects.active = obj
    
        name = bpy.path.clean_name(obj.name)
    
        bpy.ops.bim.enable_editing_attributes(obj=obj.name)
    
        ModelObjectId = bpy.data.objects[obj.name].BIMAttributeProperties.attributes[2].string_value
    
        myidDF = df.query('FileID == **@ModelObjectId**')        
    
        if myidDF.empty:
    
            print('The selected object ', ModelObjectId,' has no records in the MTO Database File!')
    
        else:
    
            ##### Add the header Paramter   #####
    
            bpy.ops.bim.add_pset(obj=obj.name, obj_type="Object")
    
            bpy.data.objects[obj.name].PsetProperties.active_pset_name = "Graphical_Parameter"
    
            bpy.ops.bim.disable_pset_editing(obj=obj.name, obj_type="Object")
    
        #    print (bpy.data.objects[obj.name].PsetProperties.active_pset_name)
    
        #    print(bpy.data.objects[obj.name].PsetProperties.active_pset_id) 
    
            bpy.ops.bim.enable_pset_editing(pset_id=0, pset_name="Graphical_Parameter", pset_type="PSET", obj=obj.name, obj_type="Object")  
    
            # Loop to add the Graphical Data related to each object ID
    
            for column in myidDF:
    
        #        print (column.count) 
    
                bpy.data.objects[obj.name].PsetProperties.prop_name = column
    
                if myidDF.iloc[0][column] is None:
    
                        bpy.data.objects[obj.name].PsetProperties.prop_value = "-"
    
                        bpy.ops.bim.add_proposed_prop(obj=obj.name, obj_type="Object", prop_name=column, prop_value="-")
    
                else:
    
                    bpy.data.objects[obj.name].PsetProperties.prop_value = myidDF.iloc[0][column]
    
                    bpy.ops.bim.add_proposed_prop(obj=obj.name, obj_type="Object", prop_name=column, prop_value=myidDF.iloc[0][column])            
    
            #Save the add grpahical data to the object
    
            bpy.ops.bim.edit_pset(obj=obj.name, obj_type="Object", pset_id=0)
    
            obj.select_set(False)
    
    #bpy.ops.bim.save_project(filepath="C:\\Users\\far\\Desktop\\BIM\\Blender IFC\\", Modlenamex,".ifc", should_save_as=True, save_as_invoked=True)
    
    bpy.ops.bim.save_project(filepath="C:\\Users\\far\\Desktop\\BIM\\Blender IFC\\" +  Modlenamex + ".ifc",should_save_as=True, save_as_invoked=True)
    
    print ('This is the total selected object: ', len(bpy.context.selected_objects))
    
    print ('Finiiiiiiiiished Running the Code')
  2. B

    Somthing I encountered as well and have it on my ToDo for years.

    Double the elements in a file to add new pset.properties too results in much much more than double the time it takes. For small modells (less than 1k elements) it does not matter, but as soon as there are more than 5k elements we are no longer talking about minutes but hours ...

    ATM I am still happy because the biggest model I need to add pset.attributes too is 3.5k elements. It takes around 45 minutes to add all the pset.properties.

    I do not use any sql, just pure python and ifcopenshell. Parse the model, add one pset.attribute with a value to any IfcBuildingElement, write the model to a new file name.

  3. S

    Hi @FirasAr

    if you like you can use the code view in Markdown, just start the first line with ```(backtick) python and close it in the same way, like this:

    
    query = ("""SELECT '0, ' + LEFT([filename],23) + '.dgn, Design Model:' + cast(cast([Id] as bigint) as varchar(100)) as FileID,
    
    [Trade],[Sub Trade],[Construction Zone Number],[Room Number],[Level 1],[Level 2],[Level 3],[Level 4],[Level 6],[BIM Code],
    
    [BIM Description],[CSI Code],[Unit],cast(cast([Quantity] as bigint) as varchar(100)) as Quantity,[Electrical Zone],[HVAC Zone],[Fire Fighting Zone],[Fire Evacuation Zone],[Nominal Size],
    
    [Asset Code],[Function],[Circuit Number],[Equipment Mechanical Interface],[Equipment Electrical Interface],[Equipment Parent],[Fire Resistance Rating],
    
    [Control Circuit Number],[Asset Code 2],[Asset Code 3] FROM [Tandem].[dbo].[myTable] where [filename] like '%"""+ Modlenamex + "%'")
    
    
    df = pd.read_sql(query, cnxn)
    
    
    if df.empty:
    
       print('The selected file has no records in the MTO database table or you have not selected all items!')
    
       bpy.ops.bim.save_project(filepath="C:\Users\far\Desktop\BIM\Blender IFC\" + Modlenamex + ".ifc", should_save_as=True, 
    
       save_as_invoked=True)
    
       print ('Finiiiiiiiiished Running the Code')
    
    
    else:
    
       for obj in selection:
    
       obj.select_set(True)
    

    cheers

  4. C

    I haven't looked at your code too hard but likely the issue is that you're trying to work on the IFC using the bpy.ops methods.

    If you want to do things quickly to IFC with code, you're much better off using the IfcOpenShell library directly:

    https://docs.ifcopenshell.org/ifcopenshell-python.html

    I also started with bpy.ops methods as it's quite intuitive when you first begin, but in the long run it's not feasible for a lot of stuff.

  5. M
  6. E

    Well, as an IfcOpenShell newbie, I was querying the property names. For some models properties are applied per element type and the query is quite fast (as I know it now), but for some models properties are applied per element, and, oh boy, it almost takes ages to process the file.

    So, if it is possible to apply the type value - do it. And yes, use IfcOpenShell directly, it saves a lot of machine cycles.

  7. F
  8. F

    @bernd said:

    Somthing I encountered as well and have it on my ToDo for years.

    Double the elements in a file to add new pset.properties too results in much much more than double the time it takes. For small modells (less than 1k elements) it does not matter, but as soon as there are more than 5k elements we are no longer talking about minutes but hours ...

    ATM I am still happy because the biggest model I need to add pset.attributes too is 3.5k elements. It takes around 45 minutes to add all the pset.properties.

    I do not use any sql, just pure python and ifcopenshell. Parse the model, add one pset.attribute with a value to any IfcBuildingElement, write the model to a new file name.

    Thank you for your comment, I would advise you to refer to the below anwers

Login or Register to reply.