public async Task <GridOutputs> Handler(GridInputs 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 <GridInputs>(RegionEndpoint.USWest1); } var l = new InvocationWrapper <GridInputs, GridOutputs>(store, Grid.Execute); var output = await l.InvokeAsync(args); return(output); }
/// <summary> /// /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A GridOutputs instance containing computed results and the model with any new elements.</returns> public static GridOutputs Execute(Dictionary <string, Model> inputModels, GridInputs input) { var output = new GridOutputs(); var extentPolygons = new List <Polygon>(); inputModels.TryGetValue("Envelope", out var envelopeModel); if (envelopeModel != null) { Console.WriteLine("Got envelope model"); var envelopes = envelopeModel.AllElementsOfType <Envelope>(); extentPolygons = ExtractPolygonsFromElements(envelopes, (e) => e.Profile?.Perimeter?.TransformedPolygon(e.Transform)); } inputModels.TryGetValue("Levels", out var levelsModel); if (levelsModel != null && extentPolygons.Count == 0) { var levelVolumes = levelsModel.AllElementsOfType <LevelVolume>(); extentPolygons = ExtractPolygonsFromElements(levelVolumes, (e) => e.Profile?.Perimeter?.TransformedPolygon(e.Transform)); } inputModels.TryGetValue("Floors", out var floorsModel); if (floorsModel != null && extentPolygons.Count == 0) { var floorVolumes = floorsModel.AllElementsOfType <Floor>(); extentPolygons = ExtractPolygonsFromElements(floorVolumes, (e) => e.Profile?.Perimeter?.TransformedPolygon(e.Transform)); } if (extentPolygons.Count == 0 && input.Mode == GridInputsMode.Typical) { // establish a default grid if there's nothing to base it on extentPolygons.Add(Polygon.Rectangle((0, 0), (40, 40))); output.Warnings.Add("Your model contains no Envelopes, Levels, or Floors from which to calculate extents — we've created a default grid for you."); } foreach (var gridArea in input.GridAreas) { output.Model.AddElements(CreateGridArea(input, output, extentPolygons, gridArea)); } return(output); }
private static Transform GetOrigin(GridAreas gridArea, List <Polygon> envelopePolygons, GridInputs input) { var transform = new Transform(); // Automatically assume origin from envelope shape if (envelopePolygons.Count > 0) { var bounds = Polygon.FromAlignedBoundingBox2d(envelopePolygons.SelectMany(polygon => polygon.Vertices).Select(vertex => new Vector3(vertex.X, vertex.Y))); var axes = CalculateAxes(bounds); transform = new Transform(axes.x.Start, (axes.x.End - axes.x.Start).Unitized(), (axes.y.End - axes.y.Start).Unitized(), Vector3.ZAxis); } // Use deprecated manual origin, if it exists if (gridArea.Orientation != null && !gridArea.Orientation.Equals(new Transform())) { transform = gridArea.Orientation; } // Apply origin overrides if set if (input.Overrides?.GridOrigins != null) { foreach (var overrideOrigin in input.Overrides.GridOrigins) { if (overrideOrigin.Identity.Name == gridArea.Name) { transform = overrideOrigin.Value.Transform; } } } return(transform); }
private static List <Grid2dElement> CreateGridArea( GridInputs input, GridOutputs output, List <Polygon> envelopePolygons, GridAreas gridArea ) { var transform = GetOrigin(gridArea, envelopePolygons, input); GridExtentsOverride extentsOverrideMatch = null; if (input.Overrides?.GridExtents != null) { extentsOverrideMatch = input.Overrides.GridExtents.FirstOrDefault(o => o.Identity.Name.Equals(gridArea.Name)); if (extentsOverrideMatch != null) { // TODO: multiple grid areas doesn't seem to be working right now, so we just assume a single grid area, // and totally overwrite the grid polygons. envelopePolygons = new List <Polygon>() { extentsOverrideMatch.Value.Extents }; } } var origin = transform.Origin; var uDirection = transform.XAxis; var vDirection = transform.YAxis; if (input.ShowDebugGeometry) { // Draw origin output.Model.AddElement(new Line(origin - uDirection, origin + uDirection)); output.Model.AddElement(new Line(origin - vDirection, origin + vDirection)); } var uOverride = input.Overrides?.UGridSubdivisions?.FirstOrDefault(o => o.Identity.Name.Equals(gridArea.Name))?.Value.UGrid; var vOverride = input.Overrides?.VGridSubdivisions?.FirstOrDefault(o => o.Identity.Name.Equals(gridArea.Name))?.Value.VGrid; var standardizedRecords = GetStandardizedRecords(output, gridArea, input, envelopePolygons, transform, uOverride, vOverride); var u = standardizedRecords.u; var v = standardizedRecords.v; // CircleRadius = GetCircleRadius(u, v); var uDivisions = GetDivisions(origin, uDirection, u); var vDivisions = GetDivisions(origin, vDirection, v); var uPoints = uDivisions.Select(division => division.Point).ToList(); var vPoints = vDivisions.Select(division => division.Point).ToList(); var boundaries = new List <List <Polygon> >(); var gridPoints = new List <Vector3>(); foreach (var uPoint in uPoints) { foreach (var vPoint in vPoints) { var offset = vPoint - origin; var gridpoint = uPoint + offset; gridPoints.Add(gridpoint); if (input.ShowDebugGeometry) { output.Model.AddElement(new Panel(new Circle(0.25).ToPolygon(), null, new Transform(gridpoint))); } } } if (gridPoints.Count == 0) { throw new Exception("No grids were able to be calculated from the given inputs."); } Polygon gridPolygon = null; try { gridPolygon = Polygon.FromAlignedBoundingBox2d(gridPoints); } catch { gridPolygon = Polygon.FromAlignedBoundingBox2d(new List <Vector3>() { origin, origin + uDirection, origin + vDirection }); } if (input.ShowDebugGeometry) { output.Model.AddElement(new ModelCurve(gridPolygon)); } var uDirectionEnd = origin + uDirection * (uOverride?.Curve.Length() ?? 1); var vDirectionEnd = origin + vDirection * (vOverride?.Curve.Length() ?? 1); var guideSegments = new List <Line>() { new Line(origin, uDirectionEnd), new Line(origin, vDirectionEnd) }; if (envelopePolygons.Count() > 0) { var polygons = envelopePolygons.Concat(new List <Polygon>() { gridPolygon }).ToList(); var unions = Polygon.UnionAll(polygons).ToList(); var boundary = PolygonFromAlignedBoundingBox2d( unions.Select(u => u.Vertices).SelectMany(x => x).Append(origin).Append(uDirectionEnd).Append(vDirectionEnd), guideSegments); boundaries.Add(new List <Polygon>() { boundary }); } else { // use points min and max var boundary = PolygonFromAlignedBoundingBox2d( gridPolygon.Vertices.Append(origin).Append(uDirectionEnd).Append(vDirectionEnd), guideSegments); boundaries.Add(new List <Polygon>() { boundary }); } var texts = new List <(Vector3 location, Vector3 facingDirection, Vector3 lineDirection, string text, Color?color)>(); var grid2dElements = new List <Grid2dElement>(); foreach (var boundary in boundaries.SelectMany(boundaryList => boundaryList).ToList()) { var gridNodes = new List <GridNode>(); var grid = MakeGrid(boundary, origin, uDirection, vDirection, uPoints, vPoints); var uGridLines = CreateGridLines(input, output.Model, origin, uDivisions, grid.V, GridlineMaterialU, GridlineNamesIdentityAxis.U); var vGridLines = CreateGridLines(input, output.Model, origin, vDivisions, grid.U, GridlineMaterialV, GridlineNamesIdentityAxis.V); var allGridLines = uGridLines.Union(vGridLines); CheckDuplicatedNames(allGridLines, out var deduplicatedNamesGridLines); AddGridLinesTexts(allGridLines, deduplicatedNamesGridLines, texts); if (input.ShowDebugGeometry) { var uCurve = new Line(origin, origin + uDirection); var vCurve = new Line(origin, origin + vDirection); output.Model.AddElement(new ModelCurve(uCurve, Debug.MagentaMaterial)); output.Model.AddElement(new ModelCurve(vCurve, Debug.MagentaMaterial)); } foreach (var uGridLine in uGridLines) { foreach (var vGridLine in vGridLines) { if (uGridLine.Line.Intersects(vGridLine.Line, out var intersection, includeEnds: true)) { var gridNodeTransform = new Transform(intersection); gridNodes.Add(new GridNode(gridNodeTransform, uGridLine.Id.ToString(), vGridLine.Id.ToString(), Guid.NewGuid(), $"{uGridLine.Name}{vGridLine.Name}")); if (input.ShowDebugGeometry) { output.Model.AddElement(new Panel(new Circle(0.25).ToPolygon(), Debug.MagentaMaterial, new Transform(intersection))); Debug.DrawPoint(output.Model, intersection, Debug.LightweightBlueMaterial); } }