예제 #1
0
        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);
        }
예제 #2
0
        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);
                            }
                        }