Improved libnest2d caching

This commit is contained in:
tamasmeszaros 2018-07-27 12:28:14 +02:00
parent c430f57187
commit 84f97e1f64
22 changed files with 1178 additions and 768 deletions

View file

@ -535,17 +535,18 @@ void arrangeRectangles() {
proba[0].rotate(Pi/3);
proba[1].rotate(Pi-Pi/3);
// std::vector<Item> input(25, Rectangle(70*SCALE, 10*SCALE));
std::vector<Item> input;
input.insert(input.end(), prusaParts().begin(), prusaParts().end());
// input.insert(input.end(), prusaExParts().begin(), prusaExParts().end());
input.insert(input.end(), stegoParts().begin(), stegoParts().end());
// input.insert(input.end(), stegoParts().begin(), stegoParts().end());
// input.insert(input.end(), rects.begin(), rects.end());
input.insert(input.end(), proba.begin(), proba.end());
// input.insert(input.end(), proba.begin(), proba.end());
// input.insert(input.end(), crasher.begin(), crasher.end());
Box bin(250*SCALE, 210*SCALE);
Coord min_obj_distance = 6*SCALE;
auto min_obj_distance = static_cast<Coord>(0*SCALE);
using Placer = NfpPlacer;
using Packer = Arranger<Placer, FirstFitSelection>;
@ -554,21 +555,45 @@ void arrangeRectangles() {
Packer::PlacementConfig pconf;
pconf.alignment = Placer::Config::Alignment::CENTER;
pconf.starting_point = Placer::Config::Alignment::CENTER;
pconf.starting_point = Placer::Config::Alignment::BOTTOM_LEFT;
pconf.rotations = {0.0/*, Pi/2.0, Pi, 3*Pi/2*/};
pconf.object_function = [&bin](Placer::Pile pile, double area,
double norm, double penality) {
double norm_2 = std::nan("");
pconf.object_function = [&bin, &norm_2](Placer::Pile pile, const Item& item,
double /*area*/, double norm, double penality) {
using pl = PointLike;
auto bb = ShapeLike::boundingBox(pile);
auto ibb = item.boundingBox();
auto minc = ibb.minCorner();
auto maxc = ibb.maxCorner();
auto& sh = pile.back();
auto rv = Nfp::referenceVertex(sh);
auto c = bin.center();
auto d = PointLike::distance(rv, c);
double score = double(d)/norm;
if(std::isnan(norm_2)) norm_2 = pow(norm, 2);
// We get the distance of the reference point from the center of the
// heat bed
auto cc = bb.center();
auto top_left = PointImpl{getX(minc), getY(maxc)};
auto bottom_right = PointImpl{getX(maxc), getY(minc)};
auto a = pl::distance(ibb.maxCorner(), cc);
auto b = pl::distance(ibb.minCorner(), cc);
auto c = pl::distance(ibb.center(), cc);
auto d = pl::distance(top_left, cc);
auto e = pl::distance(bottom_right, cc);
auto area = bb.width() * bb.height() / norm_2;
auto min_dist = std::min({a, b, c, d, e}) / norm;
// The score will be the normalized distance which will be minimized,
// effectively creating a circle shaped pile of items
double score = 0.8*min_dist + 0.2*area;
// If it does not fit into the print bed we will beat it
// with a large penality
// with a large penality. If we would not do this, there would be only
// one big pile that doesn't care whether it fits onto the print bed.
if(!NfpPlacer::wouldFit(bb, bin)) score = 2*penality - score;
return score;
@ -577,7 +602,7 @@ void arrangeRectangles() {
Packer::SelectionConfig sconf;
// sconf.allow_parallel = false;
// sconf.force_parallel = false;
// sconf.try_triplets = false;
// sconf.try_triplets = true;
// sconf.try_reverse_order = true;
// sconf.waste_increment = 0.005;
@ -630,7 +655,7 @@ void arrangeRectangles() {
<< " %" << std::endl;
std::cout << "Bin usage: (";
unsigned total = 0;
size_t total = 0;
for(auto& r : result) { std::cout << r.size() << " "; total += r.size(); }
std::cout << ") Total: " << total << std::endl;
@ -643,9 +668,11 @@ void arrangeRectangles() {
<< input.size() - total << " elements!"
<< std::endl;
svg::SVGWriter::Config conf;
using SVGWriter = svg::SVGWriter<PolygonImpl>;
SVGWriter::Config conf;
conf.mm_in_coord_units = SCALE;
svg::SVGWriter svgw(conf);
SVGWriter svgw(conf);
svgw.setSize(bin);
svgw.writePackGroup(result);
// std::for_each(input.begin(), input.end(), [&svgw](Item& item){ svgw.writeItem(item);});