IfcOpenShell, how to add a new property and value to an object?

edited August 25 in General

Hey guys, I'm pretty new to IfcOpenShell.
What I'm trying to achieve is to iterate through a dictionary of attributes (keys) and their corresponding values and add them to an existing object.
I know I can access an object's attributes using something like:
wall.Name
or even change the Name to something that I want:
wall.Name = 'some value'
However, I don't want to have to type the name of the attribute since I'm iterating through a dictionary of attribute names and values.
Additionally, I know it is possible to change the values inside the someobject.get_info(), although that does not update the real object's attributes.
If I try to print the object, it still has the "original" set of attributes:
print(str(someobject))
Something like:
currentObject.my_custom_attributeName = my_custom_attributeValue
does not work.
How can I achieve this?
Thank you!

Tagged:

Comments

  • What about assigning a propertyset with Python IfOpenShell?


    # Create and assign property set import ifcopenshell ifc_file = 'path\to_your\ifc_file' ifcfile = ifcopenshell.open(ifc_file) products = ifcfile.by_type("IfcProduct") owner_history = ifcfile.by_type("IfcOwnerHistory")[0] walls=[] for i in products: if i.is_a("IfcWall"): walls.append(i) property_values = [ ifcfile.createIfcPropertySingleValue("Some Property Set Name ", "Some Property Name", ifcfile.create_entity("IfcText", "Some Value"), None), ] for wall in walls: property_set = ifcfile.createIfcPropertySet(wall.GlobalId, owner_history, "Some Property Set Name ", None, property_values) ifcfile.createIfcRelDefinesByProperties(wall.GlobalId, owner_history, None, None, [wall], property_set) ifcfile.write(ifc_file)
    Jesusbill
  • I just tested this little script on a simple IfcWall,

    IFC file after running this script.

  • In IFC, attributes are fixed. If you want to add arbitrary properties, use property sets, not attributes. This is as @Coen has explained. However, there is a simpler method using the IfcOpenShell API.

    import ifcopenshell
    import ifcopenshell.api
    ifc = ifcopenshell.open('path\to_your\ifc_file')
    element = ifc.by_type("IfcElement")[0] # Just as an example, you will need to select the elements you want to add properties to yourself.
    pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Your Property Set Name")
    ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"foo": "foobar", "foo2": "foobaz"})
    
  • @Moult
    Maybe it's convenient to mention how to install the ifcopenshell.api as you described here.

  • edited August 26

    Thanks for your answers @Moult and @Coen!
    But what should I do in case I need to change the actual attributes of an object? I mean, I know I can type wall.Name = "Some other name", or wall.OwnerHistory = "some new value", etc. However, if I have a dictionary with a set of keys (attribute names that already exist on target object) and values (attribute values that I want to change on target object), what should I do?
    It should be something like:
    1. Select target object given an ID
    2. Iterate through a given dictionary and then change the values of target object's attributes

    Do you have any advice?
    Thank you once again.

  • @Coen indeed thanks.

    @FDinis once you have the pset element, use ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"foo": "foobar", "foo2": "foobaz"}). It will take care of editing it.

  • @Moult
    Thank you! :)

  • great code examples.

    @Moult said:
    In IFC, attributes are fixed. If you want to add arbitrary properties, use property sets, not attributes. This is as @Coen has explained. However, there is a simpler method using the IfcOpenShell API.

    import ifcopenshell
    import ifcopenshell.api
    ifc = ifcopenshell.open('path\to_your\ifc_file')
    element = ifc.by_type("IfcElement")[0] # Just as an example, you will need to select the elements you want to add properties to yourself.
    pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Your Property Set Name")
    ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"foo": "foobar", "foo2": "foobaz"})
    

    asumed I do not want to add a new pset but edit a property from a existing pset. What is a simple method to retrieve the pset entities what works with IFC2x3? ifcopenshell.util.element.get_psets(e) returns the contents but not the entity.

    cheers bernd

  • @bernd - Do you want to edit a single occurrence of a property, aka for a single object, or are you trying to edit all instances of a certain property?

  • @bernd the latest IfcOpenShell util module has a fix for exactly this purpose, ifcopenshell.util.element.get_psets(e) will now return an id for each pset so you can easily grab it for editing.

  • edited November 3

    @Moult said:
    @bernd the latest IfcOpenShell util module has a fix for exactly this purpose, ifcopenshell.util.element.get_psets(e) will now return an id for each pset so you can easily grab it for editing.

    means I need to use 0.7.0 ?

  • edited November 3

    @vpajic said:
    @bernd - Do you want to edit a single occurrence of a property, aka for a single object, or are you trying to edit all instances of a certain property?

    both, but for the latter I just iterate over all single ones

  • @bernd you don't need to, the util module is Python only so you can just grab the latest Python files from there.

  • @Moult said:
    @bernd you don't need to, the util module is Python only so you can just grab the latest Python files from there.

    ahh sure that would work too.

    I upgraded to 0.70 anyway ...

    BTW: works great with this is it is much simpler to get the pset.

    cheers bernd

  • It does not work to access a changed property. Still the old value is used before the edit. Is there a way this is possible without writing and rereading the IFC file?

    As a workaround I do save the properties in separate dicts, but this gets complicated as more properties are involved or if a property is for some reason changed twice.

    cheers bernd

  • @bernd I don't understand. You don't need to write (serialise) and re-read the IFC file.

    import ifcopenshell
    import ifcopenshell.api
    import ifcopenshell.util.element
    ifc = ifcopenshell.api.run("project.create_file")
    element = ifc.createIfcWall()
    pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Pset_Name")
    ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"foo": "foobar", "foo2": "foobaz"})
    psets = ifcopenshell.util.element.get_psets(element)
    ifcopenshell.api.run("pset.edit_pset", ifc, pset=ifc.by_id(psets["Pset_Name"]["id"]), properties={"foo": "changed"})
    print(ifcopenshell.util.element.get_psets(element))
    
  • edited November 24

    ok works great here ...

    BTW: related in the regard of property types ... https://github.com/IfcOpenShell/IfcOpenShell/issues/1889

  • @bernd have you tested dions commit related to this issue?

  • NO not yet, ATM I do not need to change the property type, but I wanted to save the link in case it is needed.
    ATM I only change property values, but I make heavy usage of this :-) works great so far.

  • By observing the problems with IfcOpenShell in recent months, in fact, I think that only one "tool" can solve more than 90% of related problems: a complete documentation. Link: https://pythonhosted.org/eppy/Main_Tutorial.html
    I came across a Python plug-in for parsing idf files, called eppy, on Sunday. I read the documentation on Monday morning and completed the development of a computing plug-in in the afternoon. There are detailed calculation examples, code examples, and even clear explanations of some algorithms and data structures in the documentation of eppy.

    Obviously IfcOpenShell does not have such a clear documentation, many functions are "fuzzy" for beginners, and the calculation examples are not very abundant.

    I hope that enthusiastic researchers can refer to the documentation of eppy to write a documentation of IfcOpenShell. This can be more friendly to beginners

Sign In or Register to comment.