/// <summary> /// The SiteBySketch function. /// </summary> /// <param name="inputModels">The input models.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A SiteBySketchOutputs instance containing computed results and the model with any new elements.</returns> public static SiteBySketchOutputs Execute(Dictionary <string, Model> inputModels, SiteBySketchInputs input) { var lamina = new Elements.Geometry.Solids.Lamina(input.Perimeter, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { lamina }); var sitMatl = new Material("site", Palette.Emerald, 0.0f, 0.0f); var output = new SiteBySketchOutputs(Math.Abs(input.Perimeter.Area())); var site = new Site(input.Perimeter, Math.Abs(input.Perimeter.Area()), null, sitMatl, geomRep, false, Guid.NewGuid(), ""); output.Model.AddElement(site); return(output); }
/// <summary> /// The LevelBySketch function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A LevelBySketchOutputs instance containing computed results and the model with any new elements.</returns> public static LevelBySketchOutputs Execute(Dictionary <string, Model> inputModels, LevelBySketchInputs input) { var lamina = new Elements.Geometry.Solids.Lamina(input.Perimeter, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { lamina }); var lvlMatl = new Material("level", Palette.White, 0.0f, 0.0f); var output = new LevelBySketchOutputs(input.Perimeter.Area()); output.model.AddElement(new Level(0.0, Guid.NewGuid(), "")); output.model.AddElement(new LevelPerimeter(0.0, input.Perimeter, Guid.NewGuid(), "")); output.model.AddElement(new Panel(input.Perimeter, lvlMatl, null, geomRep, false, Guid.NewGuid(), "")); return(output); }
/// <summary> /// Generates a planar Site from a supplied sketch. /// </summary> /// <param name="inputModels">The input models.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A SiteBySketchOutputs instance containing computed results and the model with any new elements.</returns> public static SiteBySketchOutputs Execute(Dictionary <string, Model> inputModels, SiteBySketchInputs input) { var geomRep = new Elements.Geometry.Solids.Lamina(input.Perimeter, false); var siteMaterial = new Material("site", Palette.Emerald, 0.0f, 0.0f); var area = input.Perimeter.Area(); var output = new SiteBySketchOutputs(area); var site = new Site() { Perimeter = input.Perimeter, Area = area, Material = siteMaterial, Representation = geomRep, }; output.Model.AddElement(site); return(output); }
/// <summary> /// The ProduceLayout function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A ProduceLayoutOutputs instance containing computed results and the model with any new elements.</returns> public static ProduceLayoutOutputs Execute(Dictionary <string, Model> inputModels, ProduceLayoutInputs input) { // convert the inputs to meters var minAisle = input.MinAisleWidth / 39.37; if (minAisle == 0) { minAisle = 1; } ProduceLayoutOutputs output = new ProduceLayoutOutputs(); Model model = null; IList <Room> rooms = null; //test inputModels.Clear(); // we want Departments as inputs! if (inputModels.TryGetValue("Departments", out model)) { rooms = model.AllElementsOfType <Room>().ToList(); } else { throw new ApplicationException("Need Departments as input!"); model = new Model(); // default: double inputLength = 100; double inputWidth = 30; double inputHeight = 5; var rectangle = Polygon.Rectangle(inputLength, inputWidth); var mass = new Mass(rectangle, inputHeight); output.model.AddElement(mass); var material = new Material("office", new Color(0, 0, 1.0, 0.5)); var solid = new Elements.Geometry.Solids.Extrude(rectangle, inputHeight, Vector3.ZAxis, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { solid }); Room r = new Room(rectangle, Vector3.ZAxis, "Section 1", "100", "produce", "100", rectangle.Area(), 1.0, 0, 0, inputHeight, rectangle.Area(), new Transform(), material, geomRep, false, System.Guid.NewGuid(), "Section 1"); model.AddElement(r); rooms = new List <Room>(); rooms.Add(r); } // ok, now the real work begins... from the room // this function only deals with certain departments. var appropriateRooms = rooms.Where(r => r.Department == "produce"); if (appropriateRooms.Count() == 0) { throw new ApplicationException("This function works only on rooms with 'produce' department"); } foreach (var r in appropriateRooms) { // make a 2D grid var grid = new Elements.Spatial.Grid2d(r.Perimeter, new Transform()); // we want to subdivide: var geom = grid.V.GetCellGeometry(); var sideLength = grid.V.Domain.Length; //grid.U.GetCellGeometry().Length(); var standardDepth = 0.889; // 35.5" var standardWidth = 1.22; // 48" double available = sideLength - (2.0 * standardDepth); int count = (int)(available / (2 * standardDepth + minAisle)); // debug: System.Console.WriteLine("side Length: " + sideLength + " available: " + available + " count: " + count); System.Console.WriteLine("Min Aisle: " + minAisle); grid.V.DivideByPattern(new double[] { standardDepth, standardDepth, minAisle }, PatternMode.Cycle, FixedDivisionMode.RemainderAtEnd); grid.U.DivideByFixedLength(standardWidth); var produce = new Material("Produce", Colors.Gray, 0f, 0f, null, Guid.NewGuid()); // now we will try making the shelving for (int i = 0; i < grid.V.Cells.Count; i++) { for (int j = 0; j < grid.U.Cells.Count; j++) { var cell = grid.GetCellAtIndices(j, i); // make a poly from each gridcell // shelf, shelf, aisle int c = i + 1; if (((c % 3) == 0)) { // we skip for the aisle } else { var height = 0.9; var material = new Material(Colors.Brown, 0, 0, Guid.NewGuid(), "ProduceBase"); var shelfMass = new Mass((Polygon)cell.GetCellGeometry(), height, material); // for the angled base, start by copying it up. var p = (Polygon)cell.GetCellGeometry(); p.Transform(new Transform(0, 0, height)); Vector3 tmpOrigin = p.Vertices.First(); double rotAngle = 30; if ((c % 3) == 2) { tmpOrigin = p.Vertices[2]; rotAngle = -30; } // this is dumb. But it's a hackathon p.Transform(new Transform(-1 * tmpOrigin.X, -1 * tmpOrigin.Y, -1 * tmpOrigin.Z)); var rotate = new Transform(); rotate.Rotate(Vector3.XAxis, rotAngle); p.Transform(rotate); p.Transform(new Transform(tmpOrigin.X, tmpOrigin.Y, tmpOrigin.Z)); var angle = new Elements.Geometry.Solids.Lamina(p, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { angle }); var envelope = new Envelope(p, 0.0, height, Vector3.ZAxis, 0.0, new Transform(), produce, geomRep, false, System.Guid.NewGuid(), ""); output.model.AddElement(shelfMass); output.model.AddElement(envelope); } } } } return(output); }
/// <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); }
/// <summary> /// The LevelsFromGraphQLAndPerimeter function. /// </summary> /// <param name="model">The input model.</param> /// <param name="input">The arguments to the execution.</param> /// <returns>A LevelsFromGraphQLAndPerimeterOutputs instance containing computed results and the model with any new elements.</returns> public static LevelsFromGraphQLAndPerimeterOutputs Execute(Dictionary <string, Model> inputModels, LevelsFromGraphQLAndPerimeterInputs input) { //get the connection and query inputs which should have been provided as JSON data var connectionInfoFilePath = input.Connection.LocalFilePath; var connJSON = System.IO.File.ReadAllText(connectionInfoFilePath); dynamic connectionArgs = Newtonsoft.Json.JsonConvert.DeserializeObject(connJSON); if (connectionArgs.URI == null) { throw new ArgumentException("URI must be provided."); } var uri = connectionArgs.URI.Value; var headers = new Dictionary <string, string>(); if (connectionArgs.Headers != null) { headers = connectionArgs.Headers.ToObject <Dictionary <string, string> >(); } //the GraphQL query to get all the levels and the data we need to create the Hypar levels var levelQuery = @" query ($buidingName:String, $projectName: String) { Levels: Level(filter: { Building: { Name:$buidingName, Projects_some: { Name:$projectName} } }) { Id Abbreviation Elevation(unit:m) Name } } "; //the variables required for the GraphQL levels query var queryVariables = new Dictionary <string, object>(); queryVariables.Add("buidingName", "Dynamo Tower"); queryVariables.Add("projectName", "Project Graph"); var client = new ReallySimpleGraphQLClient(uri, headers); var response = client.SendRequest(levelQuery, queryVariables); if (response == null) { throw new ArgumentException("No data was returned: Check connection and query."); } var newElements = new List <Element>(); int lvlCount = 0; if (response.Levels != null) { var lamina = new Elements.Geometry.Solids.Lamina(input.Perimeter, false); var geomRep = new Representation(new List <Elements.Geometry.Solids.SolidOperation>() { lamina }); var lvlMatl = new Material("level", Colors.White, 0.0f, 0.0f); foreach (dynamic lvl in response.Levels) { var elevation = lvl.Elevation.Value; var name = lvl.Name.Value; var Id = lvl.Id.Value; Guid idGuid; if (!Guid.TryParse((string)Id, out idGuid)) { idGuid = Guid.NewGuid(); } newElements.Add(new Level(elevation, idGuid, name)); newElements.Add(new LevelPerimeter(elevation, input.Perimeter, Guid.NewGuid(), name)); newElements.Add(new Panel(input.Perimeter, lvlMatl, new Transform(0, 0, elevation), geomRep, false, Guid.NewGuid(), name)); lvlCount++; } } var output = new LevelsFromGraphQLAndPerimeterOutputs(lvlCount); output.Model.AddElements(newElements); return(output); }