public void Merge() { var polygons = new List <Polygon> { new Polygon ( new [] { Vector3.Origin, new Vector3(8.0, 0.0), new Vector3(8.0, 3.0), new Vector3(0.0, 3.0) } ), new Polygon ( new [] { new Vector3(5.0, 0.0), new Vector3(8.0, 0.0), new Vector3(8.0, 20.0), new Vector3(5.0, 20.0) } ), new Polygon ( new [] { new Vector3(10.0, 0.0), new Vector3(20.0, 0.0), new Vector3(20.0, 3.0), new Vector3(10.0, 3.0) } ) }; var merged = Shaper.Merge(polygons); Assert.Equal(2, merged.Count); }
public void Spine() { var spine = ShapeMaker.L(Vector3.Origin, new Vector3(100.0, 100.0), 25.0).Spine(); Assert.Equal(2, spine.Count); spine = ShapeMaker.C(Vector3.Origin, new Vector3(100.0, 100.0), 25.0).Spine(); Assert.Equal(3, spine.Count); spine = ShapeMaker.X(Vector3.Origin, new Vector3(100.0, 100.0), 25.0).Spine(); Assert.Equal(4, spine.Count); var model = new Model(); var corridors = new List <Polygon>(); foreach (var line in spine) { corridors.Add(new Polyline(new[] { line.Start, line.End }).Offset(1.0, EndType.Square).First()); } corridors = Shaper.Merge(corridors); foreach (var corridor in corridors) { model.AddElement(new Space(corridor, 4.0, new Material(Palette.Aqua, 0.0f, 0.0f, false, null, false, Guid.NewGuid(), "corridor"))); } model.ToGlTF("../../../../GeometryExTests/output/polygon.Spine.glb"); }
/// <summary> /// The PlanByProgram function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A PlanByProgramOutputs instance containing computed results and the model with any new elements.</returns> public static PlanByProgramOutputs Execute(Dictionary <string, Model> inputModels, PlanByProgramInputs input) { var rmDefModel = inputModels["Program"]; var rmDefs = new List <RoomDefinition>(rmDefModel.AllElementsOfType <RoomDefinition>().ToList()); if (rmDefs.Count == 0) { throw new ArgumentException("No Program found."); } var suites = Placer.PlaceSuites(input, rmDefs); var tmpput = new PlanByProgramOutputs(); var roomCount = 0; var roomArea = 0.0; foreach (var suite in suites) { roomCount += suite.Rooms.Count; foreach (var room in suite.Rooms) { var extrude = new Elements.Geometry.Solids.Extrude(new Profile(room.Perimeter), room.Height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { extrude }); tmpput.Model.AddElement(new Elements.Room(room.Perimeter, Vector3.ZAxis, room.Suite, room.SuiteID, room.Department, room.Number, room.DesignArea, room.DesignRatio, 0.0, room.Elevation, room.Height, room.Area, new Transform(), room.ColorAsMaterial, geomRep, false, Guid.NewGuid(), room.Name)); roomArea += room.Area; } } var suitesByElevation = suites.GroupBy(s => s.Elevation); var totalArea = 0.0; foreach (var group in suitesByElevation) { var elevation = group.First().Elevation; var suiteprints = new List <Polygon>(); foreach (var suite in group) { if (input.ConformFloorsToRooms) { var roomPrints = Shaper.Merge(suite.RoomsAsPolygons); if (roomPrints.Count == 0) { suiteprints.Add(suite.CompassCorridor.Box.Offset(input.CorridorWidth).First()); } foreach (var roomPrint in roomPrints) { suiteprints.Add(roomPrint.Offset(input.CorridorWidth).First()); } } else { suiteprints.Add(suite.CompassCorridor.Box.Offset(input.CorridorWidth).First()); } } suiteprints = Shaper.Merge(suiteprints); foreach (var footprint in suiteprints) { tmpput.Model.AddElement(new Floor(footprint, 0.1, new Transform(0.0, 0.0, elevation - 0.1), BuiltInMaterials.Concrete, null, false, Guid.NewGuid(), "")); tmpput.Model.AddElement(new Level(elevation, Guid.NewGuid(), elevation.ToString())); totalArea += footprint.Area(); } } var output = new PlanByProgramOutputs(roomCount, roomArea, totalArea - roomArea, totalArea) { Model = tmpput.Model }; return(output); }
/// <summary> /// Generates Rooms of a supplied area on each incoming Level deployed along the Level's straight skeleton spine which is used as a central corridor path. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A RoomsByLevelsOutputs instance containing computed results and the model with any new elements.</returns> public static RoomsByLevelsOutputs Execute(Dictionary <string, Model> inputModels, RoomsByLevelsInputs input) { var levels = new List <LevelPerimeter>(); inputModels.TryGetValue("Levels", out var lvlModel); if (lvlModel != null) { levels.AddRange(lvlModel.AllElementsOfType <LevelPerimeter>()); } if (levels.Count == 0) { throw new ArgumentException("No LevelPerimeters found."); } levels = levels.OrderBy(l => l.Elevation).ToList(); var stories = new List <Story>(); for (var i = 0; i < levels.Count - 1; i++) { var perimeter = levels[i].Perimeter; var elevation = levels[i].Elevation; var height = (levels[i + 1].Elevation - levels[i].Elevation) - 0.5; // replace this number with a plenum height var spine = levels[i].Perimeter.Spine(); var sections = levels[i].Perimeter.Jigsaw(); var endSects = new List <Polygon>(); var midSects = new List <Polygon>(); var corridors = new List <Polygon>(); var story = new Story(perimeter) { Elevation = elevation }; foreach (var line in spine) { corridors.Add(line.ToPolyline().Offset(input.CorridorWidth * 0.5, EndType.Square).First()); } corridors = Shaper.Merge(corridors); foreach (var corridor in corridors) { story.AddCorridor(new RoomKit.Room(corridor.Straighten(input.CorridorWidth * 0.1).Simplify(input.CorridorWidth * 0.9), height), false); } foreach (var polygon in sections) { if (polygon.Vertices.Count == 3) { endSects.Add(polygon.AlignedBox()); continue; } midSects.Add(polygon); } var scaffolds = new List <Polygon>(endSects); foreach (var midSect in midSects) { scaffolds.AddRange(Shaper.Differences(midSect.ToList(), endSects)); } var roomRows = new List <RoomRow>(); foreach (var polygon in scaffolds) { roomRows.Add(new RoomRow(polygon)); } foreach (var row in roomRows) { var result = row.AddRoomByArea(row.Area * 0.5, height, elevation); result = row.AddRoomByArea(row.Area * 0.5, height, elevation); row.Infill(height, true); } var rowRooms = new List <RoomKit.Room>(); foreach (var row in roomRows) { rowRooms.AddRange(row.Rooms); } foreach (var room in rowRooms) { story.AddRoom(room); } stories.Add(story); } var rooms = new List <Elements.Room>(); foreach (var story in stories) { foreach (var room in story.Rooms) { room.Color = Palette.Aqua; var solid = new Elements.Geometry.Solids.Extrude(room.Perimeter, room.Height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); rooms.Add(new Elements.Room(room.Perimeter, Vector3.ZAxis, "", "", "", "", input.RoomArea, room.Ratio, 0.0, room.Elevation, room.Height, room.Area, null, room.ColorAsMaterial, geomRep, false, Guid.NewGuid(), room.Name)); } foreach (var room in story.Corridors) { room.Color = Palette.White; var solid = new Elements.Geometry.Solids.Extrude(room.Perimeter, room.Height, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); rooms.Add(new Elements.Room(room.Perimeter, Vector3.ZAxis, "", "", "", "", input.RoomArea, room.Ratio, 0.0, room.Elevation, room.Height, room.Area, null, room.ColorAsMaterial, geomRep, false, Guid.NewGuid(), room.Name)); } } var output = new RoomsByLevelsOutputs(rooms.Count / levels.Count, rooms.Count); foreach (var room in rooms) { output.Model.AddElement(room); } return(output); }
/// <summary> /// /// </summary> /// <param name="inputs"></param> /// <param name="roomDefs"></param> /// <returns></returns> public static List <Suite> PlaceSuites(PlanByProgramInputs inputs, List <RoomDefinition> roomDefs) { bool northeast = true; bool minCoord = true; bool diagonal = inputs.DiagonalAdjacency; if (inputs.PrimaryDirection == PrimaryDirection.Southwest) { northeast = false; } if (inputs.CoordinateAdjacency == CoordinateAdjacency.Maximum) { minCoord = false; } var suites = SuiteMaker(inputs, roomDefs, inputs.SuiteRatio); var footPrints = new List <Polygon> { suites.First().CompassCorridor.Box }; var anchorSuite = suites.First(); var elevation = 0.0; var height = 0.0; foreach (var suite in suites.Skip(1)) { var testHeight = suite.Rooms.OrderByDescending(r => r.Height).First().Height; if (testHeight > height) { height = testHeight; } var footprint = PlaceAdjacentToSuite(anchorSuite.CompassCorridor.Box, suite.CompassCorridor.Box, footPrints, northeast, minCoord, diagonal); if (footprint == null && inputs.MultipleLevels == true) { elevation += height + inputs.PlenumHeight; footPrints.Clear(); footprint = suite.CompassCorridor.Box; anchorSuite = suite; } if (footprint == null && inputs.MultipleLevels == false) { footprint = PlaceAdjacentToFootprint(suite.CompassCorridor.Box, footPrints, diagonal); if (footprint != null) { height = 0.0; } } if (footprint == null) { continue; } if (!Shaper.NearEqual(suite.CompassCorridor.AspectRatio, footprint.Compass().AspectRatio)) { suite.Rotate(Vector3.Origin, 90.0); } suite.MoveFromTo(suite.CompassCorridor.SW, footprint.Compass().SW); suite.Elevation = elevation; footPrints.Add(suite.CompassCorridor.Box); footPrints = Shaper.Merge(footPrints); } return(suites); }