XbimGeometry icon indicating copy to clipboard operation
XbimGeometry copied to clipboard

Exception in BRepPrimAPI_MakePrism after switching to 5.1.328

Open baron-instalsoft opened this issue 4 years ago • 3 comments

CreateContext on throw exception when attached ifc file is loaded on version 5.1.328. Version 5.1.317 loads file without problems.

Assemblies and versions affected:

Xbim.Geometry 5.1.328

Steps (or code) to reproduce the issue:

using (var model = IfcStore.Open("MakePrismError.ifc"))
{
    var context = new Xbim3DModelContext(model);
    context.CreateContext();
}

Minimal file to reproduce the issue:

MakePrismError.zip

Expected behavior:

Context is created without exception

Actual behavior or exception details:

Exception is thrown:

External component has thrown an exception. at BRepPrimAPI_MakePrism.{ctor}(BRepPrimAPI_MakePrism* , TopoDS_Shape* , gp_Vec* , Boolean , Boolean ) at Xbim.Geometry.XbimSolid.Init(IIfcExtrudedAreaSolid solid, IIfcProfileDef overrideProfileDef, ILogger logger) at Xbim.Geometry.XbimSolid..ctor(IIfcExtrudedAreaSolid solid, ILogger logger) at Xbim.Geometry.XbimGeometryCreator.CreateSolid(IIfcExtrudedAreaSolid ifcSolid, ILogger logger) at Xbim.Geometry.XbimGeometryCreator.Create(IIfcGeometricRepresentationItem geomRep, IIfcAxis2Placement3D objectLocation, ILogger logger) at Xbim.Geometry.Engine.Interop.XbimGeometryEngine.Create(IIfcGeometricRepresentationItem ifcRepresentation, ILogger logger) at Xbim.ModelGeometry.Scene.Xbim3DModelContext.<>c__DisplayClass39_0.<WriteShapeGeometries>b__0(Int32 shapeId) at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1() at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask) at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object )

Additional Details

Attached file is a file form client with deleted most of parts. Don't look at warnings, they are due those deletions.

baron-instalsoft avatar Sep 30 '20 11:09 baron-instalsoft

Ok, so I took a quick look at this and although I’m not 100% sure that I have a fully solid/exact solution for the problem I think that I at least have something that Steve can continue to look into (mainly see that it doesn’t break anything else….) (Also, I have a slightly modified version of xbim myself that allows me to easily change tolerance/fuzzy-factor, deflection, etc., but other than that it should be fairly up-to-date with the development version and I can reproduce the issue (exception) when trying to load the attached file.)

What I found is: #96985 (IfcExtrudedAreaSolid) is the problematic shape. Using the default file tolerance of 1E-05, we get an exception in BRepPrimAPI_MakePrism (XbimSolid.cpp: void XbimSolid::Init(IIfcExtrudedAreaSolid^ repItem, IIfcProfileDef^ overrideProfileDef, ILogger^ logger)).

Using a tolerance of 0.035 the geometry is correctly created (However, the wire/loop is not closed when constructed, but the ShapeFix_Wire appears to fix it)

Using a tolerance of 0.009 the geometry is correctly created. However, in addition to the wire/loop not being closed when constructed (but the ShapeFix_Wire appears to fix it), we also see that after the face is created (using BRepBuilderAPI_MakeFace), the ShapeAnalysis_Wire returns true on CheckSelfIntersection(), and then ShapeFix_Shape/BRepBuilderAPI_MakeFace is NOT able to fix it. Still, the geometry can be created using the “unfixed” face.

Using a tolerance below 0.008 will not work (exception)…

Ok, so now to the solution! After I found the above info I took a look in the OCC documentation and found that sometimes you also need to call ShapeFix_Wireframe in order to fix any issues. So, if ShapeFix_Shape/BRepBuilderAPI_MakeFace wasn’t able to fix the face, I then applied ShapeFix_Wireframe in a similar fashion afterwards. Now, this didn’t make any difference, BUT it made me miss calling return after the fix had been found to not work… …which then made ShapeFix_Edge be called at the end of the function. And then, TA-DA, suddenly everything worked even with the default file precision of 1E-05!!!!!

So, to sum up, in “XbimFace.cpp” in “void XbimFace::Init(IIfcProfileDef^ profile, ILogger^ logger)” (line 1026 in development branch) when we have “//it is a standard profile that can be built as a single wire” we should NO longer return early from the function even if wireChecker.CheckSelfIntersection() (line 1071) returns true and the face appears not to have been fixed. Instead, we should always let “ShapeFix_Edge” et al (line 1111) process the face before returning.

Now, the reason I started to look into this was that I had a couple of other models that also stopped at this very same exception. These models now work fine, however, I guess some other tests are further needed in order to see that this “solution” doesn’t break anything else…

By the way, how can I see how date/commits correspond to (nuget) releases?? For instance, how do I see which was the last commit to master before release 5.1.317??

/Mikael

jomijomi avatar Oct 15 '20 00:10 jomijomi

We should be adding tags to source. Will try to set this up.

martin1cerny avatar Oct 15 '20 06:10 martin1cerny

This sounds really interesting I will have a good look shortly, thanks for joining the "Harry Potter" school of Opencascade Magic Tricks Mikael, your input is very welcome

SteveLockley avatar Oct 15 '20 12:10 SteveLockley