2018-05-17 10:37:26 +02:00
|
|
|
#include <iostream>
|
|
|
|
|
#include <string>
|
2018-06-28 16:14:17 +02:00
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
//#define DEBUG_EXPORT_NFP
|
2018-05-17 10:37:26 +02:00
|
|
|
|
|
|
|
|
#include <libnest2d.h>
|
|
|
|
|
#include <libnest2d/geometries_io.hpp>
|
|
|
|
|
|
|
|
|
|
#include "printer_parts.h"
|
|
|
|
|
#include "benchmark.h"
|
2018-06-05 12:02:45 +02:00
|
|
|
#include "svgtools.hpp"
|
2018-06-28 16:14:17 +02:00
|
|
|
//#include <libnest2d/optimizer.hpp>
|
|
|
|
|
//#include <libnest2d/optimizers/simplex.hpp>
|
2018-05-17 10:37:26 +02:00
|
|
|
|
|
|
|
|
using namespace libnest2d;
|
|
|
|
|
using ItemGroup = std::vector<std::reference_wrapper<Item>>;
|
|
|
|
|
|
2018-06-05 12:02:45 +02:00
|
|
|
std::vector<Item>& _parts(std::vector<Item>& ret, const TestData& data)
|
|
|
|
|
{
|
|
|
|
|
if(ret.empty()) {
|
|
|
|
|
ret.reserve(data.size());
|
|
|
|
|
for(auto& inp : data)
|
|
|
|
|
ret.emplace_back(inp);
|
2018-05-17 10:37:26 +02:00
|
|
|
}
|
2018-06-05 12:02:45 +02:00
|
|
|
|
|
|
|
|
return ret;
|
2018-05-17 10:37:26 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-05 12:02:45 +02:00
|
|
|
std::vector<Item>& prusaParts() {
|
|
|
|
|
static std::vector<Item> ret;
|
|
|
|
|
return _parts(ret, PRINTER_PART_POLYGONS);
|
2018-05-17 10:37:26 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-05 12:02:45 +02:00
|
|
|
std::vector<Item>& stegoParts() {
|
|
|
|
|
static std::vector<Item> ret;
|
|
|
|
|
return _parts(ret, STEGOSAUR_POLYGONS);
|
2018-05-17 10:37:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void arrangeRectangles() {
|
|
|
|
|
using namespace libnest2d;
|
|
|
|
|
|
|
|
|
|
const int SCALE = 1000000;
|
2018-06-28 16:14:17 +02:00
|
|
|
std::vector<Rectangle> rects = {
|
|
|
|
|
{80*SCALE, 80*SCALE},
|
|
|
|
|
{60*SCALE, 90*SCALE},
|
|
|
|
|
{70*SCALE, 30*SCALE},
|
|
|
|
|
{80*SCALE, 60*SCALE},
|
|
|
|
|
{60*SCALE, 60*SCALE},
|
|
|
|
|
{60*SCALE, 40*SCALE},
|
|
|
|
|
{40*SCALE, 40*SCALE},
|
|
|
|
|
{10*SCALE, 10*SCALE},
|
|
|
|
|
{10*SCALE, 10*SCALE},
|
|
|
|
|
{10*SCALE, 10*SCALE},
|
|
|
|
|
{10*SCALE, 10*SCALE},
|
|
|
|
|
{10*SCALE, 10*SCALE},
|
|
|
|
|
{5*SCALE, 5*SCALE},
|
|
|
|
|
{5*SCALE, 5*SCALE},
|
|
|
|
|
{5*SCALE, 5*SCALE},
|
|
|
|
|
{5*SCALE, 5*SCALE},
|
|
|
|
|
{5*SCALE, 5*SCALE},
|
|
|
|
|
{5*SCALE, 5*SCALE},
|
|
|
|
|
{5*SCALE, 5*SCALE},
|
|
|
|
|
{20*SCALE, 20*SCALE}
|
|
|
|
|
};
|
2018-05-17 10:37:26 +02:00
|
|
|
|
2018-06-28 16:14:17 +02:00
|
|
|
// std::vector<Rectangle> rects = {
|
|
|
|
|
// {20*SCALE, 10*SCALE},
|
|
|
|
|
// {20*SCALE, 10*SCALE},
|
|
|
|
|
// {20*SCALE, 20*SCALE},
|
|
|
|
|
// };
|
2018-05-17 10:37:26 +02:00
|
|
|
|
2018-06-28 16:14:17 +02:00
|
|
|
// std::vector<Item> input {
|
|
|
|
|
// {{0, 0}, {0, 20*SCALE}, {10*SCALE, 0}, {0, 0}}
|
|
|
|
|
// };
|
2018-05-17 10:37:26 +02:00
|
|
|
|
2018-06-28 16:14:17 +02:00
|
|
|
std::vector<Item> input;
|
|
|
|
|
input.insert(input.end(), prusaParts().begin(), prusaParts().end());
|
|
|
|
|
// input.insert(input.end(), stegoParts().begin(), stegoParts().end());
|
|
|
|
|
// input.insert(input.end(), rects.begin(), rects.end());
|
2018-05-17 10:37:26 +02:00
|
|
|
|
2018-06-28 16:14:17 +02:00
|
|
|
Box bin(250*SCALE, 210*SCALE);
|
|
|
|
|
|
|
|
|
|
Coord min_obj_distance = 6*SCALE;
|
|
|
|
|
|
|
|
|
|
using Packer = Arranger<NfpPlacer, DJDHeuristic>;
|
|
|
|
|
|
|
|
|
|
Packer::PlacementConfig pconf;
|
|
|
|
|
pconf.alignment = NfpPlacer::Config::Alignment::CENTER;
|
|
|
|
|
// pconf.rotations = {0.0, Pi/2.0, Pi, 3*Pi/2};
|
|
|
|
|
Packer::SelectionConfig sconf;
|
|
|
|
|
sconf.allow_parallel = true;
|
|
|
|
|
sconf.force_parallel = false;
|
|
|
|
|
sconf.try_reverse_order = false;
|
|
|
|
|
Packer arrange(bin, min_obj_distance, pconf, sconf);
|
|
|
|
|
|
|
|
|
|
arrange.progressIndicator([&](unsigned r){
|
2018-06-05 12:02:45 +02:00
|
|
|
// svg::SVGWriter::Config conf;
|
|
|
|
|
// conf.mm_in_coord_units = SCALE;
|
|
|
|
|
// svg::SVGWriter svgw(conf);
|
|
|
|
|
// svgw.setSize(bin);
|
|
|
|
|
// svgw.writePackGroup(arrange.lastResult());
|
2018-06-28 16:14:17 +02:00
|
|
|
// svgw.save("debout");
|
|
|
|
|
std::cout << "Remaining items: " << r << std::endl;
|
|
|
|
|
}).useMinimumBoundigBoxRotation();
|
2018-05-17 10:37:26 +02:00
|
|
|
|
|
|
|
|
Benchmark bench;
|
|
|
|
|
|
|
|
|
|
bench.start();
|
2018-06-28 16:14:17 +02:00
|
|
|
auto result = arrange.arrange(input.begin(),
|
2018-05-17 10:37:26 +02:00
|
|
|
input.end());
|
|
|
|
|
|
|
|
|
|
bench.stop();
|
|
|
|
|
|
2018-06-28 16:14:17 +02:00
|
|
|
std::vector<double> eff;
|
|
|
|
|
eff.reserve(result.size());
|
|
|
|
|
|
|
|
|
|
auto bin_area = double(bin.height()*bin.width());
|
|
|
|
|
for(auto& r : result) {
|
|
|
|
|
double a = 0;
|
|
|
|
|
std::for_each(r.begin(), r.end(), [&a] (Item& e ){ a += e.area(); });
|
|
|
|
|
eff.emplace_back(a/bin_area);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::cout << bench.getElapsedSec() << " bin count: " << result.size()
|
|
|
|
|
<< std::endl;
|
|
|
|
|
|
|
|
|
|
std::cout << "Bin efficiency: (";
|
|
|
|
|
for(double e : eff) std::cout << e*100.0 << "% ";
|
|
|
|
|
std::cout << ") Average: "
|
|
|
|
|
<< std::accumulate(eff.begin(), eff.end(), 0.0)*100.0/result.size()
|
|
|
|
|
<< " %" << std::endl;
|
|
|
|
|
|
|
|
|
|
std::cout << "Bin usage: (";
|
|
|
|
|
unsigned total = 0;
|
|
|
|
|
for(auto& r : result) { std::cout << r.size() << " "; total += r.size(); }
|
|
|
|
|
std::cout << ") Total: " << total << std::endl;
|
2018-05-17 10:37:26 +02:00
|
|
|
|
|
|
|
|
for(auto& it : input) {
|
|
|
|
|
auto ret = ShapeLike::isValid(it.transformedShape());
|
|
|
|
|
std::cout << ret.second << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-28 16:14:17 +02:00
|
|
|
if(total != input.size()) std::cout << "ERROR " << "could not pack "
|
|
|
|
|
<< input.size() - total << " elements!"
|
|
|
|
|
<< std::endl;
|
|
|
|
|
|
2018-06-05 12:02:45 +02:00
|
|
|
svg::SVGWriter::Config conf;
|
|
|
|
|
conf.mm_in_coord_units = SCALE;
|
|
|
|
|
svg::SVGWriter svgw(conf);
|
|
|
|
|
svgw.setSize(bin);
|
|
|
|
|
svgw.writePackGroup(result);
|
2018-06-28 16:14:17 +02:00
|
|
|
// std::for_each(input.begin(), input.end(), [&svgw](Item& item){ svgw.writeItem(item);});
|
2018-06-05 12:02:45 +02:00
|
|
|
svgw.save("out");
|
2018-05-17 10:37:26 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-28 16:14:17 +02:00
|
|
|
|
|
|
|
|
|
2018-05-17 10:37:26 +02:00
|
|
|
int main(void /*int argc, char **argv*/) {
|
|
|
|
|
arrangeRectangles();
|
|
|
|
|
// findDegenerateCase();
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
|
}
|