[FOR V0.19] How do I set IFC attributes that are not PSets?

This forum section is only for IFC-related issues
User avatar
Moult
Posts: 129
Joined: Sat Jan 05, 2019 11:46 am
Contact:

[FOR V0.19] How do I set IFC attributes that are not PSets?

Postby Moult » Mon Jan 21, 2019 11:42 am

I see how to add PSets (by double clicking an object and clicking Edit IFC Properties), but how do I set regular IFC attributes? For instance, if I have a wall, I see that attribute #9 is a "PredefinedType" which should be of type "IfcWallTypeEnum" which can take up to 11 enumeration constants. How do I fill this value in? Or how do I fill in the "Description" IfcText that all IFC objects should have?

Relevant links:

http://www.buildingsmart-tech.org/ifc/I ... fcwall.htm
http://www.buildingsmart-tech.org/ifc/I ... peenum.htm
http://www.buildingsmart-tech.org/ifc/I ... fcroot.htm
Last edited by Moult on Wed Jan 30, 2019 8:25 am, edited 2 times in total.
I also blog about 3D rendering, architecture, software and other on thinkMoult.com. RSS / Atom feed available for your convenience.
User avatar
yorik
Site Admin
Posts: 10725
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: How do I set IFC attributes that are not PSets?

Postby yorik » Mon Jan 21, 2019 12:48 pm

This is not possible yet.. These "hard-coded", type-specific things could become proper FreeCAD properties I think...

Would you like to give it a try implementing this one? It's simple, I think it would be a perfect task to get you on track ;)

Basically it involves:

- Adding a new enumeration property to walls, in https://github.com/FreeCAD/FreeCAD/blob ... ll.py#L507
- Modifying the IFC importer to set that property, for ex after https://github.com/FreeCAD/FreeCAD/blob ... FC.py#L811
- Modifying the IFC exporter to export that property after https://github.com/FreeCAD/FreeCAD/blob ... C.py#L1762
User avatar
Moult
Posts: 129
Joined: Sat Jan 05, 2019 11:46 am
Contact:

Re: How do I set IFC attributes that are not PSets?

Postby Moult » Sat Jan 26, 2019 11:43 am

Thanks Yorik! I have implemented in this to an extent. Now is a good time to get a review :)

Here is a video of it working on my computer:

https://peertube.social/videos/watch/67 ... 60cc6e9d04

Here are the two branches for you to look through:

https://github.com/Moult/BIM_Workbench/ ... te-support
https://github.com/Moult/FreeCAD/commits/fix-ifc

The functionality works through two json files, ifc_products.json and ifc_types.json. As the name suggests, the first holds all the non-abstract IfcProduct classes that FreeCAD needs to support. It has a list of attributes (including all inherited attributes) for each product, and all possible enum values too. The ifc_types.json, also as the name suggests, holds all the IFC data types, like IfcLabel, IfcInteger, and so on. It also has a mapping of these to FreeCAD's App::Property* types, so we can support it better. The json files live in the presets dir just like the pset csv.

https://github.com/Moult/BIM_Workbench/ ... lements.py
https://github.com/Moult/FreeCAD/blob/f ... ducts.json
https://github.com/Moult/FreeCAD/blob/f ... types.json

In the Arch module itself, I have:

1. Refactored IfcAttribute's property to be called IfcData. This was to prevent confusion as then it would be ambiguous what to store the actual attributes in. This also prevents the Ifc data being spread around. I have the idea to store IfcData = { "IfcUID": ..., "settings": ..., "attributes": ..., "psets": ... } in the future.
2. Based on the json file and the selected role, new fields will be added to the arch component under the "IFC Attributes" category. The data is there, but is actually stored in obj.IfcData["attributes"] as a json serialised string. Perhaps the pset implementation can be ported to this technique too, instead of the ";;" separators currently used. It will read the json to know what type of App::Property* it needs to be.
3. It can import and export attributes.

There are a few issues still, and this is expected:

1. Previously, some hard coded IFC attributes were set based on FreeCAD values. Currently, if a user defines their own value, it will override these FreeCAD values.
2. These JSON files are IFC4Add2. This means that IfcOpenShell _must_ be compiled with IFC4 support, otherwise it will not work. Also, some of the previous code hardcoded attributes of IFC2x3, and so they will need to be removed in favour of reading from the json file.
3. I do not think I can generate a JSON file for IFC2x3, because I don't know where their XSD file is for that version. It is possible that it doesn't exist. If so, this code will break 2x3 support, which is not good. Not sure how to best handle this.
I also blog about 3D rendering, architecture, software and other on thinkMoult.com. RSS / Atom feed available for your convenience.
User avatar
yorik
Site Admin
Posts: 10725
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: How do I set IFC attributes that are not PSets?

Postby yorik » Sat Jan 26, 2019 10:32 pm

Amazing work!! The way you implemented it is really elegant. Congrats!

I think we still need to tie something to the built-in properties, it is weird for ex. for a wall to have a "height" property twice, one that is "manual" and one "automatic", so to speak..

I agree with moving the IfcAttributes stuff to IfcData, and reserve IfcAttributes for proper IFC Attributes. After the 0.18 release I'd also like to rename IFC Role to IFC Type, I think that's what everybody will find logical. Arch/BIM objects should have an "IFC" properties group where we put all that's regarding IFC (type, attributes, etc)

Also, now, when an Arch component-based object is loaded from a file, a setProperties() function is run. We should use that to detect old IfcAttributes and transfer everything needed to IfcData

Regarding IFC4, a large number of people still use IFC2x3. And will do for a long time I think... So we cannot do something that will make IFC2x3 not work. But, I think we can also implement stuff that will only work with IFC4 (that's even a good incentive for people to use it more ;) ) and simply be transparently discarded with IFC2x3. We just need to take care of documenting that properly.
User avatar
Moult
Posts: 129
Joined: Sat Jan 05, 2019 11:46 am
Contact:

Re: How do I set IFC attributes that are not PSets?

Postby Moult » Sun Jan 27, 2019 12:37 pm

Thanks for the feedback, Yorik! I have tried to address all of these issues in the latest commits:

https://github.com/Moult/FreeCAD/commits/fix-ifc

Specifically:

1. In SetProperties, if any IfcAttributes is found, it is migrated to IfcData. I have tested opening an older FreeCAD file and it seems to work.
2. I have included JSON files for 2x3, and it now loads different JSON files depending on the schema. This allows us to support multiple IFC versions easily. The JSON files for 2x3 cannot be autogenerated as the old spec didn't have an XSD. I have converted your old hardcoded values into a JSON file, with empty attributes. So it'll load it, and simply not load the attributes features. Therefore, no IFC4 attribute code will be triggered. Now, it supports both IFC2x3 and IFC4. If you have IFC2x3, these new features will not appear. If you have IFC4, you will see all these new features.
3. I've refactored the IFC related code into ArchIFC.py to be reused. This allows site objects and building storey objects to also have IFC attributes.
4. IFC4 attributes, when added for the first time, are set up with an expression that links them to native FreeCAD properties. This makes it "smart" by default, but users have the option to override in case they want to be creative with their data :) The export code is also updated to call a 2x3 export function, which maintains the old behaviour, but if IFC4 is available, it will use the smart attributes.
I also blog about 3D rendering, architecture, software and other on thinkMoult.com. RSS / Atom feed available for your convenience.
User avatar
yorik
Site Admin
Posts: 10725
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: How do I set IFC attributes that are not PSets?

Postby yorik » Mon Jan 28, 2019 2:30 pm

It's better not make all the arch stuff depend on ifcopenshell. It might not be installed on every users machine, and will render the Arch WB unusable. Also, the next version of ifcopenshell (0.6) will support multiple schemas. I'm not sure how the schema identification works.
In any case, you should put the import ifcopenshell inside a try/except, and see what to do if it's not installed...

And another thing that is good to be aware of, FreeCAD has a huge amount of heavy dependencies. We always try to apply the "late loading" philosophy: Only load components when they will effectively be used. Otherwise the FreeCAD startup quickly becomes very slow. Ifcopenshell is quite a heavy load, as it pushes a lot of OCC stuff. So it should not happen on module init. In python, you can import a module as many times as you want, with no harm. Only the first time it gets actually loaded. So I would actually import ifcopenshell not in the file header (because that file will be imported at init) but inside the functions that will use it.

But great progresses overall! I'm really glad someone else is tackling this code!

Just FYI, since this is becoming quite a large rework, in any case it'll be for after the 0.18 release okay? We're in feature freeze mode after all :)
User avatar
Moult
Posts: 129
Joined: Sat Jan 05, 2019 11:46 am
Contact:

Re: How do I set IFC attributes that are not PSets?

Postby Moult » Tue Jan 29, 2019 10:23 am

Thanks for the feedback! I have pushed code around a little bit and removed the dependency for ifcopenshell. After all, it was only actually loading it to check the IFC version which is completely overkill. Now, I have added a little config option in the GUI which allows users to switch between IFC2X3 and IFC4. So now none of the code imports ifcopenshell :)

I've created a PR to track the issue and perhaps we can continue discussion on there. I think it is a good idea to wait until after 0.18 is released, as it is certainly growing to be a "big change".

https://github.com/FreeCAD/FreeCAD/pull/1938
I also blog about 3D rendering, architecture, software and other on thinkMoult.com. RSS / Atom feed available for your convenience.
User avatar
bernd
Posts: 7068
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: How do I set IFC attributes that are not PSets?

Postby bernd » Tue Jan 29, 2019 12:44 pm

yorik wrote:
Sat Jan 26, 2019 10:32 pm
Amazing work!! The way you implemented it is really elegant. Congrats!
+1

yorik wrote:
Sat Jan 26, 2019 10:32 pm
After the 0.18 release I'd also like to rename IFC Role to IFC Type, I think that's what everybody will find logical.
+1

yorik wrote:
Sat Jan 26, 2019 10:32 pm
Arch/BIM objects should have an "IFC" properties group where we put all that's regarding IFC (type, attributes, etc)
+1