PartContainer::Parts PartContainer::getAllAttachedParts(Part* part) const { Parts parts = getAttachedParts(part); for(Part* p : parts) { Parts tmp = getAllAttachedParts(p); parts.insert(parts.end(), tmp.begin(), tmp.end()); } return parts; }
void ResultsGenerator::Begin(Parts &parts, const Parts &sheets) { m_remains.clear(); for (auto s = 0; s <= 1; s++) { m_sizes[s].clear(); for (auto pPart = parts.begin(); pPart != parts.end(); pPart++) m_sizes[s].AddPart(*pPart, s); // order from big to small std::sort(m_sizes[s].begin(), m_sizes[s].end(), std::greater_equal<Size>()); for (auto pSize = m_sizes[s].begin(); pSize != m_sizes[s].end(); pSize++) { std::sort(pSize->other_sizes.begin(), pSize->other_sizes.end(), std::greater_equal<OtherSize>()); // set pointer to the smallest size pSize->other_sizes.SetMin(); } } m_sheets = sheets; }
extern "C" int DLLEXPORT new_layout2d( LayoutRect * layout_rects, unsigned int num, scalar sheet_x, scalar sheet_y, scalar cut_size, Layout ** res) { Rect sheet; sheet.Size[0] = sheet_x; sheet.Size[1] = sheet_y; Parts parts; for (unsigned int i = 0; i < num; i++) { auto rect = &layout_rects[i]; Part part(rect->size[0], rect->size[1], rect->can_rotate != 0, rect->amount); part.Tag = (int)i; parts.push_back(part); } // merge parts with the same relevant characteristics std::map<PartKey, std::list<Part*> > unique_parts_map; for (auto i = parts.begin(); i != parts.end(); i++) { PartKey part_key; part_key.rect = i->rect; part_key.can_rotate = i->Rotate; part_key.normalize(); unique_parts_map[part_key].push_back(&*i); } Parts unique_parts; for (auto i = unique_parts_map.begin(); i != unique_parts_map.end(); i++) { Part part; part.rect = i->first.rect; part.Rotate = i->first.can_rotate; part.parts = i->second; // calculate combined amount part.Amount = 0; for_each(part.parts.begin(), part.parts.end(), [&part](Part * el) { part.Amount += el->Amount; }); unique_parts.push_back(part); } LayoutBuilder layout_builder; // initialize amounts vector Amounts remains(unique_parts.size()); // assing amount offsets to parts // and amounts to remains auto offset = 0; std::for_each(unique_parts.begin(), unique_parts.end(), [&offset, &remains](Part & part) { part.AmountOffset = offset++; remains[part.AmountOffset] = part.Amount; }); // initialize sizes lookups Sizes sizes[2]; for (auto s = 0; s <= 1; s++) { for (auto pPart = unique_parts.begin(); pPart != unique_parts.end(); pPart++) sizes[s].AddPart(*pPart, s); // order from big to small std::sort(sizes[s].begin(), sizes[s].end(), std::greater_equal<Size>()); for (auto pSize = sizes[s].begin(); pSize != sizes[s].end(); pSize++) { std::sort(pSize->other_sizes.begin(), pSize->other_sizes.end(), std::greater_equal<OtherSize>()); pSize->other_sizes.SetMin(); } } scalar min_size[2]; Layout2d optimizer(sizes, min_size, &remains); optimizer.put_SawThickness(cut_size); int ret = optimizer.new_optimize(sheet, layout_builder) ? 1 : 0; if (ret) { unique_ptr<Layout> layout(new Layout); layout_builder.simplify(); layout_builder.check(); layout_builder.to_layout(*layout); *res = layout.release(); // report back new amounts for (size_t i = 0; i < parts.size(); i++) { layout_rects[i].amount = parts[i].Amount; } } return ret; }