public static void Affinity(TestFitPackage tf) { foreach (ProgramPackage program in tf.ProgramPackages) { int accessibility = 0; foreach (Char dir in program.AccessDirections) { if (dir == '1') { accessibility++; } } program.Affinity = new List <int>(); if (program.IsPrivate && accessibility <= 1) { program.Affinity.Add(1); } else if (!program.IsPrivate && accessibility == 1) { program.Affinity.Add(2); program.Affinity.Add(3); } else if (accessibility == 4) { program.Affinity.Add(3); program.Affinity.Add(2); } } }
public static CirculationPackage CirculationTypes(TestFitPackage tf) { //Trim circulation axis to floor plate region, shatter, and characterize. List <Curve> circulationAxis = tf.FloorPlanPackage.CirculationAxisCurves; Curve floorProfile = tf.FloorPlanPackage.FloorProfile; List <Curve> trimmedCirculationAxis = new List <Curve>(); foreach (Curve axis in circulationAxis) { Curve trimmedAxis = Curves.TrimWithClosedCurve(floorProfile, axis); trimmedCirculationAxis.Add(trimmedAxis); } //Shatter trimmed axis. List <Curve> circulationSegments = Curves.ShatterToSegments(trimmedCirculationAxis); //Characterize segments and format as CirculationPackage. CirculationPackage classifiedAxisSegments = Select.CirculationConfig(tf, circulationSegments); //Unify main curves before offset. List <Curve> simplifiedCurves = Curves.JoinColinear(classifiedAxisSegments.MainCurves); classifiedAxisSegments.MainCurves = simplifiedCurves; return(classifiedAxisSegments); }
public static void Priority(TestFitPackage tf) { for (int i = 0; i < tf.ProgramPackages.Count; i++) { tf.ProgramPackages[i].Priority = i; } }
public static TestFitPackage DieFive(double side) { //A simple test fit configuration modeled after the five side of a since die. //Center point is core. //Other four are structure. //TODO: Implement circulation. double frc = side / 6; double r = side / 5; Curve floorProfile = RegionsFactory.RectangleWHC(side, side, Point3d.Origin); Curve coreCurve = RegionsFactory.CenteredCircleRadius(r); List <Curve> strCurves = new List <Curve>(); strCurves.Add(RegionsFactory.CircleCR(new Point3d(2 * frc, 2 * frc, 0), r)); strCurves.Add(RegionsFactory.CircleCR(new Point3d(-2 * frc, 2 * frc, 0), r)); strCurves.Add(RegionsFactory.CircleCR(new Point3d(-2 * frc, -2 * frc, 0), r)); strCurves.Add(RegionsFactory.CircleCR(new Point3d(2 * frc, -2 * frc, 0), r)); FloorPlanPackage FloorPlan = new FloorPlanPackage(floorProfile, coreCurve, null, strCurves, null, null); TestFitPackage TestFit = new TestFitPackage(FloorPlan, null); return(TestFit); }
public static CirculationPackage CirculationConfig(TestFitPackage tf, List <Curve> axisSegments) { //Classifications. List <bool> TouchesEdge = new List <bool>(); List <bool> TouchesCore = new List <bool>(); List <bool> IsLong = new List <bool>(); double avgLength = Utils.GetAverageLength(axisSegments); Interval lengthRange = Utils.GetLengthRange(axisSegments); for (int i = 0; i < axisSegments.Count; i++) { bool floorProfileEdgeTest = Confirm.CurvesIntersect(axisSegments[i], tf.FloorPlanPackage.FloorProfile, true); TouchesEdge.Add(floorProfileEdgeTest); bool coreEdgeTest = Confirm.CurvesIntersect(axisSegments[i], tf.FloorPlanPackage.CoreProfile, true); TouchesCore.Add(coreEdgeTest); bool isLong = (axisSegments[i].GetLength() > avgLength) ? true : false; IsLong.Add(isLong); } List <Curve> MainCirculationCurves = new List <Curve>(); List <Curve> OptionalCirculationCurves = new List <Curve>(); for (int i = 0; i < axisSegments.Count; i++) { if (TouchesCore[i] == false && TouchesEdge[i] == false) { MainCirculationCurves.Add(axisSegments[i]); } else if (TouchesCore[i] == true) { MainCirculationCurves.Add(axisSegments[i]); } else if (TouchesEdge[i] == true && IsLong[i] == true) { MainCirculationCurves.Add(axisSegments[i]); } else { OptionalCirculationCurves.Add(axisSegments[i]); } } bool hasOneAxis = Confirm.AllAxisColinear(MainCirculationCurves); if (hasOneAxis) { Curve singleAxisCurve = Curves.ExtendToBounds(tf.FloorPlanPackage.FloorProfile, MainCirculationCurves[0]); MainCirculationCurves.Clear(); MainCirculationCurves.Add(singleAxisCurve); } CirculationPackage ClassifiedCirculation = new CirculationPackage(MainCirculationCurves, OptionalCirculationCurves); return(ClassifiedCirculation); }
public void CircleInSquare_CircleIsSmaller() { TestFitPackage TestEnv = TestFitFactory.DieFive(1); bool result = Logic.Relationships.Confirm.TestFit.CoreIsSmaller(TestEnv); Assert.IsTrue(result); }
public void DieFive_ReturnsOneRegion() { TestFitPackage TestEnv = TestFitFactory.DieFive(1); List <Brep> resultGeometry = Logic.Relationships.Identify.FloorPlateRegions(TestEnv); bool testResult = (resultGeometry.Count == 1) ? true : false; Assert.IsTrue(testResult); }
protected override void SolveInstance(IGH_DataAccess DA) { TestFitPackage tf = null; DA.GetData(0, ref tf); bool active = false; DA.GetData(1, ref active); if (!active) { return; } //Parse FloorPlanPackage for main working area(s). List <Brep> baseFloorRegions = Identify.FloorPlateRegions(tf); //Categorize circulation segments into "main" and "option" types. CirculationPackage circ = Identify.CirculationTypes(tf); //Sanitization: generate and remove all obstacles from workable space. (Circulation, Structure, etc.) List <Brep> validFloorRegions = Identify.AvailableFloorSpace(baseFloorRegions, tf, circ); //First-pass subdivision: coarse division based on proximity and proportion. List <Brep> optimizedFloorRegions = Identify.OptimalFloorSpaceConfiguration(validFloorRegions, tf); //Parse ProgramPackage(s) and format information/relationships into manifest. ProgramManifest pm = Identify.ProgramManifest(tf); //Assign program targets to each zone, based on priority + affinity, and subdivide to rooms. ZoneManifest zm = Identify.ZoneManifest(optimizedFloorRegions, pm, tf); //Populate zones and solve test fit. Terrain.Solution(zm, pm); List <string> debugText = new List <string>(); foreach (ZonePackage zone in zm.Zones) { string output = null; foreach (int target in zone.ProgramTargets) { output = output + target + " "; } debugText.Add(output); } DA.SetData(0, pm); DA.SetData(1, zm); DA.SetDataList(2, debugText); }
//Tests specifically about fidelity of the TestFit problem proposed. public static bool Fidelity(TestFitPackage tf) { List <bool> testResults = new List <bool>(); //Tests may get a little redundant here for the sake of a readable list of restrictions. testResults.Add(MainProfileIsClosed(tf)); testResults.Add(CoreProfileIsClosed(tf)); testResults.Add(CoreIsSmaller(tf)); testResults.Add(AllStructureCurvesAreClosed(tf)); return(true); }
public static bool CoreIsSmaller(TestFitPackage tf) { Brep floor = Brep.CreatePlanarBreps(tf.FloorPlanPackage.FloorProfile)[0]; Brep core = Brep.CreatePlanarBreps(tf.FloorPlanPackage.CoreProfile)[0]; double floorArea = floor.GetArea(); double coreArea = core.GetArea(); bool isSmaller = (coreArea < floorArea) ? true : false; return(isSmaller); }
public static bool AllStructureCurvesAreClosed(TestFitPackage tf) { List <Curve> curvesToCheck = tf.FloorPlanPackage.StructureProfiles; foreach (Curve curve in curvesToCheck) { if (curve.IsClosed != true) { return(false); } } return(true); }
/// <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 static void Distribution(TestFitPackage tf) { List <ProgramPackage> programs = tf.ProgramPackages; int maximizedCount = 0; double nonMaximizedUse = 0; foreach (ProgramPackage program in programs) { if (program.Quota == 0) { maximizedCount++; } else { double quotaArea = program.OccupationArea * program.Quota; double usage = quotaArea / tf.FloorPlanPackage.BaseArea; nonMaximizedUse = nonMaximizedUse + usage; } } double maximizedUse = (maximizedCount != 0) ? (1 - nonMaximizedUse) / maximizedCount : 0; List <double> distributions = new List <double>(); for (int i = 0; i < tf.ProgramPackages.Count; i++) { if (programs[i].Quota == 0) { distributions.Add(maximizedUse * 100); } else { double quotaArea = Brep.CreatePlanarBreps(programs[i].OccupationBoundary)[0].GetArea() * programs[i].Quota; double usage = quotaArea / tf.FloorPlanPackage.BaseArea; distributions.Add(usage * 100); } } for (int i = 0; i < programs.Count; i++) { programs[i].Distribution = distributions[i]; } }
public static void Target(TestFitPackage tf) { foreach (ProgramPackage program in tf.ProgramPackages) { if (program.Quota != 0) { program.Target = program.Quota; } else { double availableArea = (program.Distribution / 100) * tf.FloorPlanPackage.BaseArea; double target = availableArea / program.OccupationArea; program.Target = Convert.ToInt32(Math.Round(target)); } program.Remaining = program.Target; } }
public static ProgramManifest ProgramManifest(TestFitPackage tf) { //Parse base statistics from floor areas. var approximateTotalArea = tf.FloorPlanPackage.BaseArea; //Perform measurements and confirmations. var isPossible = Confirm.Program.RequestIsPossible(tf.ProgramPackages, approximateTotalArea); var maximizedCount = Confirm.Program.MaximizedCount(tf.ProgramPackages); Update.Program.Distribution(tf); Update.Program.Target(tf); Update.Program.Affinity(tf); Update.Program.Enmity(tf); Update.Program.Priority(tf); ProgramManifest pm = new ProgramManifest(tf.ProgramPackages, isPossible, maximizedCount); pm.AllAdvice = tf.AllAdvice; return(pm); }
protected override void SolveInstance(IGH_DataAccess DA) { FloorPlanPackage floorPlan = null; DA.GetData(0, ref floorPlan); List <ProgramPackage> programInfo = new List <ProgramPackage>(); DA.GetDataList(1, programInfo); TestFitPackage TestFit = new TestFitPackage(floorPlan, programInfo); //Perform tests for data fidelity. bool allTestsPassed = Confirm.TestFit.Fidelity(TestFit); if (!allTestsPassed) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Test Fit Package is not valid."); } DA.SetData(0, TestFit); }
protected override void SolveInstance(IGH_DataAccess DA) { ProgramManifest pmOld = null; if (!DA.GetData(0, ref pmOld)) { return; } var pm = Utils.DeepClone(pmOld); ZoneManifest zmOld = null; if (!DA.GetData(1, ref zmOld)) { return; } var zm = Utils.DeepClone(zmOld); var allAdvice = new List <AdvicePackage>(); DA.GetDataList(2, allAdvice); if (pm.AllAdvice != null) { allAdvice.AddRange(pm.AllAdvice); } foreach (AdvicePackage advice in allAdvice) { Logic.Update.Iteration.ApplyAdvice(advice, zm, pm); } var tf = new TestFitPackage(zm.FloorPlan, pm.ProgramPackages, allAdvice); DA.SetData(0, tf); }
public static List <Brep> AvailableFloorSpace(List <Brep> floorRegions, TestFitPackage tf, CirculationPackage circ) { //Parse exemption profiles. List <Curve> exemptionCurves = tf.FloorPlanPackage.ExemptionProfiles; List <Brep> exemptionRegions = new List <Brep>(); foreach (Curve exemption in exemptionCurves) { Brep exemptionSurface = Brep.CreatePlanarBreps(exemption)[0]; exemptionRegions.Add(exemptionSurface); } //Remove spaces designated by exemptions. List <Brep> nonExemptRegions = Select.NotExemptRegions(floorRegions, exemptionRegions); //Parse regions of core that need egress and circulation axis. List <Curve> coreAccessCurves = tf.FloorPlanPackage.CoreAccessCurves; List <Curve> circulationCurves = tf.FloorPlanPackage.CirculationAxisCurves; //Remove space for core access and egress requirements. Only if circulation axis do not already connect all egress requirements. List <Curve> coreCurvesToGiveEgress = Select.CoreCurvesWithoutEgress(coreAccessCurves, circulationCurves); if (coreCurvesToGiveEgress.Count != 0) { List <Curve> bestSourceOfEgress = Select.BestSourceOfEgress(coreCurvesToGiveEgress, circulationCurves); List <Brep> newExemptionsForEgress = Select.OrthogonalEgress(coreCurvesToGiveEgress, bestSourceOfEgress); //nonExemptRegions = newExemptionsForEgress; nonExemptRegions = Select.NotExemptRegions(nonExemptRegions, newExemptionsForEgress); } //Remove circulation zones of main circulation items. List <Curve> mainCirculationSegments = circ.MainCurves; List <Brep> circulationExemptions = new List <Brep>(); foreach (Curve segment in mainCirculationSegments) { int minDist = 4; Curve extendedSegment = segment.Extend(CurveEnd.Both, minDist / 2, CurveExtensionStyle.Line); Brep circRegion = Brep.CreatePlanarBreps(Curves.OffsetClosed(extendedSegment, minDist / 2, true))[0]; circulationExemptions.Add(circRegion); } //nonExemptRegions = Select.NotCirculationRegions(nonExemptRegions, circulationExemptions); nonExemptRegions = Select.NotExemptRegions(nonExemptRegions, circulationExemptions); //Remove columns. Still unsure if this is the best move. //Disabled for now, for performance reasons. Maybe check collision on population? List <Curve> structureObstacles = tf.FloorPlanPackage.StructureProfiles; List <Brep> structureExemptions = new List <Brep>(); foreach (Curve str in structureObstacles) { structureExemptions.Add(Brep.CreatePlanarBreps(str)[0]); } //nonExemptRegions = Select.NotExemptRegions(nonExemptRegions, structureExemptions); return(nonExemptRegions); }
public static ZoneManifest ZoneManifest(List <Brep> zonesToParse, ProgramManifest pm, TestFitPackage tf) { List <ZonePackage> zpList = new List <ZonePackage>(); double totalArea = 0; foreach (Brep zone in zonesToParse) { ZonePackage zp = new ZonePackage(zone); if (zp.BaseArea < 10) { //Stopgap solution for micro-zones generated by weird circulation corners. continue; } totalArea = totalArea + zp.BaseArea; EdgeCurves edgeCurvePackage = Select.ZoneEdgeCurves(zone, tf, zonesToParse); Update.Zone.EdgeClassification(zp, edgeCurvePackage); Update.Zone.Adjacencies(zp); Update.Zone.AffinityType(zp); zpList.Add(zp); } ZoneManifest zm = new ZoneManifest(zpList, totalArea) { FloorPlan = tf.FloorPlanPackage }; Update.Program.ZonePreference(pm, zm); Update.Zone.Popularity(zm, pm); Update.Zone.ProgramPriority(zm, pm); Update.Zone.ReservedArea(zm, pm); Update.Zone.ProgramTargets(zm, pm); Update.Zone.RoomConfiguration(zm, pm); return(zm); }
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); }
public static bool CoreProfileIsClosed(TestFitPackage tf) { return(tf.FloorPlanPackage.CoreProfile.IsClosed); }