mirror of
https://github.com/FULU-Foundation/OrcaSlicer-bambulab.git
synced 2026-06-09 23:28:28 -04:00
261 lines
7.1 KiB
C++
261 lines
7.1 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
|
|
#include <libnest2d.h>
|
|
#include <libnest2d/geometries_io.hpp>
|
|
|
|
#include "printer_parts.h"
|
|
#include "benchmark.h"
|
|
|
|
namespace {
|
|
using namespace libnest2d;
|
|
using ItemGroup = std::vector<std::reference_wrapper<Item>>;
|
|
//using PackGroup = std::vector<ItemGroup>;
|
|
|
|
template<int SCALE, class Bin >
|
|
void exportSVG(PackGroup& result, const Bin& bin) {
|
|
|
|
std::string loc = "out";
|
|
|
|
static std::string svg_header =
|
|
R"raw(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
|
<svg height="500" width="500" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
)raw";
|
|
|
|
int i = 0;
|
|
for(auto r : result) {
|
|
std::fstream out(loc + std::to_string(i) + ".svg", std::fstream::out);
|
|
if(out.is_open()) {
|
|
out << svg_header;
|
|
Item rbin( Rectangle(bin.width(), bin.height()) );
|
|
for(unsigned i = 0; i < rbin.vertexCount(); i++) {
|
|
auto v = rbin.vertex(i);
|
|
setY(v, -getY(v)/SCALE + 500 );
|
|
setX(v, getX(v)/SCALE);
|
|
rbin.setVertex(i, v);
|
|
}
|
|
out << ShapeLike::serialize<Formats::SVG>(rbin.rawShape()) << std::endl;
|
|
for(Item& sh : r) {
|
|
Item tsh(sh.transformedShape());
|
|
for(unsigned i = 0; i < tsh.vertexCount(); i++) {
|
|
auto v = tsh.vertex(i);
|
|
setY(v, -getY(v)/SCALE + 500);
|
|
setX(v, getX(v)/SCALE);
|
|
tsh.setVertex(i, v);
|
|
}
|
|
out << ShapeLike::serialize<Formats::SVG>(tsh.rawShape()) << std::endl;
|
|
}
|
|
out << "\n</svg>" << std::endl;
|
|
}
|
|
out.close();
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
template< int SCALE, class Bin>
|
|
void exportSVG(ItemGroup& result, const Bin& bin, int idx) {
|
|
|
|
std::string loc = "out";
|
|
|
|
static std::string svg_header =
|
|
R"raw(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
|
<svg height="500" width="500" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
)raw";
|
|
|
|
int i = idx;
|
|
auto r = result;
|
|
// for(auto r : result) {
|
|
std::fstream out(loc + std::to_string(i) + ".svg", std::fstream::out);
|
|
if(out.is_open()) {
|
|
out << svg_header;
|
|
Item rbin( Rectangle(bin.width(), bin.height()) );
|
|
for(unsigned i = 0; i < rbin.vertexCount(); i++) {
|
|
auto v = rbin.vertex(i);
|
|
setY(v, -getY(v)/SCALE + 500 );
|
|
setX(v, getX(v)/SCALE);
|
|
rbin.setVertex(i, v);
|
|
}
|
|
out << ShapeLike::serialize<Formats::SVG>(rbin.rawShape()) << std::endl;
|
|
for(Item& sh : r) {
|
|
Item tsh(sh.transformedShape());
|
|
for(unsigned i = 0; i < tsh.vertexCount(); i++) {
|
|
auto v = tsh.vertex(i);
|
|
setY(v, -getY(v)/SCALE + 500);
|
|
setX(v, getX(v)/SCALE);
|
|
tsh.setVertex(i, v);
|
|
}
|
|
out << ShapeLike::serialize<Formats::SVG>(tsh.rawShape()) << std::endl;
|
|
}
|
|
out << "\n</svg>" << std::endl;
|
|
}
|
|
out.close();
|
|
|
|
// i++;
|
|
// }
|
|
}
|
|
}
|
|
|
|
|
|
void findDegenerateCase() {
|
|
using namespace libnest2d;
|
|
|
|
auto input = PRINTER_PART_POLYGONS;
|
|
|
|
auto scaler = [](Item& item) {
|
|
for(unsigned i = 0; i < item.vertexCount(); i++) {
|
|
auto v = item.vertex(i);
|
|
setX(v, 100*getX(v)); setY(v, 100*getY(v));
|
|
item.setVertex(i, v);
|
|
}
|
|
};
|
|
|
|
auto cmp = [](const Item& t1, const Item& t2) {
|
|
return t1.area() > t2.area();
|
|
};
|
|
|
|
std::for_each(input.begin(), input.end(), scaler);
|
|
|
|
std::sort(input.begin(), input.end(), cmp);
|
|
|
|
Box bin(210*100, 250*100);
|
|
BottomLeftPlacer placer(bin);
|
|
|
|
auto it = input.begin();
|
|
auto next = it;
|
|
int i = 0;
|
|
while(it != input.end() && ++next != input.end()) {
|
|
placer.pack(*it);
|
|
placer.pack(*next);
|
|
|
|
auto result = placer.getItems();
|
|
bool valid = true;
|
|
|
|
if(result.size() == 2) {
|
|
Item& r1 = result[0];
|
|
Item& r2 = result[1];
|
|
valid = !Item::intersects(r1, r2) || Item::touches(r1, r2);
|
|
valid = (valid && !r1.isInside(r2) && !r2.isInside(r1));
|
|
if(!valid) {
|
|
std::cout << "error index: " << i << std::endl;
|
|
exportSVG<100>(result, bin, i);
|
|
}
|
|
} else {
|
|
std::cout << "something went terribly wrong!" << std::endl;
|
|
}
|
|
|
|
|
|
placer.clearItems();
|
|
it++;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void arrangeRectangles() {
|
|
using namespace libnest2d;
|
|
|
|
|
|
// std::vector<Rectangle> input = {
|
|
// {80, 80},
|
|
// {110, 10},
|
|
// {200, 5},
|
|
// {80, 30},
|
|
// {60, 90},
|
|
// {70, 30},
|
|
// {80, 60},
|
|
// {60, 60},
|
|
// {60, 40},
|
|
// {40, 40},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {20, 20},
|
|
// {80, 80},
|
|
// {110, 10},
|
|
// {200, 5},
|
|
// {80, 30},
|
|
// {60, 90},
|
|
// {70, 30},
|
|
// {80, 60},
|
|
// {60, 60},
|
|
// {60, 40},
|
|
// {40, 40},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {10, 10},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {5, 5},
|
|
// {20, 20}
|
|
// };
|
|
|
|
auto input = PRINTER_PART_POLYGONS;
|
|
|
|
const int SCALE = 1000000;
|
|
// const int SCALE = 1;
|
|
|
|
Box bin(210*SCALE, 250*SCALE);
|
|
|
|
auto scaler = [&SCALE, &bin](Item& item) {
|
|
// double max_area = 0;
|
|
for(unsigned i = 0; i < item.vertexCount(); i++) {
|
|
auto v = item.vertex(i);
|
|
setX(v, SCALE*getX(v)); setY(v, SCALE*getY(v));
|
|
item.setVertex(i, v);
|
|
// double area = item.area();
|
|
// if(max_area < area) {
|
|
// max_area = area;
|
|
// bin = item.boundingBox();
|
|
// }
|
|
}
|
|
};
|
|
|
|
Coord min_obj_distance = 2*SCALE;
|
|
|
|
std::for_each(input.begin(), input.end(), scaler);
|
|
|
|
Arranger<BottomLeftPlacer, DJDHeuristic> arrange(bin, min_obj_distance);
|
|
|
|
Benchmark bench;
|
|
|
|
bench.start();
|
|
auto result = arrange(input.begin(),
|
|
input.end());
|
|
|
|
bench.stop();
|
|
|
|
std::cout << bench.getElapsedSec() << std::endl;
|
|
|
|
for(auto& it : input) {
|
|
auto ret = ShapeLike::isValid(it.transformedShape());
|
|
std::cout << ret.second << std::endl;
|
|
}
|
|
|
|
exportSVG<SCALE>(result, bin);
|
|
|
|
}
|
|
|
|
int main(void /*int argc, char **argv*/) {
|
|
arrangeRectangles();
|
|
// findDegenerateCase();
|
|
return EXIT_SUCCESS;
|
|
}
|