Ejemplo n.º 1
0
        public void Grid1dFixedDivisions()
        {
            var length      = 10;
            var panelTarget = 3;
            var sacrificial = 0;
            var inMiddle    = new Grid1d(new Line(new Vector3(0, 0, 0), new Vector3(length, 0, 0)));
            var atStart     = new Grid1d(new Line(new Vector3(0, 1, 0), new Vector3(length, 1, 0)));
            var atEnd       = new Grid1d(new Line(new Vector3(0, 2, 0), new Vector3(length, 2, 0)));
            var atBothEnds  = new Grid1d(new Line(new Vector3(0, 3, 0), new Vector3(length, 3, 0)));

            inMiddle.DivideByFixedLength(panelTarget, FixedDivisionMode.RemainderNearMiddle, sacrificial);
            atStart.DivideByFixedLength(panelTarget, FixedDivisionMode.RemainderAtStart, sacrificial);
            atEnd.DivideByFixedLength(panelTarget, FixedDivisionMode.RemainderAtEnd, sacrificial);
            atBothEnds.DivideByFixedLength(panelTarget, FixedDivisionMode.RemainderAtBothEnds, sacrificial);

            Assert.Equal(panelTarget, inMiddle.Cells.First().Domain.Length);
            Assert.Equal(panelTarget, inMiddle.Cells.Last().Domain.Length);

            Assert.NotEqual(panelTarget, atStart.Cells.First().Domain.Length);
            Assert.Equal(panelTarget, atStart.Cells.Last().Domain.Length);

            Assert.Equal(panelTarget, atEnd.Cells.First().Domain.Length);
            Assert.NotEqual(panelTarget, atEnd.Cells.Last().Domain.Length);

            Assert.NotEqual(panelTarget, atBothEnds.Cells.First().Domain.Length);
            Assert.NotEqual(panelTarget, atBothEnds.Cells.Last().Domain.Length);
        }
Ejemplo n.º 2
0
        public void Grid1d()
        {
            this.Name = "Elements_Spatial_Grid1d";

            // <example>
            // Create a 1d Grid from a line
            var line = new Line(new Vector3(5, 0, 0), new Vector3(60, 0, 0));
            var grid = new Grid1d(line);

            // Divide the grid into sections of length 10, and leave remainders
            // at both ends
            grid.DivideByFixedLength(10, FixedDivisionMode.RemainderAtBothEnds);

            // Take the second grid segment and subdivide it
            // into 5 equal length segments
            grid[1].DivideByCount(5);

            // Take the third grid segment and subdivide it into
            // segments of approximate length 3
            grid[2].DivideByApproximateLength(3);

            // Take the fourth grid segment and subdivide it by a repeating pattern
            var pattern = new[] { 1.0, 1.5 };

            grid[3].DivideByPattern(pattern);

            // Retrieve all bottom-level cells.
            // Note that grid.Cells gets the top-level cells only, and
            // grid.GetCells() recursively gets the bottom-level individual cells.
            var cells = grid.GetCells();

            // Get lines representing each cell
            var lines = cells.Select(c => c.GetCellGeometry()).OfType <Line>();

            // Create walls from lines, and assign a random color material
            List <Wall> walls = new List <Wall>();
            var         rand  = new Random();

            foreach (var wallLine in lines)
            {
                var color = new Color(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), 1.0);
                walls.Add(new StandardWall(wallLine, 0.1, 3.0, new Material(color.ToString(), color, 0, 0, null, false, false)));
            }

            // Create rectangles from top-level grid cells
            var topLevelCells = grid.Cells.Select(c => c.GetCellGeometry()).OfType <Line>();
            var cellRects     = new List <ModelCurve>();

            foreach (var topLevelCell in topLevelCells)
            {
                var rect = Polygon.Rectangle(topLevelCell.Start - new Vector3(0, 2, 0), topLevelCell.End + new Vector3(0, 2, 0));
                cellRects.Add(new ModelCurve(rect));
            }
            // </example>

            this.Model.AddElements(cellRects);
            this.Model.AddElements(walls);
        }
Ejemplo n.º 3
0
        private void AddEdge(long key, long startVertexId, long endVertexId)
        {
            if (this.Points.TryGetValue(startVertexId, out var start) && this.Points.TryGetValue(endVertexId, out var end))
            {
                var dist = start.DistanceTo(end);
                var line = new Line(start, end);

                if (!SkipSubdivide && dist > DivisionLength && (start.X != end.X || start.Y != end.Y))
                {
                    var indices = new List <long>()
                    {
                        startVertexId
                    };

                    var grid = new Grid1d(line);
                    grid.DivideByFixedLength(DivisionLength, FixedDivisionMode.RemainderAtBothEnds);
                    var cells = grid.GetCells();

                    // Get lines representing each 10' cell
                    var cellLines = cells.Select(c => c.GetCellGeometry()).OfType <Line>().ToArray();

                    // Add end of each division except for last point
                    foreach (var cellLine in cellLines.SkipLast(1))
                    {
                        var index = this._maxVertexKey + 1;
                        var point = cellLine.PointAt(1.0);
                        this.Points.Add(index, point);
                        indices.Add(index);
                        this._maxVertexKey = index;
                    }

                    // Add right point
                    indices.Add(endVertexId);
                    this.Lines.Add(key, indices);
                }
                else
                {
                    this.Lines.Add(key, new List <long>()
                    {
                        startVertexId, endVertexId
                    });
                }
            }
            else
            {
                throw new Exception("Malformed geometry found: no vertex found at address for this edge.");
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Construct a set of elements from this rule for a given definition.
        /// </summary>
        /// <param name="definition">The definition to instantiate.</param>
        public List <Element> Instantiate(ComponentDefinition definition)
        {
            var arrayElements = new List <Element>();
            var newVertices   = PolylinePlacementRule.TransformPolyline(this, definition);

            var path = IsClosed ? new Polygon(newVertices) : new Polyline(newVertices);

            var grid1d = new Grid1d(path);

            switch (SpacingRule.SpacingMode)
            {
            case SpacingMode.ByLength:
                grid1d.DivideByFixedLength(SpacingRule.Value);
                break;

            case SpacingMode.ByApproximateLength:
                grid1d.DivideByApproximateLength(SpacingRule.Value);
                break;

            case SpacingMode.ByCount:
                grid1d.DivideByCount((int)SpacingRule.Value);
                break;
            }

            var separators = grid1d.GetCellSeparators();

            foreach (var sep in separators)
            {
                ElementDefinition.IsElementDefinition = true;
                var transform = new Transform(definition.OrientationGuide);
                transform.Concatenate(new Transform(sep));
                var instance = ElementDefinition.CreateInstance(transform, Guid.NewGuid().ToString());
                arrayElements.Add(instance);
            }
            return(arrayElements);
        }
        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);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// The Structure function.
        /// </summary>
        /// <param name="model">The model.
        /// Add elements to the model to have them persisted.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A StructureOutputs instance containing computed results.</returns>
        public static StructureOutputs Execute(Dictionary <string, Model> models, StructureInputs input)
        {
            var model    = new Model();
            var warnings = new List <string>();

            Elements.Validators.Validator.DisableValidationOnConstruction = true;

            CellComplex cellComplex = null;
            Line        longestEdge = null;

#if DEBUG
            var sw = new Stopwatch();
            sw.Start();
#endif

            if (models.ContainsKey(BAYS_MODEL_NAME))
            {
                var cellsModel = models[BAYS_MODEL_NAME];
                cellComplex = cellsModel.AllElementsOfType <CellComplex>().First();
            }
            else
            {
                warnings.Add("Adding the Bays function to your workflow will give you more configurability. We'll use the default configuration for now.");

                // Create a cell complex with some defaults.
                if (!models.ContainsKey(LEVELS_MODEL_NAME))
                {
                    throw new Exception("If Bays are not supplied Levels are required.");
                }

                var levels       = models[LEVELS_MODEL_NAME];
                var levelVolumes = levels.AllElementsOfType <LevelVolume>().ToList();
                if (levelVolumes.Count == 0)
                {
                    throw new Exception("No LevelVolumes found in your Levels model. Please use a level function that generates LevelVolumes, such as Simple Levels by Envelope");
                }

                // Replicate the old behavior by creating a
                // grid using the envelope's first level base polygon's longest
                // edge as the U axis and its perpendicular as the
                // V axis.

                var firstLevel          = levelVolumes[0];
                var firstLevelPerimeter = firstLevel.Profile.Perimeter;
                longestEdge = firstLevelPerimeter.Segments().OrderBy(s => s.Length()).Last();

                var longestEdgeTransform = longestEdge.TransformAt(0.5);
                var t = new Transform(longestEdge.Start, longestEdgeTransform.XAxis, longestEdge.Direction(), Vector3.ZAxis);

                var toWorld = new Transform(t);
                toWorld.Invert();
                var bbox = new BBox3(firstLevelPerimeter.Vertices.Select(o => toWorld.OfVector(o)).ToList());

                var l = bbox.Max.Y - bbox.Min.Y;
                var w = bbox.Max.X - bbox.Min.X;

                var origin = t.OfVector(bbox.Min);

                var uGrid = new Grid1d(new Line(origin, origin + t.YAxis * l));
                uGrid.DivideByFixedLength(DEFAULT_U);

                var vGrid = new Grid1d(new Line(origin, origin + t.XAxis * w));

                vGrid.DivideByFixedLength(DEFAULT_V);
                var grid = new Grid2d(uGrid, vGrid);

                var u = grid.U;
                var v = grid.V;

                cellComplex = new CellComplex(Guid.NewGuid(), "Temporary Cell Complex");

                // Draw level volumes from each level down.
                for (var i = 1; i < levelVolumes.Count; i++)
                {
                    var levelVolume     = levelVolumes.ElementAt(i);
                    var perimeter       = levelVolume.Profile.Perimeter.Offset(-0.5)[0];
                    var g2d             = new Grid2d(perimeter, grid.U, grid.V);
                    var levelElevation  = levelVolume.Transform.Origin.Z;
                    var lastLevelVolume = levelVolumes.ElementAt(i - 1);
                    foreach (var cell in g2d.GetCells())
                    {
                        foreach (var crv in cell.GetTrimmedCellGeometry())
                        {
                            cellComplex.AddCell((Polygon)crv, lastLevelVolume.Height, levelElevation - lastLevelVolume.Height, g2d.U, g2d.V);
                            if (i == levelVolumes.Count - 1)
                            {
                                cellComplex.AddCell((Polygon)crv, levelVolume.Height, levelElevation, g2d.U, g2d.V);
                            }
                        }
                    }
                }
            }

#if DEBUG
            Console.WriteLine($"{sw.ElapsedMilliseconds} ms for getting or creating a cell complex.");
            sw.Restart();
#endif

            Vector3 primaryDirection;
            Vector3 secondaryDirection;
            IEnumerable <GridLine> gridLines = null;

            if (models.ContainsKey(GRIDS_MODEL_NAME))
            {
                var gridsModel = models[GRIDS_MODEL_NAME];
                gridLines = gridsModel.AllElementsOfType <GridLine>();

                // Group by direction.
                var gridGroups = gridLines.GroupBy(gl => gl.Curve.TransformAt(0).ZAxis).ToList();
                primaryDirection   = gridGroups[0].Key;
                secondaryDirection = gridGroups[1].Key;
            }
            else
            {
                warnings.Add("Adding the Grids function to your workflow will enable you to position and orient the grid. We'll use the default configuration for now with the grid oriented along the longest edge of the structure.");
                // Define the primary direction from the longest edge of the site.
                primaryDirection   = longestEdge.Direction();
                secondaryDirection = longestEdge.TransformAt(0.5).XAxis;
            }

#if DEBUG
            Console.WriteLine($"{sw.ElapsedMilliseconds} ms for getting or creating grids.");
            sw.Restart();
#endif

            var structureMaterial = new Material("Steel", Colors.Gray, 0.5, 0.3);
            model.AddElement(structureMaterial, false);
            model.AddElement(BuiltInMaterials.ZAxis, false);

            var wideFlangeFactory = new WideFlangeProfileFactory();
            var shsProfileFactory = new SHSProfileFactory();
            var rhsProfileFactory = new RHSProfileFactory();

            var columnTypeName   = input.ColumnType.ToString();
            var columnProfile    = GetProfileFromName(columnTypeName, wideFlangeFactory, rhsProfileFactory, shsProfileFactory);
            var colProfileBounds = columnProfile.Perimeter.Bounds();
            var colProfileDepth  = colProfileBounds.Max.Y - colProfileBounds.Min.Y;

            var     girderTypeName     = input.GirderType.ToString();
            Profile girderProfile      = null;
            double  girderProfileDepth = 0;
            if (girderTypeName.StartsWith("LH"))
            {
                girderProfileDepth = Units.InchesToMeters(double.Parse(girderTypeName.Split("LH")[1]));
            }
            else
            {
                girderProfile = GetProfileFromName(girderTypeName, wideFlangeFactory, rhsProfileFactory, shsProfileFactory);
                var girdProfileBounds = girderProfile.Perimeter.Bounds();
                girderProfileDepth = girdProfileBounds.Max.Y - girdProfileBounds.Min.Y;

                // Set the profile down by half its depth so that
                // it sits under the slab.
                girderProfile.Transform(new Transform(new Vector3(0, -girderProfileDepth / 2 - input.SlabThickness)));
            }

            Profile beamProfile      = null;
            double  beamProfileDepth = 0;

            var beamTypeName = input.BeamType.ToString();
            if (beamTypeName.StartsWith("LH"))
            {
                beamProfileDepth = Units.InchesToMeters(double.Parse(beamTypeName.Split("LH")[1]));
            }
            else
            {
                beamProfile = GetProfileFromName(beamTypeName, wideFlangeFactory, rhsProfileFactory, shsProfileFactory);
                var beamProfileBounds = beamProfile.Perimeter.Bounds();
                beamProfileDepth = beamProfileBounds.Max.Y - beamProfileBounds.Min.Y;

                // Set the profile down by half its depth so that
                // it sits under the slab.
                beamProfile.Transform(new Transform(new Vector3(0, -beamProfileDepth / 2 - input.SlabThickness)));
            }

            var edges               = cellComplex.GetEdges();
            var lowestTierSet       = false;
            var lowestTierElevation = double.MaxValue;

            var columnDefintions       = new Dictionary <(double memberLength, Profile memberProfile), Column>();
            var girderDefinitions      = new Dictionary <(double memberLength, Profile memberProfile), GeometricElement>();
            var beamDefinitions        = new Dictionary <(double memberLength, Profile memberProfile), GeometricElement>();
            var girderJoistDefinitions = new Dictionary <(double memberLength, double depth), GeometricElement>();
            var beamJoistDefinitions   = new Dictionary <(double memberLength, double depth), GeometricElement>();

            LProfileFactory lProfileFactory;
            LProfile        L8 = null;
            LProfile        L5 = null;
            LProfile        L2 = null;
            LProfile        L3 = null;

            if (girderProfile == null || beamProfile == null)
            {
                lProfileFactory = new LProfileFactory();
                L8 = Task.Run(async() => await lProfileFactory.GetProfileByTypeAsync(LProfileType.L8X8X1_2)).Result;
                L5 = Task.Run(async() => await lProfileFactory.GetProfileByTypeAsync(LProfileType.L5X5X1_2)).Result;
                L2 = Task.Run(async() => await lProfileFactory.GetProfileByTypeAsync(LProfileType.L2X2X1_8)).Result;
                L3 = Task.Run(async() => await lProfileFactory.GetProfileByTypeAsync(LProfileType.L3X2X3_16)).Result;
            }

#if DEBUG
            Console.WriteLine($"{sw.ElapsedMilliseconds} ms for getting all beam and column profiles.");
            sw.Restart();
#endif

            var xy = new Plane(Vector3.Origin, Vector3.ZAxis);

            // Order edges from lowest to highest.
            foreach (Elements.Spatial.CellComplex.Edge edge in edges.OrderBy(e =>
                                                                             Math.Min(cellComplex.GetVertex(e.StartVertexId).Value.Z, cellComplex.GetVertex(e.EndVertexId).Value.Z)
                                                                             ))
            {
                var memberLength = edge.Length(cellComplex);
                var start        = cellComplex.GetVertex(edge.StartVertexId).Value;
                var end          = cellComplex.GetVertex(edge.EndVertexId).Value;
                var direction    = (end - start).Unitized();

                var warningRepresentation = new Representation(new List <SolidOperation>()
                {
                    new Extrude(Polygon.Rectangle(0.01, 0.01), 0.01, Vector3.ZAxis, false)
                });

                if (edge.IsVertical(cellComplex))
                {
                    // For vertical edges that are not on the grid, we need
                    // a heuristic to determine when we should place a column.
                    // You don't want to place a column all the time because
                    // for non-grid-aligned structures, when you place columns
                    // at every intersection of the envelope and the grid, you
                    // can get columns that are too close together. Instead, we
                    // place a column based on the distance from that column along
                    // a grid line back to a primary grid intersection. If that
                    // distance exceeds the maximum allowable neighbor span,
                    // we place a column.
                    if (!edge.StartsOnGrid(cellComplex))
                    {
                        var maxDistance = double.MinValue;
                        foreach (var e in edge.GetCells().SelectMany(c => c.GetEdges().Where(e =>
                                                                                             e != edge &&
                                                                                             e.StartsOrEndsOnGrid(cellComplex) &&
                                                                                             e.StartsOrEndsAtThisVertex(edge.StartVertexId, cellComplex) &&
                                                                                             e.IsHorizontal(cellComplex))))
                        {
                            var d = e.Length(cellComplex);
                            maxDistance = Math.Max(maxDistance, d);
                        }

                        if (maxDistance < input.MaximumNeighborSpan)
                        {
                            continue;
                        }
                    }

                    var    origin   = start.IsLowerThan(end) ? start : end;
                    var    rotation = Vector3.XAxis.PlaneAngleTo(primaryDirection);
                    Column columnDefinition;
                    if (!columnDefintions.ContainsKey((memberLength, columnProfile)))
                    {
                        columnDefinition = new Column(Vector3.Origin, memberLength, columnProfile, structureMaterial, name: columnProfile.Name)
                        {
                            IsElementDefinition = true
                        };
                        columnDefinition.Representation.SkipCSGUnion = true;
                        columnDefintions.Add((memberLength, columnProfile), columnDefinition);
                        model.AddElement(columnDefinition, false);
                    }
                    else
                    {
                        columnDefinition = columnDefintions[(memberLength, columnProfile)];
Ejemplo n.º 7
0
        /// <summary>
        /// The Noisewall function.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A NoisewallOutputs instance containing computed results and the model with any new elements.</returns>
        public static NoisewallOutputs Execute(Dictionary <string, Model> inputModels, NoisewallInputs input)
        {
            // Setup inputs
            var    wallCentres       = input.NoisewallSetoutCentres;
            var    toleranceGap      = input.ToleranceGap;
            double wallHeight        = input.NoisewallPanelHeight;
            var    wallDepth         = input.NoisewallPanelDepth;
            var    wallWidth         = wallCentres - toleranceGap;
            var    setoutPolylineCrv = input.SetoutCurve;
            var    colour            = input.Colour;



            // Model smooth setout crv
            var verts            = setoutPolylineCrv.Vertices as List <Vector3>;
            var bezier           = new Bezier(verts);
            var bezierModelCurve = new ModelCurve(bezier, new Material("Green", Colors.Green));

            // Divide curve
            var grid = new Grid1d(bezier);

            grid.DivideByFixedLength(wallCentres, FixedDivisionMode.RemainderAtBothEnds);
            var cells    = grid.GetCells();
            var lines    = cells.Select(c => c.GetCellGeometry()).OfType <Line>();
            int numWalls = lines.Count();

            List <Wall> walls = new List <Wall>();
            List <Beam> beams = new List <Beam>();


            // Create Beam profile
            var profile = WideFlangeProfileServer.Instance.GetProfileByType(WideFlangeProfileType.W10x100);

            // Model beam at origin
            Line        line        = new Line(Vector3.Origin, new Vector3(0, 0, wallHeight));
            List <Beam> linearBeams = new List <Beam>();

            // Create range between 0 and 2pi with nDivisions
            List <double> normalisedRange = new List <double>();
            double        max             = 2 * Math.PI;
            double        min             = 0;
            int           nDivisions      = numWalls;
            double        diff            = (max - min) / nDivisions;
            double        d = min;

            foreach (int i in Enumerable.Range(0, nDivisions - 1))
            {
                d = d + diff;
                normalisedRange.Add(min + d);
            }


            // Setup random heights within range
            int        wallMinHeight     = 6;
            int        wallMaxHeight     = 9;
            Random     rand              = new Random();
            List <int> randomWallHeights = new List <int>();

            foreach (int i in Enumerable.Range(0, numWalls))
            {
                randomWallHeights.Add(rand.Next(wallMinHeight, wallMaxHeight));
            }



            // // Base sin wave function parameters
            // List<double> normalisedHeights = new List<double>();
            // foreach (double number in normalisedRange)
            // {
            //     normalisedHeights.Add(Math.Sin(number));
            // }

            // // Remap heights
            // List<double> remappedHeights = new List<double>();
            // foreach (double number in normalisedHeights)
            // {
            //     remappedHeights.Add(Remap(number, min, max, wallMinHeight, wallMaxHeight));
            // }


            int increment = 0;

            foreach (var setoutLine in lines)
            {
                // Set wall
                wallHeight = randomWallHeights.ElementAt(increment);
                //  Factor in tolerance Gap using vector math
                // panelHeight = remappedHeights.ElementAt(increment);
                wallHeight = input.NoisewallPanelHeight;


                var     noisewallLength         = wallCentres - toleranceGap * 2;
                Vector3 lineStartPoint          = setoutLine.Start;
                Vector3 lineEndPoint            = setoutLine.End;
                Vector3 lineDirectionUnitVector = (lineEndPoint - lineStartPoint).Unitized();
                var     noisewallCentreline     = new Line(lineStartPoint + lineDirectionUnitVector * toleranceGap, lineEndPoint - lineDirectionUnitVector * toleranceGap);

                // Create beam transforms
                Transform perpFrame         = setoutLine.TransformAt(0);
                Transform centreSetoutPlane = setoutLine.TransformAt(0.5);
                Transform orientBeams       = new Transform(setoutLine.Start, perpFrame.ZAxis, perpFrame.YAxis);

                // Model Beams
                var linearBeam = new Beam(line, profile, BuiltInMaterials.Steel, 0, 0, 0, orientBeams);
                beams.Add(linearBeam);

                // Model Walls
                Material     lightConcrete = new Material("Light Concrete", colour, 0.1, 0.0);
                StandardWall wall          = new StandardWall(noisewallCentreline, wallDepth, wallHeight, lightConcrete);
                walls.Add(wall);
                increment++;
            }

            // Create output object and add parameters
            var output = new NoisewallOutputs(walls.Count);

            // Add elements to output display
            output.Model.AddElement(bezierModelCurve);
            output.Model.AddElements(walls);
            output.Model.AddElements(beams);

            return(output);
        }