예제 #1
0
        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);
        }
예제 #2
0
        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);
        }