public async Task <PanelsFromWallsOutputs> Handler(PanelsFromWallsInputs 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 <PanelsFromWallsInputs>(RegionEndpoint.USWest1); } var l = new InvocationWrapper <PanelsFromWallsInputs, PanelsFromWallsOutputs>(store, PanelsFromWalls.Execute); var output = await l.InvokeAsync(args); return(output); }
private static List <WallPanel> ProcessWallsByProfile(PanelsFromWallsInputs input, List <WallByProfile> allWallsByProfile, out int totalCount, out int uniqueCount, out int nonStandardCount) { var panelsOut = new List <WallPanel>(); Dictionary <string, Color> colorMap = new Dictionary <string, Color>(); uniqueCount = 0; nonStandardCount = 0; var rand = new Random(); int uniqueIDCounter = 0; foreach (var wall in allWallsByProfile) { var centerline = wall.Centerline; var profile = wall.Profile; var clVec = centerline.Direction(); var wallNormal = clVec.Cross(Vector3.ZAxis); var toWall = new Transform(centerline.Start, clVec, wallNormal); var fromWall = new Transform(toWall); fromWall.Invert(); var flatProfile = fromWall.OfProfile(profile); var polygons = new[] { flatProfile.Perimeter }.Union(flatProfile.Voids).Select(p => Make2d(p)).ToList(); var grid = new Grid2d(polygons); grid.U.DivideByFixedLength(input.PanelLength, FixedDivisionMode.RemainderAtEnd); foreach (var cell in grid.GetCells()) { var cellGeometry = cell.GetTrimmedCellGeometry().OfType <Polygon>(); var isTrimmed = cell.IsTrimmed(); if (!isTrimmed) { var polygon = Make2d(cellGeometry.FirstOrDefault()); if (polygon == null) { continue; } var cellProfile = new Profile(polygon); var thicknessTransform = new Transform(0, 0, -wall.Thickness / 2.0); cellProfile = thicknessTransform.OfProfile(cellProfile); var extrude = new Extrude(cellProfile, wall.Thickness, Vector3.ZAxis, false); var identifier = $"{Math.Round(cell.U.Domain.Length, 2)} x {Math.Round(cell.V.Domain.Length, 2)}"; Color color = default(Color); if (colorMap.ContainsKey(identifier)) { color = colorMap[identifier]; } else { color = new Color(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), 1.0); colorMap.Add(identifier, color); } var material = input.ColorCodeByLength ? new Material(color, 0, 0, false, null, true, Guid.NewGuid(), color.ToString()) : BuiltInMaterials.Concrete; var geomRep = new Representation(new[] { extrude }); var panel = new WallPanel(identifier, cellProfile, true, wall.Thickness, toWall, material, geomRep, false, Guid.NewGuid(), ""); panelsOut.Add(panel); } else { foreach (var polygon in cellGeometry) { var cellProfile = new Profile(polygon); var thicknessTransform = new Transform(0, 0, -wall.Thickness / 2.0); cellProfile = thicknessTransform.OfProfile(cellProfile); var extrude = new Extrude(cellProfile, wall.Thickness, Vector3.ZAxis, false); var identifier = $"C-{uniqueIDCounter++:00}"; var color = new Color(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), 1.0); colorMap.Add(identifier, color); var material = input.ColorCodeByLength ? new Material(color, 0, 0, false, null, true, Guid.NewGuid(), color.ToString()) : BuiltInMaterials.Concrete; var geomRep = new Representation(new[] { extrude }); var panel = new WallPanel(identifier, cellProfile, true, wall.Thickness, toWall, material, geomRep, false, Guid.NewGuid(), ""); panelsOut.Add(panel); } } } } totalCount = panelsOut.Count; return(panelsOut); }
/// <summary> /// The PanelsFromWalls function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A PanelsFromWallsOutputs instance containing computed results and the model with any new elements.</returns> public static PanelsFromWallsOutputs Execute(Dictionary <string, Model> inputModels, PanelsFromWallsInputs input) { var allWalls = new List <Wall>(); var allWallsByProfile = new List <WallByProfile>(); inputModels.TryGetValue("Walls", out Model wallModel); if (wallModel == null || (!wallModel.AllElementsOfType <Wall>().Any() && !wallModel.AllElementsOfType <WallByProfile>().Any())) { throw new ArgumentException("No Walls found."); } allWalls.AddRange(wallModel.AllElementsOfType <Wall>()); allWallsByProfile.AddRange(wallModel.AllElementsOfType <WallByProfile>()); var panels = ProcessWallsAndStandardWalls(input, allWalls, out int totalCount, out int uniqueCount, out int nonStandardCount); var panels2d = ProcessWallsByProfile(input, allWallsByProfile, out int totalCountP, out int uniqueCountP, out int nonStandardCountP); var output = new PanelsFromWallsOutputs(totalCount + totalCountP, nonStandardCount + nonStandardCountP, uniqueCount + uniqueCountP); output.model.AddElements(panels); output.model.AddElements(panels2d); return(output); }
private static List <WallPanel> ProcessWallsAndStandardWalls(PanelsFromWallsInputs input, List <Wall> allWalls, out int totalCount, out int uniqueCount, out int nonStandardCount) { var wallCenterlines = allWalls.Select(TryGetCenterlineFromWall).Where(s => s != null); var endPoints = wallCenterlines.SelectMany(l => new[] { l.Start, l.End }); var network = new Network(wallCenterlines); Dictionary <Elements.Spatial.Edge, Grid1d> edgeGrids = new Dictionary <Elements.Spatial.Edge, Grid1d>(); foreach (var edge in network.Edges) { var edgeLine = network.GetEdgeLine(edge); var grid = new Grid1d(edgeLine); edgeGrids.Add(edge, grid); var cornerAtStart = network[edge.From].Valence > 1; var cornerAtEnd = network[edge.To].Valence > 1; var cornerCount = (cornerAtStart ? 1 : 0) + (cornerAtEnd ? 1 : 0); var cornerLength = input.CornerLength; if (cornerLength * cornerCount > edgeLine.Length()) { cornerLength = edgeLine.Length() / cornerCount; } if (cornerAtStart) { grid.SplitAtOffset(cornerLength); } if (cornerAtEnd) { grid.SplitAtOffset(cornerLength, true); } Grid1d gridToSubdivide = null; if (!grid.IsSingleCell) { switch (grid.Cells.Count) { case 3: gridToSubdivide = grid[1]; break; case 2: if (cornerCount == 1) { if (cornerAtStart) { gridToSubdivide = grid[1]; } if (cornerAtEnd) { gridToSubdivide = grid[0]; } } break; default: gridToSubdivide = grid; break; } if (gridToSubdivide != null) { gridToSubdivide.DivideByFixedLength(input.PanelLength, FixedDivisionMode.RemainderAtEnd); } } } List <Line> lines = new List <Line>(); foreach (var edgeGrid in edgeGrids) { if (edgeGrid.Value == null) { continue; } var cells = edgeGrid.Value.IsSingleCell ? new List <Grid1d> { edgeGrid.Value } : edgeGrid.Value.GetCells(); var cellGeometry = cells.Select(c => c.GetCellGeometry()).OfType <Line>(); lines.AddRange(cellGeometry); } // Create walls from lines, and assign a random color material var walls = new List <WallPanel>(); var rand = new Random(); var colorMap = new Dictionary <int, Color>(); colorMap.Add(KeyFromLength(input.CornerLength), Colors.Red); if (input.CornerLength != input.PanelLength) { colorMap.Add(KeyFromLength(input.PanelLength), Colors.Blue); } foreach (var wallLine in lines) { var color = default(Color); var lengthKey = KeyFromLength(wallLine.Length()); if (colorMap.ContainsKey(lengthKey)) { color = colorMap[lengthKey]; } else { color = new Color(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), 1.0); colorMap.Add(lengthKey, color); } var mat = input.ColorCodeByLength ? new Material(color, 0, 0, false, null, true, Guid.NewGuid(), color.ToString()) : BuiltInMaterials.Concrete; walls.Add(CreateSimpleWallPanel(wallLine, 0.1, 3.0, mat)); } nonStandardCount = lines.Where(l => KeyFromLength(l.Length()) != KeyFromLength(input.PanelLength) && KeyFromLength(l.Length()) != KeyFromLength(input.CornerLength)).Count(); totalCount = walls.Count; uniqueCount = Math.Min(totalCount, colorMap.Count()); return(walls); }