-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A small IFC file is stuck in an infinite loop generating geometry #633
Comments
Recreated this issue in my local bouncer, and found where to set the angular resolution and linear tolerance in the import settings. These are the same as used by ODA, which is nice for #632 (they both seem to use a BRep underneath). Unfortunately changing the LOD doesn't help the issue. Using IfcConvert from the 0.7.0 build from IfcOpenShell website also locks up indefinitely, so the problem is in the latest version of the library. Building IfcOpenShell from source and running IfcConvert under the debugger shows it breaks in What happens in this function is that it tries to evaluate a sequence of curves on a face (edges in a contour). At the start of the loop it tries to remove the last evaluated edge from the list of edges ( The The debugging symbols lose where they are here so its not obvious why this call fails. The method itself is in OCCT so not easy to modify. |
@sebjf could it be that the problem lies in OCCT? |
Hi @carmenfan the problem is definitely in OCCT. The fault occurs in Unify Same Domain Build() stage, which merges coincident faces/edges that lie on coincident surfaces/curves. Specifically, its in This method iterates through all the Edges in a Shape (which sit on a curved surface). For each, it gets the Curve formed by the projection of the Edge ( In a second nested loop it iterates through all Edges that start at the same Vertex as When this second loop exits, it picks up the next Edge in the Shape and repeats. In the second nested loop, The problem is the termination criteria of the second nested loop. This loop only terminates when there are no more edges in In Concrete.ifc however, this method encounters a 'CurEdge' that never triggers this criteria, causing it to get stuck in the loop indefinitely. It is not entirely obvious why this criteria is never reached, but it seems to be an interaction between two parts of this method:
This second check occurs before 'CurEdge' is updated, meaning if it fails 'CurEdge' goes straight back to be removed from 'theVEmap' - if this operation does not decrement 'theVEmap' (which it doesn't) the loop gets stuck. I believe the intent behind how this is written is that it if What is not clear to me at the moment is whether it should be possible to call Another possible fix is to gate the curve updates differently, and make sure that 'CurEdge' is always updated by this loop. |
@sebjf would updating OCCT fixes this? (building it takes forever though 😆). Might worth checking if they've identified the issue else where and have since fixed it |
As I've found 😆 (I had to rebuild with optimisation off to investigate properly!) It is a known issue: https://tracker.dev.opencascade.org/view.php?id=32949 Reported last year but without working steps to reproduce. Someone posted another example a couple of months ago, but no activity since. |
A straightforward fix is to detect the exact condition that leads to the infinite loop (i.e. CurEdge is not removed from the theVEmap, and is not changed by the third nested loop). This can be done by modifying If it's the case that As it is without this info, the explicit test is safer. It is also highly efficient, using properties that are practically already available, just storing them for a little longer, and sits in a couple of lines at the end of the method. Concrete.ifc with the modifications: Dev NotesOpenShell 0.0.7 will make a copy of all dependencies locally, as source, which is nice. So modifications of OCCT can be attempted in-place. The debugger will find the source of the dependencies on its own but they won't automatically rebuild. The OCCT project will have a Visual Studio solution already created for it, e.g. in
This builds into
The IfcOpenShell project takes the libraries from
So, when modifying OCCT, the modified libraries must be copied from |
Bouncer Fix Regarding bouncer compatibility,
Using build-deps of OpenShell-0.6.0 allows us to see OpenShell-0.6.0 is using OCCT Using depends, we can confirm that the prebuilt bouncer binaries dynamically link the OCCT binaries. Unfortunately, building Building IfcOpenShell The SHA is The cmake changes (e.g. made through cmake-gui) are summarised below: (Note specifically that SCHEMA_VERSIONS will not be detected automatically and must be added using Add Entry)
This allows OpenShell-0.6.0 to build, and bouncer to link with OpenShell-0.6.0 and OCCT-7.3.0. However, in this configuration, Concrete.ifc loads in fine! Therefore, the bug must have been introduced between 7.3.0 and 7.5.0, and the existing OpenShell-0.6.0 binaries built using this version. Building a checkout of V7_5_0 (exactly) is binary compatible with the existing OpenShell-0.6.0 build, and the infinite loop manifests. Applying the fix above to this branch allows the existing bouncer/openshell to work with Concrete.ifc. PR Regarding the PR, the file containing the fix has undergone a number of changes since 7.5.3, so we will probably need to re-create the issue in master and make a PR based there, while duplicating the fix in our own fork of 7.3.0 until we upgrade at a later date. Using a modified version of IfcOpenShell-0.7.0, we have extracted just the shape causing the issue, however this does not import into Draw.exe built from the same tag/branch as used by IfcOpenShell-0.7.0, because the importer doesn't know about file version 3, even though it wrote it. Adding a snippet to the beginning of DRAWEXE allows us to recreate the issue inside OCCT-7.5.3 (separate to IfcOpenShell, and the customer's file) and demonstrate the fix works. However, adding the same snippet in master fails. Our fix works, but then another part of the application fails with an access violation. This time in another area, because the code checks if an edge is null, and if so does something, but assumes that thing succeeds when it doesn't - basically the same type of bug that we just fixed! (At least this one is fairly straightforward to fix as well...)
|
ISSUE #633 add regression test, update OCCT to fix the issue
Description
A customer IFC file of ~6MB is timing out. Upon inspection, it seems to be stuck on an infinite loop whilst trying to generate geometry.
Link to the model: https://asitesol.sharepoint.com/:f:/s/3DRepoTeamFolder/EvYJY_cTSr1CjSS6grflBRcBtCXPMDaIg6hAuvnafjogfQ?e=LSPGu5
The log is stuck on this stage forever until times out:
My suspicion is that it is trying to generate too high level LOD on a some tiny curves, resulting in the same vertice is being generated and it never hits the loop terminating condition (have seen something similar before in IFC Open shell years ago). So tweaking the LOD configurations may be the easiest fix as we are looking into this anyway with #632
The text was updated successfully, but these errors were encountered: