public void Building() { this.Name = "Building"; var elevations = new[] { 0.0, 3.0, 6.0, 9.0, 12.0, 15.0 }; var opening = new Opening(5, 5, 2, 2); var wallType = new WallType("Concrete", 0.1); var floorType = new FloorType("Concrete", 0.15); var beamType = new StructuralFramingType("Wide Flange", WideFlangeProfileServer.Instance.GetProfileByName("W36x245"), BuiltInMaterials.Steel); var site = Polygon.Ngon(6, 20.0); foreach (var el in elevations) { var slab = new Floor(site, floorType, el, null, new List <Opening>() { opening }); this.Model.AddElement(slab); var edgeBeams = slab.CreateEdgeBeams(beamType); this.Model.AddElements(edgeBeams); var segs = site.Segments(); for (var i = 0; i < segs.Length - 2; i++) { var wall = new StandardWall(slab.Transform.OfLine(segs[i]), wallType, 3.0); this.Model.AddElement(wall); } } }
public void WallWithAddedOpenings() { this.Name = "WallWithAddedOpenings"; var testWallType = new WallType("test", new List <MaterialLayer> { new MaterialLayer(new Material("blue", Colors.Blue, 0.0f, 0.0f), 0.1) }); var l = new Line(new Vector3(0, 0, 0), new Vector3(10, 10, 0)); var openings = new List <Opening>() { new Opening(1.0, 2.0, 1.0, 1.0), new Opening(3.0, 1.0, 1.0, 2.0), new Opening(Polygon.Ngon(3, 2.0), 8, 2) }; var frameProfile = new Profile(Polygon.Rectangle(0.075, 0.01)); var w = new StandardWall(l, testWallType, 3.0, null); this.Model.AddElement(w); List <StandardWall> updatedWalls = new List <StandardWall>(this.Model.ElementsOfType <StandardWall>()); foreach (StandardWall wall in updatedWalls) { wall.Openings.AddRange(openings); } this.Model.UpdateElements(updatedWalls); Assert.Equal(3, w.Openings.Count); }
public void TransformedAndSerializedWalls() { this.Name = "TransformedSerializedWalls"; var a = Vector3.Origin; var b = new Vector3(0, 5.0, 0.0); var line = new Line(a, b); var wall1 = new StandardWall(line, 0.1, 3.0, BuiltInMaterials.Mass); this.Model.AddElement(wall1); var c = new Vector3(0, 0, 3.0); var d = new Vector3(0, 5, 3.0); var line1 = new Line(c, d); var wall2 = new StandardWall(line1, 0.1, 3.0, BuiltInMaterials.Void); wall2.Transform.Rotate(Vector3.ZAxis, 45); this.Model.AddElement(wall2); var json = this.Model.ToJson(); var newModel = Model.FromJson(json); // Add the new walls back to the original model // and transform them var walls = newModel.AllElementsOfType <StandardWall>(); foreach (var w in walls) { w.Id = Guid.NewGuid(); w.Transform.Move(new Vector3(5, 0)); this.Model.AddElement(w); } }
public static void AddLine(Line line, Model model) { var material = new Material(Colors.White, 0.0, 0.0, System.Guid.NewGuid(), "divider"); var verticallyAdjustedLine = new Line(new Vector3(line.Start.X, line.Start.Y, -0.1), new Vector3(line.End.X, line.End.Y, -0.1)); var wall = new StandardWall(verticallyAdjustedLine, 0.4, 1.2, material); model.AddElement(wall); }
private static IfcProduct ToIfc(this StandardWall wall, IfcLocalPlacement localPlacement, IfcProductDefinitionShape shape) { var ifcWall = new IfcWallStandardCase(IfcGuid.ToIfcGuid(Guid.NewGuid()), null, wall.Name, null, null, localPlacement, shape, null); return(ifcWall); }
private static void RayIntersectsNewlyGeneratedElement() { var wall = new StandardWall(new Line(Vector3.Origin, new Vector3(10, 0, 0)), 0.3, 3); var ray = new Ray(new Vector3(5, 5, 1), new Vector3(0, -1, 0)); var doesIntersect = ray.Intersects(wall, out var result); Assert.True(doesIntersect); }
public void ProfileWithNoVoids() { var a = Vector3.Origin; var b = new Vector3(0.0, 5.0); var line = new Line(a, b); var testWallType = new WallType("test", 0.1); var wall = new StandardWall(line, testWallType, 4.0); Assert.Empty(wall.Openings); }
public void Wall() { this.Name = "IfcWall"; var line = new Line(Vector3.Origin, new Vector3(10, 10, 0)); var line1 = new Line(new Vector3(10, 10, 0), new Vector3(10, 15, 0)); var wallType = new WallType("test", 0.2); var wall = new StandardWall(line, wallType, 3); var wall1 = new StandardWall(line1, wallType, 2); this.Model.AddElement(wall); this.Model.AddElement(wall1); }
public void Wall() { var line = new Line(Vector3.Origin, new Vector3(10, 10, 0)); var line1 = new Line(new Vector3(10, 10, 0), new Vector3(10, 15, 0)); var wall = new StandardWall(line, 0.2, 3); var wall1 = new StandardWall(line1, 0.2, 2); var model = new Model(); model.AddElement(wall); model.AddElement(wall1); model.ToIFC(ConstructIfcPath("IfcWall")); }
public void Example() { this.Name = "Elements_StandardWall"; // <example> // Create a wall. var line = new Line(new Vector3(0, 0, 0), new Vector3(10, 10, 0)); var wall = new StandardWall(line, 0.1, 3.0); wall.AddOpening(1, 2, 1, 2); wall.AddOpening(3, 1, 1, 2); // </example> this.Model.AddElement(wall); }
private static IfcProduct ToIfc(this StandardWall wall, Guid id, IfcLocalPlacement localPlacement, IfcProductDefinitionShape shape) { var ifcWall = new IfcWallStandardCase(IfcGuid.ToIfcGuid(id), null, wall.Name, null, null, localPlacement, shape, null, IfcWallTypeEnum.NOTDEFINED); return(ifcWall); }
public void WallWithAddedOpenings() { this.Name = "WallWithAddedOpenings"; var p = Polygon.Ngon(5, 10); foreach (var l in p.Segments()) { var w = new StandardWall(l, 0.1, 3.0, null); w.AddOpening(1, 1, 1, 2, 1.0, 1.0); w.AddOpening(1, 2, 3, 1, 1.0, 1.0); w.AddOpening(Polygon.Ngon(3, 2.0), 8, 2, 1.0, 0.0); this.Model.AddElement(w); } }
public void WallWithAddedOpenings() { this.Name = "WallWithAddedOpenings"; var l = new Line(new Vector3(0, 0, 0), new Vector3(10, 10, 0)); var w = new StandardWall(l, 0.1, 3.0, null); var openings = new List <Opening>() { new Opening(1.0, 2.0, 1.0, 1.0), new Opening(3.0, 1.0, 1.0, 2.0), new Opening(Polygon.Ngon(3, 2.0), 8, 2) }; w.Openings.AddRange(openings); this.Model.AddElement(w); }
public void Example() { this.Name = "Elements_StandardWall"; // <example> // Create a wall. var line = new Line(new Vector3(0, 0, 0), new Vector3(10, 10, 0)); var wall = new StandardWall(line, 0.1, 3.0); // Create some openings. var openings = new List <Opening>() { new Opening(1.0, 2.0, 1.0, 1.0), new Opening(3.0, 1.0, 1.0, 2.0) }; wall.Openings.AddRange(openings); // </example> this.Model.AddElement(wall); }
public void CoreElementTransformsAreIdempotentDuringSerialization() { var model = new Model(); // Create a floor with an elevation. // This will mutate the element's transform. var floor = new Floor(Polygon.L(20, 20, 5), 0.1, new Transform(0, 0, 0.5)); model.AddElement(floor); var beam = new Beam(new Line(Vector3.Origin, new Vector3(5, 5, 5)), Polygon.Rectangle(0.1, 0.1)); model.AddElement(beam); var wall = new StandardWall(new Line(Vector3.Origin, new Vector3(20, 0, 0)), 0.2, 3.5); model.AddElement(wall); // Serialize the floor, recording the mutated transform. var json = model.ToJson(); // Deserialize the floor, which will deserialize the elevation // and add it to the transform. var newModel = Model.FromJson(json); var newFloor = newModel.AllElementsOfType <Floor>().First(); Assert.Equal(floor.Transform, newFloor.Transform); var newBeam = newModel.AllElementsOfType <Beam>().First(); Assert.Equal(beam.Transform, newBeam.Transform); var newWall = newModel.AllElementsOfType <StandardWall>().First(); Assert.Equal(wall.Transform, newWall.Transform); }
public void Example() { this.Name = "Elements_Wall"; // <example> // Create a wall type. var wallType = new WallType("test", new List <MaterialLayer> { new MaterialLayer(BuiltInMaterials.Concrete, 0.1) }); // Create some openings. var openings = new List <Opening>() { new Opening(1.0, 2.0, 1.0, 1.0), new Opening(3.0, 1.0, 1.0, 2.0) }; var line = new Line(new Vector3(0, 0, 0), new Vector3(10, 10, 0)); var wall = new StandardWall(line, wallType, 3.0, openings); // </example> this.Model.AddElement(wall); }
/// <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); }
/// <summary> /// The PhoneBoothLayout function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A PhoneBoothLayoutOutputs instance containing computed results and the model with any new elements.</returns> public static PhoneBoothLayoutOutputs Execute(Dictionary <string, Model> inputModels, PhoneBoothLayoutInputs input) { var spacePlanningZones = inputModels["Space Planning Zones"]; var levelsModel = inputModels["Levels"]; var levels = spacePlanningZones.AllElementsOfType <LevelElements>(); var levelVolumes = levelsModel.AllElementsOfType <LevelVolume>(); var output = new PhoneBoothLayoutOutputs(); var configJson = File.ReadAllText("./PhoneBoothConfigurations.json"); var configs = JsonConvert.DeserializeObject <SpaceConfiguration>(configJson); var wallMat = new Material("Drywall", new Color(0.9, 0.9, 0.9, 1.0), 0.01, 0.01); var glassMat = new Material("Glass", new Color(0.7, 0.7, 0.7, 0.3), 0.3, 0.6); var mullionMat = new Material("Storefront Mullions", new Color(0.5, 0.5, 0.5, 1.0)); foreach (var lvl in levels) { var corridors = lvl.Elements.OfType <Floor>(); var corridorSegments = corridors.SelectMany(p => p.Profile.Segments()); var meetingRmBoundaries = lvl.Elements.OfType <SpaceBoundary>().Where(z => z.Name == "Phone Booth"); var levelVolume = levelVolumes.First(l => l.Name == lvl.Name); var wallCandidateLines = new List <(Line line, string type)>(); foreach (var room in meetingRmBoundaries) { var spaceBoundary = room.Boundary; Line orientationGuideEdge = FindEdgeAdjacentToSegments(spaceBoundary.Perimeter.Segments(), corridorSegments, out var wallCandidates); var exteriorWalls = FindEdgeAdjacentToSegments(wallCandidates, levelVolume.Profile.Segments(), out var solidWalls, 0.6); wallCandidateLines.AddRange(solidWalls.Select(s => (s, "Solid"))); var orientationTransform = new Transform(Vector3.Origin, orientationGuideEdge.Direction(), Vector3.ZAxis); var boundaryCurves = new List <Polygon>(); boundaryCurves.Add(spaceBoundary.Perimeter); boundaryCurves.AddRange(spaceBoundary.Voids ?? new List <Polygon>()); var grid = new Grid2d(boundaryCurves, orientationTransform); grid.U.DivideByApproximateLength(input.MinimumSize, EvenDivisionMode.RoundDown); foreach (var cell in grid.GetCells()) { var rect = cell.GetCellGeometry() as Polygon; var segs = rect.Segments(); var width = segs[0].Length(); var depth = segs[1].Length(); Line glassWall = null; var trimmedGeo = cell.GetTrimmedCellGeometry(); if (!cell.IsTrimmed() && trimmedGeo.Count() > 0) { glassWall = segs[0]; output.Model.AddElement(InstantiateLayout(configs, width, depth, rect, room.Transform)); } else if (trimmedGeo.Count() > 0) { var largestTrimmedShape = trimmedGeo.OfType <Polygon>().OrderBy(s => s.Area()).Last(); glassWall = largestTrimmedShape.Segments().OrderBy(s => s.PointAt(0.5).DistanceTo(segs[0].PointAt(0.5))).FirstOrDefault(); var cinchedVertices = rect.Vertices.Select(v => largestTrimmedShape.Vertices.OrderBy(v2 => v2.DistanceTo(v)).First()).ToList(); var cinchedPoly = new Polygon(cinchedVertices); output.Model.AddElement(InstantiateLayout(configs, width, depth, cinchedPoly, room.Transform)); } if (glassWall != null) { wallCandidateLines.Add((glassWall, "Glass")); } } var cellSeparators = grid.GetCellSeparators(GridDirection.V, true); wallCandidateLines.AddRange(grid.GetCellSeparators(GridDirection.V, true).OfType <Curve>().Select(c => (new Line(c.PointAt(0), c.PointAt(1)), "Partition"))); } var mullionSize = 0.07; var doorWidth = 0.9; var doorHeight = 2.1; var sideLightWidth = 0.4; var totalStorefrontHeight = Math.Min(2.7, levelVolume.Height); var mullion = new StandardWall(new Line(new Vector3(-mullionSize / 2, 0, 0), new Vector3(mullionSize / 2, 0, 0)), mullionSize, totalStorefrontHeight, mullionMat); mullion.IsElementDefinition = true; if (input.CreateWalls) { foreach (var wallCandidate in wallCandidateLines) { if (wallCandidate.type == "Solid") { output.Model.AddElement(new StandardWall(wallCandidate.line, 0.2, levelVolume.Height, wallMat, levelVolume.Transform)); } else if (wallCandidate.type == "Partition") { output.Model.AddElement(new StandardWall(wallCandidate.line, 0.1, levelVolume.Height, wallMat, levelVolume.Transform)); } else if (wallCandidate.type == "Glass") { var grid = new Grid1d(wallCandidate.line); grid.SplitAtOffsets(new[] { sideLightWidth, sideLightWidth + doorWidth }); grid[2].DivideByApproximateLength(2); var separators = grid.GetCellSeparators(true); var beam = new Beam(wallCandidate.line, Polygon.Rectangle(mullionSize, mullionSize), mullionMat, 0, 0, 0, isElementDefinition: true); output.Model.AddElement(beam.CreateInstance(levelVolume.Transform, "Base Mullion")); output.Model.AddElement(beam.CreateInstance(levelVolume.Transform.Concatenated(new Transform(0, 0, doorHeight)), "Base Mullion")); output.Model.AddElement(beam.CreateInstance(levelVolume.Transform.Concatenated(new Transform(0, 0, totalStorefrontHeight)), "Base Mullion")); foreach (var separator in separators) { // var line = new Line(separator, separator + new Vector3(0, 0, levelVolume.Height)); // output.Model.AddElement(new ModelCurve(line, BuiltInMaterials.XAxis, levelVolume.Transform)); var instance = mullion.CreateInstance(new Transform(separator, wallCandidate.line.Direction(), Vector3.ZAxis, 0).Concatenated(levelVolume.Transform), "Mullion"); output.Model.AddElement(instance); } output.Model.AddElement(new StandardWall(wallCandidate.line, 0.05, totalStorefrontHeight, glassMat, levelVolume.Transform)); var headerHeight = levelVolume.Height - totalStorefrontHeight; if (headerHeight > 0.01) { output.Model.AddElement(new StandardWall(wallCandidate.line, 0.2, headerHeight, wallMat, levelVolume.Transform.Concatenated(new Transform(0, 0, totalStorefrontHeight)))); } } } } } InstancePositionOverrides(input.Overrides, output.Model); return(output); }
private static int PanelLevels(List <Level> envLevels, Line[] boundarySegments, double panelWidth, double glassLeftRight, double glassTopBottom, Model model, Color panelColor) { var panelMat = new Material("panel", panelColor, 0.8f, 0.5f); var panelCount = 0; for (var i = 1; i < envLevels.Count - 1; i++) { var level1 = envLevels[i]; var level2 = envLevels[i + 1]; foreach (var s in boundarySegments) { FacadePanel masterPanel = null; Panel masterGlazing = null; var d = s.Direction(); var bottomSegments = DivideByLengthFromCenter(s, panelWidth); try { for (var j = 0; j < bottomSegments.Count(); j++) { var bs = bottomSegments[j]; var t = new Transform(bs.Start + new Vector3(0, 0, level1.Elevation), d, d.Cross(Vector3.ZAxis)); var l = bs.Length(); // If the segment width is within Epsilon of // the input panel width, then create a // panel with glazing. if (Math.Abs(l - panelWidth) < Vector3.EPSILON) { if (masterPanel == null) { // Create a master panel for each level. // This panel will be instanced at every location. CreateFacadePanel($"FP_{i}", panelWidth, level2.Elevation - level1.Elevation, glassLeftRight, glassTopBottom, 0.1, panelWidth, panelMat, t, out masterPanel, out masterGlazing); model.AddElement(masterPanel); model.AddElement(masterGlazing); } // Create a panel instance. var panelInstance = masterPanel.CreateInstance(t, $"FP_{i}_{j}"); model.AddElement(panelInstance, false); var glazingInstance = masterGlazing.CreateInstance(t, $"FG_{i}_{j}"); model.AddElement(glazingInstance, false); } // Otherwise, create a panel with not glazing. else { CreateStandardPanel($"FP_{i}_{j}", l, level2.Elevation - level1.Elevation, 0.1, t, panelMat, out FacadePanel panel); model.AddElement(panel); } panelCount++; } if (i == envLevels.Count - 2) { var parapet = new StandardWall(new Line(new Vector3(s.Start.X, s.Start.Y, level2.Elevation), new Vector3(s.End.X, s.End.Y, level2.Elevation)), 0.1, 0.9, panelMat); model.AddElement(parapet); } } catch (Exception ex) { Console.WriteLine(ex); continue; } } } return(panelCount); }
/// <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 Walls function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A WallsOutputs instance containing computed results and the model with any new elements.</returns> public static WallsOutputs Execute(Dictionary <string, Model> inputModels, WallsInputs input) { var output = new WallsOutputs(); var defaultWallMaterial = new Material("Wall", Colors.White); if (input.Overrides?.Additions?.Walls != null) { // Get identities for additions var additionCenters = input.Overrides.Additions.Walls.Select(x => (x.Value.CenterLine.PointAt(0.5), x.Id)).Cast <(Vector3 RoughLocation, string Id)>().ToList(); // match edit overrides to addition Ids. var editsByAdditionId = input.Overrides.Walls?.Select(wallEdit => (additionCenters.OrderBy(ac => ac.RoughLocation.DistanceTo(wallEdit.Identity.RoughLocation)).First().Id, wallEdit) ).ToDictionary(x => x.Id, x => x.wallEdit) ?? new Dictionary <string, WallsOverride>(); // match property edit overrides to addition Ids. We have to do a little extra manual cleanup here, // since the property edits are a separate override altogether — the hypar web UI doesn't // automatically remove these from the overrides list. var propertiesByAdditionId = new Dictionary <string, WallPropertiesOverride>(); foreach (var match in input.Overrides.WallProperties?.Select(wallEdit => (additionCenters.OrderBy(ac => ac.RoughLocation.DistanceTo(wallEdit.Identity.RoughLocation)).First().Id, wallEdit) ) ?? new List <(string Id, WallPropertiesOverride)>()) { if (!propertiesByAdditionId.ContainsKey(match.Id)) { propertiesByAdditionId.Add(match.Id, match.wallEdit); } else // non-associated edits don't get deleted automatically, so we might have strays. Find out which one is closer. { var currentEdit = propertiesByAdditionId[match.Id]; var additionCenter = additionCenters.First(ac => ac.Id == match.Id); if (currentEdit.Identity.RoughLocation.DistanceTo(additionCenter.RoughLocation) > match.wallEdit.Identity.RoughLocation.DistanceTo(additionCenter.RoughLocation)) { propertiesByAdditionId[match.Id] = match.wallEdit; } } } // for every addition foreach (var newWall in input.Overrides.Additions.Walls) { var wallLine = newWall.Value.CenterLine; var wallCenter = wallLine.PointAt(0.5); // get matching edit overrides editsByAdditionId.TryGetValue(newWall.Id, out var matchingEdits); wallLine = matchingEdits?.Value?.CenterLine ?? wallLine; propertiesByAdditionId.TryGetValue(newWall.Id, out var matchingProperties); var wallThickness = matchingProperties?.Value.Thickness ?? 0.15; var wallheight = matchingProperties?.Value.Height ?? 3.0; // create wall var wall = new StandardWall(wallLine, wallThickness, wallheight, defaultWallMaterial); // attach identity information and associated overrides wall.AdditionalProperties["Rough Location"] = wallCenter; Identity.AddOverrideIdentity(wall, newWall); if (matchingProperties != null) { Identity.AddOverrideIdentity(wall, matchingProperties); } if (matchingEdits != null) { Identity.AddOverrideIdentity(wall, matchingEdits); } // add wall to model output.Model.AddElement(wall); } } return(output); }
/// <summary> /// Adds facade Panels to one or more Masses named 'envelope'. /// </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 FacadeOutputs instance containing computed results.</returns> public static FacadeByEnvelopeOutputs Execute(Dictionary <string, Model> models, FacadeByEnvelopeInputs input) { List <Envelope> envelopes; List <Level> levels = null; var model = new Model(); var envelopeModel = models[ENVELOPE_MODEL_NAME]; envelopes = envelopeModel.AllElementsOfType <Envelope>().Where(e => e.Elevation >= 0.0).ToList(); if (envelopes.Count() == 0) { throw new Exception("No element of type 'Envelope' could be found in the supplied model."); } var levelsModel = models[LEVELS_MODEL_NAME]; levels = levelsModel.AllElementsOfType <Level>().ToList(); if (levels.Count() == 0) { throw new Exception("No element of type 'Level' could be found in the supplied model."); } levels.Sort(new LevelComparer()); var panelCount = 0; var panelMat = new Material("envelope", new Color(1.0, 1.0, 1.0, 1), 0.5f, 0.5f); List <Level> envLevels = null; var wireframeMaterial = new Material("wireframe", new Color(0.5, 0.5, 0.5, 1.0)); foreach (var envelope in envelopes) { var boundarySegments = envelope.Profile.Perimeter.Segments(); Level last = null; if (envLevels != null) { // If levels don't correspond exactly with the change // in envelopes, then we need the last level of the previous // set to become the first level of the next set. last = envLevels.Last(); } envLevels = levels.Where(l => l.Elevation >= envelope.Elevation && l.Elevation <= envelope.Elevation + envelope.Height).ToList(); if (last != null) { envLevels.Insert(0, last); } for (var i = 0; i < envLevels.Count - 1; i++) { var level1 = envLevels[i]; var level2 = envLevels[i + 1]; foreach (var s in boundarySegments) { FacadePanel masterPanel = null; Panel masterGlazing = null; var d = s.Direction(); var bottomSegments = DivideByLengthFromCenter(s, input.PanelWidth); try { for (var j = 0; j < bottomSegments.Count(); j++) { var bs = bottomSegments[j]; var t = new Transform(bs.Start + new Vector3(0, 0, level1.Elevation), d, d.Cross(Vector3.ZAxis)); var l = bs.Length(); // If the segment width is within Epsilon of // the input panel width, then create a // panel with glazing. if (Math.Abs(l - input.PanelWidth) < Vector3.EPSILON) { if (masterPanel == null) { // Create a master panel for each level. // This panel will be instanced at every location. CreateFacadePanel($"FP_{i}", input.PanelWidth, level2.Elevation - level1.Elevation, input.GlassLeftRightInset, input.GlassTopBottomInset, 0.1, input.PanelWidth, panelMat, t, out masterPanel, out masterGlazing); model.AddElement(masterPanel); model.AddElement(masterGlazing); } // Create a panel instance. var panelInstance = masterPanel.CreateInstance(t, $"FP_{i}_{j}"); model.AddElement(panelInstance, false); var glazingInstance = masterGlazing.CreateInstance(t, $"FG_{i}_{j}"); model.AddElement(glazingInstance, false); } // Otherwise, create a panel with not glazing. else { CreateStandardPanel($"FP_{i}_{j}", l, level2.Elevation - level1.Elevation, 0.1, t, panelMat, out FacadePanel panel); model.AddElement(panel); } panelCount++; } if (i == envLevels.Count - 2) { var parapet = new StandardWall(new Line(new Vector3(s.Start.X, s.Start.Y, level2.Elevation), new Vector3(s.End.X, s.End.Y, level2.Elevation)), 0.1, 0.9, panelMat); model.AddElement(parapet); } } catch (Exception ex) { Console.WriteLine(ex); continue; } } } } var output = new FacadeByEnvelopeOutputs(panelCount); output.model = model; return(output); }