xBimTeam / XbimGeometry

XbimGeometry contains the CLR interop libraries and the c++ engine used to compute the 3D geometry of models.
https://xbimteam.github.io/
Other
260 stars 131 forks source link

Incorrect curve parameters when creating XbimCurve for trimmed ellipse #447

Open ChernyshevDS opened 1 year ago

ChernyshevDS commented 1 year ago

Hello again. I've encountered a problem with incorrect mesh generation when trying to load a specific IFC4 model (stripped file is attached below). Some of the elements seem to have distorted geometry:

изображение

I beleive that I've managed to find the source of the issue. When loading the model I've received a number of the same warnings like:

Failed to project vertex to edge geometry, start point assumed

This warning is generated in XbimCompound::InitAdvancedFaces(IEnumerable<IIfcFace^>^ faces, ILogger^ logger), specifically for the entity IfcEdgeCurve #189964. It has underlying EdgeGeometry of IfcTrimmedCurve #189961 which trims an IfcEllipse #189960 with trimming defined with cartesian points.

The end trimming point clearly lies on the ellipse, but XbimCurve::LocatePointOnCurve returns false. I beleive it is caused by incorrect Geom_Curve construction in void XbimCurve::Init(IIfcTrimmedCurve^ curve, ILogger^ logger).

OpenCascade has a limitation for ellipse shape: unlike IfcEllipse, it should always have a major radius greater than minor radius. To overcome this limitation there is an additional rotation by Pi/2 applied to ellipse in XbimCurve::Init(IIfcEllipse^, ILogger^) in case when SemiAxis1 < SemiAxis2. This rotation of course has to be taken into account when adjusting trimming parameters.

There is a piece of code in XbimCurve::Init(IIfcTrimmedCurve^ curve, ILogger^ logger) that does exactly that:

if (isEllipse)
{
    IIfcEllipse^ ellipse = (IIfcEllipse^)curve->BasisCurve;
    if (ellipse->SemiAxis1 < ellipse->SemiAxis2)
    {
        u1 -= Math::PI / 2;
        u2 -= Math::PI / 2;
    }
}

However, it should not be applied to parameters u1 and u2 if they were previously calculated from cartesian points with GeomLib_Tool::Parameter, because they are already calculated from ellipse rotated by Pi/2.

I've made some corrections and created a patch: fix_trimmed_ellipse.patch

Corrected model: изображение

Assemblies and versions affected:

XbimGeometry 5.1.403, commit https://github.com/xBimTeam/XbimGeometry/commit/24a3db9442b33578eebf9fbf2eb58074cc3afc56

Minimal file to reproduce the issue:

IFC VK L4.ifc.stripped.ifc.txt

andyward commented 1 year ago

Thanks for this detailed investigation! Any chance you can submit as a PR rather than a patch? Ideally you'll add a quick test using your stripped model (that'll help ensure we keep this fixed as we merge with the incoming v6 changes.)

ChernyshevDS commented 1 year ago

@andyward Done: https://github.com/xBimTeam/XbimGeometry/pull/449