public async Task <EnvelopeBySiteOutputs> Handler(EnvelopeBySiteInputs args, ILambdaContext context) { if (this.store == null) { // Preload the dependencies (if they exist), // so that they are available during model deserialization. var asmLocation = this.GetType().Assembly.Location; var asmDir = Path.GetDirectoryName(asmLocation); var asmName = Path.GetFileNameWithoutExtension(asmLocation); var depPath = Path.Combine(asmDir, $"{asmName}.Dependencies.dll"); if (File.Exists(depPath)) { Console.WriteLine($"Loading dependencies from assembly: {depPath}..."); Assembly.LoadFrom(depPath); Console.WriteLine("Dependencies assembly loaded."); } this.store = new S3ModelStore <EnvelopeBySiteInputs>(RegionEndpoint.USWest1); } var l = new InvocationWrapper <EnvelopeBySiteInputs, EnvelopeBySiteOutputs>(store, EnvelopeBySite.Execute); var output = await l.InvokeAsync(args); return(output); }
public async Task <EnvelopeBySiteOutputs> Handler(EnvelopeBySiteInputs args, ILambdaContext context) { // Preload dependencies (if they exist), // so that they are available during model deserialization. var sw = System.Diagnostics.Stopwatch.StartNew(); var asmLocation = this.GetType().Assembly.Location; var asmDir = Path.GetDirectoryName(asmLocation); // Explicitly load the dependencies project, it might have types // that aren't used in the function but are necessary for correct // deserialization. var asmName = Path.GetFileNameWithoutExtension(asmLocation); var depPath = Path.Combine(asmDir, $"{asmName}.Dependencies.dll"); if (File.Exists(depPath)) { Console.WriteLine($"Loading dependencies assembly from: {depPath}..."); Assembly.LoadFrom(depPath); Console.WriteLine("Dependencies assembly loaded."); } // Load all reference assemblies. Console.WriteLine($"Loading all referenced assemblies."); foreach (var asm in this.GetType().Assembly.GetReferencedAssemblies()) { try { Assembly.Load(asm); } catch (Exception e) { Console.WriteLine($"Failed to load {asm.FullName}"); Console.WriteLine(e.Message); } } sw.Stop(); Console.WriteLine($"Time to load assemblies: {sw.Elapsed.TotalSeconds})"); if (this.store == null) { this.store = new S3ModelStore <EnvelopeBySiteInputs>(RegionEndpoint.USWest1); } var l = new InvocationWrapper <EnvelopeBySiteInputs, EnvelopeBySiteOutputs>(store, EnvelopeBySite.Execute); var output = await l.InvokeAsync(args); 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); // 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> /// 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); }