public static List <Envelope> SliceAtHeight(MeshElement meshElement, double cutHeight, Boolean showDebugGeometry)
        {
            var bbox   = new BBox3(TransformedVertices(meshElement.Mesh.Vertices, meshElement.Transform));
            var bottom = bbox.Min.Z;
            var top    = bbox.Max.Z;
            var solids = new List <Elements.Geometry.Solids.SolidOperation>();
            var solid  = new Elements.Geometry.Solids.Solid();

            foreach (var face in meshElement.Mesh.Triangles)
            {
                var vertices = TransformedVertices(face.Vertices, meshElement.Transform);
                solid.AddFace(new Polygon(vertices));
            }
            solids.Add(new Elements.Geometry.Solids.ConstructedSolid(solid));
            var rep = new Representation(solids);
            var env = new Envelope(Polygon.Rectangle(new Vector3(bbox.Min.X, bbox.Min.Y), new Vector3(bbox.Max.X, bbox.Max.Y)), bottom, top - bottom, Vector3.ZAxis, 0, new Transform(), _debugMaterial, rep, false, Guid.NewGuid(), "");

            return(SliceAtHeight(env, cutHeight, showDebugGeometry));
        }
        public static List <Envelope> SliceAtHeight(Envelope envelope, double cutHeight, Boolean showDebugGeometry)
        {
            var debugMaterial = new Material("DebugSolid", new Color(1, 0, 0, 1));

            var plane = new Plane(new Vector3(0, 0, cutHeight), Vector3.ZAxis);
            var top   = envelope.Elevation + envelope.Height;
            var envelopesForBlockage = new List <Envelope>();
            var newUpperSolids       = new List <Elements.Geometry.Solids.SolidOperation>();

            Polygon slice = null;

            foreach (var solidOp in envelope.Representation.SolidOperations)
            {
                var intersections = new List <Vector3>();
                var newUpperSolid = new Elements.Geometry.Solids.Solid();

                foreach (var face in solidOp.Solid.Faces)
                {
                    var polygon = face.Value.Outer.ToPolygon();
                    if (solidOp.LocalTransform != null)
                    {
                        polygon = (Polygon)polygon.Transformed(solidOp.LocalTransform);
                    }
                    if (envelope.Transform != null)
                    {
                        polygon = (Polygon)polygon.Transformed(envelope.Transform);
                    }

                    var faceIntersections = new List <Vector3>();

                    foreach (var segment in polygon.Segments())
                    {
                        if (segment.Intersects(plane, out var intersection))
                        {
                            intersections.Add(intersection);
                            faceIntersections.Add(intersection);
                        }
                    }

                    if (faceIntersections.Count == 0)
                    {
                        if (polygon.Centroid().Z > cutHeight)
                        {
                            newUpperSolid.AddFace(polygon);
                        }
                    }
                    else if (faceIntersections.Count > 1)
                    {
                        faceIntersections = faceIntersections.OrderBy(p => p.X).ThenBy(p => p.Y).ToList();
                        var splitLine = new Polyline(faceIntersections);
                        var splits    = polygon.Split(splitLine);
                        foreach (var split in splits)
                        {
                            if (split.Centroid().Z > cutHeight)
                            {
                                newUpperSolid.AddFace(split);
                            }
                        }
                    }
                }

                if (intersections.Count >= 3)
                {
                    slice = ConvexHull.FromPoints(intersections);
                    slice = slice.Project(new Plane(new Vector3(), Vector3.ZAxis));
                }
                else if (intersections.Count > 0)
                {
                    Console.WriteLine($"Failed to intersect polygon for East Midtown: Found {intersections.Count} point");
                }

                newUpperSolids.Add(new Elements.Geometry.Solids.ConstructedSolid(newUpperSolid));
            }

            if (slice != null)
            {
                var extrude1 = new Elements.Geometry.Solids.Extrude(slice, cutHeight, Vector3.ZAxis, false);
                var rep1     = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                {
                    extrude1
                });
                var env1 = new Envelope(slice, 0, cutHeight, Vector3.ZAxis, 0, new Transform(), _debugMaterial, rep1, false, Guid.NewGuid(), "");
                envelopesForBlockage.Add(env1);

                var rep2 = new Representation(newUpperSolids);
                var env2 = new Envelope(slice, 0, cutHeight, Vector3.ZAxis, 0, new Transform(), _debugMaterial, rep2, false, Guid.NewGuid(), "");
                envelopesForBlockage.Add(env2);

                if (showDebugGeometry)
                {
                    Model.AddElement(env1);
                    Model.AddElement(env2);
                }
            }

            return(envelopesForBlockage);
        }