public void CreateBuilding( Plane basePlane, double floorHeight, double?targetBuildingArea = null, int?floorCount = null, double width = 0, double length = 0, double depth = 0, bool isCurved = false, bool createCores = false, double hallwayToDepth = 0, double coreSizeFactorFloors = 0, double coreSizeFactorArea = 0) { Length = length; Width = width; Depth = depth; BasePlane = basePlane; FloorHeight = floorHeight; IsCurved = isCurved; this.hallwayToDepth = hallwayToDepth; this.coreSizeFactorFloors = coreSizeFactorFloors; this.coreSizeFactorArea = coreSizeFactorArea; using (var point = Point.ByCoordinates(Width / 2, Length / 2)) using (var zAxis = Vector.ZAxis()) { BaseCenter = Plane.ByOriginNormal(point, zAxis); } Setup(); Surface baseSurface = MakeBaseSurface(); if (baseSurface == null) { throw new ArgumentException("Could not create building shape."); } // Surface is constructed with lower left corner at (0,0). Move and rotate to given base plane. baseSurface = TransformFromOrigin(baseSurface); FloorArea = baseSurface.Area; if (floorCount != null) { FloorCount = (int)floorCount; } else if (targetBuildingArea != null) { FloorCount = (int)Math.Ceiling((double)targetBuildingArea / FloorArea); } else { throw new ArgumentException($"Either {nameof(floorCount)} or {nameof(targetBuildingArea)} is required."); } Mass = baseSurface.Thicken(FloorCount * FloorHeight, both_sides: false); TotalVolume = Mass.Volume; FacadeArea = Mass.Area - (2 * FloorArea); for (int i = 0; i < FloorCount; i++) { using (var offsetVector = Vector.ByCoordinates(0, 0, i * FloorHeight)) { Floors.Add(new[] { (Surface)baseSurface.Translate(offsetVector) }); FloorElevations.Add(BasePlane.Origin.Z + (i * FloorHeight)); } } using (var offsetVector = Vector.ByCoordinates(0, 0, FloorCount * FloorHeight)) { TopPlane = (Plane)BasePlane.Translate(offsetVector); } baseSurface.Dispose(); if (createCores) { var coreBases = MakeCoreSurface(); if (coreBases == null || coreBases.Count == 0) { NetFloors = Floors; return; } // Transform all cores from origin. foreach (var coreBase in coreBases) { using (var core = coreBase.Thicken(FloorCount * FloorHeight, both_sides: false)) { Cores.Add(TransformFromOrigin(core)); } coreBase.Dispose(); } // Cut cores out of floors. NetFloors = new List <Surface[]>(); foreach (var floor in Floors) { NetFloors.Add(Cores.Aggregate(floor, (f, core) => f.SelectMany( surface => surface.SubtractFrom(core)) .Cast <Surface>() .ToArray())); } } else { NetFloors = Floors; } }