From a4b1543736adf922d61bd12e376822d67a3ad186 Mon Sep 17 00:00:00 2001 From: Bernold Kraft Date: Thu, 7 Nov 2019 09:44:30 +0100 Subject: [PATCH 1/5] Reintroducing lazy handling of non-closed IfcClosedShells --- Xbim.Geometry.Engine/XbimCompound.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Xbim.Geometry.Engine/XbimCompound.cpp b/Xbim.Geometry.Engine/XbimCompound.cpp index 44d28b5eb..38cbefa05 100644 --- a/Xbim.Geometry.Engine/XbimCompound.cpp +++ b/Xbim.Geometry.Engine/XbimCompound.cpp @@ -565,11 +565,18 @@ namespace Xbim if (volume < 0) pCompound->Reverse(); double oneCubicMillimetre = Math::Pow(closedShell->Model->ModelFactors->OneMilliMeter, 3); volume = Math::Abs(volume); - if (/*volume != 0 && */volume < oneCubicMillimetre) //sometimes zero volume is just a badly defined shape so let it through maybe + if (volume < oneCubicMillimetre) //sometimes zero volume is just a badly defined shape so let it through maybe { - XbimGeometryCreator::LogWarning(logger, closedShell, "Very small closed IfcClosedShell has been ignored"); - pCompound->Nullify(); - pCompound = nullptr; + if (0 == volume) + { + XbimGeometryCreator::LogWarning(logger, closedShell, "Non-closed IfcClosedShell #{0} detected", closedShell->EntityLabel); + } + else + { + XbimGeometryCreator::LogWarning(logger, closedShell, "Very small closed IfcClosedShell (#{0} mm3) has been ignored", volume); + pCompound->Nullify(); + pCompound = nullptr; + } } } } @@ -581,10 +588,12 @@ namespace Xbim } } } + void XbimCompound::Init(IIfcOpenShell^ openShell, ILogger^ logger) { Init((IIfcConnectedFaceSet^)openShell, logger); } + bool XbimCompound::Sew() { From dd654e3fad5a9ded24f84a66d71e5735104ae7ee Mon Sep 17 00:00:00 2001 From: Bernold Kraft Date: Tue, 19 Nov 2019 15:18:29 +0100 Subject: [PATCH 2/5] Adopting volume properties in geometry wrappers --- Xbim.Geometry.Engine/XbimCompound.cpp | 20 ++++++++--- Xbim.Geometry.Engine/XbimCompound.h | 7 ++-- Xbim.Geometry.Engine/XbimGeometryObject.h | 12 ++++--- .../XbimGeometryObjectSet.cpp | 18 +++++++++- Xbim.Geometry.Engine/XbimGeometryObjectSet.h | 1 + .../XbimPoint3DWithTolerance.h | 2 ++ Xbim.Geometry.Engine/XbimShell.cpp | 17 ++++++++-- Xbim.Geometry.Engine/XbimShell.h | 3 +- Xbim.Geometry.Engine/XbimShellSet.cpp | 33 +++++++++++++++++++ Xbim.Geometry.Engine/XbimShellSet.h | 3 ++ Xbim.Geometry.Engine/XbimSolid.cpp | 10 +++--- Xbim.Geometry.Engine/XbimSolid.h | 2 +- Xbim.Geometry.Engine/XbimSolidSet.cpp | 31 ++++++++++++++--- Xbim.Geometry.Engine/XbimSolidSet.h | 3 +- 14 files changed, 136 insertions(+), 26 deletions(-) diff --git a/Xbim.Geometry.Engine/XbimCompound.cpp b/Xbim.Geometry.Engine/XbimCompound.cpp index 38cbefa05..f968400e8 100644 --- a/Xbim.Geometry.Engine/XbimCompound.cpp +++ b/Xbim.Geometry.Engine/XbimCompound.cpp @@ -629,18 +629,30 @@ namespace Xbim return true; } - double XbimCompound::Volume::get() + Nullable XbimCompound::Volume::get() { if (IsValid) { GProp_GProps gProps; BRepGProp::VolumeProperties(*pCompound, gProps, Standard_True); GC::KeepAlive(this); - return gProps.Mass(); + double mass = gProps.Mass(); + if (0 != mass) + return Nullable(mass); } - else - return 0; + + return Nullable(); } + + double XbimCompound::VolumeValid::get() + { + if (IsValid) + { + return Solids->VolumeValid + Shells->VolumeValid; + } + return 0; + } + //This method copes with faces that may be advanced as well as ordinary XbimShell^ XbimCompound::InitAdvancedFaces(IEnumerable^ faces, ILogger^ logger) { diff --git a/Xbim.Geometry.Engine/XbimCompound.h b/Xbim.Geometry.Engine/XbimCompound.h index c875a5837..ee9fa65a2 100644 --- a/Xbim.Geometry.Engine/XbimCompound.h +++ b/Xbim.Geometry.Engine/XbimCompound.h @@ -111,9 +111,10 @@ namespace Xbim XbimCompound^ Cut(XbimCompound^ solids, double tolerance, ILogger^ logger); XbimCompound^ Union(XbimCompound^ solids, double tolerance, ILogger^ logger); XbimCompound^ Intersection(XbimCompound^ solids, double tolerance, ILogger^ logger); - virtual property XbimRect3D BoundingBox {XbimRect3D get()override ; } - virtual property double Volume{double get(); } - virtual property double SewingTolerance {double get() {return _sewingTolerance;}} + virtual property XbimRect3D BoundingBox { XbimRect3D get() override ; } + virtual property Nullable Volume { Nullable get() override; } + virtual property double VolumeValid { double get(); } + virtual property double SewingTolerance { double get() {return _sewingTolerance;}} //moves the compound to the new positio void Move(IIfcAxis2Placement3D^ position); diff --git a/Xbim.Geometry.Engine/XbimGeometryObject.h b/Xbim.Geometry.Engine/XbimGeometryObject.h index fa8e1b4f8..24c90cd0e 100644 --- a/Xbim.Geometry.Engine/XbimGeometryObject.h +++ b/Xbim.Geometry.Engine/XbimGeometryObject.h @@ -71,6 +71,8 @@ namespace Xbim virtual property int Count {int get() abstract; } virtual IXbimGeometryObject^ Trim() abstract; virtual void Mesh(IXbimMeshReceiver^ mesh, double precision, double deflection, double angle) abstract; + // Predefined null volume, overridden by inhertance + virtual property Nullable Volume {Nullable get() { return Nullable(); }} }; ref class XbimGeometryObject abstract: IXbimGeometryObject @@ -85,16 +87,18 @@ namespace Xbim !XbimGeometryObject() {}; #pragma endregion - virtual property bool IsValid{bool get() abstract; } + virtual property bool IsValid{bool get() abstract; } virtual property bool IsSet{bool get() abstract; } - virtual property XbimGeometryObjectType GeometryType{XbimGeometryObjectType get() abstract;} + virtual property XbimGeometryObjectType GeometryType{XbimGeometryObjectType get() abstract;} virtual bool Equals(IXbimGeometryObject^ , double ){ throw gcnew NotImplementedException("Function not implemented"); } virtual bool Intersects(IXbimGeometryObject^ , double ){ throw gcnew NotImplementedException("Function not implemented"); } virtual property XbimRect3D BoundingBox {XbimRect3D get() abstract; }; virtual IXbimGeometryObject^ Transform(XbimMatrix3D matrix3D) abstract; virtual IXbimGeometryObject^ TransformShallow(XbimMatrix3D matrix3D) abstract; - virtual property String^ ToBRep{String^ get(); } - virtual property Object^ Tag {Object^ get() { return tag; }; void set(Object^ value) { tag = value; }; } + // Predefined null volume, overridden by inhertance + virtual property Nullable Volume {Nullable get() { return Nullable(); }} + virtual property String^ ToBRep{String^ get(); } + virtual property Object^ Tag {Object^ get() { return tag; }; void set(Object^ value) { tag = value; }; } }; } } diff --git a/Xbim.Geometry.Engine/XbimGeometryObjectSet.cpp b/Xbim.Geometry.Engine/XbimGeometryObjectSet.cpp index c0374c133..b84953fc7 100644 --- a/Xbim.Geometry.Engine/XbimGeometryObjectSet.cpp +++ b/Xbim.Geometry.Engine/XbimGeometryObjectSet.cpp @@ -598,6 +598,7 @@ namespace Xbim if (pBuilder != nullptr) delete pBuilder; return XbimGeometryObjectSet::Empty; } + IXbimGeometryObjectSet^ XbimGeometryObjectSet::Cut(IXbimSolidSet^ solids, double tolerance, ILogger^ logger) { return PerformBoolean(BOPAlgo_CUT, (IEnumerable^)this, solids, tolerance, logger); @@ -609,7 +610,6 @@ namespace Xbim return PerformBoolean(BOPAlgo_CUT, (IEnumerable^)this, gcnew XbimSolidSet(solid), tolerance, logger); } - IXbimGeometryObjectSet^ XbimGeometryObjectSet::Union(IXbimSolidSet^ solids, double tolerance, ILogger^ logger) { return PerformBoolean(BOPAlgo_FUSE, (IEnumerable^)this, solids, tolerance, logger); @@ -631,5 +631,21 @@ namespace Xbim if (Count == 0) return XbimGeometryObjectSet::Empty; return PerformBoolean(BOPAlgo_COMMON, (IEnumerable^)this, gcnew XbimSolidSet(solid), tolerance, logger); } + + double XbimGeometryObjectSet::VolumeValid::get() + { + if (IsValid) + { + double total = 0; + for each (IXbimGeometryObject ^ obj in geometryObjects) + { + Nullable vol = obj->Volume; + if (vol.HasValue) + total += vol.Value; + } + return total; + } + return 0; + } } } diff --git a/Xbim.Geometry.Engine/XbimGeometryObjectSet.h b/Xbim.Geometry.Engine/XbimGeometryObjectSet.h index df692714c..f381c0cf5 100644 --- a/Xbim.Geometry.Engine/XbimGeometryObjectSet.h +++ b/Xbim.Geometry.Engine/XbimGeometryObjectSet.h @@ -72,6 +72,7 @@ namespace Xbim virtual IXbimGeometryObjectSet^ Intersection(IXbimSolidSet^ solids, double tolerance, ILogger^ logger); virtual IXbimGeometryObjectSet^ Intersection(IXbimSolid^ solid, double tolerance, ILogger^ logger); virtual bool Sew(); + virtual property double VolumeValid { double get(); } #pragma endregion virtual void Add(IXbimGeometryObject^ geomObj){ geometryObjects->Add(geomObj); } diff --git a/Xbim.Geometry.Engine/XbimPoint3DWithTolerance.h b/Xbim.Geometry.Engine/XbimPoint3DWithTolerance.h index ffc787668..c4a64f816 100644 --- a/Xbim.Geometry.Engine/XbimPoint3DWithTolerance.h +++ b/Xbim.Geometry.Engine/XbimPoint3DWithTolerance.h @@ -36,6 +36,8 @@ namespace Xbim virtual property double Tolerance{double get(){ return tolerance; }; } virtual property XbimPoint3D VertexGeometry {XbimPoint3D get() { return point; }; } virtual property XbimRect3D BoundingBox {XbimRect3D get(); } + virtual property Nullable Volume {Nullable get() { return Nullable(); }} + virtual IXbimGeometryObject^ Transform(XbimMatrix3D matrix3D); virtual IXbimGeometryObject^ TransformShallow(XbimMatrix3D matrix3D); virtual property String^ ToBRep{String^ get(); } diff --git a/Xbim.Geometry.Engine/XbimShell.cpp b/Xbim.Geometry.Engine/XbimShell.cpp index 2ed62b899..3b4ca3ac5 100644 --- a/Xbim.Geometry.Engine/XbimShell.cpp +++ b/Xbim.Geometry.Engine/XbimShell.cpp @@ -270,8 +270,21 @@ namespace Xbim BRepCheck_Shell checker(*pShell); BRepCheck_Status result = checker.Closed(); GC::KeepAlive(this); - return result == BRepCheck_NoError; - + return result == BRepCheck_NoError; + } + + Nullable XbimShell::Volume::get() + { + if (IsValid) + { + GProp_GProps gProps; + BRepGProp::VolumeProperties(*pShell, gProps, Standard_True); + GC::KeepAlive(this); + double mass = gProps.Mass(); + if (0 != mass) + return Nullable(mass); + } + return Nullable(); } IXbimGeometryObject^ XbimShell::Transform(XbimMatrix3D matrix3D) diff --git a/Xbim.Geometry.Engine/XbimShell.h b/Xbim.Geometry.Engine/XbimShell.h index 0eda9e798..ee2c22335 100644 --- a/Xbim.Geometry.Engine/XbimShell.h +++ b/Xbim.Geometry.Engine/XbimShell.h @@ -57,9 +57,10 @@ namespace Xbim virtual property IXbimEdgeSet^ Edges{ IXbimEdgeSet^ get(); } virtual property IXbimVertexSet^ Vertices{IXbimVertexSet^ get(); } virtual property XbimRect3D BoundingBox{XbimRect3D get() override; } - virtual property bool IsClosed{bool get(); } + virtual property bool IsClosed { bool get(); } virtual property double SurfaceArea { double get(); } virtual property bool IsPolyhedron { bool get(); } + virtual property Nullable Volume { Nullable get() override; } virtual IXbimGeometryObjectSet^ Cut(IXbimSolidSet^ solids, double tolerance, ILogger^ logger); virtual IXbimGeometryObjectSet^ Cut(IXbimSolid^ solid, double tolerance, ILogger^ logger); virtual IXbimGeometryObjectSet^ Union(IXbimSolidSet^ solids, double tolerance, ILogger^ logger); diff --git a/Xbim.Geometry.Engine/XbimShellSet.cpp b/Xbim.Geometry.Engine/XbimShellSet.cpp index 0762e3190..524e41120 100644 --- a/Xbim.Geometry.Engine/XbimShellSet.cpp +++ b/Xbim.Geometry.Engine/XbimShellSet.cpp @@ -190,5 +190,38 @@ namespace Xbim if (Count == 0) return XbimGeometryObjectSet::Empty; return XbimGeometryObjectSet::PerformBoolean(BOPAlgo_COMMON, (IEnumerable^)this, gcnew XbimSolidSet(solid), tolerance, logger); } + + Nullable XbimShellSet::Volume::get() + { + double totalVol = 0; + if (IsValid) + { + for each (XbimShell ^ shell in shells) + { + Nullable sVol = shell->Volume; + if (sVol.HasValue) + totalVol += sVol.Value; + else + // Prevent returning wrong partial values, better no value + return Nullable(); + } + } + return Nullable(totalVol); + } + + double XbimShellSet::VolumeValid::get() + { + double totalVol = 0; + if (IsValid) + { + for each (XbimShell ^ shell in shells) + { + Nullable sVol = shell->Volume; + if (sVol.HasValue) + totalVol += sVol.Value; + } + } + return totalVol; + } } } diff --git a/Xbim.Geometry.Engine/XbimShellSet.h b/Xbim.Geometry.Engine/XbimShellSet.h index ef9d4ad86..564572f02 100644 --- a/Xbim.Geometry.Engine/XbimShellSet.h +++ b/Xbim.Geometry.Engine/XbimShellSet.h @@ -56,8 +56,11 @@ namespace Xbim virtual IXbimGeometryObjectSet^ Intersection(IXbimSolid^ solid, double tolerance, ILogger^ logger); virtual property bool IsPolyhedron{ bool get(); } virtual void Union(double tolerance); + + virtual property double VolumeValid { double get(); } #pragma endregion + virtual property Nullable Volume { Nullable get() override; } // Inherited via XbimSetObject virtual IXbimGeometryObject ^ Transformed(IIfcCartesianTransformationOperator ^ transformation) override; diff --git a/Xbim.Geometry.Engine/XbimSolid.cpp b/Xbim.Geometry.Engine/XbimSolid.cpp index 492b10a00..b767b52ee 100644 --- a/Xbim.Geometry.Engine/XbimSolid.cpp +++ b/Xbim.Geometry.Engine/XbimSolid.cpp @@ -1863,17 +1863,19 @@ namespace Xbim return true; } - double XbimSolid::Volume::get() + Nullable XbimSolid::Volume::get() { if (IsValid) { GProp_GProps gProps; BRepGProp::VolumeProperties(*pSolid, gProps, Standard_True); GC::KeepAlive(this); - return gProps.Mass(); + double mass = gProps.Mass(); + if (0 != mass) + return Nullable(mass); } - else - return 0; + + return Nullable(); } bool XbimSolid::IsPolyhedron::get() diff --git a/Xbim.Geometry.Engine/XbimSolid.h b/Xbim.Geometry.Engine/XbimSolid.h index 76f4c98b0..af3a36b87 100644 --- a/Xbim.Geometry.Engine/XbimSolid.h +++ b/Xbim.Geometry.Engine/XbimSolid.h @@ -90,7 +90,7 @@ namespace Xbim virtual property IXbimVertexSet^ Vertices{IXbimVertexSet^ get(); } virtual property XbimRect3D BoundingBox{XbimRect3D get() override;} virtual property bool IsClosed{bool get(); } - virtual property double Volume{double get(); } + virtual property Nullable Volume{ Nullable get() override; } virtual property double SurfaceArea { double get(); } virtual property bool IsPolyhedron { bool get(); } virtual property bool HasValidTopology{bool get(); } diff --git a/Xbim.Geometry.Engine/XbimSolidSet.cpp b/Xbim.Geometry.Engine/XbimSolidSet.cpp index 338b43a46..885d12583 100644 --- a/Xbim.Geometry.Engine/XbimSolidSet.cpp +++ b/Xbim.Geometry.Engine/XbimSolidSet.cpp @@ -276,17 +276,37 @@ namespace Xbim return solids == nullptr ? 0 : solids->Count; } - double XbimSolidSet::Volume::get() + Nullable XbimSolidSet::Volume::get() { - double vol = 0; + double totalVol = 0; if (IsValid) { for each (XbimSolid^ solid in solids) { - vol += solid->Volume; + Nullable sVol = solid->Volume; + if (sVol.HasValue) + totalVol += sVol.Value; + else + // Prevent returning wrong partial values, better no value + return Nullable(); + } + } + return Nullable(totalVol); + } + + double XbimSolidSet::VolumeValid::get() + { + double totalVol = 0; + if (IsValid) + { + for each (XbimSolid ^ solid in solids) + { + Nullable sVol = solid->Volume; + if (sVol.HasValue) + totalVol += sVol.Value; } } - return vol; + return totalVol; } IXbimGeometryObject^ XbimSolidSet::Transform(XbimMatrix3D matrix3D) @@ -952,7 +972,8 @@ namespace Xbim XbimSolidSet^ basic = dynamic_cast(set); if (basic != nullptr) { - return basic->Volume; + Nullable vol = basic->Volume; + return vol.HasValue ? vol.Value : 0; } return ret; } diff --git a/Xbim.Geometry.Engine/XbimSolidSet.h b/Xbim.Geometry.Engine/XbimSolidSet.h index 0964bc7ef..59c679a76 100644 --- a/Xbim.Geometry.Engine/XbimSolidSet.h +++ b/Xbim.Geometry.Engine/XbimSolidSet.h @@ -126,7 +126,8 @@ namespace Xbim virtual property bool IsPolyhedron{ bool get(); } virtual IXbimGeometryObject^ Transform(XbimMatrix3D matrix3D) ; virtual IXbimGeometryObject^ TransformShallow(XbimMatrix3D matrix3D); - virtual property double Volume{double get(); } + virtual property Nullable Volume { Nullable get() override; } + virtual property double VolumeValid { double get(); } virtual IXbimSolidSet^ Range(int start, int count); //moves the solid set to the new position void Move(IIfcAxis2Placement3D^ position); From 1a38991208954243f64f49e4f7605354315218e4 Mon Sep 17 00:00:00 2001 From: Bernold Kraft Date: Tue, 19 Nov 2019 15:46:13 +0100 Subject: [PATCH 3/5] Propagating volume property to shape data wrapper --- Xbim.Geometry.Engine/XbimGeometryCreator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Xbim.Geometry.Engine/XbimGeometryCreator.cpp b/Xbim.Geometry.Engine/XbimGeometryCreator.cpp index 916bbf99f..5838fdce3 100644 --- a/Xbim.Geometry.Engine/XbimGeometryCreator.cpp +++ b/Xbim.Geometry.Engine/XbimGeometryCreator.cpp @@ -341,6 +341,7 @@ namespace Xbim ((XbimShapeGeometry^)shapeGeom)->BoundingBox = geometryObject->BoundingBox; ((XbimShapeGeometry^)shapeGeom)->LOD = XbimLOD::LOD_Unspecified, ((XbimShapeGeometry^)shapeGeom)->Format = storageType; + ((XbimShapeGeometry^)shapeGeom)->Volume = geometryObject->Volume; return shapeGeom; } } @@ -370,6 +371,7 @@ namespace Xbim ((XbimShapeGeometry^)shapeGeom)->BoundingBox = geometryObject->BoundingBox; ((XbimShapeGeometry^)shapeGeom)->LOD = XbimLOD::LOD_Unspecified, ((XbimShapeGeometry^)shapeGeom)->Format = storageType; + ((XbimShapeGeometry^)shapeGeom)->Volume = geometryObject->Volume; } } return shapeGeom; From dbf3c13fd48b4d389db781a1c54bc1c884d8b0b3 Mon Sep 17 00:00:00 2001 From: Bernold Kraft Date: Thu, 5 Dec 2019 13:35:41 +0100 Subject: [PATCH 4/5] More logging output if reversing mesh orientation --- Xbim.Geometry.Engine/XbimCompound.cpp | 6 +++++- Xbim.ModelGeometry.Scene/Xbim3DModelContext.cs | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Xbim.Geometry.Engine/XbimCompound.cpp b/Xbim.Geometry.Engine/XbimCompound.cpp index f968400e8..1b79f53d8 100644 --- a/Xbim.Geometry.Engine/XbimCompound.cpp +++ b/Xbim.Geometry.Engine/XbimCompound.cpp @@ -562,7 +562,11 @@ namespace Xbim GProp_GProps gProps; BRepGProp::VolumeProperties(*pCompound, gProps, Standard_True); double volume = gProps.Mass(); - if (volume < 0) pCompound->Reverse(); + if (volume < 0) + { + XbimGeometryCreator::LogWarning(logger, closedShell, "Inverted IfcClosedShell #{0} detected", closedShell->EntityLabel); + pCompound->Reverse(); + } double oneCubicMillimetre = Math::Pow(closedShell->Model->ModelFactors->OneMilliMeter, 3); volume = Math::Abs(volume); if (volume < oneCubicMillimetre) //sometimes zero volume is just a badly defined shape so let it through maybe diff --git a/Xbim.ModelGeometry.Scene/Xbim3DModelContext.cs b/Xbim.ModelGeometry.Scene/Xbim3DModelContext.cs index 07dd54245..19626b0c6 100644 --- a/Xbim.ModelGeometry.Scene/Xbim3DModelContext.cs +++ b/Xbim.ModelGeometry.Scene/Xbim3DModelContext.cs @@ -941,7 +941,8 @@ private HashSet WriteProductsWithFeatures(XbimCreateContextHelper contextHe GeometryHash = 0, LOD = XbimLOD.LOD_Unspecified, Format = geomType, - BoundingBox = elementGeom.BoundingBox + BoundingBox = elementGeom.BoundingBox, + Volume = geom.Volume }; var memStream = new MemoryStream(0x4000); @@ -1295,7 +1296,7 @@ private void WriteShapeGeometries(XbimCreateContextHelper contextHelper, ReportP var localPercentageParsed = contextHelper.PercentageParsed; var localTally = contextHelper.Tally; // var dedupCount = 0; - var xbimTessellator = new XbimTessellator(Model, geomStorageType); + var xbimTessellator = new XbimTessellator(Model, geomStorageType, _logger); //var geomHash = new ConcurrentDictionary(); //var mapLookup = new ConcurrentDictionary(); @@ -1385,7 +1386,6 @@ private void WriteShapeGeometries(XbimCreateContextHelper contextHelper, ReportP } if (geomModel != null && geomModel.IsValid) { - shapeGeom = Engine.CreateShapeGeometry(geomModel, precision, deflection, deflectionAngle, geomStorageType, _logger); if (isFeatureElementShape) { From 10e3106f63302db6340712b6d3b23e0727846745 Mon Sep 17 00:00:00 2001 From: Bernold Kraft Date: Thu, 5 Dec 2019 15:09:04 +0100 Subject: [PATCH 5/5] Fixing geometry tests --- .../Ifc4GeometryTests.cs | 14 ++++---- .../IfcBooleanTests.cs | 34 +++++++++++++------ .../LocationAndPlacementTests.cs | 4 +-- .../PrimitiveGeometryTests.cs | 2 +- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/Xbim.Geometry.Engine.Interop.Tests/Ifc4GeometryTests.cs b/Xbim.Geometry.Engine.Interop.Tests/Ifc4GeometryTests.cs index 5c3685b68..8a872ec03 100644 --- a/Xbim.Geometry.Engine.Interop.Tests/Ifc4GeometryTests.cs +++ b/Xbim.Geometry.Engine.Interop.Tests/Ifc4GeometryTests.cs @@ -41,7 +41,7 @@ public void Can_build_ifcadvancedbrep_with_faulty_surface_orientation() Assert.IsTrue(pfs != null, "No IIfcAdvancedBrep found"); var solid = geomEngine.CreateSolid(pfs, logger); - Assert.AreEqual(102264692, solid.Volume, 0.99); + Assert.AreEqual(102264692, solid.Volume.Value, 0.99); Assert.AreEqual(14, solid.Faces.Count); } @@ -55,7 +55,7 @@ public void Can_build_solid_swept_disk_pipe() Assert.IsTrue(pfs != null, "No IIfcPolygonalFaceSet found"); var pipe = geomEngine.CreateSolid(pfs, logger); - Assert.AreEqual(129879, pipe.Volume, 0.99); + Assert.AreEqual(129879, pipe.Volume.Value, 0.99); Assert.AreEqual(15, pipe.Faces.Count); } @@ -201,7 +201,7 @@ public void CsgSolidBoundingBoxTest() { Assert.IsTrue(er.Entity != null, "No IfcCsgSolid found"); var solid = geomEngine.CreateSolidSet(er.Entity, logger).FirstOrDefault(); - Assert.IsTrue(Math.Abs(solid.Volume - solid.BoundingBox.Volume) < 1e-5); + Assert.IsTrue(Math.Abs((solid.Volume - solid.BoundingBox.Volume) ?? double.NaN) < 1e-5); } } @@ -214,7 +214,7 @@ public void ExtrudedAreaSolidBasicTest() var eas = model.Instances.OfType().FirstOrDefault(); Assert.IsNotNull(eas); var solid = geomEngine.CreateSolid(eas); - Assert.IsTrue(Math.Abs(solid.Volume - solid.BoundingBox.Volume) < 1e-5); + Assert.IsTrue(Math.Abs((solid.Volume - solid.BoundingBox.Volume) ?? double.NaN) < 1e-5); } } [TestMethod] @@ -238,7 +238,7 @@ public void BrepSolidModelBasicTest() var shape = model.Instances.OfType().FirstOrDefault(); Assert.IsNotNull(shape); var geom = geomEngine.CreateSolidSet(shape).FirstOrDefault(); - Assert.IsTrue(Math.Abs(geom.Volume - geom.BoundingBox.Volume) < 1e-5); + Assert.IsTrue(Math.Abs((geom.Volume - geom.BoundingBox.Volume) ?? double.NaN) < 1e-5); } } @@ -269,7 +269,7 @@ public void AdvancedMultiSegmentPolylineTest() var shape = model.Instances.OfType().FirstOrDefault(); Assert.IsNotNull(shape); var geom = geomEngine.CreateSolid(shape); - Assert.IsTrue(Math.Abs(geom.Volume - 72767) < 1); + Assert.IsTrue(Math.Abs(geom.Volume.Value - 72767) < 1); } } @@ -281,7 +281,7 @@ public void BrepSolidModelAdvancedTest() var shape = model.Instances.OfType().FirstOrDefault(); Assert.IsNotNull(shape); var geom = geomEngine.CreateSolid(shape); - Assert.IsTrue(Math.Abs(geom.Volume - 0.83333333) < 1e-5); + Assert.IsTrue(Math.Abs(geom.Volume.Value - 0.83333333) < 1e-5); } } diff --git a/Xbim.Geometry.Engine.Interop.Tests/IfcBooleanTests.cs b/Xbim.Geometry.Engine.Interop.Tests/IfcBooleanTests.cs index 3186292cf..a146aeae9 100644 --- a/Xbim.Geometry.Engine.Interop.Tests/IfcBooleanTests.cs +++ b/Xbim.Geometry.Engine.Interop.Tests/IfcBooleanTests.cs @@ -115,7 +115,7 @@ public void SubtractionResultsInClosedWindow() var cutWall = transformedWall.Cut(transformedOpening, model.ModelFactors.Precision, logger).FirstOrDefault(); Assert.IsNotNull(cutWall, "Cut wall should not be null"); // note this faceted brep already has the openings cut out and we are cutting them again so the volume should not change - var volDiff = cutWall.Volume - transformedWall.Volume; + var volDiff = (cutWall.Volume - transformedWall.Volume) ?? 0; Assert.IsTrue(Math.Abs(volDiff) < 1e-5); // Assert.IsTrue(er.Entity != null, "No IfcBooleanResult found"); // var solid = geomEngine.CreateSolid(er.Entity, logger); @@ -659,17 +659,23 @@ public void IfcHalfspace_Test() var halfSpaceSolid = geomEngine.CreateSolid(halfSpace, logger); var cut = solid.Cut(halfSpaceSolid, 1e-5); Assert.IsTrue(cut.Count > 0); - Assert.IsTrue(Math.Abs((solid.Volume * .25) - cut.First.Volume) < 1e-5); + Assert.IsTrue(solid.Volume.HasValue); + Assert.IsTrue(cut.First.Volume.HasValue); + Assert.IsTrue(Math.Abs(((solid.Volume * .25) - cut.First.Volume) ?? double.NaN) < 1e-5); //move the halfspace plane up baseSurface.Position.Location.Z = 30; halfSpaceSolid = geomEngine.CreateSolid(halfSpace, logger); cut = solid.Cut(halfSpaceSolid, 1e-5); - Assert.IsTrue(Math.Abs((solid.Volume * .75) - cut.First.Volume) < 1e-5); + Assert.IsTrue(solid.Volume.HasValue); + Assert.IsTrue(cut.First.Volume.HasValue); + Assert.IsTrue(Math.Abs(((solid.Volume * .75) - cut.First.Volume) ?? double.NaN) < 1e-5); //reverse halfspace agreement halfSpace.AgreementFlag = true; halfSpaceSolid = geomEngine.CreateSolid(halfSpace, logger); cut = solid.Cut(halfSpaceSolid, 1e-5); - Assert.IsTrue(Math.Abs((solid.Volume * .25) - cut.First.Volume) < 1e-5); + Assert.IsTrue(solid.Volume.HasValue); + Assert.IsTrue(cut.First.Volume.HasValue); + Assert.IsTrue(Math.Abs(((solid.Volume * .25) - cut.First.Volume) ?? double.NaN) < 1e-5); } } @@ -708,20 +714,26 @@ public void IfcPolygonalBoundedHalfspace_Test() var halfSpaceSolid = geomEngine.CreateSolid(polygonalBoundedHalfspace, logger); var cut = solid.Cut(halfSpaceSolid, 1e-5); - Assert.IsTrue(cut.Count > 0); - Assert.IsTrue(Math.Abs((solid.Volume) - cut.First.Volume - 1000) < 1e-5); + Assert.IsTrue(cut.Count > 0); + Assert.IsTrue(solid.Volume.HasValue); + Assert.IsTrue(cut.First.Volume.HasValue); + Assert.IsTrue(Math.Abs((solid.Volume - cut.First.Volume - 1000) ?? double.NaN) < 1e-5); //reverse halfspace agreement polygonalBoundedHalfspace.AgreementFlag = true; halfSpaceSolid = geomEngine.CreateSolid(polygonalBoundedHalfspace, logger); cut = solid.Cut(halfSpaceSolid, 1e-5); - Assert.IsTrue(Math.Abs(solid.Volume - cut.First.Volume) < 1e-5); + Assert.IsTrue(solid.Volume.HasValue); + Assert.IsTrue(cut.First.Volume.HasValue); + Assert.IsTrue(Math.Abs((solid.Volume - cut.First.Volume) ?? double.NaN) < 1e-5); //move the plane up plane.Position.Location.Z = 20; halfSpaceSolid = geomEngine.CreateSolid(polygonalBoundedHalfspace, logger); - cut = solid.Cut(halfSpaceSolid, 1e-5); - Assert.IsTrue(Math.Abs(solid.Volume - cut.First.Volume - 500) < 1e-5); + cut = solid.Cut(halfSpaceSolid, 1e-5); + Assert.IsTrue(solid.Volume.HasValue); + Assert.IsTrue(cut.First.Volume.HasValue); + Assert.IsTrue(Math.Abs((solid.Volume - cut.First.Volume - 500) ?? double.NaN) < 1e-5); //some realistic data polyLine.Points[0].SetXY(0, 0); @@ -881,11 +893,11 @@ public void CuttingOpeningInCompositeProfileDefTest() Assert.IsTrue(cutSolid.IsValid); if (uncutItem.Volume <= cutSolid.Volume) uncut++; Assert.IsTrue(uncut <= 3, "More than two solids are uncut, there should only be two"); - vol += cutSolid.Volume; + vol += cutSolid.Volume ?? double.NaN; } Assert.IsTrue(uncut == 2); var scutVol = singleCut.Sum(s => s.Volume); - Assert.IsTrue(Math.Abs(vol - scutVol) < 1e-5); + Assert.IsTrue(Math.Abs((vol - scutVol) ?? double.NaN) < 1e-5); } diff --git a/Xbim.Geometry.Engine.Interop.Tests/LocationAndPlacementTests.cs b/Xbim.Geometry.Engine.Interop.Tests/LocationAndPlacementTests.cs index 767db5d9d..765e10a98 100644 --- a/Xbim.Geometry.Engine.Interop.Tests/LocationAndPlacementTests.cs +++ b/Xbim.Geometry.Engine.Interop.Tests/LocationAndPlacementTests.cs @@ -103,7 +103,7 @@ public void MoveAndCopyTest() ax3D.Location.Y = 100; var solidA = geomEngine.Moved(solid, ax3D) as IXbimSolid; Assert.IsNotNull(solidA, "Should be the same type as the master"); - Assert.IsTrue(Math.Abs(solidA.Volume - solid.Volume) < 1e-9, "Volume has changed"); + Assert.IsTrue(Math.Abs((solidA.Volume - solid.Volume) ?? double.NaN) < 1e-9, "Volume has changed"); var displacement = solidA.BoundingBox.Centroid() - solid.BoundingBox.Centroid(); Assert.IsTrue(displacement == new XbimVector3D(0, 100, 0)); var bbA = solidA.BoundingBox; @@ -228,7 +228,7 @@ public void TransformSolidRectangularProfileDef() transform.OffsetY += 200; transform.OffsetZ += 300; solid2 = (IXbimSolid)solid.Transform(transform); - Assert.IsTrue(Math.Abs(solid.Volume - solid2.Volume) < 0.001, "Volume differs"); + Assert.IsTrue(Math.Abs((solid.Volume - solid2.Volume) ?? double.NaN) < 0.001, "Volume differs"); transform.Invert(); solid2 = (IXbimSolid)solid2.Transform(transform); s1Verts = solid.Vertices.ToList(); diff --git a/Xbim.Geometry.Engine.Interop.Tests/PrimitiveGeometryTests.cs b/Xbim.Geometry.Engine.Interop.Tests/PrimitiveGeometryTests.cs index 8bb4956ef..7ccb415f0 100644 --- a/Xbim.Geometry.Engine.Interop.Tests/PrimitiveGeometryTests.cs +++ b/Xbim.Geometry.Engine.Interop.Tests/PrimitiveGeometryTests.cs @@ -87,7 +87,7 @@ public void can_trim_composite_curve() var solid = geomEngine.CreateSolidSet(er.Entity, logger); Assert.AreEqual(1, solid.Count); - Assert.AreEqual(solid.First().Volume, 12.6, 0.1); + Assert.AreEqual(solid.First().Volume.Value, 12.6, 0.1); } } }