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