public List <PatternDemand2d> Process() { _patternDemands = new List <PatternDemand2d>(); var addedBlanks = new List <Rect>(); var residualDemand = new Dictionary <Rect, int>(_demand); bool allDemandComplete = false; Rect newBlank = null; while (!allDemandComplete) { //var orderedSizes = residualDemand.Where(x => x.Value > 0).Select(x => x.Key).OrderBy(x => x.Height * x.Width).ToList(); //ordered by area var orderedSizes = _sort(residualDemand.Where(x => x.Value > 0).Select(x => x.Key).ToList()).ToList(); var stack = new Stack <Rect>(orderedSizes); stack.Reverse(); var pattern = new Pattern2d(); addedBlanks = new List <Rect>(); pattern.Master = _master; pattern.SetMasterSpace(); bool masterIsComplete = false; while (!masterIsComplete) { if (stack.Count == 0) { masterIsComplete = true; } else { newBlank = stack.Pop(); var tempDemand = residualDemand[newBlank]; if (tempDemand == 0) { continue; } bool blankFits = true; while (blankFits) { var blankCopy = new Rect(newBlank); if (pattern.Blanks.Count > 0) { SetSpaces(pattern, _master); } blankFits = false; var longSide = blankCopy.Width >= blankCopy.Width ? blankCopy.Width : blankCopy.Y; var shortSide = longSide == blankCopy.Width ? blankCopy.Height : blankCopy.Width; var orderedSpaces = pattern.Spaces.OrderBy(x => x.Y).ThenBy(x => x.X); foreach (var space in orderedSpaces) { if (FitsLongToHeight(blankCopy, space, longSide, shortSide)) // { blankFits = true; } else if (FitsShortToHeight(blankCopy, space, longSide, shortSide)) { blankFits = true; } if (blankFits == true) { blankCopy.X = space.X; blankCopy.Y = space.Y; pattern.Blanks.Add(blankCopy); if (!addedBlanks.Contains(newBlank)) { addedBlanks.Add(newBlank); } tempDemand--; break; } } if (tempDemand == 0) { break; } } } if (masterIsComplete) { if (pattern.Blanks.Count > 0) { SetSpaces(pattern, _master); } var max = MaxPatterns(pattern, residualDemand, addedBlanks); foreach (var i in addedBlanks) { var sub = max * pattern.Blanks.Count(x => x.Equals(i)); residualDemand[i] -= sub; } _patternDemands.Add(new PatternDemand2d { Pattern = pattern, Demand = max }); if (residualDemand.Count(x => x.Value > 0) == 0) { allDemandComplete = true; } } } } return(_patternDemands); }
public List <PatternDemand2d> Process(Dictionary <Rect, int> demand, Func <List <Rect>, List <Rect> > sort, Rect master, Predicate <int> rotate) { _patternComplete = new Dictionary <Pattern2d, bool>(); _patternDemands = new List <PatternDemand2d>(); //return this var addedBlanks = new List <Rect>(); var residualDemand = new Dictionary <Rect, int>(demand); bool allDemandComplete = false; Rect newBlank = null; while (!allDemandComplete) { if (residualDemand.Sum(x => x.Value) == 0) { break; } //var orderedSizes = residualDemand.Where(x => x.Value > 0).Select(x => x.Key).OrderBy(x => x.Height * x.Width).ToList(); //ordered by area var orderedSizes = sort(residualDemand.Where(x => x.Value > 0).Select(x => x.Key).ToList()).ToList(); //sort blanks, remove demand = 0 var stack = new Stack <Rect>(orderedSizes); //choose pattern to fill based on largest space if (_patternDemands.Count(x => x.Pattern.Blanks.Count == 16) > 0) { } foreach (var pat in _patternDemands) { if (!_patternComplete.ContainsKey(pat.Pattern)) { } } var patsBySumOfUsedArea = _patternDemands.OrderBy(x => x.Pattern.Blanks.Sum(z => z.Height * z.Width)); var parentPatterns = patsBySumOfUsedArea .Where(x => !_patternComplete[x.Pattern]) .Select(x => x.Pattern).ToList();//order by largest area of space that's not complete var parentPattern = parentPatterns.FirstOrDefault(); var isNewPattern = false; if (parentPattern == null) { parentPattern = new Pattern2d(); //_patternDemands.Add(new PatternDemand2d { Pattern = parentPattern, Demand = int.MaxValue }); //_patternComplete.Add(parentPattern, false); parentPattern.Master = master; parentPattern.SetMasterSpace(); isNewPattern = true; parentPatterns.Add(parentPattern); } //_patternMaxCount.Add(pattern, int.MaxValue); var newPattern = parentPattern.GetCopy(); addedBlanks = new List <Rect>(); bool masterIsComplete = false; bool blankFits = false; var tryCount = 0; //used in rotate, rotate first, rotate first 2 etc if (stack.Count == 0) { masterIsComplete = true; } else { foreach (var p in parentPatterns) { foreach (var size in orderedSizes) { newBlank = size; parentPattern = p; newPattern = parentPattern.GetCopy(); blankFits = false; if (stack.Count == 0) { } if (newBlank.Width == 48) { } var tempDemand = residualDemand[newBlank]; if (tempDemand == 0) { continue; //pop next blank } var blankCopy = new Rect(size); if (rotate(tryCount)) { blankCopy.Rotate(); } //if (pattern.Blanks.Count > 0) //_algservice.SetSpaces(pattern, master); var longSide = blankCopy.Width >= blankCopy.Width ? blankCopy.Width : blankCopy.Y; var shortSide = longSide == blankCopy.Width ? blankCopy.Height : blankCopy.Width; var orderedSpaces = parentPattern.Spaces.OrderBy(x => x.Y).ThenBy(x => x.X); foreach (var space in orderedSpaces) { if (_algservice.FitsWidthToWidth(blankCopy, space)) // { blankFits = true; } else if (_algservice.FitsWidthToHeight(blankCopy, space)) { blankCopy.Rotate(); blankFits = true; } if (blankFits == true) { blankCopy.X = space.X; blankCopy.Y = space.Y; newPattern.Blanks.Add(blankCopy); //if (!addedBlanks.Contains(newBlank)) addedBlanks.Add(newBlank); tempDemand--; break; } } if (blankFits) { break; } } } if (!blankFits && !isNewPattern) { newPattern = new Pattern2d(); //_patternDemands.Add(new PatternDemand2d { Pattern = parentPattern, Demand = int.MaxValue }); //_patternComplete.Add(parentPattern, false); newPattern.Master = master; newPattern.SetMasterSpace(); isNewPattern = true; _patternComplete.Add(newPattern, false); AddPatternDemand(newPattern, 1); continue; } if (newPattern.Blanks.Count(x => x.Height == 48 && x.Width == 48) == 1) { } var samePattern = _patternDemands.FirstOrDefault(x => x.Pattern.Equals(newPattern)); var parentPatDemand = _patternDemands.FirstOrDefault(x => x.Pattern.Equals(parentPattern)); if (samePattern != null) { samePattern.Demand++; residualDemand[newBlank]--; if (!isNewPattern) { parentPatDemand.Demand--; } } else { if (!isNewPattern) { parentPatDemand.Demand--; AddPatternDemand(newPattern, 1); residualDemand[newBlank]--; } else //new pattern without any same already added { //RemovePatternFromDemands(parentPattern); //_patternComplete.Remove(parentPattern); AddPatternDemand(newPattern, 1); residualDemand[newBlank]--; } _patternComplete.Add(newPattern, false); } if (!isNewPattern && parentPatDemand.Demand == 0) { RemovePatternFromDemands(parentPattern); _patternComplete.Remove(parentPattern); } //SubtractDemand(parentPattern, newPattern, newBlank, residualDemand); _algservice.SetSpaces(parentPattern, master); _algservice.SetSpaces(newPattern, master); var completedPat = new List <Pattern2d>(); foreach (var pd in _patternComplete.Where(x => x.Value == false)) { if (!DoAnyBlanksFit(pd.Key, residualDemand.Where(x => x.Value > 0).Select(x => x.Key).ToList())) { completedPat.Add(pd.Key); } } completedPat.ForEach(x => _patternComplete[x] = true); } _algservice.SetSpaces(parentPattern, master); _algservice.SetSpaces(newPattern, master); //if (blankFits == true) { /* * if (masterIsComplete) * { * if (pattern.Blanks.Count > 0) * _algservice.SetSpaces(pattern, master); * var max = _algservice.MaxPatterns(pattern, residualDemand, addedBlanks); * foreach (var i in addedBlanks) * { * var sub = max * pattern.Blanks.Count(x => x.Equals(i)); * residualDemand[i] -= sub; * * } * _patternDemands.Add(new PatternDemand2d { Pattern = pattern, Demand = max }); * if (residualDemand.Count(x => x.Value > 0) == 0) * allDemandComplete = true; * }*/ } } return(_patternDemands); }