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 IReadOnlyCollection <IBuildingFacade> CreateFacades(ISubdivisionGeometry geometry, IEnumerable <Footprint> footprints, INamedDataCollection hierarchicalParameters) { Contract.Requires(geometry != null); Contract.Requires(footprints != null); Contract.Requires(hierarchicalParameters != null); //Accumulate results var results = new List <IBuildingFacade>(); //Calculate external wall thickness var thickness = hierarchicalParameters.ExternalWallThickness(Random); var material = hierarchicalParameters.ExternalWallMaterial(Random); var footprintArr = footprints.OrderBy(a => a.BottomIndex).ToArray(); for (var i = 0; i < footprintArr.Length; i++) { var footprint = footprintArr[i]; var topIndex = (i == footprintArr.Length - 1) ? (_floors[_floors.Keys.Max()].FloorIndex) : (footprintArr[i + 1].BottomIndex - 1); //Sanity check that we have the correct number of facades if (footprint.Facades.Count != footprint.Shape.Count) { throw new InvalidOperationException(string.Format("Tried to created {0} facades for {1} walls", footprint.Facades.Count, footprint.Shape.Count)); } //Generate wall sections to fill in Vector2[] inner; IReadOnlyList <IReadOnlyList <Vector2> > corners; var sections = footprint.Shape.Sections(thickness, out inner, out corners); //Create the tiny bits of facade in the corners CreateCornerFacades(geometry, footprint, topIndex, corners, material); //Now iterate through sides and create facades CreatePrimaryFacades(footprint, sections, results); } return(results); }