コード例 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="moveTo"></param>
        /// <returns></returns>
        private CompassBox MakeMech(Vector3 moveTo)
        {
            var mechPerim = Polygon.Rectangle(mechLength, mechWidth);
            var mechTopo  = new CompassBox(mechPerim);

            mechPerim = mechPerim.MoveFromTo(mechTopo.W, moveTo);
            mechTopo  = new CompassBox(mechPerim);
            mechPerim = mechPerim.Rotate(Position, Rotation);
            var lastLevel  = Levels.SkipLast(1).Last();
            var mechHeight = lastLevel.Elevation - Levels.First().Elevation;
            var extrude    = new Elements.Geometry.Solids.Extrude(mechPerim, mechHeight, Vector3.ZAxis, false);
            var geomRep    = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
            {
                extrude
            });
            var mechMatl = new Material(new Color(0.2f, 0.2f, 0.2f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "mech");
            var ctr      = mechPerim.Centroid();

            Mechanicals.Add(new MechanicalCorridor(mechPerim, Vector3.ZAxis, Rotation,
                                                   new Vector3(ctr.X, ctr.Y, Levels.First().Elevation),
                                                   new Vector3(ctr.X, ctr.Y, Levels.First().Elevation + mechHeight),
                                                   mechHeight, mechPerim.Area() * mechHeight, "",
                                                   new Transform(0.0, 0.0, Levels.First().Elevation),
                                                   mechMatl, geomRep, false, Guid.NewGuid(), ""));
            return(mechTopo);
        }
コード例 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="insertAt"></param>
        /// <returns></returns>
        private CompassBox MakeBaths(Vector3 moveTo)
        {
            var bathPerim = Polygon.Rectangle(bathLength, bathWidth);
            var bathTopo  = new CompassBox(bathPerim);

            bathPerim = bathPerim.MoveFromTo(bathTopo.W, moveTo);
            bathTopo  = new CompassBox(bathPerim);
            bathPerim = bathPerim.Rotate(Position, Rotation);
            var bathLevels = Levels.Where(l => l.Elevation >= 0.0);
            var bathMatl   = new Material(new Color(0.0f, 0.6f, 1.0f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "bath");

            var i = 0;

            foreach (var level in bathLevels.SkipLast(2))
            {
                var bathHeight = bathLevels.ElementAt(i + 1).Elevation - bathLevels.ElementAt(i).Elevation - 1.0;
                var extrude    = new Elements.Geometry.Solids.Extrude(bathPerim, bathHeight, Vector3.ZAxis, false);
                var geomRep    = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                {
                    extrude
                });
                Restrooms.Add(new Room(bathPerim, Vector3.ZAxis, "", "", "", "", 0.0, 0.0, Rotation, bathLevels.ElementAt(i).Elevation,
                                       bathHeight, bathPerim.Area(), new Transform(0.0, 0.0, bathLevels.ElementAt(i).Elevation), bathMatl, geomRep, false, Guid.NewGuid(), "Restroom"));
                i++;
            }
            return(bathTopo);
        }
コード例 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stairs"></param>
        /// <param name="liftSvc"></param>
        private void MakeLifts(List <CompassBox> stairs, int liftSvc)
        {
            var liftMatl  = new Material(new Color(1.0f, 0.9f, 0.4f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "lift");
            var liftPolys = new List <Polygon>()
            {
                Polygon.Rectangle(liftSize, liftSize)
            };

            for (var i = 0; i < (LiftQuantity * 0.5) - 1; i++)
            {
                var liftPerim = Polygon.Rectangle(liftSize, liftSize);
                var liftTopo  = new CompassBox(liftPerim);
                var lastTopo  = new CompassBox(liftPolys.Last());
                liftPolys.Add(liftPerim.MoveFromTo(liftTopo.SW, lastTopo.SE));
            }
            var firstTopo = new CompassBox(liftPolys.First());
            var stairTopo = stairs.First();
            var makePolys = new List <Polygon>();

            foreach (var polygon in liftPolys)
            {
                makePolys.Add(polygon.MoveFromTo(firstTopo.SW, stairTopo.SE).Rotate(Position, Rotation));
            }
            liftPolys.Clear();
            liftPolys.Add(Polygon.Rectangle(liftSize, liftSize));
            for (var i = 0; i < (LiftQuantity * 0.5) - 1; i++)
            {
                var liftPerim = Polygon.Rectangle(liftSize, liftSize);
                var liftTopo  = new CompassBox(liftPerim);
                var lastTopo  = new CompassBox(liftPolys.Last());
                liftPolys.Add(liftPerim.MoveFromTo(liftTopo.SW, lastTopo.SE));
            }
            firstTopo = new CompassBox(liftPolys.First());
            stairTopo = stairs.Last();
            foreach (var polygon in liftPolys)
            {
                makePolys.Add(polygon.MoveFromTo(firstTopo.NW, stairTopo.NE).Rotate(Position, Rotation));
            }
            var liftSvcFactor = 0;

            foreach (var polygon in makePolys)
            {
                var lastLevel  = Levels.SkipLast((int)liftSvc * liftSvcFactor).Last();
                var liftHeight = lastLevel.Elevation - Levels.First().Elevation;
                if (liftHeight > 10.0)
                {
                    var extrude = new Elements.Geometry.Solids.Extrude(polygon, liftHeight, Vector3.ZAxis, false);
                    var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                    {
                        extrude
                    });
                    Lifts.Add(new LiftShaft(polygon, Vector3.ZAxis, Rotation, Levels.First().Elevation,
                                            liftHeight, polygon.Area() * liftHeight, "",
                                            new Transform(0.0, 0.0, Levels.First().Elevation), liftMatl, geomRep,
                                            false, Guid.NewGuid(), ""));
                }
                liftSvcFactor++;
            }
        }
コード例 #4
0
ファイル: CompassBoxTests.cs プロジェクト: cs-util/GeometryEx
        public void CompassBoxCreate()
        {
            var polygon =
                new Polygon
                (
                    new[]
            {
                new Vector3(0.0, 0.0),
                new Vector3(4.0, 0.0),
                new Vector3(4.0, 4.0),
                new Vector3(0.0, 4.0)
            }
                );
            var box = new CompassBox(polygon);

            Assert.Equal(2.0, box.C.X);
            Assert.Equal(2.0, box.C.Y);
            Assert.Equal(0.0, box.SW.X);
            Assert.Equal(0.0, box.SW.Y);
            Assert.Equal(1.0, box.SSW.X);
            Assert.Equal(0.0, box.SSW.Y);
            Assert.Equal(2.0, box.S.X);
            Assert.Equal(0.0, box.S.Y);
            Assert.Equal(3.0, box.SSE.X);
            Assert.Equal(0.0, box.SSE.Y);
            Assert.Equal(4.0, box.SE.X);
            Assert.Equal(0.0, box.SE.Y);
            Assert.Equal(4.0, box.ESE.X);
            Assert.Equal(1.0, box.ESE.Y);
            Assert.Equal(4.0, box.E.X);
            Assert.Equal(2.0, box.E.Y);
            Assert.Equal(4.0, box.ENE.X);
            Assert.Equal(3.0, box.ENE.Y);
            Assert.Equal(4.0, box.NE.X);
            Assert.Equal(4.0, box.NE.Y);
            Assert.Equal(3.0, box.NNE.X);
            Assert.Equal(4.0, box.NNE.Y);
            Assert.Equal(2.0, box.N.X);
            Assert.Equal(4.0, box.N.Y);
            Assert.Equal(1.0, box.NNW.X);
            Assert.Equal(4.0, box.NNW.Y);
            Assert.Equal(0.0, box.NW.X);
            Assert.Equal(4.0, box.NW.Y);
            Assert.Equal(0.0, box.WNW.X);
            Assert.Equal(3.0, box.WNW.Y);
            Assert.Equal(0.0, box.W.X);
            Assert.Equal(2.0, box.W.Y);
            Assert.Equal(0.0, box.WSW.X);
            Assert.Equal(1.0, box.WSW.Y);

            Assert.Equal(16.0, box.Compass.Count);
        }
コード例 #5
0
        /// <summary>
        /// Moves all Rooms along a 3D vector calculated between the supplied Vector3 points.
        /// </summary>
        /// <param name="from">Vector3 base point of the move.</param>
        /// <param name="to">Vector3 target point of the move.</param>
        /// <returns>
        /// None.
        /// </returns>
        public void MoveFromTo(Vector3 from, Vector3 to)
        {
            foreach (Room room in Rooms)
            {
                room.MoveFromTo(from, to);
            }
            Perimeter = Perimeter.MoveFromTo(from, to);
            var ang = Perimeter.Segments().OrderByDescending(s => s.Length()).ToList().First();

            Angle        = Math.Atan2(ang.End.Y - ang.Start.Y, ang.End.X - ang.Start.X) * (180 / Math.PI);
            perimeterJig = Perimeter.Rotate(Vector3.Origin, Angle * -1);
            compass      = perimeterJig.Compass();
            insert.MoveFromTo(from, to);
            Row = new Line(compass.SW, compass.SE).Rotate(Vector3.Origin, Angle);
        }
コード例 #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bathTopo"></param>
        /// <returns></returns>
        private List <CompassBox> MakeStairs(CompassBox bathTopo)
        {
            var stairTopos = new List <CompassBox>();

            for (int i = 0; i < 2; i++)
            {
                Vector3 from;
                Vector3 to;
                var     stairHeight = 0.0;
                var     lastLevel   = Levels.Last();

                var stairPerim = Polygon.Rectangle(stairLength, stairWidth);
                var stairTopo  = new CompassBox(stairPerim);
                if (i == 0)
                {
                    from        = stairTopo.SW;
                    to          = bathTopo.NW;
                    stairHeight = lastLevel.Elevation - Levels.First().Elevation + stairEntry;
                }
                else
                {
                    from        = stairTopo.NW;
                    to          = bathTopo.SW;
                    stairHeight = lastLevel.Elevation - Levels.First().Elevation;
                }
                stairPerim = stairPerim.MoveFromTo(from, to);
                stairTopo  = new CompassBox(stairPerim);
                stairTopos.Add(stairTopo);
                stairPerim = stairPerim.Rotate(Position, Rotation);
                var extrude = new Elements.Geometry.Solids.Extrude(stairPerim, stairHeight, Vector3.ZAxis, false);
                var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                {
                    extrude
                });
                var stairMatl = new Material(new Color(1.0f, 0.0f, 0.0f, 0.8f), 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "stair");
                Stairs.Add(new StairEnclosure(stairPerim, Vector3.ZAxis, Rotation, Levels.First().Elevation,
                                              stairHeight, stairPerim.Area() * stairHeight, "",
                                              new Transform(0.0, 0.0, Levels.First().Elevation),
                                              stairMatl, geomRep, false, Guid.NewGuid(), ""));
            }
            return(stairTopos);
        }
コード例 #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="levels"></param>
        /// <param name="rotation"></param>
        public CoreMaker(List <LevelPerimeter> levels, double setback, double rotation)
        {
            Levels = new List <LevelPerimeter>();
            Levels.AddRange(levels.OrderBy(l => l.Elevation).ToList());
            Restrooms   = new List <Room>();
            Mechanicals = new List <MechanicalCorridor>();
            Stairs      = new List <StairEnclosure>();
            Lifts       = new List <LiftShaft>();
            Rotation    = rotation;
            var corePerim = PlaceCore(setback, rotation);

            Perimeter = corePerim ?? throw new InvalidOperationException("No valid service core location found.");
            Elevation = Levels.First().Elevation;
            var coreTopo   = new CompassBox(corePerim);
            var bathTopo   = MakeBaths(coreTopo.W);
            var mechTopo   = MakeMech(bathTopo.E);
            var stairTopos = MakeStairs(bathTopo);

            MakeLifts(stairTopos, LiftService);

            //Following section for debug.
            //Comment for deployment.

            //Mechanicals.Clear();
            //var ctr = corePerim.Centroid();
            //var lastLevel = Levels.Last();
            //var mechHeight = lastLevel.Elevation - Levels.First().Elevation + 5.0;
            //var extrude = new Elements.Geometry.Solids.Extrude(corePerim, mechHeight, Vector3.ZAxis, 0.0, false);
            //var geomRep = new Representation(new List<Elements.Geometry.Solids.SolidOperation>() { extrude });
            //var mechMatl = new Material(new Color(0.2f, 0.2f, 0.2f, 0.8f), 0.0f, 0.0f, Guid.NewGuid(), "mech");
            //Mechanicals.Add(new MechanicalCorridor(corePerim, Vector3.ZAxis, Rotation,
            //                                       new Vector3(ctr.X, ctr.Y, Levels.First().Elevation),
            //                                       new Vector3(ctr.X, ctr.Y, Levels.First().Elevation + mechHeight),
            //                                       mechHeight, corePerim.Area() * mechHeight, "",
            //                                       new Transform(0.0, 0.0, Levels.First().Elevation),
            //                                       mechMatl, geomRep, Guid.NewGuid(), ""));
        }
コード例 #8
0
        /// <summary>
        /// The RoomsByFloorsTest function.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A RoomsByFloorsTestOutputs instance containing computed results and the model with any new elements.</returns>
        public static RoomsByFloorsTestOutputs Execute(Dictionary <string, Model> inputModels, RoomsByFloorsTestInputs input)
        {
            var floors = new List <Floor>();

            inputModels.TryGetValue("Floors", out var model);
            if (model == null)
            {
                throw new ArgumentException("No Floors found.");
            }
            floors.AddRange(model.AllElementsOfType <Floor>());

            floors = floors.OrderBy(f => f.Elevation).Where(f => f.Elevation >= 0.0).ToList();
            var upperFloorArea = 0.0;

            foreach (var floor in floors.Skip(1).SkipLast(2))
            {
                upperFloorArea += floor.Profile.Perimeter.Area();
            }

            var retlColor = Palette.Emerald;
            var offcColor = Palette.Cobalt;
            var retlMatl  = new Material("retail", retlColor, 0.0f, 0.0f);
            var offcMatl  = new Material("office", offcColor, 0.0f, 0.0f);

            var rooms        = new List <Room>();
            var grdRooms     = 0;
            var grdArea      = 0.0;
            var upArea       = 0.0;
            var typRooms     = 0;
            var typRoomCount = 0;

            for (var i = 0; i < floors.Count() - 2; i++)
            {
                var floor   = floors.ElementAt(i);
                var ceiling = floors.ElementAt(i + 1);
                var height  = ceiling.ProfileTransformed().Perimeter.Vertices.First().Z
                              - floor.ProfileTransformed().Perimeter.Vertices.First().Z
                              - floor.Thickness - 0.7;
                var offPerims = ceiling.Profile.Perimeter.Offset(input.PlanSetback * -1);
                if (offPerims.Count() == 0)
                {
                    throw new InvalidOperationException("Plan Setback too deep. No valid room boundaries could be created.");
                }
                var perimeter = offPerims.First();
                var perimBox  = new CompassBox(perimeter);

                var xDiv = 1.0;
                var yDiv = 1.0;

                var xRoomSize = 1.0;
                var yRoomSize = 1.0;

                var roomColor = offcColor;

                if (i == 0)
                {
                    xDiv      = input.GroundFloorRoomLengthDivisions;
                    yDiv      = input.GroundFloorRoomWidthDivisions;
                    xRoomSize = (int)Math.Ceiling(perimBox.SizeX / xDiv);
                    yRoomSize = (int)Math.Ceiling(perimBox.SizeY / yDiv);
                    grdRooms  = (int)Math.Floor(xDiv * yDiv);
                    grdArea   = perimeter.Area();
                    roomColor = retlColor;
                }
                else
                {
                    xDiv          = input.TypicalFloorRoomsLengthDivisions;
                    yDiv          = input.TypicalFloorRoomsWidthDivisions;
                    xRoomSize     = (int)Math.Ceiling(perimBox.SizeX / xDiv);
                    yRoomSize     = (int)Math.Ceiling(perimBox.SizeY / yDiv);
                    typRooms      = (int)Math.Floor(xDiv * yDiv);
                    typRoomCount += typRooms;
                    upArea       += perimeter.Area();
                }

                var perimeters = new List <Polygon>();
                var loc        = perimBox.SW;

                for (var x = 0; x < xDiv; x++)
                {
                    for (var y = 0; y < yDiv; y++)
                    {
                        var perim = Polygon.Rectangle(xRoomSize, yRoomSize);
                        var pTopo = new CompassBox(perim);
                        perimeters.Add(perim.MoveFromTo(pTopo.SW, loc));
                        loc = new Vector3(loc.X, loc.Y + yRoomSize, 0.0);
                    }
                    loc = new Vector3(loc.X + xRoomSize, perimBox.SW.Y, 0.0);
                }

                foreach (var perim in perimeters)
                {
                    var name = "Office";
                    var matl = offcMatl;
                    if (i == 0)
                    {
                        name = "Retail";
                        matl = retlMatl;
                    }
                    var rPerim = perim.Rotate(floor.Profile.Perimeter.Centroid(), input.PlanRotation);
                    if (!rPerim.Intersects(perimeter))
                    {
                        continue;
                    }
                    var rmPerims = perimeter.Intersection(rPerim);
                    foreach (var rmPerim in rmPerims)
                    {
                        var roomPerims = rmPerim.Offset(-0.2);
                        if (roomPerims.Count() == 0)
                        {
                            continue;
                        }
                        foreach (var room in roomPerims)
                        {
                            Representation geomRep = null;
                            if (input.RoomsIn3D)
                            {
                                var solid = new Elements.Geometry.Solids.Extrude(room, height, Vector3.ZAxis, false);
                                geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                                {
                                    solid
                                });
                            }
                            else
                            {
                                var solid = new Elements.Geometry.Solids.Lamina(room, false);
                                geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>()
                                {
                                    solid
                                });
                            }
                            var rm = new Room(room, Vector3.ZAxis, "", "", "", "", 0.0, 0.0, 0.0, floor.Elevation, height, room.Area(), new Transform(floor.Transform), matl, geomRep, false, Guid.NewGuid(), name);
                            rm.Transform.Move(new Vector3(0.0, 0.0, 0.7));
                            rooms.Add(rm);
                        }
                    }
                }
            }

            var output = new RoomsByFloorsTestOutputs(grdRooms, grdArea, typRooms, typRoomCount, upArea);

            foreach (var room in rooms)
            {
                output.Model.AddElement(room);
            }
            return(output);
        }
コード例 #9
0
        /// <summary>
        /// Creates the shell of a building service core by attempting to place a footprint of various side ratios and rotations within the smallest envelope of the building. If the specified service core cannot fit within the building, the core is displaced to the exterior at the midpoint of the longest side of the highest envelope.
        /// </summary>
        /// <param name="inputs">Inputs from the UI.</param>
        /// <param name="envelopes">List of Envelopes from an incoming model.</param>
        /// <returns>A CoreDef structure specifying a service core.</returns>
        public static CoreDef MakeCore(CoreByEnvelopeInputs inputs, List <Envelope> envelopes)
        {
            var height = 0.0;

            envelopes = envelopes.OrderBy(e => e.Elevation).ToList();
            envelopes.ForEach(e => height += e.Height);
            height += inputs.ServiceCorePenthouseHeight;
            var footprint = envelopes.First().Profile.Perimeter;
            var ftArea    = Math.Abs(footprint.Area());
            var area      = ftArea * inputs.PercentageArea;
            var crown     = envelopes.Last().Profile.Perimeter;
            var crownOff  = crown.Offset(inputs.MinimumPerimeterOffset * -1.0);

            if (crownOff.Count() > 0)
            {
                crown = crownOff.First();
            }
            var angLine   = crown.Segments().OrderByDescending(s => s.Length()).ToList().First();
            var angle     = Math.Atan2(angLine.End.Y - angLine.Start.Y, angLine.End.X - angLine.Start.X) * (180 / Math.PI);
            var perimeter = Shaper.RectangleByArea(area, inputs.LengthToWidthRatio);

            perimeter = perimeter.Rotate(perimeter.Centroid(), angle);
            var compass = new CompassBox(perimeter);
            var coreDef = new CoreDef
            {
                perimeter = perimeter,
                elevation = envelopes.First().Elevation,
                height    = height,
                length    = compass.SizeX,
                width     = compass.SizeY,
                rotation  = angle
            };
            var positions = new List <Vector3>();
            var centroid  = crown.Centroid();
            var coordGrid = new CoordinateGrid(crown);

            positions.AddRange(coordGrid.Available);
            if (crown.Covers(centroid))
            {
                positions = positions.OrderBy(p => p.DistanceTo(centroid)).ToList();
                positions.Insert(0, centroid);
            }
            foreach (var position in positions)
            {
                perimeter = perimeter.MoveFromTo(perimeter.Centroid(), position);
                var rotation = coreDef.rotation;
                while (rotation <= angle + 90.0)
                {
                    perimeter = perimeter.Rotate(position, rotation);
                    if (crown.Covers(perimeter))
                    {
                        coreDef.perimeter = perimeter;
                        coreDef.rotation  = rotation;
                        return(coreDef); // Return the first successful interior placement.
                    }
                    rotation += CORE_ROTATE_INCREMENT;
                }
            }

            // If no internal position found, place the service core to penetrate all envelopes along their longest side.

            angLine   = footprint.Segments().OrderByDescending(s => s.Length()).ToList().First();
            angle     = Math.Atan2(angLine.End.Y - angLine.Start.Y, angLine.End.X - angLine.Start.X) * (180 / Math.PI);
            perimeter = Shaper.RectangleByArea(area, inputs.LengthToWidthRatio);
            perimeter = perimeter.MoveFromTo(perimeter.Centroid(), angLine.Midpoint()).Rotate(angLine.Midpoint(), angle);
            crown     = envelopes.Last().Profile.Perimeter;
            if (!perimeter.Intersects(crown))
            {
                angLine   = crown.Segments().OrderByDescending(s => s.Length()).ToList().First();
                angle     = Math.Atan2(angLine.End.Y - angLine.Start.Y, angLine.End.X - angLine.Start.X) * (180 / Math.PI);
                perimeter = Shaper.RectangleByArea(area, inputs.LengthToWidthRatio);
                perimeter = perimeter.MoveFromTo(perimeter.Centroid(), angLine.Midpoint()).Rotate(angLine.Midpoint(), angle);
            }
            coreDef.perimeter = perimeter;
            return(coreDef);
        }