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 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); }
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); }
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); }