/// <summary> /// The EnvelopeByCenterline function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A EnvelopeByCenterlineOutputs instance containing computed results and the model with any new elements.</returns> public static EnvelopeByCenterlineOutputs Execute(Dictionary <string, Model> inputModels, EnvelopeByCenterlineInputs input) { var Centerline = input.Centerline; var perimeter = Centerline.Offset(input.BarWidth / 2, EndType.Butt).First(); // Create the foundation Envelope. var extrude = new Elements.Geometry.Solids.Extrude(perimeter, input.FoundationDepth, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var fndMatl = new Material("foundation", new Color(0.6, 0.60000002384185791, 0.6, 1), 0.0f, 0.0f); var envMatl = new Material("envelope", new Color(0.3, 0.7, 0.7, 0.6), 0.0f, 0.0f); var envelopes = new List <Envelope>() { new Envelope(perimeter, input.FoundationDepth * -1, input.FoundationDepth, Vector3.ZAxis, 0.0, new Transform(0.0, 0.0, input.FoundationDepth * -1), fndMatl, geomRep, false, Guid.NewGuid(), "") }; // Create the Envelope at the location's zero plane. var output = new EnvelopeByCenterlineOutputs(input.BuildingHeight, input.FoundationDepth); extrude = new Elements.Geometry.Solids.Extrude(perimeter, input.BuildingHeight, Vector3.ZAxis, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(perimeter, 0.0, input.BuildingHeight, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, Guid.NewGuid(), "")); output.Model.AddElements(envelopes); var sketch = new Sketch(input.Centerline, Guid.NewGuid(), "Centerline Sketch"); output.Model.AddElement(sketch); return(output); }
/// <summary> /// /// </summary> /// <param name="insertAt"></param> /// <returns></returns> private CompassBox MakeBaths(Vector3 moveTo) { var bathPerim = Polygon.Rectangle(bathLength, bathWidth); var bathTopo = new CompassBox(bathPerim); bathPerim = bathPerim.MoveFromTo(bathTopo.W, moveTo); bathTopo = new CompassBox(bathPerim); bathPerim = bathPerim.Rotate(Position, Rotation); var bathLevels = Levels.Where(l => l.Elevation >= 0.0); var bathMatl = new Material(new Color(0.0f, 0.6f, 1.0f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "bath"); var i = 0; foreach (var level in bathLevels.SkipLast(2)) { var bathHeight = bathLevels.ElementAt(i + 1).Elevation - bathLevels.ElementAt(i).Elevation - 1.0; var extrude = new Elements.Geometry.Solids.Extrude(bathPerim, bathHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); Restrooms.Add(new Room(bathPerim, Vector3.ZAxis, "", "", "", "", 0.0, 0.0, Rotation, bathLevels.ElementAt(i).Elevation, bathHeight, bathPerim.Area(), new Transform(0.0, 0.0, bathLevels.ElementAt(i).Elevation), bathMatl, geomRep, false, Guid.NewGuid(), "Restroom")); i++; } return(bathTopo); }
/// <summary> /// /// </summary> /// <param name="moveTo"></param> /// <returns></returns> private CompassBox MakeMech(Vector3 moveTo) { var mechPerim = Polygon.Rectangle(mechLength, mechWidth); var mechTopo = new CompassBox(mechPerim); mechPerim = mechPerim.MoveFromTo(mechTopo.W, moveTo); mechTopo = new CompassBox(mechPerim); mechPerim = mechPerim.Rotate(Position, Rotation); var lastLevel = Levels.SkipLast(1).Last(); var mechHeight = lastLevel.Elevation - Levels.First().Elevation; var extrude = new Elements.Geometry.Solids.Extrude(mechPerim, mechHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var mechMatl = new Material(new Color(0.2f, 0.2f, 0.2f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "mech"); var ctr = mechPerim.Centroid(); Mechanicals.Add(new MechanicalCorridor(mechPerim, Vector3.ZAxis, Rotation, new Vector3(ctr.X, ctr.Y, Levels.First().Elevation), new Vector3(ctr.X, ctr.Y, Levels.First().Elevation + mechHeight), mechHeight, mechPerim.Area() * mechHeight, "", new Transform(0.0, 0.0, Levels.First().Elevation), mechMatl, geomRep, false, Guid.NewGuid(), "")); return(mechTopo); }
/// <summary> /// The CoreBySketch function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A CoreBySketchOutputs instance containing computed results and the model with any new elements.</returns> public static CoreBySketchOutputs Execute(Dictionary <string, Model> inputModels, CoreBySketchInputs input) { { //Extract the Levels from the model. var levels = new List <Level>(); inputModels.TryGetValue("Levels", out var model); if (model == null || model.AllElementsOfType <Level>().Count() == 0) { throw new ArgumentException("No Levels found."); } levels.AddRange(model.AllElementsOfType <Level>()); var top = levels.OrderByDescending(l => l.Elevation).First().Elevation + input.CoreHeightAboveRoof; var elevation = levels.OrderBy(l => l.Elevation).First().Elevation; var height = top - elevation; // Create the Core extrusion. var extrude = new Elements.Geometry.Solids.Extrude(input.Perimeter, height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var corMatl = new Material("core", new Color(1.0, 1.0, 1.0, 0.6), 0.0f, 0.0f); var svcCore = new ServiceCore(input.Perimeter, Vector3.ZAxis, elevation, height, 0.0, new Transform(0.0, 0.0, elevation), corMatl, geomRep, false, Guid.NewGuid(), "serviceCore"); var output = new CoreBySketchOutputs(height); output.Model.AddElement(svcCore); return(output); } }
/// <summary> /// The CoreByEnvelope function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A CoreByEnvelopeOutputs instance containing computed results and the model with any new elements.</returns> public static CoreByEnvelopeOutputs Execute(Dictionary <string, Model> inputModels, CoreByEnvelopeInputs inputs) { var envelopes = new List <Envelope>(); inputModels.TryGetValue("Envelope", out var model); if (model == null || model.AllElementsOfType <Envelope>().Count() == 0) { throw new ArgumentException("No Envelope found."); } envelopes.AddRange(model.AllElementsOfType <Envelope>()); var coreDef = CoreMaker.MakeCore(inputs, envelopes); var extrude = new Elements.Geometry.Solids.Extrude(coreDef.perimeter, coreDef.height, Vector3.ZAxis, false); var corRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var corMatl = new Material("serviceCore", Palette.White, 0.0f, 0.0f); var output = new CoreByEnvelopeOutputs(coreDef.length, coreDef.width, coreDef.rotation); //envelopes.ForEach(e => output.model.AddElement(e)); output.model.AddElement(new ServiceCore(coreDef.perimeter, Vector3.ZAxis, coreDef.elevation, coreDef.height, 0.0, new Transform(0.0, 0.0, coreDef.elevation), corMatl, corRep, false, Guid.NewGuid(), "Service Core")); return(output); }
/// <summary> /// Generate a volume of a given width /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A EnvolopeByPolylineOutputs instance containing computed results and the model with any new elements.</returns> public static EnvolopeByPolylineOutputs Execute(Dictionary <string, Model> inputModels, EnvolopeByPolylineInputs input) { Polyline polyline = input.BuildingAxis; if (polyline == null) { throw new ArgumentException("Please draw the axe of the building."); } Polygon perimeter = input.BuildingAxis.Offset(input.BuildingWidth / 2, EndType.Butt).First(); var envMatl = new Material("envelope", new Color(0.3, 0.7, 0.7, 0.6), 0.0f, 0.0f); var envelopes = new List <Envelope>(); // Create the Envelope at the location's zero plane. var output = new EnvolopeByPolylineOutputs(perimeter.ToPolyline().Length() * input.BuildingHeight, perimeter.Area()); var extrude = new Elements.Geometry.Solids.Extrude(perimeter, input.BuildingHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(perimeter, 0.0, input.BuildingHeight, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, Guid.NewGuid(), "")); output.Model.AddElements(envelopes); var sketch = new ModelCurve(polyline, name: "Centerline Sketch"); output.Model.AddElement(sketch); return(output); }
/// <summary> /// Generates a building Envelope from a sketch of the footprint, a building height, and a setback configuration. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A EnvelopeBySketchOutputs instance containing computed results and the model with any new elements.</returns> public static EnvelopeBySketchOutputs Execute(Dictionary<string, Model> inputModels, EnvelopeBySketchInputs input) { Elements.Geometry.Solids.Extrude extrude; Representation geomRep; var envelopes = new List<Envelope>(); var envMatl = new Material("envelope", new Color(0.3, 0.7, 0.7, 0.6), 0.0f, 0.0f); // Create the foundation Envelope. if (input.FoundationDepth > 0) { extrude = new Elements.Geometry.Solids.Extrude(input.Perimeter, input.FoundationDepth, Vector3.ZAxis, false); geomRep = new Representation(new List<Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(input.Perimeter, input.FoundationDepth * -1, input.FoundationDepth, Vector3.ZAxis, 0.0, new Transform(0.0, 0.0, input.FoundationDepth * -1), envMatl, geomRep, false, Guid.NewGuid(), "")); } // Create the Envelope at the location's zero plane. var tiers = Math.Floor(input.BuildingHeight / input.SetbackInterval); var tierHeight = tiers > 1 ? input.BuildingHeight / tiers : input.BuildingHeight; var polygon = input.Perimeter; if (polygon.IsClockWise()) { polygon = polygon.Reversed(); } extrude = new Elements.Geometry.Solids.Extrude(polygon, tierHeight, Vector3.ZAxis, false); geomRep = new Representation(new List<Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(input.Perimeter, 0.0, tierHeight, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, Guid.NewGuid(), "")); // Create the remaining Envelope Elements. var offsFactor = -1; var elevFactor = 1; for (int i = 0; i < tiers - 1; i++) { var tryPer = input.Perimeter.Offset(input.SetbackDepth * offsFactor); tryPer = tryPer.OrderByDescending(p => p.Area()).ToArray(); if (tryPer.Count() == 0 || tryPer.First().Area() < input.MinimumTierArea) { break; } polygon = tryPer.First(); if (polygon.IsClockWise()) { polygon = polygon.Reversed(); } extrude = new Elements.Geometry.Solids.Extrude(polygon, tierHeight, Vector3.ZAxis, false); geomRep = new Representation(new List<Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(tryPer.First(), tierHeight * elevFactor, tierHeight, Vector3.ZAxis, 0.0, new Transform(0.0, 0.0, tierHeight * elevFactor), envMatl, geomRep, false, Guid.NewGuid(), "")); offsFactor--; elevFactor++; } var output = new EnvelopeBySketchOutputs(input.BuildingHeight, input.FoundationDepth); envelopes = envelopes.OrderBy(e => e.Elevation).ToList(); foreach (var env in envelopes) { output.Model.AddElement(env); } return output; }
/// <summary> /// /// </summary> /// <param name="stairs"></param> /// <param name="liftSvc"></param> private void MakeLifts(List <CompassBox> stairs, int liftSvc) { var liftMatl = new Material(new Color(1.0f, 0.9f, 0.4f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "lift"); var liftPolys = new List <Polygon>() { Polygon.Rectangle(liftSize, liftSize) }; for (var i = 0; i < (LiftQuantity * 0.5) - 1; i++) { var liftPerim = Polygon.Rectangle(liftSize, liftSize); var liftTopo = new CompassBox(liftPerim); var lastTopo = new CompassBox(liftPolys.Last()); liftPolys.Add(liftPerim.MoveFromTo(liftTopo.SW, lastTopo.SE)); } var firstTopo = new CompassBox(liftPolys.First()); var stairTopo = stairs.First(); var makePolys = new List <Polygon>(); foreach (var polygon in liftPolys) { makePolys.Add(polygon.MoveFromTo(firstTopo.SW, stairTopo.SE).Rotate(Position, Rotation)); } liftPolys.Clear(); liftPolys.Add(Polygon.Rectangle(liftSize, liftSize)); for (var i = 0; i < (LiftQuantity * 0.5) - 1; i++) { var liftPerim = Polygon.Rectangle(liftSize, liftSize); var liftTopo = new CompassBox(liftPerim); var lastTopo = new CompassBox(liftPolys.Last()); liftPolys.Add(liftPerim.MoveFromTo(liftTopo.SW, lastTopo.SE)); } firstTopo = new CompassBox(liftPolys.First()); stairTopo = stairs.Last(); foreach (var polygon in liftPolys) { makePolys.Add(polygon.MoveFromTo(firstTopo.NW, stairTopo.NE).Rotate(Position, Rotation)); } var liftSvcFactor = 0; foreach (var polygon in makePolys) { var lastLevel = Levels.SkipLast((int)liftSvc * liftSvcFactor).Last(); var liftHeight = lastLevel.Elevation - Levels.First().Elevation; if (liftHeight > 10.0) { var extrude = new Elements.Geometry.Solids.Extrude(polygon, liftHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); Lifts.Add(new LiftShaft(polygon, Vector3.ZAxis, Rotation, Levels.First().Elevation, liftHeight, polygon.Area() * liftHeight, "", new Transform(0.0, 0.0, Levels.First().Elevation), liftMatl, geomRep, false, Guid.NewGuid(), "")); } liftSvcFactor++; } }
public static rg.Brep ToRgBrep(this Elements.Geometry.Solids.Extrude extrude) { var profile = extrude.Profile.ToSurface(); var dir = extrude.Direction.ToRgVector(); dir.Unitize(); dir *= extrude.Height; return(ExtrudeBrep(profile, dir)); }
private static Envelope CreateFoundation(Polygon perimeter, double depth) { var extrude = new Elements.Geometry.Solids.Extrude(perimeter, depth, Vector3.ZAxis, 0.0, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var material = BuiltInMaterials.Concrete; return(new Envelope(perimeter, depth * -1, depth, Vector3.ZAxis, 0.0, new Transform(0.0, 0.0, depth * -1), material, geomRep, Guid.NewGuid(), "")); }
/// <summary> /// /// </summary> /// <param name="bathTopo"></param> /// <returns></returns> private List <CompassBox> MakeStairs(CompassBox bathTopo) { var stairTopos = new List <CompassBox>(); for (int i = 0; i < 2; i++) { Vector3 from; Vector3 to; var stairHeight = 0.0; var lastLevel = Levels.Last(); var stairPerim = Polygon.Rectangle(stairLength, stairWidth); var stairTopo = new CompassBox(stairPerim); if (i == 0) { from = stairTopo.SW; to = bathTopo.NW; stairHeight = lastLevel.Elevation - Levels.First().Elevation + stairEntry; } else { from = stairTopo.NW; to = bathTopo.SW; stairHeight = lastLevel.Elevation - Levels.First().Elevation; } stairPerim = stairPerim.MoveFromTo(from, to); stairTopo = new CompassBox(stairPerim); stairTopos.Add(stairTopo); stairPerim = stairPerim.Rotate(Position, Rotation); var extrude = new Elements.Geometry.Solids.Extrude(stairPerim, stairHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var stairMatl = new Material(new Color(1.0f, 0.0f, 0.0f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "stair"); Stairs.Add(new StairEnclosure(stairPerim, Vector3.ZAxis, Rotation, Levels.First().Elevation, stairHeight, stairPerim.Area() * stairHeight, "", new Transform(0.0, 0.0, Levels.First().Elevation), stairMatl, geomRep, false, Guid.NewGuid(), "")); } return(stairTopos); }
/// <summary> /// Creates a Roof from a supplied Polygon sketch and a supplied elevation. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A RoofBySketchOutputs instance containing computed results and the model with any new elements.</returns> public static RoofBySketchOutputs Execute(Dictionary <string, Model> inputModels, RoofBySketchInputs input) { var extrude = new Elements.Geometry.Solids.Extrude(input.Perimeter, input.RoofThickness, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var roofMatl = BuiltInMaterials.Concrete; var output = new RoofBySketchOutputs(input.Perimeter.Area()); output.Model.AddElement(new Roof(input.Perimeter, input.RoofElevation, input.RoofThickness, input.Perimeter.Area(), new Transform(0.0, 0.0, input.RoofElevation - input.RoofThickness), roofMatl, geomRep, false, Guid.NewGuid(), "")); return(output); }
private void StairFlightMaker(Line flightLine, int threadNumber, double threadDepth, double actualRiserHeigh, double runWidth, double elevation, double structuralDepth) { List <Vector3> profileVertices = new List <Vector3>(); Vector3 riserVector = Vector3.ZAxis * actualRiserHeigh; Vector3 threadVector = Vector3.XAxis * threadDepth; // Add first point profileVertices.Add(new Vector3()); for (int i = 0; i < threadNumber; i++) { profileVertices.Add(profileVertices[i * 2] + riserVector); profileVertices.Add(profileVertices[i * 2] + riserVector + threadVector); } profileVertices.Add(CalculateEndStairUnderside(structuralDepth, riserVector, threadVector, profileVertices.Last())); profileVertices.Add(CalculateStartStairUnderside(structuralDepth, riserVector, threadVector)); Polygon profile = new Polygon(profileVertices); Vector3 flightStartingPoint = flightLine.Start + Vector3.ZAxis * elevation + Vector3.ZAxis.Cross(flightLine.Direction()).Negate() * runWidth / 2; Transform transform = new Transform(flightStartingPoint, flightLine.Direction(), Vector3.ZAxis); var extrude1 = new Elements.Geometry.Solids.Extrude(profile, runWidth, Vector3.YAxis, false); // var extrude2 = new Elements.Geometry.Solids.Extrude(profile, runWidth / 2, Vector3.YAxis.Negate(), false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude1 }); var stairMaterial = new Material("Concrete", Colors.White, 0.5, 0.1, _texturePath); Stairs.Add(new Stair(0, actualRiserHeigh, actualRiserHeigh, 0, profile, transform, stairMaterial, geomRep, false, Guid.NewGuid(), "")); }
private static Polygon AddRoomFromCell(Grid2d cell, string department, Material material, Model model, double circulationWidth, double height) { var polygons = cell.GetTrimmedCellGeometry(); if (polygons.Count() == 0) { return(null); } var polygon = (Polygon)polygons.First(); var newPoints = polygon.Vertices.ToList().ToArray().Shrink(circulationWidth); var newPolygon = new Polygon(newPoints); var solid = new Elements.Geometry.Solids.Extrude(newPolygon, height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); var room = new Room((Polygon)newPolygon, Vector3.ZAxis, "Section 1", "100", department, "100", newPolygon.Area(), 1.0, 0, 0, 10, newPolygon.Area(), new Transform(), material, geomRep, false, System.Guid.NewGuid(), "Section 1"); model.AddElement(room); return(newPolygon); }
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); }
/// <summary> /// Generates a building Envelope from a Site boundary. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A EnvelopeBySiteOutputs instance containing computed results and the model with any new elements.</returns> public static EnvelopeBySiteOutputs Execute(Dictionary <string, Model> inputModels, EnvelopeBySiteInputs input) { // Retrieve site information from incoming models. var sites = new List <Site>(); inputModels.TryGetValue("Site", out var model); if (model == null) { throw new ArgumentException("No Site found."); } sites.AddRange(model.AllElementsOfType <Site>()); sites = sites.OrderByDescending(e => e.Perimeter.Area()).ToList(); var output = new EnvelopeBySiteOutputs(input.BuildingHeight, input.FoundationDepth); // Set input values based on whether we should consider setbacks var siteSetback = input.SiteSetback; var setbackInterval = input.UseSetbacks ? input.SetbackInterval : 0; var setbackDepth = input.UseSetbacks ? input.SetbackDepth : 0; var xy = new Plane((0, 0, 0), (0, 0, 1)); foreach (var site in sites) { var siteCentroid = site.Perimeter.Centroid(); var overridesForSite = input.Overrides?.EnvelopeFootprint?.Where(o => site.Perimeter.Contains(o.Identity.SiteCentroid)) ?? new List <EnvelopeFootprintOverride>(); var perims = site.Perimeter.Offset(siteSetback * -1); if (perims.Count() == 0) { continue; } perims = perims.OrderByDescending(p => p.Area()).ToArray(); var perimeter = perims.First(); if (perimeter.Area() < input.MinimumTierArea) { continue; } var envelopes = new List <Envelope>(); // Create the foundation Envelope. var fndElevation = input.FoundationDepth * -1; var matchingFndOverride = overridesForSite.FirstOrDefault(o => o.Identity.Elevation.ApproximatelyEquals(fndElevation, 1)); var fndPerimeter = matchingFndOverride?.Value?.Perimeter?.Project(xy) ?? perimeter; var extrude = new Elements.Geometry.Solids.Extrude(perimeter, input.FoundationDepth, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var fndMatl = new Material("foundation", Palette.Gray, 0.0f, 0.0f); var envMatl = new Material("envelope", Palette.Aqua, 0.0f, 0.0f); var fndXform = new Transform(0.0, 0.0, input.FoundationDepth * -1); var fndEnvelope = new Envelope(fndPerimeter, fndElevation, input.FoundationDepth, Vector3.ZAxis, 0.0, fndXform, fndMatl, geomRep, false, Guid.NewGuid(), "") { Perimeter = fndPerimeter.TransformedPolygon(fndXform), SiteCentroid = siteCentroid }; if (matchingFndOverride != null) { Identity.AddOverrideIdentity(fndEnvelope, matchingFndOverride); } envelopes.Add(fndEnvelope); // Create the Envelope at the location's zero plane. var matchingZeroOverride = overridesForSite.FirstOrDefault(o => o.Identity.Elevation.ApproximatelyEquals(0, 1)); var zeroPerimeter = matchingZeroOverride?.Value?.Perimeter?.Project(xy) ?? perimeter; var tiers = setbackInterval == 0 ? 0 : Math.Floor(input.BuildingHeight / setbackInterval) - 1; var tierHeight = tiers > 0 ? input.BuildingHeight / (tiers + 1) : input.BuildingHeight; extrude = new Elements.Geometry.Solids.Extrude(zeroPerimeter, tierHeight, Vector3.ZAxis, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var zeroEnvelope = new Envelope(zeroPerimeter, 0.0, tierHeight, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, Guid.NewGuid(), "") { Perimeter = zeroPerimeter, SiteCentroid = siteCentroid }; if (matchingZeroOverride != null) { Identity.AddOverrideIdentity(zeroEnvelope, matchingZeroOverride); perimeter = zeroPerimeter; // this way tiers above, if not overridden, respect the ground floor boundary. } envelopes.Add(zeroEnvelope); // Create the remaining Envelope Elements. var offsFactor = -1; var elevFactor = 1; var totalHeight = 0.0; for (int i = 0; i < tiers; i++) { if (totalHeight + tierHeight > input.BuildingHeight) { break; } var tierElev = tierHeight * elevFactor; var tryPer = perimeter.Offset(setbackDepth * offsFactor); if (tryPer.Count() == 0 || tryPer.First().Area() < input.MinimumTierArea) { break; } tryPer = tryPer.OrderByDescending(p => p.Area()).ToArray(); var matchingTierOverride = overridesForSite.FirstOrDefault(o => o.Identity.Elevation.ApproximatelyEquals(tierElev, 1)); var tierPerimeter = matchingTierOverride?.Value?.Perimeter?.Project(xy) ?? tryPer.First(); extrude = new Elements.Geometry.Solids.Extrude(tierPerimeter, tierHeight, Vector3.ZAxis, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var elevationXform = new Transform(0.0, 0.0, tierElev); var tierEnvelope = new Envelope(tierPerimeter, tierElev, tierHeight, Vector3.ZAxis, 0.0, elevationXform, envMatl, geomRep, false, Guid.NewGuid(), "") { Perimeter = tierPerimeter.TransformedPolygon(elevationXform), SiteCentroid = siteCentroid }; if (matchingTierOverride != null) { Identity.AddOverrideIdentity(tierEnvelope, matchingTierOverride); } envelopes.Add(tierEnvelope); offsFactor--; elevFactor++; totalHeight = totalHeight + tierHeight; } envelopes.OrderBy(e => e.Elevation).ToList().ForEach(e => output.Model.AddElement(e)); } return(output); }
/// <summary> /// The PreparedFoodLayout function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A PreparedFoodLayoutOutputs instance containing computed results and the model with any new elements.</returns> public static PreparedFoodLayoutOutputs Execute(Dictionary <string, Model> inputModels, PreparedFoodLayoutInputs input) { var counterDepth = input.CounterDepth / 39.37; if (counterDepth == 0) { counterDepth = 1; } var counterHeight = input.CounterHeight / 39.37; if (counterHeight == 0) { counterHeight = 1; } var aisle = input.AisleFrontage / 39.37; if (aisle <= 0) { aisle = 1.0; } PreparedFoodLayoutOutputs output = new PreparedFoodLayoutOutputs(); Model model = null; IList <Room> rooms = null; //test inputModels.Clear(); // we want Departments as inputs! if (inputModels.TryGetValue("Departments", out model)) { rooms = model.AllElementsOfType <Room>().ToList(); } else { //throw new ApplicationException("Need Departments as input!"); // default: double inputLength = 55; double inputWidth = 25; double inputHeight = 5; var rectangle = Polygon.Rectangle(inputLength, inputWidth); var mass = new Mass(rectangle, inputHeight); output.model.AddElement(mass); var material = new Material("office", new Color(0, 0, 1, 0.5)); var solid = new Elements.Geometry.Solids.Extrude(rectangle, inputHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); Room r = new Room(rectangle, Vector3.ZAxis, "Section 1", "100", "prepared", "100", rectangle.Area(), 1.0, 0, 0, inputHeight, rectangle.Area(), new Transform(), material, geomRep, false, System.Guid.NewGuid(), "Section 1"); output.model.AddElement(r); rooms = new List <Room>(); rooms.Add(r); } // ok, now the real work begins... from the room // this function only deals with certain departments. var appropriateRooms = rooms.Where(r => r.Department == "prepared"); if (appropriateRooms.Count() == 0) { throw new ApplicationException("This function works only on rooms with 'prepared' department"); } foreach (var r in appropriateRooms) { var side1 = r.Perimeter.Segments()[0]; var side2 = r.Perimeter.Segments()[1]; Console.WriteLine("side1: " + side1.Direction()); Console.WriteLine("side2: " + side2.Direction()); var line1 = side1.DivideByLength(aisle).First(); var line2 = side2.Reversed().DivideByLength(aisle).First(); var roomCenter = r.Perimeter.GetCenter(); //roomCenter.HighlightPoint(2, output.model); // var lineX = new Line( roomCenter, roomCenter + new Vector3(10,0,0)); //var lineY = new Line( roomCenter, roomCenter + new Vector3(0,5,0)); //lineX.HighlightThis(output.model); //lineY.HighlightThis(output.model); // ok - sweep is not working so we're going to have to build out the plan view and extrude up. // the "B" will be the inside curve. //line1.HighlightThis(output.model); //line2.HighlightThis(output.model); var smallerSide = (Math.Min(side1.Length(), side2.Length())); var radius = (input.CounterRadiusRatio / 100.0) * smallerSide; //var radius = (side1.Length() - line1.Length()) * 0.3; var p1 = line1.PointAt(1.0); var p2 = line2.PointAt(1.0); // p1.HighlightPoint(1,output.model); //p2.HighlightPoint(1,output.model); // p1b.HighlightPoint(0.5, output.model); //p2b.HighlightPoint(0.5, output.model); var dir1 = side2.Direction().WhichPointsTo(p1, roomCenter); var dir2 = side1.Direction().WhichPointsTo(p2, roomCenter); var line1Offset = new Line(p1, p1 + dir1 * 10); var line2Offset = new Line(p2, p2 + dir2 * 10); var line1bOffset = line1Offset.OffsetTowards(roomCenter, counterDepth); var line2bOffset = line2Offset.OffsetTowards(roomCenter, counterDepth); var p1b = line1bOffset.Start; var p2b = line2bOffset.Start; Console.WriteLine("L1Offset: " + line1Offset.Direction()); Console.WriteLine("L2Offset: " + line2Offset.Direction()); Console.WriteLine("L1bOffset: " + line1bOffset.Direction()); Console.WriteLine("L2bOffset: " + line2bOffset.Direction()); var arc = line1Offset.Fillet(line2Offset, radius); var arcB = line1bOffset.Fillet(line2bOffset, radius - counterDepth); // which end will be nearest? var closest1 = (p1.DistanceTo(arc.Start) < p1.DistanceTo(arc.End))? arc.Start : arc.End; var closest2 = (p2.DistanceTo(arc.Start) < p2.DistanceTo(arc.End))? arc.Start : arc.End; var closest1b = (p1b.DistanceTo(arcB.Start) < p1b.DistanceTo(arcB.End))? arcB.Start : arcB.End; var closest2b = (p2b.DistanceTo(arcB.Start) < p2b.DistanceTo(arcB.End))? arcB.Start : arcB.End; //line1Offset.HighlightThis(output.model); // line2Offset.HighlightThis(output.model); // redefine to the arc points line1Offset = new Line(p1, closest1); line2Offset = new Line(p2, closest2); //line1Offset.HighlightThis(output.model); //line2Offset.HighlightThis(output.model); //line1bOffset.HighlightThis(output.model); //line2bOffset.HighlightThis(output.model); // arc.HighlightThis(output.model); // arcB.HighlightThis(output.model); // ok - we want to draw the lines now // ordered list of vectors int numSegments = 10; var list = new List <Vector3>(); list.Add(p1); if (arc.Start.DistanceTo(closest1) < arc.Start.DistanceTo(closest2)) { list.AddRange(arc.Divide(numSegments)); } else { list.AddRange(arc.Reversed().Divide(numSegments)); } list.Add(p2); list.Add(p2b); if (arcB.Start.DistanceTo(closest2b) < arcB.Start.DistanceTo(closest1b)) { list.AddRange(arcB.Divide(numSegments)); } else { list.AddRange(arcB.Divide(numSegments)); } list.Add(p1b); Polygon newP = new Polygon(list); newP = newP.Reversed(); // it was the wrong way. //line1.ThickenThis(model); var counter = new Material("Countertop", Colors.Granite); var prepFoodCounter = new Elements.Geometry.Solids.Extrude(new Profile(newP), counterHeight, Vector3.ZAxis, false); Representation geomRep = null; // new Representation(new Elements.Geometry.Solids.SolidOperation[] { prepFoodCounter}); var mass = new Mass(new Profile(newP), counterHeight, counter, null, geomRep); output.model.AddElement(mass); // Console.WriteLine(output.model.ToJson(true)); //System.IO.File.WriteAllText(@"C:\temp\model.json", output.model.ToJson(true)); } return(output); }
/// <summary> /// The RoomsByFloorsTest function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A RoomsByFloorsTestOutputs instance containing computed results and the model with any new elements.</returns> public static RoomsByFloorsTestOutputs Execute(Dictionary <string, Model> inputModels, RoomsByFloorsTestInputs input) { var floors = new List <Floor>(); inputModels.TryGetValue("Floors", out var model); if (model == null) { throw new ArgumentException("No Floors found."); } floors.AddRange(model.AllElementsOfType <Floor>()); floors = floors.OrderBy(f => f.Elevation).Where(f => f.Elevation >= 0.0).ToList(); var upperFloorArea = 0.0; foreach (var floor in floors.Skip(1).SkipLast(2)) { upperFloorArea += floor.Profile.Perimeter.Area(); } var retlColor = Palette.Emerald; var offcColor = Palette.Cobalt; var retlMatl = new Material("retail", retlColor, 0.0f, 0.0f); var offcMatl = new Material("office", offcColor, 0.0f, 0.0f); var rooms = new List <Room>(); var grdRooms = 0; var grdArea = 0.0; var upArea = 0.0; var typRooms = 0; var typRoomCount = 0; for (var i = 0; i < floors.Count() - 2; i++) { var floor = floors.ElementAt(i); var ceiling = floors.ElementAt(i + 1); var height = ceiling.ProfileTransformed().Perimeter.Vertices.First().Z - floor.ProfileTransformed().Perimeter.Vertices.First().Z - floor.Thickness - 0.7; var offPerims = ceiling.Profile.Perimeter.Offset(input.PlanSetback * -1); if (offPerims.Count() == 0) { throw new InvalidOperationException("Plan Setback too deep. No valid room boundaries could be created."); } var perimeter = offPerims.First(); var perimBox = new CompassBox(perimeter); var xDiv = 1.0; var yDiv = 1.0; var xRoomSize = 1.0; var yRoomSize = 1.0; var roomColor = offcColor; if (i == 0) { xDiv = input.GroundFloorRoomLengthDivisions; yDiv = input.GroundFloorRoomWidthDivisions; xRoomSize = (int)Math.Ceiling(perimBox.SizeX / xDiv); yRoomSize = (int)Math.Ceiling(perimBox.SizeY / yDiv); grdRooms = (int)Math.Floor(xDiv * yDiv); grdArea = perimeter.Area(); roomColor = retlColor; } else { xDiv = input.TypicalFloorRoomsLengthDivisions; yDiv = input.TypicalFloorRoomsWidthDivisions; xRoomSize = (int)Math.Ceiling(perimBox.SizeX / xDiv); yRoomSize = (int)Math.Ceiling(perimBox.SizeY / yDiv); typRooms = (int)Math.Floor(xDiv * yDiv); typRoomCount += typRooms; upArea += perimeter.Area(); } var perimeters = new List <Polygon>(); var loc = perimBox.SW; for (var x = 0; x < xDiv; x++) { for (var y = 0; y < yDiv; y++) { var perim = Polygon.Rectangle(xRoomSize, yRoomSize); var pTopo = new CompassBox(perim); perimeters.Add(perim.MoveFromTo(pTopo.SW, loc)); loc = new Vector3(loc.X, loc.Y + yRoomSize, 0.0); } loc = new Vector3(loc.X + xRoomSize, perimBox.SW.Y, 0.0); } foreach (var perim in perimeters) { var name = "Office"; var matl = offcMatl; if (i == 0) { name = "Retail"; matl = retlMatl; } var rPerim = perim.Rotate(floor.Profile.Perimeter.Centroid(), input.PlanRotation); if (!rPerim.Intersects(perimeter)) { continue; } var rmPerims = perimeter.Intersection(rPerim); foreach (var rmPerim in rmPerims) { var roomPerims = rmPerim.Offset(-0.2); if (roomPerims.Count() == 0) { continue; } foreach (var room in roomPerims) { Representation geomRep = null; if (input.RoomsIn3D) { var solid = new Elements.Geometry.Solids.Extrude(room, height, Vector3.ZAxis, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); } else { var solid = new Elements.Geometry.Solids.Lamina(room, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); } var rm = new Room(room, Vector3.ZAxis, "", "", "", "", 0.0, 0.0, 0.0, floor.Elevation, height, room.Area(), new Transform(floor.Transform), matl, geomRep, false, Guid.NewGuid(), name); rm.Transform.Move(new Vector3(0.0, 0.0, 0.7)); rooms.Add(rm); } } } } var output = new RoomsByFloorsTestOutputs(grdRooms, grdArea, typRooms, typRoomCount, upArea); foreach (var room in rooms) { output.Model.AddElement(room); } return(output); }
/// <summary> /// Generates a building Envelope from a Site boundary. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A EnvelopeBySiteOutputs instance containing computed results and the model with any new elements.</returns> public static EnvelopeBySiteOutputs Execute(Dictionary <string, Model> inputModels, EnvelopeBySiteInputs input) { // Retrieve site information from incoming models. var sites = new List <Site>(); inputModels.TryGetValue("Site", out var model); if (model == null) { throw new ArgumentException("No Site found."); } sites.AddRange(model.AllElementsOfType <Site>()); sites = sites.OrderByDescending(e => e.Perimeter.Area()).ToList(); var output = new EnvelopeBySiteOutputs(input.BuildingHeight, input.FoundationDepth); foreach (var site in sites) { var perims = site.Perimeter.Offset(input.SiteSetback * -1); if (perims.Count() == 0) { continue; } perims = perims.OrderByDescending(p => p.Area()).ToArray(); var perimeter = perims.First(); if (perimeter.Area() < input.MinimumTierArea) { continue; } // Create the foundation Envelope. var extrude = new Elements.Geometry.Solids.Extrude(perimeter, input.FoundationDepth, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var fndMatl = new Material("foundation", Palette.Gray, 0.0f, 0.0f); var envMatl = new Material("envelope", Palette.Aqua, 0.0f, 0.0f); var envelopes = new List <Envelope>() { new Envelope(perimeter, input.FoundationDepth * -1, input.FoundationDepth, Vector3.ZAxis, 0.0, new Transform(0.0, 0.0, input.FoundationDepth * -1), fndMatl, geomRep, false, Guid.NewGuid(), "") }; // Create the Envelope at the location's zero plane. var tiers = Math.Floor(input.BuildingHeight / input.SetbackInterval); var tierHeight = tiers > 0 ? input.BuildingHeight / tiers : input.BuildingHeight; extrude = new Elements.Geometry.Solids.Extrude(perimeter, tierHeight, Vector3.ZAxis, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(perimeter, 0.0, tierHeight, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, Guid.NewGuid(), "")); // Create the remaining Envelope Elements. var offsFactor = -1; var elevFactor = 1; for (int i = 0; i < tiers; i++) { var tryPer = perimeter.Offset(input.SetbackDepth * offsFactor); if (tryPer.Count() == 0 || tryPer.First().Area() < input.MinimumTierArea) { break; } tryPer = tryPer.OrderByDescending(p => p.Area()).ToArray(); extrude = new Elements.Geometry.Solids.Extrude(tryPer.First(), tierHeight, Vector3.ZAxis, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(tryPer.First(), tierHeight * elevFactor, tierHeight, Vector3.ZAxis, 0.0, new Transform(0.0, 0.0, tierHeight * elevFactor), envMatl, geomRep, false, Guid.NewGuid(), "")); offsFactor--; elevFactor++; } envelopes.OrderBy(e => e.Elevation).ToList().ForEach(e => output.Model.AddElement(e)); } return(output); }
/// <summary> /// The PlanByProgram function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A PlanByProgramOutputs instance containing computed results and the model with any new elements.</returns> public static PlanByProgramOutputs Execute(Dictionary <string, Model> inputModels, PlanByProgramInputs input) { var rmDefModel = inputModels["Program"]; var rmDefs = new List <RoomDefinition>(rmDefModel.AllElementsOfType <RoomDefinition>().ToList()); if (rmDefs.Count == 0) { throw new ArgumentException("No Program found."); } var suites = Placer.PlaceSuites(input, rmDefs); var tmpput = new PlanByProgramOutputs(); var roomCount = 0; var roomArea = 0.0; foreach (var suite in suites) { roomCount += suite.Rooms.Count; foreach (var room in suite.Rooms) { var extrude = new Elements.Geometry.Solids.Extrude(new Profile(room.Perimeter), room.Height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); tmpput.Model.AddElement(new Elements.Room(room.Perimeter, Vector3.ZAxis, room.Suite, room.SuiteID, room.Department, room.Number, room.DesignArea, room.DesignRatio, 0.0, room.Elevation, room.Height, room.Area, new Transform(), room.ColorAsMaterial, geomRep, false, Guid.NewGuid(), room.Name)); roomArea += room.Area; } } var suitesByElevation = suites.GroupBy(s => s.Elevation); var totalArea = 0.0; foreach (var group in suitesByElevation) { var elevation = group.First().Elevation; var suiteprints = new List <Polygon>(); foreach (var suite in group) { if (input.ConformFloorsToRooms) { var roomPrints = Shaper.Merge(suite.RoomsAsPolygons); if (roomPrints.Count == 0) { suiteprints.Add(suite.CompassCorridor.Box.Offset(input.CorridorWidth).First()); } foreach (var roomPrint in roomPrints) { suiteprints.Add(roomPrint.Offset(input.CorridorWidth).First()); } } else { suiteprints.Add(suite.CompassCorridor.Box.Offset(input.CorridorWidth).First()); } } suiteprints = Shaper.Merge(suiteprints); foreach (var footprint in suiteprints) { tmpput.Model.AddElement(new Floor(footprint, 0.1, new Transform(0.0, 0.0, elevation - 0.1), BuiltInMaterials.Concrete, null, false, Guid.NewGuid(), "")); tmpput.Model.AddElement(new Level(elevation, Guid.NewGuid(), elevation.ToString())); totalArea += footprint.Area(); } } var output = new PlanByProgramOutputs(roomCount, roomArea, totalArea - roomArea, totalArea) { Model = tmpput.Model }; return(output); }
/// <summary> /// Generates Rooms of a supplied area on each incoming Level deployed along the Level's straight skeleton spine which is used as a central corridor path. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A RoomsByLevelsOutputs instance containing computed results and the model with any new elements.</returns> public static RoomsByLevelsOutputs Execute(Dictionary <string, Model> inputModels, RoomsByLevelsInputs input) { var levels = new List <LevelPerimeter>(); inputModels.TryGetValue("Levels", out var lvlModel); if (lvlModel != null) { levels.AddRange(lvlModel.AllElementsOfType <LevelPerimeter>()); } if (levels.Count == 0) { throw new ArgumentException("No LevelPerimeters found."); } levels = levels.OrderBy(l => l.Elevation).ToList(); var stories = new List <Story>(); for (var i = 0; i < levels.Count - 1; i++) { var perimeter = levels[i].Perimeter; var elevation = levels[i].Elevation; var height = (levels[i + 1].Elevation - levels[i].Elevation) - 0.5; // replace this number with a plenum height var spine = levels[i].Perimeter.Spine(); var sections = levels[i].Perimeter.Jigsaw(); var endSects = new List <Polygon>(); var midSects = new List <Polygon>(); var corridors = new List <Polygon>(); var story = new Story(perimeter) { Elevation = elevation }; foreach (var line in spine) { corridors.Add(line.ToPolyline().Offset(input.CorridorWidth * 0.5, EndType.Square).First()); } corridors = Shaper.Merge(corridors); foreach (var corridor in corridors) { story.AddCorridor(new RoomKit.Room(corridor.Straighten(input.CorridorWidth * 0.1).Simplify(input.CorridorWidth * 0.9), height), false); } foreach (var polygon in sections) { if (polygon.Vertices.Count == 3) { endSects.Add(polygon.AlignedBox()); continue; } midSects.Add(polygon); } var scaffolds = new List <Polygon>(endSects); foreach (var midSect in midSects) { scaffolds.AddRange(Shaper.Differences(midSect.ToList(), endSects)); } var roomRows = new List <RoomRow>(); foreach (var polygon in scaffolds) { roomRows.Add(new RoomRow(polygon)); } foreach (var row in roomRows) { var result = row.AddRoomByArea(row.Area * 0.5, height, elevation); result = row.AddRoomByArea(row.Area * 0.5, height, elevation); row.Infill(height, true); } var rowRooms = new List <RoomKit.Room>(); foreach (var row in roomRows) { rowRooms.AddRange(row.Rooms); } foreach (var room in rowRooms) { story.AddRoom(room); } stories.Add(story); } var rooms = new List <Elements.Room>(); foreach (var story in stories) { foreach (var room in story.Rooms) { room.Color = Palette.Aqua; var solid = new Elements.Geometry.Solids.Extrude(room.Perimeter, room.Height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); rooms.Add(new Elements.Room(room.Perimeter, Vector3.ZAxis, "", "", "", "", input.RoomArea, room.Ratio, 0.0, room.Elevation, room.Height, room.Area, null, room.ColorAsMaterial, geomRep, false, Guid.NewGuid(), room.Name)); } foreach (var room in story.Corridors) { room.Color = Palette.White; var solid = new Elements.Geometry.Solids.Extrude(room.Perimeter, room.Height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); rooms.Add(new Elements.Room(room.Perimeter, Vector3.ZAxis, "", "", "", "", input.RoomArea, room.Ratio, 0.0, room.Elevation, room.Height, room.Area, null, room.ColorAsMaterial, geomRep, false, Guid.NewGuid(), room.Name)); } } var output = new RoomsByLevelsOutputs(rooms.Count / levels.Count, rooms.Count); foreach (var room in rooms) { output.Model.AddElement(room); } return(output); }
/// <summary> /// The SectionLayout function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A SectionLayoutOutputs instance containing computed results and the model with any new elements.</returns> public static SectionLayoutOutputs Execute(Dictionary <string, Model> inputModels, SectionLayoutInputs input) { Envelope envelope = null; inputModels.TryGetValue("Envelope", out var model); var height = 0.0; if (model != null) { var envelopes = new List <Envelope>(); envelopes.AddRange(model.AllElementsOfType <Envelope>()); var aboveGradeEnvelopes = envelopes.Where(e => e.Elevation >= 0.0).ToList(); if (aboveGradeEnvelopes.Count() > 0) { envelope = aboveGradeEnvelopes.First(); height = envelope.Height - 1.0; } } if (envelope == null) { var envMatl = new Material("envelope", new Color(1.0, 1.0, 1.0, 0.2), 0.0f, 0.0f); height = 10.0; var footprint = Polygon.Rectangle(60, 40); var extrude = new Elements.Geometry.Solids.Extrude(footprint, height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); envelope = new Envelope(footprint, 0.0, height, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, System.Guid.NewGuid(), ""); } var output = new SectionLayoutOutputs(10); var grid = new Grid2d(envelope.Profile.Perimeter); var length = grid.V.Domain.Length; var width = grid.U.Domain.Length; //Define Dimensions of non-prdoduct spaces var entryDepth = 5; var checkoutDepth = entryDepth + 5; var percentService = .25; //var buildingArea = envelope.Profile.Perimeter.Area(); var circulationWidth = input.CirculationWidth; //Variables driving the division of the main shelf space var matAlpha = input.Transparency; if (matAlpha > 1) { matAlpha = 1; } var _percentProduce = input.PercentProduce; var _percentPrepared = input.PercentPrepared; var _percentGeneral = input.PercentGeneral; var _percentRefrigerated = input.PercentRefrigerated; var _percentLeft = _percentProduce + _percentPrepared; var _leftSplit = _percentProduce / (_percentProduce + _percentPrepared); var totalShelf = _percentLeft + _percentGeneral + _percentRefrigerated; var percentLeft = _percentLeft / totalShelf; var percentGeneral = _percentGeneral / totalShelf + percentLeft; //var percentRefrigerated = _percentRefrigerated / totalShelf; //Split into rooms front to back grid.V.SplitAtParameters(new[] { entryDepth / length, checkoutDepth / length, (1 - percentService) }); var mainEntryWidth = 10; var secEntryWidth = 5; var mainEntryPosition = .4; var secEntryPosition = .8; if (input.EntryRight) { mainEntryPosition = 1 - mainEntryPosition; secEntryPosition = 1 - secEntryPosition; } var mainEntryLeft = mainEntryPosition - mainEntryWidth / 2 / length; var mainEntryRight = mainEntryPosition + mainEntryWidth / 2 / length; var secEntryLeft = secEntryPosition - secEntryWidth / 2 / length; var secEntryRight = secEntryPosition + secEntryWidth / 2 / length; var entryArea = grid.GetCellAtIndices(0, 0); entryArea.U.SplitAtParameters(new[] { mainEntryLeft, mainEntryRight, secEntryLeft, secEntryRight }); var front1 = entryArea.GetCellAtIndices(0, 0); var entry1 = entryArea.GetCellAtIndices(1, 0); var front2 = entryArea.GetCellAtIndices(2, 0); var entry2 = entryArea.GetCellAtIndices(3, 0); var front3 = entryArea.GetCellAtIndices(4, 0); var checkoutArea = grid.GetCellAtIndices(0, 1); var shelfArea = grid.GetCellAtIndices(0, 2); var serviceAreaCell = grid.GetCellAtIndices(0, 3); //Split Shelf Area into sub-rooms shelfArea.U.SplitAtParameters(new[] { percentLeft, percentGeneral }); var left = shelfArea.GetCellAtIndices(0, 0); left.V.SplitAtParameter(_leftSplit); var produce = left.GetCellAtIndices(0, 0); produce.U.SplitAtParameter(.5); var produce1 = produce.GetCellAtIndices(0, 0); var produce2 = produce.GetCellAtIndices(1, 0); var prepared = left.GetCellAtIndices(0, 1); var general = shelfArea.GetCellAtIndices(1, 0); general.V.SplitAtParameter(.5); var general1 = general.GetCellAtIndices(0, 0); var general2 = general.GetCellAtIndices(0, 1); var refrig = shelfArea.GetCellAtIndices(2, 0); refrig.V.SplitAtParameter(.5); var refrig1 = refrig.GetCellAtIndices(0, 0); var refrig2 = refrig.GetCellAtIndices(0, 1); var entryMaterial = new Material("entry material", new Color(0, 0, 1, matAlpha)); var frontMaterial = new Material("front material", new Color(.9, .7, .7, matAlpha)); var checkoutMaterial = new Material("checkout material", new Color(0, .5, .5, matAlpha)); var serviceMaterial = new Material("service material", new Color(.25, .25, .25, matAlpha)); var produceMaterial = new Material("produce material", new Color(0, 1, 0, matAlpha)); var preparedMaterial = new Material("prepared material", new Color(1, .25, .25, matAlpha)); var generalMaterial = new Material("general material", new Color(1, 0, 0, matAlpha)); var refrigMaterial = new Material("refrigerated material", new Color(.75, .75, 1, matAlpha)); var otherMaterial = new Material("other material", new Color(0, 0, 0, matAlpha)); //Label and return rooms --> shelf area excluded due to inclusion of sub-rooms //AddRoomFromCell(entryArea, "entry", entryMaterial, output.model, circulationWidth); AddRoomFromCell(front1, "front1", frontMaterial, output.model, circulationWidth, height); AddRoomFromCell(entry1, "entrance1", entryMaterial, output.model, circulationWidth, height); AddRoomFromCell(front2, "front2", frontMaterial, output.model, circulationWidth, height); AddRoomFromCell(entry2, "entrance2", entryMaterial, output.model, circulationWidth, height); AddRoomFromCell(front3, "front3", frontMaterial, output.model, circulationWidth, height); AddRoomFromCell(checkoutArea, "checkout", checkoutMaterial, output.model, circulationWidth, height); AddRoomFromCell(serviceAreaCell, "service", serviceMaterial, output.model, circulationWidth, height); AddRoomFromCell(produce1, "produce", produceMaterial, output.model, circulationWidth, height); AddRoomFromCell(produce2, "produce", produceMaterial, output.model, circulationWidth, height); AddRoomFromCell(prepared, "prepared", preparedMaterial, output.model, circulationWidth, height); AddRoomFromCell(general1, "general", generalMaterial, output.model, circulationWidth, height); AddRoomFromCell(general2, "general", generalMaterial, output.model, circulationWidth, height); AddRoomFromCell(refrig1, "refrig", refrigMaterial, output.model, circulationWidth, height); AddRoomFromCell(refrig2, "refrig", refrigMaterial, output.model, circulationWidth, height); //Create wall between service space and rest of the building var wallThickness = new Vector3(0, .5, 0); var cellSeps = serviceAreaCell.GetCellSeparators(GridDirection.U); var servSep = cellSeps[0]; var wallPt1 = servSep.PointAt(0); var wallPt4 = servSep.PointAt(1) + wallThickness; var wallProfile = Polygon.Rectangle(wallPt1, wallPt4); wallProfile = wallProfile.FitMost(envelope.Profile.Perimeter.Offset(-0.1).First()); var serviceWall = new Wall(wallProfile, height); output.model.AddElement(serviceWall); return(output); }
/// <summary> /// The ProduceLayout function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A ProduceLayoutOutputs instance containing computed results and the model with any new elements.</returns> public static ProduceLayoutOutputs Execute(Dictionary <string, Model> inputModels, ProduceLayoutInputs input) { // convert the inputs to meters var minAisle = input.MinAisleWidth / 39.37; if (minAisle == 0) { minAisle = 1; } ProduceLayoutOutputs output = new ProduceLayoutOutputs(); Model model = null; IList <Room> rooms = null; //test inputModels.Clear(); // we want Departments as inputs! if (inputModels.TryGetValue("Departments", out model)) { rooms = model.AllElementsOfType <Room>().ToList(); } else { throw new ApplicationException("Need Departments as input!"); model = new Model(); // default: double inputLength = 100; double inputWidth = 30; double inputHeight = 5; var rectangle = Polygon.Rectangle(inputLength, inputWidth); var mass = new Mass(rectangle, inputHeight); output.model.AddElement(mass); var material = new Material("office", new Color(0, 0, 1.0, 0.5)); var solid = new Elements.Geometry.Solids.Extrude(rectangle, inputHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); Room r = new Room(rectangle, Vector3.ZAxis, "Section 1", "100", "produce", "100", rectangle.Area(), 1.0, 0, 0, inputHeight, rectangle.Area(), new Transform(), material, geomRep, false, System.Guid.NewGuid(), "Section 1"); model.AddElement(r); rooms = new List <Room>(); rooms.Add(r); } // ok, now the real work begins... from the room // this function only deals with certain departments. var appropriateRooms = rooms.Where(r => r.Department == "produce"); if (appropriateRooms.Count() == 0) { throw new ApplicationException("This function works only on rooms with 'produce' department"); } foreach (var r in appropriateRooms) { // make a 2D grid var grid = new Elements.Spatial.Grid2d(r.Perimeter, new Transform()); // we want to subdivide: var geom = grid.V.GetCellGeometry(); var sideLength = grid.V.Domain.Length; //grid.U.GetCellGeometry().Length(); var standardDepth = 0.889; // 35.5" var standardWidth = 1.22; // 48" double available = sideLength - (2.0 * standardDepth); int count = (int)(available / (2 * standardDepth + minAisle)); // debug: System.Console.WriteLine("side Length: " + sideLength + " available: " + available + " count: " + count); System.Console.WriteLine("Min Aisle: " + minAisle); grid.V.DivideByPattern(new double[] { standardDepth, standardDepth, minAisle }, PatternMode.Cycle, FixedDivisionMode.RemainderAtEnd); grid.U.DivideByFixedLength(standardWidth); var produce = new Material("Produce", Colors.Gray, 0f, 0f, null, Guid.NewGuid()); // now we will try making the shelving for (int i = 0; i < grid.V.Cells.Count; i++) { for (int j = 0; j < grid.U.Cells.Count; j++) { var cell = grid.GetCellAtIndices(j, i); // make a poly from each gridcell // shelf, shelf, aisle int c = i + 1; if (((c % 3) == 0)) { // we skip for the aisle } else { var height = 0.9; var material = new Material(Colors.Brown, 0, 0, Guid.NewGuid(), "ProduceBase"); var shelfMass = new Mass((Polygon)cell.GetCellGeometry(), height, material); // for the angled base, start by copying it up. var p = (Polygon)cell.GetCellGeometry(); p.Transform(new Transform(0, 0, height)); Vector3 tmpOrigin = p.Vertices.First(); double rotAngle = 30; if ((c % 3) == 2) { tmpOrigin = p.Vertices[2]; rotAngle = -30; } // this is dumb. But it's a hackathon p.Transform(new Transform(-1 * tmpOrigin.X, -1 * tmpOrigin.Y, -1 * tmpOrigin.Z)); var rotate = new Transform(); rotate.Rotate(Vector3.XAxis, rotAngle); p.Transform(rotate); p.Transform(new Transform(tmpOrigin.X, tmpOrigin.Y, tmpOrigin.Z)); var angle = new Elements.Geometry.Solids.Lamina(p, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { angle }); var envelope = new Envelope(p, 0.0, height, Vector3.ZAxis, 0.0, new Transform(), produce, geomRep, false, System.Guid.NewGuid(), ""); output.model.AddElement(shelfMass); output.model.AddElement(envelope); } } } } return(output); }
/// <summary> /// The RefrigeratedLayout function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A RefrigeratedLayoutOutputs instance containing computed results and the model with any new elements.</returns> public static RefrigeratedLayoutOutputs Execute(Dictionary <string, Model> inputModels, RefrigeratedLayoutInputs input) { var output = new RefrigeratedLayoutOutputs(); // convert the inputs to meters var doorSize = input.DoorSize / 39.37; var minAisle = input.MinAisleWidth / 39.37; Model model = null; IList <Room> rooms = null; // we want Departments as inputs! if (inputModels.TryGetValue("Departments", out model)) { rooms = model.AllElementsOfType <Room>().ToList(); } else { //throw new ApplicationException("Need Departments as input!"); model = new Model(); // default: double inputLength = 100; double inputWidth = 30; double inputHeight = 5; var rectangle = Polygon.Rectangle(inputLength, inputWidth); var mass = new Mass(rectangle, inputHeight); output.model.AddElement(mass); var material = new Material("office", new Color(0, 0, 1.0, 0.5)); var solid = new Elements.Geometry.Solids.Extrude(rectangle, inputHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); Room r = new Room(rectangle, Vector3.ZAxis, "Section 1", "100", "refrig", "100", rectangle.Area(), 1.0, 0, 0, inputHeight, rectangle.Area(), new Transform(), material, geomRep, false, System.Guid.NewGuid(), "Section 1"); model.AddElement(r); rooms = new List <Room>(); rooms.Add(r); } // ok, now the real work begins... from the room // this function only deals with certain departments. var appropriateRooms = rooms.Where(r => r.Department == "refrig"); if (appropriateRooms.Count() == 0) { throw new ApplicationException("This function works only on rooms with 'refrig' department"); } foreach (var r in appropriateRooms) { // make a 2D grid var grid = new Elements.Spatial.Grid2d(r.Perimeter, new Transform()); // we want to subdivide: var side1 = r.Perimeter.Segments().First(); var side2 = r.Perimeter.Segments()[1]; var geom = grid.U.GetCellGeometry(); var sideLength = grid.U.Domain.Length; //grid.U.GetCellGeometry().Length(); var standardDepth = 0.889; // 35.5" double available = sideLength - (2.0 * standardDepth); int count = (int)(available / (2 * standardDepth + input.MinAisleWidth)); // debug: System.Console.WriteLine("sideLength: " + sideLength + " available: " + available + " count: " + count); grid.U.DivideByPattern(new double[] { standardDepth, standardDepth, minAisle }, PatternMode.Cycle, FixedDivisionMode.RemainderAtEnd); grid.V.DivideByFixedLength(doorSize); // now we will try making the shelving for (int i = 0; i < grid.U.Cells.Count; i++) { for (int j = 0; j < grid.V.Cells.Count; j++) { var cell = grid.GetCellAtIndices(i, j); // make a poly from each gridcell // shelf, shelf, aisle int c = i + 1; if (((c % 3) == 0)) { // we skip for the aisle } else { var height = 2.0; var material = new Material(Colors.Gray, 0, 0, Guid.NewGuid(), "Refrigerator"); var shelfMass = new Mass((Polygon)cell.GetCellGeometry(), height, material); output.model.AddElement(shelfMass); } } } } return(output); }
/// <summary> /// /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A SpaceSubdivide2Outputs instance containing computed results and the model with any new elements.</returns> public static SpaceSubdivide2Outputs Execute(Dictionary <string, Model> inputModels, SpaceSubdivide2Inputs input) { var output = new SpaceSubdivide2Outputs(); Elements.Geometry.Solids.Extrude extrude; Representation geomRep; var envelopes = new List <Envelope>(); var envMatl = new Material("envelope", new Color(0.3, 0.7, 0.7, 0.6), 0.0f, 0.0f); List <ModelCurve> modelCurves = new List <ModelCurve>(); List <Polygon> offsetcrvs = new List <Polygon>(); List <Polygon> jigs = new List <Polygon>(); var centerlines = input.CenterLines; var sketch = input.Sketch; // var outlines = new List<Polyline>(); // var stuff = new foreach (var item in centerlines) { offsetcrvs.Add(item.Offset(2, EndType.Square).First()); } offsetcrvs.Add(sketch); foreach (var item in offsetcrvs) { jigs.AddRange(item.Jigsaw()); } foreach (var crv in offsetcrvs) { modelCurves.Add(new ModelCurve(crv)); } foreach (var crv in jigs) { modelCurves.Add(new ModelCurve(crv)); } var BuildingHeight = 30; foreach (var item in offsetcrvs) { extrude = new Elements.Geometry.Solids.Extrude(item, BuildingHeight, Vector3.ZAxis, false); geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); envelopes.Add(new Envelope(item, 0.0, BuildingHeight, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, Guid.NewGuid(), "")); } output.Model.AddElements(envelopes); output.Model.AddElements(modelCurves); return(output); }
/// <summary> /// Create a staircase of a given width aligned along a line /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A StaircaseFromLineOutputs instance containing computed results and the model with any new elements.</returns> public static StaircaseFromLineOutputs Execute(Dictionary <string, Model> inputModels, StaircaseFromLineInputs input) { if (input.StaircaseAxe == null) { throw new ArgumentException("Please draw the axe of the staircase."); } var levels = new List <Level>(); inputModels.TryGetValue("Levels", out var model); if (model == null || model.AllElementsOfType <Level>().Count() == 0) { throw new ArgumentException("No Level found."); } levels.AddRange(model.AllElementsOfType <Level>()); levels = levels.OrderBy(l => l.Elevation).ToList(); //Build a polygon aligned with the line Line stairCaseAxe = input.StaircaseAxe; // stairCaseAxe.Direction double uniteDePassage = input.Width; if (uniteDePassage == 0) { throw new ArgumentException("Can't create a stair with no width."); } double runWidth = 0; double thread = 0.3; double maxRiser = 0.14; double levelHeight = 3.5; double structuralDepth = 0.175; if (uniteDePassage == 1) { runWidth = 0.9; } else if (uniteDePassage == 2) { runWidth = 1.4; } else { runWidth = 0.6 * uniteDePassage; } double wallWidth = 0.2; double landingWidth = 2.5; double realLandingWidth = Math.Max(landingWidth, runWidth); double runLengh = Math.Ceiling(Math.Ceiling(levelHeight / maxRiser) / 2) * thread; double totalLenght = wallWidth * 2 + runWidth + realLandingWidth + runLengh; double totalWidth = wallWidth + runWidth + wallWidth + runWidth + wallWidth; Vector3 widthDirection = Vector3.ZAxis.Cross(stairCaseAxe.Direction()).Negate(); Vector3 footprintWidth = widthDirection * totalWidth; Vector3 footprintLenght = stairCaseAxe.Direction() * totalLenght; Polygon staircaseFoorprint = new Polygon(new List <Vector3> { stairCaseAxe.Start, stairCaseAxe.Start + footprintLenght, stairCaseAxe.Start + footprintLenght + footprintWidth, stairCaseAxe.Start + footprintWidth, }); var envelopeMatl = new Material("envelope", new Color(0.3, 0.7, 0.7, 0.2), 0.0f, 0.0f); var stairEnclosures = new List <StairEnclosure>(); var stairs = new List <Stair>(); var extrude = new Elements.Geometry.Solids.Extrude(staircaseFoorprint, levels.Last().Elevation, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); stairEnclosures.Add(new StairEnclosure(staircaseFoorprint, Vector3.ZAxis, 0.0, 0.0, levels.Last().Elevation, staircaseFoorprint.Area(), "1", new Transform(), envelopeMatl, geomRep, false, Guid.NewGuid(), "")); Vector3 stairPathStart = stairCaseAxe.Start + widthDirection * (wallWidth + runWidth / 2); Vector3 secondFlightPathStart = stairPathStart + stairCaseAxe.Direction() * runLengh + widthDirection * (runWidth + wallWidth); List <Line> stairPaths = new List <Line> { new Line(stairPathStart, stairPathStart + stairCaseAxe.Direction() * runLengh), new Line(secondFlightPathStart, secondFlightPathStart + stairCaseAxe.Direction().Negate() * runLengh) }; StairMaker stairMaker = new StairMaker(maxRiser, thread, structuralDepth, runWidth, stairPaths, levels); var output = new StaircaseFromLineOutputs(2); output.Model.AddElements(stairEnclosures); output.Model.AddElements(stairMaker.Stairs); return(output); }
/// <summary> /// Generates a Roof from a DXF Polyline and supplied elevation and thickness values. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A RoofByDXFOutputs instance containing computed results and the model with any new elements.</returns> public static RoofByDXFOutputs Execute(Dictionary <string, Model> inputModels, RoofByDXFInputs input) { DxfFile dxfFile; using (FileStream fs = new FileStream(input.DXF.LocalFilePath, FileMode.Open)) { dxfFile = DxfFile.Load(fs); } var polygons = new List <Polygon>(); foreach (DxfEntity entity in dxfFile.Entities) { if (entity.EntityType != DxfEntityType.LwPolyline) { continue; } var pline = (DxfLwPolyline)entity; if (pline.IsClosed == false) { continue; } var vertices = pline.Vertices.ToList(); var verts = new List <Vector3>(); vertices.ForEach(v => verts.Add(new Vector3(v.X, v.Y))); polygons.Add(new Polygon(verts)); } if (polygons.Count == 0) { throw new ArgumentException("No LWPolylines found in DXF."); } polygons = polygons.OrderByDescending(p => Math.Abs(p.Area())).ToList(); var polygon = polygons.First().IsClockWise() ? polygons.First().Reversed() : polygons.First(); polygons = polygons.Skip(1).ToList(); polygons.ForEach(p => p = p.IsClockWise() ? p : p.Reversed()); var polys = new List <Polygon>(); foreach (var poly in polygons) { if (!polygon.Contains(poly)) { continue; } if (!poly.IsClockWise()) { polys.Add(poly.Reversed()); continue; } polys.Add(poly); } polys.Insert(0, polygon); var shape = new Profile(polys); var extrude = new Elements.Geometry.Solids.Extrude(shape, input.RoofThickness, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); var roofMatl = BuiltInMaterials.Concrete; var roof = new Roof(shape, input.RoofElevation, input.RoofThickness, shape.Area(), new Transform(0.0, 0.0, input.RoofElevation - input.RoofThickness), roofMatl, geomRep, false, Guid.NewGuid(), ""); var output = new RoofByDXFOutputs(shape.Area()); output.Model.AddElement(roof); return(output); }