예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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"));
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
파일: WallTests.cs 프로젝트: bertt/Elements
        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);
        }
예제 #14
0
파일: WallTests.cs 프로젝트: bertt/Elements
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        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);
        }
예제 #17
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);
        }
예제 #18
0
        /// <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);
        }
예제 #19
0
        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);
        }
예제 #20
0
        /// <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);
        }
예제 #21
0
        /// <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);
        }
예제 #22
0
        /// <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);
        }