void OldLayoutResult::CheckAndCalcStat(scalar cutThickness, const Rect& rect, Stat* outStat) const { Stat stat; stat.MakeZero(); stat.Opilki += (double)rect.Size[!s] * (double)std::min(cutThickness, rect.Size[s] - (cut + cutThickness) * kratnostj + cutThickness); scalar detailsWithCutsLength = 0; unsigned cuts = 0; for(Details::const_iterator i = details.begin(); i != details.end(); i++) { detailsWithCutsLength += (i->size + cutThickness) * i->num; cuts += i->num; } stat.Opilki += ((cut + cutThickness) * kratnostj - cutThickness) * std::min(cutThickness, rect.Size[!s] - detailsWithCutsLength + cutThickness); stat.Opilki += (detailsWithCutsLength - cutThickness) * cutThickness * (kratnostj - 1); stat.Opilki += cut * cutThickness * (cuts - 1) * kratnostj; Stat remainStat; Rect remainRect; remainRect.Size[s] = std::max<scalar>((cut + cutThickness) * kratnostj - cutThickness, 0); remainRect.Size[!s] = std::max<scalar>(rect.Size[!s] - detailsWithCutsLength, 0); if(premain != 0) { premain->CheckAndCalcStat(cutThickness, remainRect, &remainStat); } else { remainStat.MakeZero(); remainStat.AddScrap(remainRect); } stat += remainStat; Stat recurseStat; Rect recurseRect; recurseRect.Size[s] = std::max<scalar>(rect.Size[s] - (cut + cutThickness) * kratnostj, 0); recurseRect.Size[!s] = rect.Size[!s]; if(precurse != 0) { precurse->CheckAndCalcStat(cutThickness, recurseRect, &recurseStat); } else { recurseStat.MakeZero(); recurseStat.AddScrap(recurseRect); } stat += recurseStat; *outStat = stat; }
bool ResultsGenerator::NextResult(Result& out) { // check if there are still remaining parts auto pRemain = m_remains.begin(); for (; pRemain != m_remains.end(); pRemain++) if (*pRemain > 0) break; if (pRemain == m_remains.end()) return false; // no more parts Result bestResult; Amounts bestRashod(m_remains.size()); bool first = true; m_layout2d.ResetCompletedCounter(); for (auto pSheet = m_sheets.begin(); pSheet != m_sheets.end(); pSheet++) { Stat stat; stat.MakeZero(); OldLayoutResult raskroy; Amounts rashod(m_remains.size()); if (!m_layout2d.Optimize(pSheet->rect, stat, 0, raskroy, rashod)) continue; if (bestResult.Statistics < stat || first) { bestResult.amount = m_remains / rashod; if (ControlRemains && bestResult.amount > pSheet->Amount) continue; // not enough sheets bestResult.Statistics = stat; bestResult.raskroy = raskroy; bestResult.sheet = pSheet; bestRashod = rashod; first = false; } } if (first) throw CannotSetPartsException(&m_sheets, m_sizes, &m_remains); m_remains -= bestRashod * bestResult.amount; RemoveExostedSizes(); if (ControlRemains) bestResult.sheet->Amount -= bestResult.amount; #ifdef _DEBUG CheckResult(bestResult); #endif out = bestResult; return true; }