F
by FDinis on 25 Aug 2021, edited 8 Jun 2023
#
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!
C
by Coen on 25 Aug 2021
#
+3 votes
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)
C
by Coen on 25 Aug 2021
#
I just tested this little script on a simple IfcWall,

IFC file after running this script.

M
by Moult on 26 Aug 2021
#
+2 votes
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"})
C
by Coen on 26 Aug 2021
#
@Moult
Maybe it's convenient to mention how to install the ifcopenshell.api as you described here.
F
by FDinis on 26 Aug 2021, edited 26 Aug 2021
#
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:
-
Select target object given an ID
-
Iterate through a given dictionary and then change the values of target object's attributes
Do you have any advice?
Thank you once again.
M
by Moult on 5 Sep 2021
#
@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.
B
by bernd on 2 Nov 2021
#
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
V
by vpajic on 2 Nov 2021
#
@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?
M
by Moult on 3 Nov 2021
#
@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.
B
by bernd on 3 Nov 2021, edited 3 Nov 2021
#
@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 ?
B
by bernd on 3 Nov 2021, edited 3 Nov 2021
#
@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
M
by Moult on 3 Nov 2021
#
@bernd you don't need to, the util module is Python only so you can just grab the latest Python files from there.
B
by bernd on 3 Nov 2021
#
@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
B
by bernd on 4 Nov 2021
#
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
M
by Moult on 8 Nov 2021
#
+1 votes
@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))
B
by bernd on 24 Nov 2021, edited 24 Nov 2021
#
ok works great here ...
BTW: related in the regard of property types ... https://github.com/IfcOpenShell/IfcOpenShell/issues/1889
V
by vpajic on 24 Nov 2021
#
@bernd have you tested dions commit related to this issue?
B
by bernd on 25 Nov 2021
#
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.
S
by shanmama on 2 Dec 2021
#
+1 votes
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
I
by InformationWorker on 4 Aug 2022
#
Looked exactly like what I was looking for..... Sadly it does not work on my end :-(

C
by Coen on 4 Aug 2022
#
@InformationWorker
Your screenshot confuses me, :-), what are you trying to achieve? Also I don't recognize the IDE you using.
I
by InformationWorker on 5 Aug 2022, edited 5 Aug 2022
#
+1 votes
@Coen said:
@InformationWorker
Your screenshot confuses me, :-), what are you trying to achieve? Also I don't recognize the IDE you using.
Hi Coen, thanks for the reply.
- That's VScode, but the console in Blender gives thes same results. Here is the same from jupyter following your code goes well until it's time to fill/declare the properties list. I did that to rule out any issues with python.

- What I am after is:
a. the ability to check the properties of every single element (agains some source, e.g. doors should be wood, color red, classified as IfcDoor)
b. adjust the properties of elements that are non compliant (e.g. change the color of the door)
I have been trawling the internet but have not found anything more than this page. The https://wiki.osarch.org/index.php?title=IfcOpenShell_code_examples#Crash_course gives some code to retrieve information using "Selector", which offers me some better options where it comes to retreiving information in the name, but also nothing on how to update properties.
I have tried to find information on using the export to CSV from CLI but found nothing.
Addition I tried @Moult suggestion on this page too. Same thing happens :-( Looking deeper into the code, I believe it's not me it's "file.py" Here are my steps:
- am I correct that there is no function called "ifc.createIfcWall()" and that "create_entity('IfcWall')" is to be used as mentioned in the "file.py"? Or does it strip that IfcWall of during the call.

- I follow the example in the "file.py" still it does not work.


- if I try as create_entity() the response suggests there should be a type as one would expect. But as you see under #2 that gives an err.

Hope this helps, Edgar
P
by polsonmila on 19 Aug 2022
#
This is a great discussion. Thank you all for these wonderful contributions. It has helped me alot. I am creating working on creating a property set. Thanks for this insight.