I am currently investigating the IfcOpenShell capabilities in general and the additional options which are offered by connecting IfcOpenShell to FreeCAD.
I made a simple FreeCAD Arch "testcase" which consists of a wall. As long as I export this wall with and without the IfcOpenShell support both exports work well and can be visualized with different ifc viewers of my choice.
When I put a round hole inside the wall this is no longer the case - I think because it forces an export as building element proxy / triangulated geometry and not as a standard ifc element. The native FreeCAD exporter produces accurate results (by using triangulation as well as brep) - but the export with IfcOpenShell (it says export as a advanced brep) is inaccurate as you can see in the pictures.
Without IfcOpenShell serializer (native FreeCAD ifc Export):
With IfcOpenShell serializer:
Have you observed something similar ? Why is the IfcOpenShell Export not working as expected and how can we improve this ?
I already pulled the latest IfcOpenShell src recently.
Regards
Martin
Last edit: Martin Naumann 2017-05-05
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This might not be the fault of the serializer, but of your IFC viewer. Not many apps already support the IfcAdvancedBrep correctly. Mind to share the second file?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay the shape is indeed not rendered well in IFC... Could you ifcopenshell gurus have a look? Maybe we're using the serializer wrongly in FreeCAD? This is basically what we do in FreeCAD (use the attached brep file):
Well, I had a bit deeper look in the code and it seems indeed that for the IFC2X3 schema (i.e advanced is forced to false [1]) non polyhedral faces (either due to underlying surface [2] or boundary [3]) get silently discarded as a failed face does not propagate up [4]. Now that we have everyone around the same table, can we agree on how this code should behave? My initial idea was users call serialise() and if that returns False users can try again with tesselate() which will always succeed. But what to do if some faces cannot be serialized?
Yorik, with ifc_file.traverse(serialisation_result) you can count how many IfcFaces are in the result and see whether that equals the amount of TopoDS_Faces. But perhaps the code should simply fail in case one or more faces cannot be serialized according to the current schema?
Just compiled your latest changes to test.
Indeed it still fails with IFC2X3, with IFC4 it gives a bit better result (see attached IFC file), but there is still one cylindrical face missing apparently (The problem is to find apps able to read IfcAdvancedBrep! (FreeCAD and IfcOpenShell always on the vanguard ;) )
In any case I could add in FreeCAD a switch to only use the serializer if we are in IFC4, because in lower versions the serializer does the same job as FreeCAD's internal algo (IfcFacetedBrep, but it tesselates if any non-polyhedral face). The real killer feature of the serializer is its used of IfcAdvancedBrep, and it wasn't there in IFC2X3 anyway.
Otherwise, yeah, I think failing if not all the faces could be rendered is a good idea, if it is easy to implement on your side. That's quite consistent with what you did elsewhere in IfcOpenShell, and easy to handle by host applications. Otherwise we can also count faces like you suggest.
BTW, There is a change in current IfcOpenShell, many entities are written using .F. instead of $ (ex. the code snipped above gives IfcProductDefinitionShape(.F.,.F.,(#0))
many others such as IfcBuilding, IfcSite, .. also use .F. instead of $
I don't know if that is intentional? IFC++ complains about that...
many entities are written using .F. instead of $ I don't know if that is intentional?
No it wasn't, thanks for pointing that out. There has been some refactoring going on in the background, things should be more stable now.
I think failing if not all the faces could be rendered is a good idea
This is implemented now. Perhaps throwing an exception in Python rather than returning None is still a bit better though?
one cylindrical face missing apparently
This issue is still unsolved. There is a face with a cyclindrical surface written to the file, but somehow it doesn't carry over when imported back. Not sure if this is a flaw in writing or reading. There are some intricacies with these kind of faces in Open Cascade. IIRC every face needs to be bounded in both the U and V directions, which is not entirely obvious for cylindrical and surfaces with a domain of 0-2pi.
Thanks for investigating and sorry for the slow reply.
Kind regards,
Thomas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey IfcOpenShell fans and developers,
I am currently investigating the IfcOpenShell capabilities in general and the additional options which are offered by connecting IfcOpenShell to FreeCAD.
I made a simple FreeCAD Arch "testcase" which consists of a wall. As long as I export this wall with and without the IfcOpenShell support both exports work well and can be visualized with different ifc viewers of my choice.
When I put a round hole inside the wall this is no longer the case - I think because it forces an export as building element proxy / triangulated geometry and not as a standard ifc element. The native FreeCAD exporter produces accurate results (by using triangulation as well as brep) - but the export with IfcOpenShell (it says export as a advanced brep) is inaccurate as you can see in the pictures.
Without IfcOpenShell serializer (native FreeCAD ifc Export):
With IfcOpenShell serializer:
Have you observed something similar ? Why is the IfcOpenShell Export not working as expected and how can we improve this ?
I already pulled the latest IfcOpenShell src recently.
Regards
Martin
Last edit: Martin Naumann 2017-05-05
This might not be the fault of the serializer, but of your IFC viewer. Not many apps already support the IfcAdvancedBrep correctly. Mind to share the second file?
Hey Yorik,
I will have a look for some other ifc viewers. Nevertheless I uploaded the second file here: http://s000.tinyupload.com/?file_id=07813784338143612094
BTW: Awesome work from you on FreeCAD and your blog !
Thanks!
Okay the shape is indeed not rendered well in IFC... Could you ifcopenshell gurus have a look? Maybe we're using the serializer wrongly in FreeCAD? This is basically what we do in FreeCAD (use the attached brep file):
Hi,
Apologies for the late reply. The issue Yorik refers to should have been fixed with: https://github.com/IfcOpenShell/IfcOpenShell/commit/1856c499b7e77567d4b5f919823f0a4cae265854 which should fix this issue with
#0
in aggregate of entity instance references.On the other hand it makes me wonder why there is any geometry at all in that case. Are there perhaps two issues interfering here?
Can you have another look with a more recent build of IfcOpenShell? Do I need to supply one?
Kind regards,
Thomas
Hi,
Well, I had a bit deeper look in the code and it seems indeed that for the IFC2X3 schema (i.e advanced is forced to false [1]) non polyhedral faces (either due to underlying surface [2] or boundary [3]) get silently discarded as a failed face does not propagate up [4]. Now that we have everyone around the same table, can we agree on how this code should behave? My initial idea was users call serialise() and if that returns False users can try again with tesselate() which will always succeed. But what to do if some faces cannot be serialized?
Yorik, with ifc_file.traverse(serialisation_result) you can count how many IfcFaces are in the result and see whether that equals the amount of TopoDS_Faces. But perhaps the code should simply fail in case one or more faces cannot be serialized according to the current schema?
[1] https://github.com/IfcOpenShell/IfcOpenShell/blob/master/src/ifcgeom/IfcGeomSerialisation.cpp#L487
[2] https://github.com/IfcOpenShell/IfcOpenShell/blob/master/src/ifcgeom/IfcGeomSerialisation.cpp#L452
[3] https://github.com/IfcOpenShell/IfcOpenShell/blob/master/src/ifcgeom/IfcGeomSerialisation.cpp#L394
[4] https://github.com/IfcOpenShell/IfcOpenShell/blob/master/src/ifcgeom/IfcGeomSerialisation.cpp#L477
Kind regards,
Thomas
Hi Thomas,
Just compiled your latest changes to test.
Indeed it still fails with IFC2X3, with IFC4 it gives a bit better result (see attached IFC file), but there is still one cylindrical face missing apparently (The problem is to find apps able to read IfcAdvancedBrep! (FreeCAD and IfcOpenShell always on the vanguard ;) )
In any case I could add in FreeCAD a switch to only use the serializer if we are in IFC4, because in lower versions the serializer does the same job as FreeCAD's internal algo (IfcFacetedBrep, but it tesselates if any non-polyhedral face). The real killer feature of the serializer is its used of IfcAdvancedBrep, and it wasn't there in IFC2X3 anyway.
Otherwise, yeah, I think failing if not all the faces could be rendered is a good idea, if it is easy to implement on your side. That's quite consistent with what you did elsewhere in IfcOpenShell, and easy to handle by host applications. Otherwise we can also count faces like you suggest.
BTW, There is a change in current IfcOpenShell, many entities are written using .F. instead of $ (ex. the code snipped above gives
IfcProductDefinitionShape(.F.,.F.,(#0))
many others such as IfcBuilding, IfcSite, .. also use .F. instead of $
I don't know if that is intentional? IFC++ complains about that...
No it wasn't, thanks for pointing that out. There has been some refactoring going on in the background, things should be more stable now.
This is implemented now. Perhaps throwing an exception in Python rather than returning None is still a bit better though?
This issue is still unsolved. There is a face with a cyclindrical surface written to the file, but somehow it doesn't carry over when imported back. Not sure if this is a flaw in writing or reading. There are some intricacies with these kind of faces in Open Cascade. IIRC every face needs to be bounded in both the U and V directions, which is not entirely obvious for cylindrical and surfaces with a domain of 0-2pi.
Thanks for investigating and sorry for the slow reply.
Kind regards,
Thomas