public void MoveAndCopyTest()
 {
     //this test checks that a object is correctly copied and moved
     //create a box
     using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction("Test"))
         {
             {
                 var block = IfcModelBuilder.MakeBlock(m, 10, 10, 10);
                 var solid = _geomEngine.CreateSolid(block);
                 var ax3D  = IfcModelBuilder.MakeAxis2Placement3D(m);
                 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");
                 var displacement = solidA.BoundingBox.Centroid() - solid.BoundingBox.Centroid();
                 Assert.IsTrue(displacement == new XbimVector3D(0, 100, 0));
                 var bbA    = solidA.BoundingBox;
                 var solidB = _geomEngine.Moved(solid, ax3D);
                 Assert.IsTrue(bbA.Centroid() - solidB.BoundingBox.Centroid() == new XbimVector3D(0, 0, 0));
             }
         }
     }
 }
 public void ScaleAndCopyTest()
 {
     //this test checks that a object is correctly copied and moved
     //create a box
     using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction("Test"))
         {
             var block     = IfcModelBuilder.MakeBlock(m, 10, 10, 10);
             var solid     = _geomEngine.CreateSolid(block);
             var transform = IfcModelBuilder.MakeCartesianTransformationOperator3D(m);
             transform.Scale = 2;
             var solidA = _geomEngine.Transformed(solid, transform);
             var bb     = solid.BoundingBox;
             var bbA    = solidA.BoundingBox;
             Assert.IsTrue(Math.Abs(bb.Volume - 1000) < 1e-9, "Bounding box volume is incorrect in original shape");
             Assert.IsTrue(Math.Abs(bbA.Volume - 8000) < 1e-9, "Bounding box volume is incorrect in scaled shape");
             var transformNonUniform = IfcModelBuilder.MakeCartesianTransformationOperator3DnonUniform(m);
             transformNonUniform.Scale3 = 100;
             var solidB = _geomEngine.Transformed(solid, transformNonUniform);
             Assert.IsTrue(Math.Abs(solidB.BoundingBox.Volume - 100000) < 1e-9, "Bounding box volume is incorrect in non uniform scaled shape");
             Assert.IsTrue(Math.Abs(bb.Volume - 1000) < 1e-9, "Bounding box volume of original shape as been changed");
         }
     }
 }
        public void SectionWithInnerWireTest()
        {
            using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction(""))
                {
                    var csgTree       = m.Instances.New <IfcCsgSolid>();
                    var bresult       = m.Instances.New <IfcBooleanResult>();
                    var cylinderInner = IfcModelBuilder.MakeRightCircularCylinder(m, 10, 20);
                    var cylinderOuter = IfcModelBuilder.MakeRightCircularCylinder(m, 20, 20);
                    bresult.FirstOperand       = cylinderOuter;
                    bresult.SecondOperand      = cylinderInner;
                    bresult.Operator           = IfcBooleanOperator.DIFFERENCE;
                    csgTree.TreeRootExpression = bresult;

                    var solid    = geomEngine.CreateSolidSet(csgTree, logger).FirstOrDefault();
                    var plane    = IfcModelBuilder.MakePlane(m, new XbimPoint3D(cylinderInner.Position.Location.X + 1, cylinderInner.Position.Location.Y, cylinderInner.Position.Location.Z), new XbimVector3D(0, 0, 1), new XbimVector3D(0, 1, 0));
                    var cutPlane = geomEngine.CreateFace(plane, logger);
                    var section  = solid.Section(cutPlane, m.ModelFactors.PrecisionBoolean);
                    Assert.IsTrue(section.First != null, "Result should be a face");
                    Assert.IsTrue(section.First.OuterBound.Edges.Count == 1, "1 edge is required for this section of a cylinder");
                    Assert.IsTrue(section.First.InnerBounds.Count == 1, "1 inner wire is required for this section of a cylinder");
                }
            }
        }
Beispiel #4
0
        public void IfcSphereTest()
        {
            using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction("Test"))
                {
                    const double r = 0.5;

                    var sphere = IfcModelBuilder.MakeSphere(m, r);

                    var solid = geomEngine.CreateSolid(sphere);
                    Assert.IsTrue(solid.Faces.Count == 1, "1 face is required of a sphere");
                    Assert.IsTrue(solid.Vertices.Count == 2, "2 vertices are required of a sphere");
                    var meshRec = new MeshHelper();
                    meshRec.BeginUpdate();
                    geomEngine.Mesh(meshRec, solid, m.ModelFactors.Precision, m.ModelFactors.DeflectionTolerance * 10);
                    meshRec.EndUpdate();
                    Assert.IsTrue(meshRec.FaceCount == 1, "1 mesh face is required of a sphere");
                    Assert.IsTrue(meshRec.PointCount == 168, "168 mesh points are required of a sphere");
                    Assert.IsTrue(meshRec.TriangleCount == 306, "306 triangles are required of a sphere");
                    Assert.IsTrue(meshRec.TriangleCount * 3 == meshRec.TriangleIndicesCount, "Incorrect triangulation");
                    txn.Commit();
                }
            }
        }
        public void ObjectPlacementTest()
        {
            //this test checks that a object is correctly copied and moved
            //create a box
            using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction("Test"))
                {
                    var block     = IfcModelBuilder.MakeBlock(m, 50, 10, 10);
                    var solid     = _geomEngine.CreateSolid(block);
                    var placement = IfcModelBuilder.MakeLocalPlacement(m);
                    ((IfcAxis2Placement3D)placement.RelativePlacement).Location.X = 100;
                    var bb     = solid.BoundingBox;
                    var solidA = _geomEngine.Moved(solid, placement) as IXbimSolid;
                    Assert.IsNotNull(solidA, "Should be the same type as the master");
                    var displacement = solidA.BoundingBox.Centroid() - solid.BoundingBox.Centroid();
                    Assert.IsTrue(displacement == new XbimVector3D(100, 0, 0));

                    var placementRelTo = ((IfcLocalPlacement)placement.PlacementRelTo);
                    var zDir           = m.Instances.New <IfcDirection>(d => d.SetXYZ(0, 0, 1));
                    ((IfcAxis2Placement3D)placementRelTo.RelativePlacement).Axis = zDir;
                    var yDir = m.Instances.New <IfcDirection>(d => d.SetXYZ(0, 1, 0));
                    ((IfcAxis2Placement3D)placementRelTo.RelativePlacement).RefDirection = yDir; //point in Y
                    ((IfcAxis2Placement3D)placementRelTo.RelativePlacement).Location.X   = 2000;
                    var solidB = _geomEngine.Moved(solid, placement) as IXbimSolid;
                    displacement = solidB.BoundingBox.Centroid() - solid.BoundingBox.Centroid();
                    var meshbuilder = new MeshHelper();
                    _geomEngine.Mesh(meshbuilder, solidB, m.ModelFactors.Precision, m.ModelFactors.DeflectionTolerance);
                    var box = meshbuilder.BoundingBox;
                    Assert.IsTrue(displacement == new XbimVector3D(1970, 120, 0));
                }
            }
        }
 public void IfcSurfaceOfRevolutionTest()
 {
     using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
         using (var txn = m.BeginTransaction("Test"))
         {
             var cc   = IfcModelBuilder.MakeRationalBSplineCurveWithKnots(m);
             var def  = IfcModelBuilder.MakeArbitraryOpenProfileDef(m, cc);
             var rev  = IfcModelBuilder.MakeSurfaceOfRevolution(m, def);
             var face = geomEngine.CreateFace(rev);
             Assert.IsNotNull(face as IXbimFace, "Wrong type returned");
             Assert.IsTrue(((IXbimFace)face).IsValid, "Invalid face returned");
         }
 }
 public void IfcSurfaceOfLinearExtrusionTest()
 {
     using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
         using (var txn = m.BeginTransaction("Test"))
         {
             var semiCircle = IfcModelBuilder.MakeSemiCircle(m, 20);
             var def        = IfcModelBuilder.MakeArbitraryOpenProfileDef(m, semiCircle);
             var cl         = IfcModelBuilder.MakeSurfaceOfLinearExtrusion(m, def, 50, new XbimVector3D(0, 0, 1));
             var face       = geomEngine.CreateFace(cl);
             Assert.IsNotNull(face as IXbimFace, "Wrong type returned");
             Assert.IsTrue(((IXbimFace)face).IsValid, "Invalid face returned");
         }
 }
Beispiel #8
0
 public void IfcCenterLineProfileDefTest()
 {
     using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction("Test"))
         {
             var semiCircle = IfcModelBuilder.MakeSemiCircle(m, 20);
             var cl         = IfcModelBuilder.MakeCenterLineProfileDef(m, semiCircle, 5);
             var face       = geomEngine.CreateFace(cl);
             Assert.IsNotNull(face as IXbimFace, "Wrong type returned");
             Assert.IsTrue(((IXbimFace)face).IsValid, "Invalid face returned");
         }
     }
 }
 public void BooleanIntersectSolidTest()
 {
     using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction(""))
         {
             var cylinder = IfcModelBuilder.MakeRightCircularCylinder(m, 10, 20);
             var sphere   = IfcModelBuilder.MakeSphere(m, 15);
             var a        = geomEngine.CreateSolid(sphere, logger);
             var b        = geomEngine.CreateSolid(cylinder, logger);
             var solidSet = a.Intersection(b, m.ModelFactors.PrecisionBoolean);
             Assert.IsTrue(solidSet.Count == 1, "intersecting these two solids should return a single solid");
             IsSolidTest(solidSet.First);
         }
     }
 }
        public void CutTwoCylindersTest()
        {
            using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction(""))
                {
                    var cylinderInner = IfcModelBuilder.MakeRightCircularCylinder(m, 10, 20);
                    var cylinderOuter = IfcModelBuilder.MakeRightCircularCylinder(m, 20, 20);
                    var logger        = loggerFactory.CreateLogger <IfcBooleanTests>();
                    var outer         = geomEngine.CreateSolid(cylinderOuter, logger);
                    var inner         = geomEngine.CreateSolid(cylinderInner, logger);
                    var solidSet      = outer.Cut(inner, m.ModelFactors.PrecisionBoolean);

                    Assert.IsTrue(solidSet.Count == 1, "Cutting these two solids should return a single solid");
                    IsSolidTest(solidSet.First);
                    txn.Commit();
                }
            }
        }
        public void SectionOfBlockTest()
        {
            using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction(""))
                {
                    var block    = IfcModelBuilder.MakeBlock(m, 10, 15, 20);
                    var solid    = geomEngine.CreateSolid(block, logger);
                    var plane    = IfcModelBuilder.MakePlane(m, new XbimPoint3D(block.Position.Location.X + 5, block.Position.Location.Y, block.Position.Location.Z), new XbimVector3D(-1, 0, 0), new XbimVector3D(0, 1, 0));
                    var cutPlane = geomEngine.CreateFace(plane, logger);

                    var section = solid.Section(cutPlane, m.ModelFactors.PrecisionBoolean);
                    if (section.First == null)
                    {
                        Assert.IsTrue(section.First != null, "Result should be a single face");
                        Assert.IsTrue(section.First.OuterBound.Edges.Count == 4, "4 edges are required of a section of a block");
                    }
                }
            }
        }
Beispiel #12
0
        public void IfcBlockTest()
        {
            using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction("Test"))
                {
                    var block = IfcModelBuilder.MakeBlock(m, 10, 15, 20);

                    var solid = geomEngine.CreateSolid(block);

                    Assert.IsTrue(solid.Faces.Count == 6, "6 faces are required of a block");
                    Assert.IsTrue(solid.Vertices.Count == 8, "8 vertices are required of a block");
                    var meshRec = new MeshHelper();
                    geomEngine.Mesh(meshRec, solid, m.ModelFactors.Precision, m.ModelFactors.DeflectionTolerance * 10);
                    Assert.IsTrue(meshRec.FaceCount == 6, "6 mesh faces are required of a block");
                    Assert.IsTrue(meshRec.PointCount == 24, "24 mesh points are required of a block");
                    txn.Commit();
                }
            }
        }
Beispiel #13
0
        public void IfcRightCircularCylinderTest()
        {
            using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction("Test"))
                {
                    const double h = 2; const double r = 0.5;
                    var          cylinder = IfcModelBuilder.MakeRightCircularCylinder(m, r, h);

                    var solid = geomEngine.CreateSolid(cylinder);

                    Assert.IsTrue(solid.Faces.Count == 3, "3 faces are required of a cylinder");
                    Assert.IsTrue(solid.Vertices.Count == 2, "2 vertices are required of a cylinder");
                    var meshRec = new MeshHelper();
                    geomEngine.Mesh(meshRec, solid, m.ModelFactors.Precision, m.ModelFactors.DeflectionTolerance * 10);
                    Assert.IsTrue(meshRec.FaceCount == 3, "3 mesh faces are required of a cylinder");
                    Assert.IsTrue(meshRec.PointCount == 106, "106 mesh points are required of a cylinder");
                    txn.Commit();
                }
            }
        }
        public void BooleanCutSolidWithVoidNonPlanarTest()
        {
            using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction("Populate"))
                {
                    var block1 = IfcModelBuilder.MakeSphere(m, 20);
                    var block2 = IfcModelBuilder.MakeSphere(m, 5);

                    var b1     = geomEngine.CreateSolid(block1);
                    var b2     = geomEngine.CreateSolid(block2);
                    var result = b1.Cut(b2, m.ModelFactors.PrecisionBoolean);
                    Assert.IsTrue(result.Count == 1, "Cutting of these two solids should return two  solids");
                    const double vOuter = (4.0 / 3.0) * Math.PI * 20.0 * 20.0 * 20.0;
                    const double vInner = (4.0 / 3.0) * Math.PI * 5.0 * 5.0 * 5.0;
                    const double volume = vOuter - vInner;

                    Assert.IsTrue(result.First.Volume - volume <= m.ModelFactors.Precision, "Volume is incorrect");
                    txn.Commit();
                }
            }
        }
        public void IfcCsgIntersectionTest()
        {
            using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction(""))
                {
                    var csgTree = m.Instances.New <IfcCsgSolid>();
                    var bresult = m.Instances.New <IfcBooleanResult>();

                    var cylinder = IfcModelBuilder.MakeRightCircularCylinder(m, 10, 20);
                    var sphere   = IfcModelBuilder.MakeSphere(m, 15);
                    bresult.FirstOperand       = cylinder;
                    bresult.SecondOperand      = sphere;
                    bresult.Operator           = IfcBooleanOperator.INTERSECTION;
                    csgTree.TreeRootExpression = bresult;

                    var solid = geomEngine.CreateSolidSet(csgTree, logger).FirstOrDefault();
                    Assert.IsTrue(solid.Faces.Count == 3, "3 faces are required of this csg solid");
                    Assert.IsTrue(solid.Vertices.Count == 3, "3 vertices are required of this csg solid");
                }
            }
        }
 public void GridPlacementTest()
 {
     //this test checks that a object is correctly copied and moved
     //create a box
     using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction("Test"))
         {
             var block         = IfcModelBuilder.MakeBlock(m, 10, 10, 10);
             var solid         = _geomEngine.CreateSolid(block);
             var grid          = IfcModelBuilder.MakeGrid(m, 3, 100);
             var gridPlacement = m.Instances.New <IfcGridPlacement>();
             gridPlacement.PlacementLocation = m.Instances.New <IfcVirtualGridIntersection>();
             gridPlacement.PlacementLocation.IntersectingAxes.Add(grid.UAxes.Last());
             gridPlacement.PlacementLocation.IntersectingAxes.Add(grid.VAxes.Last());
             var solidA = _geomEngine.Moved(solid, gridPlacement) as IXbimSolid;
             Assert.IsNotNull(solidA, "Should be the same type as the master");
             var displacement = solidA.BoundingBox.Centroid() - solid.BoundingBox.Centroid();
             Assert.IsTrue(displacement == new XbimVector3D(200, 200, 0));
         }
     }
 }
 public void TransformSolidRectangularProfileDef()
 {
     using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction("Test"))
         {
             var profile   = IfcModelBuilder.MakeRectangleHollowProfileDef(m, 20, 10, 1);
             var extrude   = IfcModelBuilder.MakeExtrudedAreaSolid(m, profile, 40);
             var solid     = _geomEngine.CreateSolid(extrude);
             var transform = new XbimMatrix3D(); //test first with identity
             var solid2    = (IXbimSolid)solid.Transform(transform);
             var s1Verts   = solid.Vertices.ToList();
             var s2Verts   = solid2.Vertices.ToList();
             for (int i = 0; i < s1Verts.Count; i++)
             {
                 XbimVector3D v = s1Verts[i].VertexGeometry - s2Verts[i].VertexGeometry;
                 Assert.IsTrue(v.Length < m.ModelFactors.Precision, "vertices not the same");
             }
             transform.RotateAroundXAxis(Math.PI / 2);
             transform.RotateAroundYAxis(Math.PI / 4);
             transform.RotateAroundZAxis(Math.PI);
             transform.OffsetX += 100;
             transform.OffsetY += 200;
             transform.OffsetZ += 300;
             solid2             = (IXbimSolid)solid.Transform(transform);
             Assert.IsTrue(Math.Abs(solid.Volume - solid2.Volume) < 0.001, "Volume differs");
             transform.Invert();
             solid2  = (IXbimSolid)solid2.Transform(transform);
             s1Verts = solid.Vertices.ToList();
             s2Verts = solid2.Vertices.ToList();
             for (int i = 0; i < s1Verts.Count; i++)
             {
                 XbimVector3D v = s1Verts[i].VertexGeometry - s2Verts[i].VertexGeometry;
                 Assert.IsTrue(v.Length < m.ModelFactors.Precision, "vertices not the same");
             }
             txn.Commit();
         }
     }
 }
 public void SectionOfCylinderTest()
 {
     using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction(""))
         {
             var cylinder = IfcModelBuilder.MakeRightCircularCylinder(m, 20, 20);
             var solid    = geomEngine.CreateSolid(cylinder, logger);
             var plane    = IfcModelBuilder.MakePlane(m, new XbimPoint3D(cylinder.Position.Location.X + 1, cylinder.Position.Location.Y, cylinder.Position.Location.Z), new XbimVector3D(0, -1, 0), new XbimVector3D(1, 0, 0));
             var cutPlane = geomEngine.CreateFace(plane, logger);
             var section  = solid.Section(cutPlane, m.ModelFactors.PrecisionBoolean);
             Assert.IsTrue(section.First != null, "Result should be a face");
             Assert.IsTrue(section.First.OuterBound.Edges.Count == 4, "4 edges are required for this section of a cylinder");
             //repeat with section through cylinder
             plane    = IfcModelBuilder.MakePlane(m, new XbimPoint3D(cylinder.Position.Location.X + 1, cylinder.Position.Location.Y, cylinder.Position.Location.Z), new XbimVector3D(0, 0, 1), new XbimVector3D(0, 1, 0));
             cutPlane = geomEngine.CreateFace(plane, logger);
             section  = solid.Section(cutPlane, m.ModelFactors.PrecisionBoolean);
             Assert.IsTrue(section.First != null, "Result should be a face");
             Assert.IsTrue(section.First.OuterBound.Edges.Count == 1, "1 edge is required for this section of a cylinder");
             Assert.IsTrue(section.First.InnerBounds.Count == 0, "0 inner wires are required for this section of a cylinder");
         }
     }
 }
        public void BooleanCutSolidWithVoidPlanarTest()
        {
            using (var m = new MemoryModel(new Xbim.Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction("Populate"))
                {
                    var block1 = IfcModelBuilder.MakeBlock(m, 20, 20, 20);
                    var block2 = IfcModelBuilder.MakeBlock(m, 5, 5, 5);
                    block2.Position.Location.X += 10;
                    block2.Position.Location.Y += 10;
                    block2.Position.Location.Z += 10;

                    var b1     = geomEngine.CreateSolid(block1);
                    var b2     = geomEngine.CreateSolid(block2);
                    var result = b1.Cut(b2, m.ModelFactors.PrecisionBoolean);
                    Assert.IsTrue(result.Count == 1, "Cutting of these two solids should return two  solids");
                    foreach (var solid in result)
                    {
                        HelperFunctions.IsValidSolid(solid);
                    }
                    txn.Commit();
                }
            }
        }
 public void IfcHalfspace_Test()
 {
     using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
     {
         using (var txn = m.BeginTransaction(""))
         {
             var halfSpace = m.Instances.New <IfcHalfSpaceSolid>();
             halfSpace.AgreementFlag = false;
             var baseSurface = m.Instances.New <IfcPlane>();
             baseSurface.Position            = m.Instances.New <IfcAxis2Placement3D>();
             baseSurface.Position.Location   = m.Instances.New <IfcCartesianPoint>();
             baseSurface.Position.Location.X = 0;
             baseSurface.Position.Location.Y = 0;
             baseSurface.Position.Location.Z = 10;
             halfSpace.BaseSurface           = baseSurface;
             //make an extrusion
             var profile        = IfcModelBuilder.MakeRectangleHollowProfileDef(m, 20, 10, 1);
             var extrude        = IfcModelBuilder.MakeExtrudedAreaSolid(m, profile, 40);
             var solid          = geomEngine.CreateSolid(extrude, logger);
             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);
             //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);
             //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);
         }
     }
 }
        public void IfcPolygonalBoundedHalfspace_Test()
        {
            using (var m = new MemoryModel(new Ifc4.EntityFactoryIfc4()))
            {
                using (var txn = m.BeginTransaction(""))
                {
                    var polygonalBoundedHalfspace = m.Instances.New <IfcPolygonalBoundedHalfSpace>();
                    polygonalBoundedHalfspace.AgreementFlag = false;
                    var plane = m.Instances.New <IfcPlane>();
                    plane.Position          = m.Instances.New <IfcAxis2Placement3D>();
                    plane.Position.Location = m.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(0, 0, 0));

                    polygonalBoundedHalfspace.BaseSurface = plane;
                    //create the polygonal bound
                    var polyLine = m.Instances.New <IfcPolyline>();
                    polyLine.Points.Add(m.Instances.New <IfcCartesianPoint>(c => c.SetXY(0, 2.5)));
                    polyLine.Points.Add(m.Instances.New <IfcCartesianPoint>(c => c.SetXY(5, 2.5)));
                    polyLine.Points.Add(m.Instances.New <IfcCartesianPoint>(c => c.SetXY(5, -2.5)));
                    polyLine.Points.Add(m.Instances.New <IfcCartesianPoint>(c => c.SetXY(0, -2.5)));
                    polyLine.Points.Add(m.Instances.New <IfcCartesianPoint>(c => c.SetXY(0, 2.5)));
                    polygonalBoundedHalfspace.PolygonalBoundary = polyLine;

                    var basePos = m.Instances.New <IfcAxis2Placement3D>();
                    basePos.Location = m.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(0, 0, 0));
                    polygonalBoundedHalfspace.Position = basePos;
                    //make an extrusion
                    var profile        = IfcModelBuilder.MakeRectangleProfileDef(m, 20, 10);
                    var extrude        = IfcModelBuilder.MakeExtrudedAreaSolid(m, profile, 40);
                    var solid          = geomEngine.CreateSolid(extrude, logger);
                    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);

                    //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);

                    //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);

                    //some realistic data
                    polyLine.Points[0].SetXY(0, 0);
                    polyLine.Points[1].SetXY(0, 2850);
                    polyLine.Points[2].SetXY(-350, 2850);
                    polyLine.Points[3].SetXY(-350, 0);
                    polyLine.Points[4].SetXY(0, 0);
                    plane.Position.Location.SetXYZ(-5240.7742616303667, -33052.9790707385, 0.0);
                    plane.Position.Axis         = m.Instances.New <IfcDirection>(d => d.SetXYZ(0, -1, 0));
                    plane.Position.RefDirection = m.Instances.New <IfcDirection>(d => d.SetXYZ(1, 0, 0));
                    basePos.Location.SetXYZ(-5240.7742616303667, -33052.9790707385, 0);
                    basePos.Axis         = plane.Position.Axis;
                    basePos.RefDirection = plane.Position.RefDirection;

                    halfSpaceSolid = geomEngine.CreateSolid(polygonalBoundedHalfspace, logger);

                    profile.XDim = 350;
                    profile.YDim = 125;
                    profile.Position.Location.SetXY(-5415.7742616303676, -32932.529070738507);
                    extrude.Depth = 2850;
                    solid         = geomEngine.CreateSolid(extrude, logger);

                    cut = solid.Cut(halfSpaceSolid, 1e-5); //everything should be cut
                    Assert.IsTrue(cut.Count == 0);
                }
            }
        }