Пример #1
0
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;
}