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