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