changing IfcClasses with python
Hello guys , i hope you are doing good ! I have my ifc file but when i insvistigate the ifcProduct ive found out that some elements are not appropriatly assigned to their classes , like for a 'Refrigerator' it has in Ifc Class 'IfcBuildingElementProxy' instead of 'IfcElectricAppliance'
So as i Exported all the ifc Elements in a csv file I have corrected the mistaken classes :
here is the export befor correcting
here after correcting
Now i wonder how i can now correct the ifc with python ifcopenshell lib , cause i have tried to import the csv with the BlenderBIM addon but the software shuts down whenever i click in import button hahaha (weird)
I hope someone can help with this , Thank you so much !
Tagged:
Comments
If the software shuts down after trying to import a CSV, please report a bug and attach a file (or share to [email protected] if private). That's pretty critical.
In code, you can do:
See https://docs.ifcopenshell.org/autoapi/ifcopenshell/api/root/reassign_class/index.html#module-ifcopenshell.api.root.reassign_class
i'll make sure to report a bug . Thank you for helping @Moult , really appreciate it !
Hello @Moult ,
Sorry to interfere on this subject, but I'm trying to change an IFC Class on some of my models too.
Is it possible to make "ifcopenshell.api.root.reassign_class" function work inside a python script after loading file with ifcopenshell. open() ? See code below
import ifcopenshell
model = ifcopenshell.open('model.ifc')
wall = model.by_type("IfcWall")[0]
slab = ifcopenshell.api.root.reassign_class(model, product=wall, ifc_class="IfcSlab")
Last line triggers an error because "ifcopenshell.api has no attribute 'root'".
Any advice ?
Thanks a lot !!
>
did should work ( there is at least 1 x IfcWall in the model):
Omg, I'll try this this evening when I'll be home.
If this is it, I really lack some learning. I thought calling it fully with
ifcopenshell.api.root.reassign_class()
would be enough.Thanks ! I'll keep you informed !
That last line in your code is not a call but an assignment (to a ‘slab’). In Python you call a library with the import function (like Steverugi demonstrated in his line 2). So in short you didn’t call the
ifcopenshell.api.root.reassign_class()
and that’s why you were getting an error:)It is both a call and an assignment. The issue was that
ifcopenshell.api.root
module wasn't imported before it'sifcopenshell.api.root.reassign_class
method was called.Hello again,
I've been able to make it work for some models, but I have issues on some specific ones...
I managed to reproduce the issue on a simple model (linked below).
What I do is I filter some elements then I change their class from IfcBuildingElementProxy to IfcFanType (for example).
What I get is an IFC where I can't see any of those filtered elements. When I edit IFC file and look for element by GUID, I can clearly see that they are supposed to be here, as IfcFanTypes.
Any idea why we can't see any geometry ?
Thanks again <3
No sure if this is the same problem.
When selecting "Object Metadata" where the same IFCType but different "Predefined Type" the selection does not distinguish the difference in IFCType.
This was using version 240903
@Roel
I am not sure if this is related but to the best of my knowledge an IfcType has only one predefined type, if you change it on one instance the others using the same will update accordingly
Any time you edit the attributes make sure they show the desired predefined, otherwise update it from the main Object Metadata at the top ,in any case it needs to show in the Attributes too as PredefinedType and in bracktes at the top next to the Ifc class (like IfcCovering[CEILING] should appear without brackets also in the Attributes below the Name)
Thanks for the response, due to my lack of knowledge I thought there was an selection error but if you want to select all the "main" IfcType elements then you click on the "arrow" but if you want to select the PredefinedType you press Shit and click the "arrow". - Problem solved \0/ sorry it did not help the original post.
Hi @Roel
PredefinedType (PT) assignment in Bonsai still looks a tad shaky in my personal opinion
Conversely
hopefully the above won't stir a hornet's nest among other members :))
cheers
We only recently started supporting reassigning class from occurrence class to type class (and vice versa) and I do see now the geometry in Bonsai after executing your script. Previously representations were not reassigned in the way they are assigned to types, so were just left orphaned.
So it should work after this commit, to try it out you'll need the latest code from the github.
From IfcWindow documentation:
Sounds like a bug, please report it.
hi @Andrej730
I read the
NOTE
like 10 times but couldn't figure out its actual (and practical) meaning sorry, I wish someone here could translate it in plain english for me if possiblewill do thanks
E.g. there is an IfcWindow. If it has a type IfcWindowType then IfcWindow.PredefinedType should never be taken into account as IfcWindowType.PredefinedType overrides it.
So then we add a new occurrence of IfcWindowType then there is no need to fill IfcWindow.PredefinedType and it's fine to just keep it None.
And from API POV if you want to get predefined_type for an element you should use https://docs.ifcopenshell.org/autoapi/ifcopenshell/util/element/index.html#ifcopenshell.util.element.get_predefined_type instead of accessing it directly.
thank you @Andrej730 for the quick reply, truly appreciated
If I understand it properly:
If a window is an istance of a type no predefined is needed since it gets it from the very type, cool
but when I create instances from a type they do not come with their predefined as per their type unless I reassign it after
which means if no reassignment takes place after creating them they do not have a predefined type from their type
I noticed it by looking at their Attributes or extracting their data with the Spreadsheet
filter = IfcWallType, result:
filter = IfcWall, result of a newly created wall using the same IfcWallType
noted! thanks again
Sounds like there is some confusion going on in this table - it's getting PredefinedType directly from the element instead of using api method.
following your advice I tried and yes, using
element.get_predefined_type(element)
does return the correct value of the original type, but it does not reflect in the spreadsheet or UI, is it a bug or intentional? thanks@steverugi it's not a bug, it is just that the command
element.get_predefined_type(element)
looks at the type instead of the element.In my opinion, btw, the problem still exists because, from a user perspective view, the export with filter=IfcWall should show the predefined type instead of N/A...it should be inherited somehow...
@steverugi I've investigated a bit, there is a special keyword "predefined_type" that will ensure inheritance is taked into account (see selector syntax docs), opposing to "PredefinedType" that would actually retrieve "PredefinedType" attribute value from IFC element. It seems "predefined_type" should work for 99% of the cases.
Though currently it's not supported loading "predefined_type" back to ifc file. Previously it would fail completely, I've changed this in this commit - now "predefined_type" just will be skipped and will give a warning, so atleast it won't get in the way until we support it.
I found where it's coming from - it's probably occured when you were editing object attributes from Object Properties and changed it's name, which was calling attribute.edit_attributes which is discarding occurrence PredefinedType if it has a type to maintain consistency, so it's not a bug.
thanks @Andrej730
I tried it, it does
well noted, cheers
Okay, it should be possible now after this commit