private IReadOnlyDictionary <IRoomPlan, KeyValuePair <VerticalSelection, IVerticalFeature> > InsertOverlappingVerticals(IFloorPlanBuilder plan, IEnumerable <KeyValuePair <VerticalSelection, IVerticalFeature> > overlappingElements) { var result = new Dictionary <IRoomPlan, KeyValuePair <VerticalSelection, IVerticalFeature> >(); foreach (var element in overlappingElements) { //Transform overlap into coordinate frame of floor var points = element.Value.Bounds.Footprint.ToArray(); var w = element.Value.WorldTransformation * InverseWorldTransformation; for (var i = 0; i < points.Length; i++) { points[i] = Vector3.Transform(points[i].X_Y(0), w).XZ(); } //Ensure Clockwise winding if (points.Area() < 0) { Array.Reverse(points); } //Create a room which is the space of this vertical element var r = plan.Add(points, HierarchicalParameters.InternalWallThickness(Random)).Single(); //set room to use identity script // Consider: // - Should we use something other than the empty room for verticals? // - Perhaps allow vertical elements to supply their own room script? r.AddScript(1, new ScriptReference(typeof(IdentityRoom))); //Save the result result.Add(r, element); } return(result); }
protected override IEnumerable <KeyValuePair <VerticalSelection, IRoomPlan> > CreateFloorPlan(IFloorPlanBuilder builder, IReadOnlyDictionary <IRoomPlan, KeyValuePair <VerticalSelection, IVerticalFeature> > overlappingVerticalElements, IReadOnlyList <ConstrainedVerticalSelection> constrainedVerticalElements) { //IReadOnlyList<IReadOnlyList<Subsection>> sections; //IReadOnlyList<IReadOnlyList<Vector2>> overlappingVerticals; //todo: TEMPORARY FLOORPLAN DETAILS! var sections = new[] { new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0] }; var overlappingVerticals = new Vector2[][] { }; _designer.Design( Random, Metadata, ScriptReference.Find(Random), builder, sections, HierarchicalParameters.InternalWallThickness(Random), overlappingVerticals, constrainedVerticalElements ); return(new KeyValuePair <VerticalSelection, IRoomPlan> [0]); }
/// <summary> /// Create an edge builder which builds the geometry for the given edge /// </summary> /// <param name="edge"></param> /// <param name="roadLanes"></param> /// <returns></returns> protected virtual IHalfEdgeBuilder CreateHalfEdgeBuilder(HalfEdge <IVertexBuilder, IHalfEdgeBuilder, IFaceBuilder> edge, uint roadLanes) { Contract.Requires(edge != null); Contract.Requires(HierarchicalParameters != null); Contract.Ensures(Contract.Result <IHalfEdgeBuilder>() != null); var road = HierarchicalParameters.RoadLaneWidth(Random); var path = HierarchicalParameters.RoadSidewalkWidth(Random); return(new HalfEdgeRoadBuilder(edge, road, path, roadLanes)); }
public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters) { //Sanity checks if (!_floorIndex.HasValue) { throw new InvalidOperationException("Attempted to subdivide BaseFloor, but FloorIndex is not set"); } if (!_floorAltitude.HasValue) { throw new InvalidOperationException("Attempted to subdivide BaseFloor, but FloorAltitude is not set"); } //Calculate some handy values _roomHeight = bounds.Height - _floorThickness - _ceilingThickness; var roomOffsetY = -bounds.Height / 2 + _roomHeight / 2 + _floorThickness; //Find vertical elements which start on this floor var constrainedVerticalElements = ConstrainVerticalElements(this.SearchUp <IBuilding, IBuilding>(a => a, typeof(IBuildingContainer))); //Create a plan for this floor var plan = new Plan.Geometric.GeometricFloorplan(Bounds.Footprint); var overlappingVerticalRooms = InsertOverlappingVerticals( plan, this.SearchUp <IVerticalFeatureContainer, IVerticalFeatureContainer>(a => a, typeof(IBuildingContainer)).Overlapping(FloorIndex, false) ); var verticals = CreateFloorPlan(plan, overlappingVerticalRooms, constrainedVerticalElements).ToArray(); _plan = plan.Freeze(); PlanFrozen(_plan); //Create nodes for all the vertical elements which started on this floor CreateVerticalNodes(verticals); //Create Floor and ceiling (with holes for vertical sections) CreateFloors(bounds, geometry, verticals, HierarchicalParameters.DefaultCeilingMaterial(Random)); CreateCeilings(bounds, geometry, verticals, HierarchicalParameters.DefaultCeilingMaterial(Random)); //Create room scripts CreateRoomNodes(roomOffsetY, _roomHeight, _plan); //Create external facades (subsections of building over this floor facade) var externalFacades = CreateExternalFacades(bounds, _plan); //Create facades for rooms var dist = hierarchicalParameters.ExternalWallThickness(Random); CreateRoomFacades(externalFacades, roomOffsetY, dist, _plan); }
private void MaterializeMesh(Mesh <IVertexBuilder, IHalfEdgeBuilder, IFaceBuilder> mesh) { Contract.Requires(mesh != null); //Generate default footpath data HierarchicalParameters.RoadSidewalkHeight(Random); HierarchicalParameters.RoadSidewalkWidth(Random); HierarchicalParameters.RoadLaneWidth(Random); HierarchicalParameters.RoadSidewalkMaterial(Random); //Generate default building data HierarchicalParameters.MaximumBuildingHeight(Random); //Attach builders to each part of the topological mesh foreach (var vertex in mesh.Vertices.Where(v => v.Tag == null)) { vertex.Tag = CreateVertexBuilder(vertex); } foreach (var halfEdge in mesh.HalfEdges.Where(e => e.IsPrimaryEdge && e.Tag == null)) { halfEdge.Tag = CreateHalfEdgeBuilder(halfEdge, RoadLanes(halfEdge)); } foreach (var face in mesh.Faces.Where(f => f.Tag == null)) { face.Tag = CreateFaceBuilder(face); } //Create junctions (appropriate shape for different widths of road) foreach (var vertex in mesh.Vertices) { CreateJunction(Bounds.Height, vertex); } //Create roads (with appropriate widths) foreach (var edge in mesh.HalfEdges.Where(e => e.IsPrimaryEdge)) { CreateRoad(Bounds.Height, edge); } //Create blocks (with appropriate shapes for different road widths) foreach (var face in mesh.Faces) { CreateBlock(Bounds.Height, face); } }
public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters) { _internals = _designer.Internals(Random, HierarchicalParameters, ScriptReference.Find(Random)); HierarchicalParameters.Set(BuildingInternalsName, _internals); base.Subdivide(bounds, geometry, hierarchicalParameters); //Create the node which will create the building form the spec var building = (SpecBuilding)CreateChild(bounds, Quaternion.Identity, Vector3.Zero, new ScriptReference(typeof(SpecBuilding))); //Make sure sibling container subdivide before building foreach (var sibling in Parent.Children.OfType <IBuildingContainer>()) { building.AddPrerequisite(sibling, false); } //Copy neighbour data into building (from container) building.Neighbours = Neighbours; }
public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters) { this.CreateFlatPlane(geometry, "tarmac", bounds.Footprint, 1, -1); CreateFootpaths(bounds, geometry, hierarchicalParameters, hierarchicalParameters.RoadSidewalkMaterial(Random), HierarchicalParameters.RoadSidewalkHeight(Random)); }