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