mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-04 19:12:42 +00:00
Incorporating performance optimizations from libnest2d
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
//#define DEBUG_EXPORT_NFP
|
||||
|
||||
#include <libnest2d.h>
|
||||
#include <libnest2d/geometries_io.hpp>
|
||||
@@ -8,6 +10,8 @@
|
||||
#include "printer_parts.h"
|
||||
#include "benchmark.h"
|
||||
#include "svgtools.hpp"
|
||||
//#include <libnest2d/optimizer.hpp>
|
||||
//#include <libnest2d/optimizers/simplex.hpp>
|
||||
|
||||
using namespace libnest2d;
|
||||
using ItemGroup = std::vector<std::reference_wrapper<Item>>;
|
||||
@@ -36,51 +40,122 @@ std::vector<Item>& stegoParts() {
|
||||
void arrangeRectangles() {
|
||||
using namespace libnest2d;
|
||||
|
||||
auto input = stegoParts();
|
||||
|
||||
const int SCALE = 1000000;
|
||||
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}
|
||||
};
|
||||
|
||||
Box bin(210*SCALE, 250*SCALE);
|
||||
// std::vector<Rectangle> rects = {
|
||||
// {20*SCALE, 10*SCALE},
|
||||
// {20*SCALE, 10*SCALE},
|
||||
// {20*SCALE, 20*SCALE},
|
||||
// };
|
||||
|
||||
Coord min_obj_distance = 0; //6*SCALE;
|
||||
// std::vector<Item> input {
|
||||
// {{0, 0}, {0, 20*SCALE}, {10*SCALE, 0}, {0, 0}}
|
||||
// };
|
||||
|
||||
NfpPlacer::Config pconf;
|
||||
pconf.alignment = NfpPlacer::Config::Alignment::TOP_LEFT;
|
||||
Arranger<NfpPlacer, DJDHeuristic> arrange(bin, min_obj_distance, pconf);
|
||||
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());
|
||||
|
||||
// arrange.progressIndicator([&arrange, &bin](unsigned r){
|
||||
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){
|
||||
// svg::SVGWriter::Config conf;
|
||||
// conf.mm_in_coord_units = SCALE;
|
||||
// svg::SVGWriter svgw(conf);
|
||||
// svgw.setSize(bin);
|
||||
// svgw.writePackGroup(arrange.lastResult());
|
||||
// svgw.save("out");
|
||||
// std::cout << "Remaining items: " << r << std::endl;
|
||||
// });
|
||||
// svgw.save("debout");
|
||||
std::cout << "Remaining items: " << r << std::endl;
|
||||
}).useMinimumBoundigBoxRotation();
|
||||
|
||||
Benchmark bench;
|
||||
|
||||
bench.start();
|
||||
auto result = arrange(input.begin(),
|
||||
auto result = arrange.arrange(input.begin(),
|
||||
input.end());
|
||||
|
||||
bench.stop();
|
||||
|
||||
std::cout << bench.getElapsedSec() << std::endl;
|
||||
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;
|
||||
|
||||
for(auto& it : input) {
|
||||
auto ret = ShapeLike::isValid(it.transformedShape());
|
||||
std::cout << ret.second << std::endl;
|
||||
}
|
||||
|
||||
if(total != input.size()) std::cout << "ERROR " << "could not pack "
|
||||
<< input.size() - total << " elements!"
|
||||
<< std::endl;
|
||||
|
||||
svg::SVGWriter::Config conf;
|
||||
conf.mm_in_coord_units = SCALE;
|
||||
svg::SVGWriter svgw(conf);
|
||||
svgw.setSize(bin);
|
||||
svgw.writePackGroup(result);
|
||||
// std::for_each(input.begin(), input.end(), [&svgw](Item& item){ svgw.writeItem(item);});
|
||||
svgw.save("out");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(void /*int argc, char **argv*/) {
|
||||
arrangeRectangles();
|
||||
// findDegenerateCase();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -50,7 +50,9 @@ public:
|
||||
if(conf_.origo_location == BOTTOMLEFT)
|
||||
for(unsigned i = 0; i < tsh.vertexCount(); i++) {
|
||||
auto v = tsh.vertex(i);
|
||||
setY(v, -getY(v) + conf_.height*conf_.mm_in_coord_units);
|
||||
auto d = static_cast<Coord>(
|
||||
std::round(conf_.height*conf_.mm_in_coord_units) );
|
||||
setY(v, -getY(v) + d);
|
||||
tsh.setVertex(i, v);
|
||||
}
|
||||
currentLayer() += ShapeLike::serialize<Formats::SVG>(tsh.rawShape(),
|
||||
@@ -78,8 +80,8 @@ public:
|
||||
}
|
||||
|
||||
void save(const std::string& filepath) {
|
||||
unsigned lyrc = svg_layers_.size() > 1? 1 : 0;
|
||||
unsigned last = svg_layers_.size() > 1? svg_layers_.size() : 0;
|
||||
size_t lyrc = svg_layers_.size() > 1? 1 : 0;
|
||||
size_t last = svg_layers_.size() > 1? svg_layers_.size() : 0;
|
||||
|
||||
for(auto& lyr : svg_layers_) {
|
||||
std::fstream out(filepath + (lyrc > 0? std::to_string(lyrc) : "") +
|
||||
|
||||
@@ -253,7 +253,7 @@ TEST(GeometryAlgorithms, LeftAndDownPolygon)
|
||||
ASSERT_TRUE(ShapeLike::isValid(leftp.rawShape()).first);
|
||||
ASSERT_EQ(leftp.vertexCount(), leftControl.vertexCount());
|
||||
|
||||
for(size_t i = 0; i < leftControl.vertexCount(); i++) {
|
||||
for(unsigned long i = 0; i < leftControl.vertexCount(); i++) {
|
||||
ASSERT_EQ(getX(leftp.vertex(i)), getX(leftControl.vertex(i)));
|
||||
ASSERT_EQ(getY(leftp.vertex(i)), getY(leftControl.vertex(i)));
|
||||
}
|
||||
@@ -263,7 +263,7 @@ TEST(GeometryAlgorithms, LeftAndDownPolygon)
|
||||
ASSERT_TRUE(ShapeLike::isValid(downp.rawShape()).first);
|
||||
ASSERT_EQ(downp.vertexCount(), downControl.vertexCount());
|
||||
|
||||
for(size_t i = 0; i < downControl.vertexCount(); i++) {
|
||||
for(unsigned long i = 0; i < downControl.vertexCount(); i++) {
|
||||
ASSERT_EQ(getX(downp.vertex(i)), getX(downControl.vertex(i)));
|
||||
ASSERT_EQ(getY(downp.vertex(i)), getY(downControl.vertex(i)));
|
||||
}
|
||||
@@ -696,6 +696,27 @@ TEST(GeometryAlgorithms, nfpConvexConvex) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GeometryAlgorithms, pointOnPolygonContour) {
|
||||
using namespace libnest2d;
|
||||
|
||||
Rectangle input(10, 10);
|
||||
|
||||
strategies::EdgeCache<PolygonImpl> ecache(input);
|
||||
|
||||
auto first = *input.begin();
|
||||
ASSERT_TRUE(getX(first) == getX(ecache.coords(0)));
|
||||
ASSERT_TRUE(getY(first) == getY(ecache.coords(0)));
|
||||
|
||||
auto last = *std::prev(input.end());
|
||||
ASSERT_TRUE(getX(last) == getX(ecache.coords(1.0)));
|
||||
ASSERT_TRUE(getY(last) == getY(ecache.coords(1.0)));
|
||||
|
||||
for(int i = 0; i <= 100; i++) {
|
||||
auto v = ecache.coords(i*(0.01));
|
||||
ASSERT_TRUE(ShapeLike::touches(v, input.transformedShape()));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
Reference in New Issue
Block a user