public static SmSpace[] Jitter(List <SmSpace> initList, double jitterFactor) { int[] array = new int[initList.Count]; double maxDistance = jitterFactor * array.Length; Random r = new Random(42); for (int i = 0; i < array.Length; i++) { double min = Math.Max(i - maxDistance, 0); double max = Math.Min(i + maxDistance, array.Length); var item = r.Next((int)min, (int)max); array[i] = item; } var newSpaces = new SmSpace[array.Length]; for (int i = 0; i < array.Length; i++) { newSpaces[i] = new SmSpace(initList[i].type, array[i], false, initList[i].designArea); newSpaces[i].sorter = array[i]; } var outSpaces = newSpaces.OrderBy(s => s.sorter).ToArray(); return(outSpaces); }
public PlacementEngine(List <SmSpace> spaces, double leaseDepth, List <SmLevel> levels, double splitInterval, IList <Polygon> corePolys = null) { _leaseOffset = leaseDepth * _worldScale; medOffset = _leaseOffset * 0.5; splitInterval *= _worldScale; inLvls = levels; coreCrvs = new List <Polygon>(); if (corePolys != null) { foreach (var p in corePolys) { var c = p; coreCrvs.Add(c); } } firstLevel = inLvls.OrderBy(l => l._elevation).ToList()[0]; firstLevel._index = 0; boundary = firstLevel._boundaries[0].mainPoly; // System.IO.File.WriteAllText( "D:/Hypar/offsetTest.json", Newtonsoft.Json.JsonConvert.SerializeObject(boundary)); // var orientation = boundary.ClosedCurveOrientation(Vector3d.ZAxis); var ssspaces = SmSpace.Jitter(spaces, 0.99).ToList(); distinctSpaces = ssspaces.GroupBy(x => x.type).Select(y => y.First()).ToList(); _areas = ssspaces.OrderBy(s => s.sorter).Select(s => s.designArea).ToList(); _spaces = ssspaces.OrderBy(s => s.sorter).Select(s => s.roomNumber.ToString()).ToList(); _PlaceableSpaces = ssspaces; Polyline tempPoly = boundary.ToPolyline(); _boundaryPoly = tempPoly; _BoundaryCurve = boundary.ToPolyline(); Console.WriteLine(boundary.ToString()); _Core = InitCoreCrv(boundary); _SplitInterval = splitInterval; _GlobalIndex = 0; _MainFace = boundary.Difference(_Core); InitWalls(); _PlacedProgramSpaces = new List <SmSpace>(); }
public int CompareTo(object obj) { if (obj == null) { return(1); } SmSpace otherSpace = obj as SmSpace; if (otherSpace != null) { return(this.type.CompareTo(otherSpace.type)); } else { throw new ArgumentException("Object is not a SmSpace"); } }
public void ProcessPolygons(Dictionary <int, List <SmSlivers> > PolygonTree, List <string> spaceNames) { _ProcessedProgram = new Dictionary <int, SmSpace>(); //SmSpace[] initSpaces = new SmSpace[PolygonTree.Keys.Count()]; try { for (int i = 0; i < PolygonTree.Keys.Count; i++) { if (PolygonTree.TryGetValue(i, out var branchSpaces)) { if (branchSpaces != null && branchSpaces.Count > 0) { var branchPolygons = branchSpaces.Select(s => s._poly).ToList(); var rawUnion = Polygon.UnionAll(branchPolygons)[0]; if (rawUnion != null) { if (Math.Abs(rawUnion.Area()) / _PlaceableSpaces[i].designArea >= 0.25) { var space = new SmSpace(_PlaceableSpaces[i].type, _PlaceableSpaces[i].roomNumber, true, _PlaceableSpaces[i].designArea, rawUnion); space.roomLevel = firstLevel; space.sorter = i; _ProcessedProgram.Add(i, space); } } } } } } catch (Exception e) { Console.WriteLine(e.ToString()); } FirstFloorSpaces = new List <SmSpace>(); FirstFloorSpaces.AddRange(_ProcessedProgram.Values.ToList()); }
public void TryPlace(SmSpace space, int spaceIndex, List <SmSlivers> stSubs, out string report) { //Console.WriteLine("TOTAL SLIVER COUNT: "+ semiSlivers.Count); //Console.WriteLine("TOTAL stubs: "+ stSubs.Count); bool Placed = false; var areaAccumulated = 0.0; report = "Placeholder!"; double threshold = _leaseOffset * _SplitInterval; //if(!inRevit) threshold *= (_worldScale * _worldScale); while (Placed == false) { if (_GlobalIndex >= semiSlivers.Count - 1) { break; } //Console.WriteLine("current GLOBAL: " + _GlobalIndex); //Console.WriteLine($"index: {spaceIndex}, areaAccum: {areaAccumulated}"); if (Math.Abs(areaAccumulated - space.designArea) <= threshold) { if (_GlobalIndex >= semiSlivers.Count - 1) { break; } if (indecesforPurgin.Contains(stSubs[_GlobalIndex]._stIndex)) { bool placedExtras = false; while (placedExtras == false) { if (_GlobalIndex >= semiSlivers.Count - 1) { break; } if (indecesforPurgin.Contains(stSubs[_GlobalIndex]._stIndex) == false) { placedExtras = true; Placed = true; } else { int twIndex = stSubs[_GlobalIndex]._shiftIndex; // if dictionary index key exists if (_PlacedProgramSlivers.TryGetValue(spaceIndex, out var listSpaces)) { listSpaces.Add(stSubs[twIndex]); // var newList = new List<Polygon>(); // newList.AddRange(listSpaces); // _PlacedProgramSlivers[spaceIndex] = newList; } //if it doesnt... else { _PlacedProgramSlivers.Add(spaceIndex, new List <SmSlivers>() { stSubs[twIndex] }); } areaAccumulated += Math.Abs(stSubs[twIndex]._poly.Area()); _GlobalIndex++; } } } report = stSubs[_GlobalIndex]._shiftIndex.ToString(); Placed = true; break; } if (_GlobalIndex >= this.semiSlivers.Count - 1) { break; } int twIndexy = stSubs[_GlobalIndex]._shiftIndex; // if dictionary index key exists if (_PlacedProgramSlivers.TryGetValue(spaceIndex, out var _listSpaces)) { _listSpaces.Add(stSubs[twIndexy]); // var newList = new List<Polygon>(); // newList.AddRange(_listSpaces); // _PlacedProgramSlivers[spaceIndex] = newList; } //if it doesnt... else { _PlacedProgramSlivers.Add(spaceIndex, new List <SmSlivers>() { stSubs[twIndexy] }); } areaAccumulated += Math.Abs(stSubs[twIndexy]._poly.Area()); _GlobalIndex++; } }
/// <summary> /// Adds 'placed spaces' to PlacedSpaces list. /// </summary> /// <param name="firstLvlUnits"></param> /// <param name="offCrv"></param> /// <param name="mainCrv"></param> /// <param name="level"></param> /// <returns></returns> public bool TryProject(List <SmSpace> firstLvlUnits, Polygon offCrv, Polygon mainCrv, SmLevel level) { bool worked = false; for (int i = 0; i < firstLvlUnits.Count; i++) { var dupCrv = new Polygon(firstLvlUnits[i].poly.Vertices); var movedCrv = dupCrv.TransformedPolygon(new Transform(new Vector3(0, 0, offCrv.Centroid().Z))); var pts = movedCrv.Vertices.ToList(); // getting unit crv poly pts string mess; bool inBool = AllPtsIn(offCrv, pts, out mess); int s = -1; var newRmNum = firstLvlUnits[i].roomNumber.ToString().Remove(0, 1).Insert(0, level._index.ToString()); int parsedRmNum; if (Int32.TryParse(newRmNum, out parsedRmNum)) { s = parsedRmNum; } if (inBool) { var unitN = new SmSpace(firstLvlUnits[i].type, s, true, firstLvlUnits[i].designArea, movedCrv); unitN.roomLevel = level; PlacedSpaces.Add(unitN); worked = true; } else if (inBool == false && mess == "trim") { Polygon crvOut; if (TrimKeep(mainCrv, movedCrv, level, out crvOut)) { var designArea = firstLvlUnits[i].designArea; //if it is roughly the same size as the planned unit: if (Math.Abs(crvOut.Area() / designArea) >= 0.75) { var unitN = new SmSpace(firstLvlUnits[i].type, s, true, firstLvlUnits[i].designArea, crvOut); unitN.roomLevel = level; PlacedSpaces.Add(unitN); worked = true; } // else //try finding a closest best unit fit // { // var closestDistinctUnit = FindClosestUnitType(crvOut, distinctSpaces); // if (Math.Abs(crvOut.Area() / closestDistinctUnit.designArea) >= 0.75) // { // var unitN = new SmSpace(closestDistinctUnit.type, s, true, closestDistinctUnit.designArea, crvOut); // unitN.roomLevel = level; // PlacedSpaces.Add(unitN); // worked = true; // } // } } } } return(worked); }