public static List <Brep> OptimalFloorSpaceConfiguration(List <Brep> validFloorRegions, TestFitPackage tf) { Curve perimeterCurve = tf.FloorPlanPackage.FloorProfile; Curve coreCurve = tf.FloorPlanPackage.CoreProfile; List <Brep> zonesToSlice = new List <Brep>(); List <Brep> optimizedZones = new List <Brep>(); //Identify zones with irregular proximity or shape. foreach (Brep region in validFloorRegions) { bool intersectsPerimeter = Confirm.CurveRegionIntersection(perimeterCurve, region); bool intersectsCore = Confirm.CurveRegionIntersection(coreCurve, region); if (intersectsPerimeter && intersectsCore) { zonesToSlice.Add(region); } else { optimizedZones.Add(region); } } //Cut them into more manageable pieces. List <Curve> splitterCurves = Select.BestSplitterCurves(zonesToSlice, tf.FloorPlanPackage.CirculationAxisCurves, tf.FloorPlanPackage.CoreProfile); for (int i = 0; i < zonesToSlice.Count; i++) { List <Brep> splitBreps = Breps.SplitByCurve(zonesToSlice[i], splitterCurves[i]); foreach (Brep zone in splitBreps) { optimizedZones.Add(zone); } } //Identify donut zones (zones with a hole in the middle). for (int i = optimizedZones.Count - 1; i >= 0; i--) { bool isNotDonut = Confirm.RegionIsNotDonut(optimizedZones[i]); //Cut up the donuts. if (!isNotDonut) { List <Curve> donutSplitCurves = Select.DonutSplittingCurves(optimizedZones[i]); foreach (Curve crv in donutSplitCurves) { //RhinoDoc.ActiveDoc.Objects.AddCurve(crv); } List <Brep> unDonutZones = Breps.SplitByCurves(optimizedZones[i], donutSplitCurves); optimizedZones.RemoveAt(i); foreach (Brep newZone in unDonutZones) { optimizedZones.Add(newZone); } } } return(optimizedZones); }
/// <summary> /// Slices each zone into rectangular "lanes" based on dimensions of program targets. /// </summary> /// <param name="region"></param> /// <param name="zone"></param> /// <param name="pm"></param> public static void LaneConfiguration(Brep region, ZonePackage zone, ProgramManifest pm) { var zoneTargets = new List <int>(zone.ProgramTargets); var totalProjectedFill = new List <int>(); foreach (int target in zoneTargets) { totalProjectedFill.Add(0); } var regionInfo = new CurveBounds(Utils.GetBoundingBoxCurve(region)); var splitterCurves = new List <Curve>(); var sliceDirectionIsVertical = Confirm.RegionProportionIsVertical(region); var startVal = sliceDirectionIsVertical ? regionInfo.YMin : regionInfo.XMin; var maxVal = sliceDirectionIsVertical ? regionInfo.YMax : regionInfo.XMax; var activeSliceVal = startVal; var allLanePackages = new List <LanePackage>(); //Preflight checks. var targets = Confirm.Zone.TargetFulfilled(totalProjectedFill, zone.ProgramTargets); var inbounds = activeSliceVal < maxVal; //RhinoApp.WriteLine("Targets fulfilled: {0} | In bounds: {1}", targets, inbounds); while (!Confirm.Zone.TargetFulfilled(totalProjectedFill, zone.ProgramTargets) && activeSliceVal < maxVal) { //Slice lane based on remaining program. LanePackage lp = Select.NextLanePayload(zone, pm, totalProjectedFill, activeSliceVal, maxVal); allLanePackages.Add(lp); //RhinoApp.WriteLine("{0} => {1}", activeSliceVal, lp.SlicePosition); activeSliceVal = lp.SlicePosition; var splitter = sliceDirectionIsVertical ? new LineCurve(new Point2d(regionInfo.XMin, activeSliceVal), new Point2d(regionInfo.XMax, activeSliceVal)) : new LineCurve(new Point2d(activeSliceVal, regionInfo.YMax), new Point2d(activeSliceVal, regionInfo.YMin)); splitterCurves.Add(splitter); Update.Room.ProjectedFill(lp, region, splitterCurves, pm); for (int i = 0; i < lp.ProjectedFill.Count; i++) { totalProjectedFill[i] = totalProjectedFill[i] + lp.ProjectedFill[i]; } } zone.LanePackages = allLanePackages; var zoneSlices = Breps.SplitByCurves(region, splitterCurves); //RhinoApp.WriteLine("{0} splitter curves & {1} rooms.", splitterCurves.Count.ToString(), zoneSlices.Count); foreach (Brep lane in zoneSlices) { zone.Rooms.Add(new RoomPackage(lane, pm.ProgramPackages.Count)); } }