Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Xbim.Geometry.Engine.Interop.Tests/Ifc4GeometryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,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);

}
}
Expand All @@ -215,7 +215,7 @@ public void ExtrudedAreaSolidBasicTest()
var eas = model.Instances.OfType<IfcExtrudedAreaSolid>().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]
Expand Down Expand Up @@ -270,7 +270,7 @@ public void AdvancedMultiSegmentPolylineTest()
var shape = model.Instances.OfType<IfcAdvancedBrep>().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);
}
}

Expand Down
34 changes: 23 additions & 11 deletions Xbim.Geometry.Engine.Interop.Tests/IfcBooleanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,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);
Expand Down Expand Up @@ -748,17 +748,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);

}
}
Expand Down Expand Up @@ -797,20 +803,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);
Expand Down Expand Up @@ -986,11 +998,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);


}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
<PackageReference Include="System.Threading.Tasks" Version="4.3.0" />
<PackageReference Include="Xbim.Tessellator" Version="5.1.309-develop" />
<PackageReference Include="Xbim.Tessellator" Version="5.1.20209.27462" />
</ItemGroup>
<ItemGroup>
<Content Include="..\Xbim.Geometry.Engine.Interop.targets">
Expand Down
22 changes: 18 additions & 4 deletions Xbim.Geometry.Engine/XbimCompound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,10 +646,12 @@ namespace Xbim


}

void XbimCompound::Init(IIfcOpenShell^ openShell, ILogger^ logger)
{
Init((IIfcConnectedFaceSet^)openShell, logger);
}

bool XbimCompound::Sew()
{

Expand Down Expand Up @@ -685,18 +687,30 @@ namespace Xbim
return true;
}

double XbimCompound::Volume::get()
Nullable<double> 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<double>(mass);
}
else
return 0;

return Nullable<double>();
}

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
TopoDS_Shape XbimCompound::InitAdvancedFaces(IEnumerable<IIfcFace^>^ faces, ILogger^ logger)
{
Expand Down
7 changes: 4 additions & 3 deletions Xbim.Geometry.Engine/XbimCompound.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<double> Volume { Nullable<double> 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);
Expand Down
2 changes: 2 additions & 0 deletions Xbim.Geometry.Engine/XbimGeometryCreator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,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;
}
}
Expand Down Expand Up @@ -380,6 +381,7 @@ namespace Xbim
((XbimShapeGeometry^)shapeGeom)->BoundingBox = geometryObject->BoundingBox;
((XbimShapeGeometry^)shapeGeom)->LOD = XbimLOD::LOD_Unspecified,
((XbimShapeGeometry^)shapeGeom)->Format = storageType;
((XbimShapeGeometry^)shapeGeom)->Volume = geometryObject->Volume;
}
}

Expand Down
12 changes: 8 additions & 4 deletions Xbim.Geometry.Engine/XbimGeometryObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<double> Volume {Nullable<double> get() { return Nullable<double>(); }}
};

ref class XbimGeometryObject abstract: IXbimGeometryObject
Expand All @@ -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<double> Volume {Nullable<double> get() { return Nullable<double>(); }}
virtual property String^ ToBRep{String^ get(); }
virtual property Object^ Tag {Object^ get() { return tag; }; void set(Object^ value) { tag = value; }; }
};
}
}
Expand Down
17 changes: 16 additions & 1 deletion Xbim.Geometry.Engine/XbimGeometryObjectSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,6 @@ namespace Xbim
return PerformBoolean(BOPAlgo_CUT, (IEnumerable<IXbimGeometryObject^>^)this, gcnew XbimSolidSet(solid), tolerance, logger);
}


IXbimGeometryObjectSet^ XbimGeometryObjectSet::Union(IXbimSolidSet^ solids, double tolerance, ILogger^ logger)
{
return PerformBoolean(BOPAlgo_FUSE, (IEnumerable<IXbimGeometryObject^>^)this, solids, tolerance, logger);
Expand All @@ -606,5 +605,21 @@ namespace Xbim
if (Count == 0) return XbimGeometryObjectSet::Empty;
return PerformBoolean(BOPAlgo_COMMON, (IEnumerable<IXbimGeometryObject^>^)this, gcnew XbimSolidSet(solid), tolerance, logger);
}

double XbimGeometryObjectSet::VolumeValid::get()
{
if (IsValid)
{
double total = 0;
for each (IXbimGeometryObject ^ obj in geometryObjects)
{
Nullable<double> vol = obj->Volume;
if (vol.HasValue)
total += vol.Value;
}
return total;
}
return 0;
}
}
}
1 change: 1 addition & 0 deletions Xbim.Geometry.Engine/XbimGeometryObjectSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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); }

Expand Down
2 changes: 2 additions & 0 deletions Xbim.Geometry.Engine/XbimPoint3DWithTolerance.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<double> Volume {Nullable<double> get() { return Nullable<double>(); }}

virtual IXbimGeometryObject^ Transform(XbimMatrix3D matrix3D);
virtual IXbimGeometryObject^ TransformShallow(XbimMatrix3D matrix3D);
virtual property String^ ToBRep{String^ get(); }
Expand Down
14 changes: 14 additions & 0 deletions Xbim.Geometry.Engine/XbimShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,20 @@ namespace Xbim

}

Nullable<double> 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<double>(mass);
}
return Nullable<double>();
}

IXbimGeometryObject^ XbimShell::Transform(XbimMatrix3D matrix3D)
{
if (!IsValid) return nullptr;
Expand Down
3 changes: 2 additions & 1 deletion Xbim.Geometry.Engine/XbimShell.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<double> Volume { Nullable<double> 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);
Expand Down
33 changes: 33 additions & 0 deletions Xbim.Geometry.Engine/XbimShellSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,5 +190,38 @@ namespace Xbim
if (Count == 0) return XbimGeometryObjectSet::Empty;
return XbimGeometryObjectSet::PerformBoolean(BOPAlgo_COMMON, (IEnumerable<IXbimGeometryObject^>^)this, gcnew XbimSolidSet(solid), tolerance, logger);
}

Nullable<double> XbimShellSet::Volume::get()
{
double totalVol = 0;
if (IsValid)
{
for each (XbimShell ^ shell in shells)
{
Nullable<double> sVol = shell->Volume;
if (sVol.HasValue)
totalVol += sVol.Value;
else
// Prevent returning wrong partial values, better no value
return Nullable<double>();
}
}
return Nullable<double>(totalVol);
}

double XbimShellSet::VolumeValid::get()
{
double totalVol = 0;
if (IsValid)
{
for each (XbimShell ^ shell in shells)
{
Nullable<double> sVol = shell->Volume;
if (sVol.HasValue)
totalVol += sVol.Value;
}
}
return totalVol;
}
}
}
3 changes: 3 additions & 0 deletions Xbim.Geometry.Engine/XbimShellSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<double> Volume { Nullable<double> get() override; }

// Inherited via XbimSetObject
virtual IXbimGeometryObject ^ Transformed(IIfcCartesianTransformationOperator ^ transformation) override;
Expand Down
Loading