public void CircleInSquare_SelectsOne() { List <Brep> TestEnv = BrepFactory.CircleInSquare(); Brep testCircle = TestEnv[0]; Brep testSquare = TestEnv[1]; List <Brep> allRegions = Breps.SplitTwoBreps(testSquare, testCircle); List <Brep> resultGeometry = Logic.Relationships.Select.FloorFromCore(allRegions, testCircle); Assert.AreEqual(resultGeometry.Count, 1); }
public void CircleWithTransverseRectangle_SelectsTwo() { List <Brep> TestEnv = BrepFactory.CircleWithTransverseRectangle(); Brep testCircle = TestEnv[0]; Brep testRectangle = TestEnv[1]; List <Brep> allRegions = Breps.SplitTwoBreps(testCircle, testRectangle); List <Brep> resultGeometry = Logic.Relationships.Select.FloorFromCore(allRegions, testRectangle); Assert.AreEqual(resultGeometry.Count, 2); }
public static List <Brep> NotExemptRegions(List <Brep> baseRegions, List <Brep> exemptRegions) { List <Brep> validRegions = baseRegions; foreach (Brep exemption in exemptRegions) { List <Brep> latestTrimmedRegions = Breps.TrimAllIntersections(validRegions, exemption); validRegions = latestTrimmedRegions; } return(validRegions); }
public void SquareWithCircumscribedCircle_SelectsFour() { List <Brep> TestEnv = BrepFactory.SquareWithCircumscribedCircle(); Brep testCircle = TestEnv[1]; Brep testSquare = TestEnv[0]; List <Brep> allRegions = Breps.SplitTwoBreps(testCircle, testSquare); List <Brep> resultGeometry = Logic.Relationships.Select.FloorFromCore(allRegions, testSquare); Console.WriteLine(allRegions.Count); Console.WriteLine(testSquare.GetArea()); Console.WriteLine(testCircle.GetArea()); Assert.AreEqual(resultGeometry.Count, 4); }
/// <summary> /// Identify class methods parse data from TestFitPackage to prepare for calculations. /// Geometry is sent to Select class methods for processing. Each select method is solving a limited relationship problem. /// While Select methods may be over-specific and overlap with each other sometimes, they're just different groupings of all other general methods. /// Structure allows for quick readability and for Select methods to be directly tested without having to set up a whole test fit. /// </summary> /// <param name="tf"></param> /// <returns></returns> public static List <Brep> FloorPlateRegions(TestFitPackage tf) { //Parse floor and core profiles from TestFitPackage. Curve baseCurve = tf.FloorPlanPackage.FloorProfile; Curve coreCurve = tf.FloorPlanPackage.CoreProfile; Brep baseSurface = Brep.CreatePlanarBreps(baseCurve)[0]; Brep coreSurface = Brep.CreatePlanarBreps(coreCurve)[0]; List <Brep> AllRegions = Breps.SplitTwoBreps(baseSurface, coreSurface); //Determine base floor plate region. List <Brep> ValidFloorRegions = Select.FloorFromCore(AllRegions, coreSurface); return(ValidFloorRegions); }
public void CircleInSquare_NotCore() { List <Brep> TestEnv = BrepFactory.CircleInSquare(); Brep testCircle = TestEnv[0]; Brep testSquare = TestEnv[1]; List <Brep> allRegions = Breps.SplitTwoBreps(testSquare, testCircle); List <Brep> resultGeometry = Logic.Relationships.Select.FloorFromCore(allRegions, testCircle); double resultArea = resultGeometry[0].GetArea(); double profileArea = testSquare.GetArea(); double coreArea = testCircle.GetArea(); double difference = (profileArea - coreArea) - resultArea; bool tolerated = (difference < 0.01) ? true : false; Assert.IsTrue(tolerated); }
public void CircleWithTransverseRectangle_NotCore() { List <Brep> TestEnv = BrepFactory.CircleWithTransverseRectangle(); Brep testCircle = TestEnv[0]; Brep testRectangle = TestEnv[1]; List <Brep> allRegions = Breps.SplitTwoBreps(testCircle, testRectangle); List <Brep> resultGeometry = Logic.Relationships.Select.FloorFromCore(allRegions, testRectangle); Point3d coreCenter = Logic.Utils.GetRegionCenter(testRectangle); foreach (Brep region in resultGeometry) { Point3d regionCenter = Logic.Utils.GetRegionCenter(region); if (regionCenter.DistanceTo(coreCenter) < .05) { Assert.Fail(); } } }
public static List <Brep> NotCirculationRegions(List <Brep> baseRegions, List <Brep> exemptRegions) { List <Brep> validRegions = baseRegions; List <Brep> validRegionsCache = new List <Brep>(); foreach (Brep exemption in exemptRegions) { for (int i = validRegions.Count - 1; i >= 0; i--) { List <Brep> splitOperation = Breps.SplitTwoBreps(validRegions[i], exemption); if (splitOperation.Count < 1) { continue; } foreach (Brep splitBrep in splitOperation) { //Remove any regions coincident with circulation. (Can be more than one.) Point3d regionCenter = Utils.GetRegionCenter(splitBrep); if (regionCenter.DistanceTo(exemption.ClosestPoint(regionCenter)) < 0.1) { //Do nothing. } else { validRegionsCache.Add(splitBrep); } } } validRegions = validRegionsCache; validRegionsCache.Clear(); } return(validRegions); }
/// <summary> /// Breaks initial zones into generally rectangular pieces. /// Subdivides those pieces into rooms based on program sizes and quotas. /// </summary> /// <param name="zm"></param> /// <param name="pm"></param> public static void RoomConfiguration(ZoneManifest zm, ProgramManifest pm) { foreach (ZonePackage zone in zm.Zones) { zone.Rooms = new List <RoomPackage>(); List <Brep> rectangularizedZoneRegions = Breps.Rectangularize(zone); //Slice rectangularized zone regions into room lanes. foreach (Brep region in rectangularizedZoneRegions) { Update.Room.LaneConfiguration(region, zone, pm); } //Perform final measurements and prepare rooms for population. for (int i = 0; i < zone.Rooms.Count; i++) { var room = zone.Rooms[i]; Update.Room.Orientation(room, zone); Update.Room.ProgramHint(room, zone, i); } } }
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)); } }