public void GridFromCurves() { var a = Vector3.Origin; var b = new Vector3(5, 0, 1); var c = new Vector3(5, 5, 2); var d = new Vector3(0, 5, 3); var e = new Vector3(0, 0, 4); var f = new Vector3(5, 0, 5); var ctrlPts = new List <Vector3> { a, b, c, d, e, f }; var bezier1 = new Bezier(ctrlPts); var grid = new Grid1d(bezier1); grid.DivideByApproximateLength(0.5, EvenDivisionMode.RoundUp); var cellGeometry = grid.GetCells().Select(cl => cl.GetCellGeometry()); Assert.Equal(25, cellGeometry.Count()); var r = 2.0; var a1 = new Arc(new Vector3(5, 0), r, -90.0, 90.0); var arcGrid = new Grid1d(a1); arcGrid.DivideByApproximateLength(1, EvenDivisionMode.RoundDown); arcGrid.Cells[1].DivideByCount(4); var arcCellGeometry = arcGrid.GetCells().Select(cl => cl.GetCellGeometry()); Assert.Equal(9, arcCellGeometry.Count()); }
/// <summary> /// Add graph section using polygon, extruded in given direction. /// Any vertices that already exist are not created but reused. /// This way new region is connected with the rest of the graph. /// </summary> /// <param name="boundingPolygon">Base polygon</param> /// <param name="extrusionAxis">Extrusion direction</param> /// <param name="distance">Height of polygon extrusion</param> /// <param name="keyPoints">Set of 3D points, region is split with.</param> public void AddFromExtrude(Polygon boundingPolygon, Vector3 extrusionAxis, double distance, List <Vector3> keyPoints) { var gridZ = new Grid1d(new Line(boundingPolygon.Start, boundingPolygon.Start + distance * extrusionAxis)); gridZ.SplitAtPoints(keyPoints); var edgesBefore = GetEdges(); var zCells = gridZ.GetCells(); for (var i = 0; i < zCells.Count; i++) { var elevationVector = zCells[i].Domain.Min * extrusionAxis; var transformedPolygonBottom = boundingPolygon.TransformedPolygon(new Transform(elevationVector)); var grid = CreateGridFromPolygon(transformedPolygonBottom); SplitGrid(grid, keyPoints); SplitGridAtIntersectionPoints(boundingPolygon, grid, edgesBefore); var addedEdges = AddFromGrid(grid, edgesBefore); AddVerticalEdges(extrusionAxis, zCells[i].Domain.Length, addedEdges); if (i == zCells.Count - 1) { var transformedPolygonTop = boundingPolygon.TransformedPolygon( new Transform(zCells[i].Domain.Max * extrusionAxis)); grid = CreateGridFromPolygon(transformedPolygonTop); SplitGrid(grid, keyPoints); SplitGridAtIntersectionPoints(boundingPolygon, grid, edgesBefore); AddFromGrid(grid, edgesBefore); } } }
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); }
public void DivideGridFromOrigin() { var grid1 = new Grid1d(10); grid1.DivideByFixedLengthFromPosition(3, 5); var cellGeo = grid1.GetCells().Select(c => c.GetCellGeometry()); Assert.Equal(4, cellGeo.Count()); Assert.Equal(2, cellGeo.Last().Length()); Assert.Equal(3, cellGeo.ToArray()[1].Length()); }
public void SplitGridAtParameters() { var grid = new Grid1d(new Domain1d(50, 100)); grid.SplitAtParameter(0.25); var subCell = grid.Cells[1]; subCell.DivideByCount(5); subCell.Cells[3].DivideByApproximateLength(1.2, EvenDivisionMode.Nearest); var allCells = grid.GetCells(); var cellGeometry = allCells.Select(c => c.GetCellGeometry()); Assert.Equal(11, allCells.Count); }
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."); } }
public void Grid1dSerializes() { var polyline = new Polyline(new[] { new Vector3(0, 0, 0), new Vector3(10, 2, 0), new Vector3(30, 4, 0), }); var grid = new Grid1d(polyline); grid.DivideByCount(4); grid[3].DivideByFixedLength(0.4); var json = JsonConvert.SerializeObject(grid); var deserialized = JsonConvert.DeserializeObject <Grid1d>(json); Assert.Equal(grid.GetCells().Count, deserialized.GetCells().Count); Assert.Equal(0, (grid.Curve as Polyline).Start.DistanceTo((deserialized.Curve as Polyline).Start)); }
public void DivideByPatternWithoutRemainder() { var grid = new Grid1d(6); var pattern = new List <(string typename, double length)> { ("A", 2), ("B", 1) }; grid.DivideByPattern(pattern, PatternMode.Cycle, FixedDivisionMode.RemainderAtEnd); var cells = grid.GetCells(); for (int i = 0; i < cells.Count; i++) { Assert.Equal(pattern[i % pattern.Count].typename, cells[i].Type); Assert.Equal(pattern[i % pattern.Count].length, cells[i].Domain.Length, 3); } }
public void DivideByPattern() { var grid = new Grid1d(new Domain1d(60, 150)); var pattern = new List <(string typename, double length)> { ("Solid", 1), ("Glazing", 3), ("Fin", 0.2) }; grid.DivideByPattern(pattern, PatternMode.Cycle, FixedDivisionMode.RemainderAtBothEnds); var cells = grid.GetCells(); var types = cells.Select(c => c.Type); for (int i = 0; i < 10; i++) { Assert.Equal(pattern[i % pattern.Count].length, cells[i + 1].Domain.Length, 3); Assert.Equal(pattern[i % pattern.Count].typename, cells[i + 1].Type); } }
/// <summary> /// The BigBoxFacade function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A BigBoxFacadeOutputs instance containing computed results and the model with any new elements.</returns> public static BigBoxFacadeOutputs Execute(Dictionary <string, Model> inputModels, BigBoxFacadeInputs input) { Envelope envelope = null; inputModels.TryGetValue("Envelope", out var envelopeModel); if (envelopeModel != null) { var envelopes = new List <Envelope>(); envelopes.AddRange(envelopeModel.AllElementsOfType <Envelope>()); var aboveGradeEnvelopes = envelopes.Where(e => e.Elevation >= 0.0).ToList(); if (aboveGradeEnvelopes.Count() > 0) { envelope = aboveGradeEnvelopes.First(); } } if (envelope == null) { var envMatl = new Material("envelope", new Color(1.0, 1.0, 1.0, 0.2), 0.0f, 0.0f); var height = 15.0; var footprint = Polygon.Rectangle(60, 40); var extrude = new Elements.Geometry.Solids.Extrude(footprint, height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); envelope = new Envelope(footprint, 0.0, height, Vector3.ZAxis, 0.0, new Transform(), envMatl, geomRep, false, Guid.NewGuid(), ""); } var output = new BigBoxFacadeOutputs(envelope.Profile.Perimeter.Area()); var boundarySegments = envelope.Profile.Perimeter.Segments(); var panelMat = new Material("envelope", new Color(1.0, 1.0, 1.0, 1), 0.5f, 0.5f); var lowestSegment = boundarySegments.OrderBy((s) => s.Start.Average(s.End).Y).First(); foreach (var s in boundarySegments) { var d = s.Direction(); try { var t = new Transform(s.Start + new Vector3(0, 0, 0), d, d.Cross(Vector3.ZAxis)); var l = s.Length(); if (lowestSegment == s) { var grid = new Grid1d(s); var doorWidth = 4; var backwardsLine = s.Start.X > s.End.X; var reverseDirection = backwardsLine != input.EntranceOnRight; var leftDoor = 0.0; var rightDoor = 0.0; var leftDoorWidth = 0.0; var rightDoorWidth = 0.9; if (reverseDirection) { leftDoor = l / 10 * 2; rightDoor = l / 10 * 6; leftDoorWidth = doorWidth; rightDoorWidth = doorWidth * 2.0; } else { leftDoor = l / 10 * 4; rightDoor = l / 10 * 8; leftDoorWidth = doorWidth * 2.0; rightDoorWidth = doorWidth; } grid.SplitAtPositions(new [] { leftDoor - leftDoorWidth / 2.0, leftDoor + leftDoorWidth / 2.0, rightDoor - rightDoorWidth / 2.0, rightDoor + rightDoorWidth / 2.0 }); var lines = grid.GetCells().Select(c => c.GetCellGeometry()).OfType <Line>(); if (reverseDirection) { lines = lines.Reverse(); } var wallIdx = 0; foreach (var wallLine in lines) { var segmentLength = wallLine.Length(); var segmentTransform = new Transform(wallLine.Start + new Vector3(0, 0, 0), d, d.Cross(Vector3.ZAxis)); if (wallIdx == 1) { CreateStandardPanel(segmentLength, 6, envelope.Height - 6, 0.1, segmentTransform, panelMat, out FacadePanel panel); output.model.AddElement(panel); CreateBranding(envelope.Height, 10, 28, true, new Transform(wallLine.Start.Average(wallLine.End), Vector3.ZAxis, 0), output.model); } else if (wallIdx == 3) { CreateStandardPanel(segmentLength, 6, envelope.Height - 6, 0.1, segmentTransform, panelMat, out FacadePanel panel); output.model.AddElement(panel); CreateBranding(envelope.Height * 0.7, 5.5, 6, false, new Transform(wallLine.Start.Average(wallLine.End), Vector3.ZAxis, 0), output.model); } else { CreateStandardPanel(segmentLength, 0, envelope.Height, 0.1, segmentTransform, panelMat, out FacadePanel panel); output.model.AddElement(panel); } wallIdx++; } } else { CreateStandardPanel(l, 0, envelope.Height, 0.1, t, panelMat, out FacadePanel panel); output.model.AddElement(panel); } var parapetLine = new Line(new Vector3(s.Start.X, s.Start.Y, envelope.Height), new Vector3(s.End.X, s.End.Y, envelope.Height)); var parapet = new StandardWall(parapetLine, 0.4, 0.9, panelMat); output.model.AddElement(parapet); } catch (System.Exception ex) { System.Console.WriteLine(ex); } } return(output); }
/// <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); }