Change to firstfit selection because DJD needs further testing.

This commit is contained in:
tamasmeszaros
2018-07-16 16:07:29 +02:00
parent eefa1678db
commit 6bcd735655
31 changed files with 4317 additions and 826 deletions

View File

@@ -35,13 +35,17 @@ else()
set(GTEST_LIBS_TO_LINK ${GTEST_BOTH_LIBRARIES} Threads::Threads)
endif()
add_executable(bp2d_tests test.cpp svgtools.hpp printer_parts.h printer_parts.cpp)
target_link_libraries(bp2d_tests libnest2d_static ${GTEST_LIBS_TO_LINK} )
add_executable(bp2d_tests test.cpp
../tools/svgtools.hpp
# ../tools/libnfpglue.hpp
# ../tools/libnfpglue.cpp
printer_parts.h
printer_parts.cpp
${LIBNEST2D_SRCFILES}
)
target_link_libraries(bp2d_tests ${LIBNEST2D_LIBRARIES} ${GTEST_LIBS_TO_LINK} )
target_include_directories(bp2d_tests PRIVATE BEFORE ${LIBNEST2D_HEADERS}
${GTEST_INCLUDE_DIRS})
if(DEFINED LIBNEST2D_TEST_LIBRARIES)
target_link_libraries(bp2d_tests ${LIBNEST2D_TEST_LIBRARIES})
endif()
add_test(libnest2d_tests bp2d_tests)

View File

@@ -1,58 +0,0 @@
/*
* Copyright (C) Tamás Mészáros
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDE_BENCHMARK_H_
#define INCLUDE_BENCHMARK_H_
#include <chrono>
#include <ratio>
/**
* A class for doing benchmarks.
*/
class Benchmark {
typedef std::chrono::high_resolution_clock Clock;
typedef Clock::duration Duration;
typedef Clock::time_point TimePoint;
TimePoint t1, t2;
Duration d;
inline double to_sec(Duration d) {
return d.count() * double(Duration::period::num) / Duration::period::den;
}
public:
/**
* Measure time from the moment of this call.
*/
void start() { t1 = Clock::now(); }
/**
* Measure time to the moment of this call.
*/
void stop() { t2 = Clock::now(); }
/**
* Get the time elapsed between a start() end a stop() call.
* @return Returns the elapsed time in seconds.
*/
double getElapsedSec() { d = t2 - t1; return to_sec(d); }
};
#endif /* INCLUDE_BENCHMARK_H_ */

View File

@@ -1,619 +0,0 @@
#include <iostream>
#include <string>
#include <fstream>
//#define DEBUG_EXPORT_NFP
#include <libnest2d.h>
#include <libnest2d/geometries_io.hpp>
#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>>;
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);
}
return ret;
}
std::vector<Item>& prusaParts() {
static std::vector<Item> ret;
return _parts(ret, PRINTER_PART_POLYGONS);
}
std::vector<Item>& stegoParts() {
static std::vector<Item> ret;
return _parts(ret, STEGOSAUR_POLYGONS);
}
void arrangeRectangles() {
using namespace libnest2d;
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}
};
// std::vector<Rectangle> rects = {
// {20*SCALE, 10*SCALE},
// {20*SCALE, 10*SCALE},
// {20*SCALE, 20*SCALE},
// };
// std::vector<Item> input {
// {{0, 0}, {0, 20*SCALE}, {10*SCALE, 0}, {0, 0}}
// };
std::vector<Item> crasher = {
{
{-5000000, 8954050},
{5000000, 8954050},
{5000000, -45949},
{4972609, -568549},
{3500000, -8954050},
{-3500000, -8954050},
{-4972609, -568549},
{-5000000, -45949},
{-5000000, 8954050},
},
{
{-5000000, 8954050},
{5000000, 8954050},
{5000000, -45949},
{4972609, -568549},
{3500000, -8954050},
{-3500000, -8954050},
{-4972609, -568549},
{-5000000, -45949},
{-5000000, 8954050},
},
{
{-5000000, 8954050},
{5000000, 8954050},
{5000000, -45949},
{4972609, -568549},
{3500000, -8954050},
{-3500000, -8954050},
{-4972609, -568549},
{-5000000, -45949},
{-5000000, 8954050},
},
{
{-5000000, 8954050},
{5000000, 8954050},
{5000000, -45949},
{4972609, -568549},
{3500000, -8954050},
{-3500000, -8954050},
{-4972609, -568549},
{-5000000, -45949},
{-5000000, 8954050},
},
{
{-5000000, 8954050},
{5000000, 8954050},
{5000000, -45949},
{4972609, -568549},
{3500000, -8954050},
{-3500000, -8954050},
{-4972609, -568549},
{-5000000, -45949},
{-5000000, 8954050},
},
{
{-5000000, 8954050},
{5000000, 8954050},
{5000000, -45949},
{4972609, -568549},
{3500000, -8954050},
{-3500000, -8954050},
{-4972609, -568549},
{-5000000, -45949},
{-5000000, 8954050},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-9945219, -3065619},
{-9781479, -2031780},
{-9510560, -1020730},
{-9135450, -43529},
{-2099999, 14110899},
{2099999, 14110899},
{9135450, -43529},
{9510560, -1020730},
{9781479, -2031780},
{9945219, -3065619},
{10000000, -4110899},
{9945219, -5156179},
{9781479, -6190020},
{9510560, -7201069},
{9135450, -8178270},
{8660249, -9110899},
{8090169, -9988750},
{7431449, -10802200},
{6691309, -11542300},
{5877850, -12201100},
{5000000, -12771100},
{4067369, -13246399},
{3090169, -13621500},
{2079119, -13892399},
{1045279, -14056099},
{0, -14110899},
{-1045279, -14056099},
{-2079119, -13892399},
{-3090169, -13621500},
{-4067369, -13246399},
{-5000000, -12771100},
{-5877850, -12201100},
{-6691309, -11542300},
{-7431449, -10802200},
{-8090169, -9988750},
{-8660249, -9110899},
{-9135450, -8178270},
{-9510560, -7201069},
{-9781479, -6190020},
{-9945219, -5156179},
{-10000000, -4110899},
{-9945219, -3065619},
},
{
{-18000000, -1000000},
{-15000000, 22000000},
{-11000000, 26000000},
{11000000, 26000000},
{15000000, 22000000},
{18000000, -1000000},
{18000000, -26000000},
{-18000000, -26000000},
{-18000000, -1000000},
},
};
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());
input.insert(input.end(), crasher.begin(), crasher.end());
Box bin(250*SCALE, 210*SCALE);
Coord min_obj_distance = 6*SCALE;
using Packer = Arranger<NfpPlacer, DJDHeuristic>;
Packer arrange(bin, min_obj_distance);
Packer::PlacementConfig pconf;
pconf.alignment = NfpPlacer::Config::Alignment::CENTER;
pconf.rotations = {0.0/*, Pi/2.0, Pi, 3*Pi/2*/};
pconf.object_function = [&bin](NfpPlacer::Pile pile, double area,
double norm, double penality) {
auto bb = ShapeLike::boundingBox(pile);
double score = (2*bb.width() + 2*bb.height()) / norm;
if(!NfpPlacer::wouldFit(bb, bin)) score = 2*penality - score;
return score;
};
Packer::SelectionConfig sconf;
sconf.allow_parallel = true;
sconf.force_parallel = true;
sconf.try_reverse_order = true;
arrange.configure(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("debout");
std::cout << "Remaining items: " << r << std::endl;
})/*.useMinimumBoundigBoxRotation()*/;
Benchmark bench;
bench.start();
Packer::ResultType result;
try {
result = arrange.arrange(input.begin(), input.end());
} catch(GeometryException& ge) {
std::cerr << "Geometry error: " << ge.what() << std::endl;
return ;
} catch(std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
return ;
}
bench.stop();
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();
return EXIT_SUCCESS;
}

View File

@@ -2523,3 +2523,653 @@ const TestData STEGOSAUR_POLYGONS =
{84531845, 127391708},
},
};
const TestDataEx PRINTER_PART_POLYGONS_EX =
{
{
{
{533726562, 142141690},
{532359712, 143386134},
{530141290, 142155145},
{528649729, 160091460},
{533659500, 157607547},
{538669739, 160091454},
{537178168, 142155145},
{534959534, 143386102},
{533726562, 142141690},
},
{
},
},
{
{
{118305840, 11603332},
{118311095, 26616786},
{113311095, 26611146},
{109311095, 29604752},
{109300760, 44608489},
{109311095, 49631801},
{113300790, 52636806},
{118311095, 52636806},
{118308782, 103636810},
{223830940, 103636981},
{236845321, 90642174},
{236832882, 11630488},
{232825251, 11616786},
{210149075, 11616786},
{211308596, 13625149},
{209315325, 17080886},
{205326885, 17080886},
{203334352, 13629720},
{204493136, 11616786},
{118305840, 11603332},
},
{
},
},
{
{
{365619370, 111280336},
{365609100, 198818091},
{387109100, 198804367},
{387109100, 203279701},
{471129120, 203279688},
{471128689, 111283937},
{365619370, 111280336},
},
{
},
},
{
{
{479997525, 19177632},
{477473010, 21975778},
{475272613, 21969219},
{475267479, 32995796},
{477026388, 32995796},
{483041428, 22582411},
{482560272, 20318630},
{479997525, 19177632},
},
{
},
},
{
{
{476809080, 4972372},
{475267479, 4975778},
{475272613, 16002357},
{481018177, 18281994},
{482638044, 15466085},
{476809080, 4972372},
},
{
},
},
{
{
{424866064, 10276075},
{415113411, 10277960},
{411723180, 13685293},
{410473354, 18784347},
{382490868, 18784008},
{380996185, 17286945},
{380996185, 11278161},
{375976165, 11284347},
{375976165, 56389754},
{375169018, 57784347},
{371996185, 57784347},
{371996185, 53779177},
{364976165, 53784347},
{364969637, 56791976},
{369214608, 61054367},
{371474507, 61054367},
{371473155, 98298160},
{378476349, 105317193},
{407491306, 105307497},
{413509785, 99284903},
{413496185, 48304367},
{419496173, 48315719},
{422501887, 45292801},
{422500504, 39363184},
{420425079, 37284347},
{419476165, 43284347},
{413496185, 43284347},
{413497261, 30797428},
{418986175, 25308513},
{424005230, 25315076},
{428496185, 20815924},
{428512720, 13948847},
{424866064, 10276075},
},
{
},
},
{
{
{723893066, 37354349},
{717673034, 37370791},
{717673034, 44872138},
{715673034, 44867768},
{715673034, 46055353},
{699219526, 40066777},
{697880758, 37748547},
{691985477, 37748293},
{689014018, 42869257},
{691985477, 48016003},
{697575093, 48003007},
{715671494, 54589493},
{715656800, 87142158},
{759954611, 87142158},
{764193054, 82897328},
{764193054, 79872138},
{757173034, 79866968},
{757173034, 83872138},
{754419422, 83869509},
{753193054, 81739327},
{753193054, 37360571},
{723893066, 37354349},
},
{
},
},
{
{
{85607478, 4227596},
{61739211, 4230337},
{61739211, 13231393},
{58725066, 13231405},
{58721589, 27731406},
{58738375, 30262521},
{61739211, 30251413},
{61736212, 38251411},
{70759231, 38254724},
{70905600, 33317391},
{73749222, 31251468},
{76592843, 33317393},
{76739211, 38254516},
{86765007, 38251411},
{86759599, 4231393},
{85607478, 4227596},
},
{
},
},
{
{
{534839721, 53437770},
{534839721, 60849059},
{539898273, 63773857},
{545461140, 63757881},
{544859741, 53447836},
{541839721, 53437862},
{541710836, 56353878},
{540193984, 57229659},
{538859741, 53437862},
{534839721, 53437770},
},
{
},
},
{
{
{756086230, 136598477},
{732054387, 136605752},
{732052489, 172629505},
{756091994, 172627853},
{756086230, 136598477},
},
{
},
},
{
{
{100337034, 79731391},
{70296833, 79731391},
{70311095, 92263567},
{74329808, 96264260},
{96344976, 96257215},
{100344419, 92232243},
{100337034, 79731391},
},
{
},
},
{
{
{102331115, 44216643},
{67311095, 44217252},
{67311095, 69250964},
{74329808, 76264260},
{96334594, 76251411},
{103335261, 69241401},
{103345839, 44231404},
{102331115, 44216643},
},
{
},
},
{
{
{93849749, 109613798},
{91771666, 111698636},
{91772404, 174626800},
{96782902, 179645338},
{241790509, 179645349},
{246800716, 174626800},
{246802574, 111699755},
{243934250, 109616385},
{93849749, 109613798},
},
{
},
},
{
{
{15856630, 87966835},
{8414359, 91273170},
{5891847, 99010553},
{8403012, 104668172},
{13739106, 107763252},
{13739106, 116209175},
{17959116, 116219127},
{17959127, 107763252},
{23952579, 103855773},
{25806388, 96944174},
{22553953, 90543787},
{15856630, 87966835},
},
{
},
},
{
{
{503922805, 110421794},
{491110107, 123244292},
{479598157, 123244304},
{479601067, 149264312},
{494260327, 149265241},
{502929782, 157948320},
{506490250, 155806171},
{502950518, 155094962},
{507193172, 150852294},
{504364680, 148023895},
{535816833, 116571757},
{538656617, 119411542},
{542887886, 115157558},
{543594970, 118693080},
{545330008, 116966050},
{540309189, 110425901},
{503922805, 110421794},
},
{
},
},
{
{
{519310433, 62560296},
{515749982, 64702434},
{519289696, 65413661},
{515047062, 69656303},
{517875553, 72484703},
{486423431, 103936848},
{483595031, 101108448},
{479352325, 105351055},
{478645233, 101815525},
{476917724, 103520870},
{481923478, 110077233},
{518337308, 110084297},
{531130127, 97264312},
{542630127, 97281049},
{542639167, 71244292},
{527979906, 71243363},
{519310433, 62560296},
},
{
},
},
{
{
{528658425, 14775300},
{525975568, 24475413},
{522556814, 29181341},
{517517474, 32090757},
{511736147, 32698600},
{506200465, 30901018},
{501879743, 27011092},
{497782491, 14775300},
{492372374, 15588397},
{489384268, 20795320},
{491253082, 28537271},
{495185363, 34469052},
{495178475, 43927542},
{502032399, 55796416},
{524402581, 55807400},
{531706434, 44295318},
{531205383, 34469052},
{536679415, 23789946},
{535868173, 17264403},
{532873348, 15073849},
{528658425, 14775300},
},
{
},
},
{
{
{481122222, 166062916},
{478115710, 166824472},
{477103577, 169063247},
{477106058, 192070670},
{478623652, 194687013},
{525109130, 195083267},
{525117792, 198086965},
{535129140, 198091624},
{535129150, 195083267},
{539038502, 194940807},
{540865280, 193308821},
{541132038, 169100183},
{539614599, 166459484},
{481122222, 166062916},
},
{
},
},
{
{
{23771404, 13005453},
{24774973, 19182457},
{31971050, 18727127},
{32556286, 58337520},
{25390683, 58337566},
{25063762, 54707065},
{20168811, 54707252},
{20171550, 62917175},
{70810377, 202895528},
{74314421, 205588631},
{88674817, 205515176},
{91837376, 203083756},
{92280287, 199307207},
{40674807, 15904975},
{36849630, 13006690},
{23771404, 13005453},
},
{
},
},
{
{
{336421201, 2986256},
{331176570, 6498191},
{327552287, 5825511},
{324913825, 2988891},
{316226154, 2989990},
{313040282, 6275291},
{313040282, 23489990},
{307126391, 23490002},
{307140289, 25510010},
{313040282, 25510010},
{313040282, 28989990},
{307126391, 28990002},
{307140289, 31015515},
{313040282, 31010010},
{313040282, 35989990},
{304534809, 37529785},
{304524991, 73488855},
{308554680, 77518546},
{324040282, 77510010},
{324040295, 93025333},
{334574441, 93010010},
{334574441, 90989990},
{332560302, 90989990},
{332560302, 85010010},
{334560302, 85010010},
{334561237, 82010010},
{338540282, 82010010},
{339540282, 83760010},
{338540293, 93020012},
{348060655, 93014679},
{356564448, 84500000},
{356560555, 28989990},
{347334198, 29039989},
{347334198, 25510010},
{356510304, 25521084},
{356510315, 23478922},
{347560302, 23489990},
{347560302, 5775291},
{344874443, 2989990},
{336421201, 2986256},
},
{
},
},
{
{
{465152221, 31684687},
{457606880, 31688302},
{452659362, 35508617},
{449044605, 34734089},
{446478972, 31692751},
{437784814, 31692957},
{435521210, 33956565},
{435532195, 65697616},
{426028494, 65691361},
{426025938, 85049712},
{435532195, 95717636},
{435524445, 103754026},
{436995898, 105225463},
{447552204, 105226323},
{447552215, 103197497},
{444552215, 103197616},
{444552215, 99217636},
{452032195, 99217636},
{452032195, 105221758},
{465588513, 105225463},
{467059965, 103754026},
{467052215, 95717636},
{478053039, 84511285},
{478056214, 65697616},
{468552215, 65697616},
{468563959, 33957323},
{465152221, 31684687},
},
{
},
},
{
{
{764927063, 92658416},
{762115426, 94171595},
{762122741, 131696443},
{786415417, 132779578},
{793690904, 129904572},
{797383202, 124822853},
{798269157, 120142660},
{796710161, 114090278},
{793387498, 110215980},
{796094093, 103892242},
{794107594, 96994001},
{787445494, 92840355},
{764927063, 92658416},
},
{
},
},
{
{
{27496331, 123147467},
{3202195, 124246400},
{3203433, 205768600},
{20223453, 205775606},
{20223644, 163243606},
{31297341, 162189074},
{36789517, 155659691},
{36967183, 150566416},
{34468182, 145711036},
{38465496, 140400171},
{38952460, 132613091},
{34771593, 126022444},
{27496331, 123147467},
},
{
},
},
{
{
{797556553, 39197820},
{791313598, 39199767},
{789506233, 39864015},
{789522521, 48199767},
{775974570, 48195721},
{774022521, 50129235},
{774008720, 76258022},
{775974570, 78223833},
{789522521, 78219787},
{789522521, 86576919},
{797556547, 87221747},
{797556553, 39197820},
},
{
},
},
{
{
{676593113, 129820144},
{676565322, 164844636},
{701599609, 164858650},
{701599609, 129823260},
{676593113, 129820144},
},
{
},
},
{
{
{727646871, 93121321},
{709122741, 93122138},
{709122741, 125656310},
{718769809, 135145243},
{721622937, 135156111},
{724152429, 132626619},
{723734126, 112688301},
{725837154, 107378546},
{728976138, 104430846},
{735847924, 102664848},
{741289364, 104430846},
{745202882, 108599767},
{746590596, 114642158},
{751137173, 114644887},
{756151199, 109641674},
{756149037, 94634278},
{754642761, 93122138},
{727646871, 93121321},
},
{
},
},
{
{
{135915724, 185598906},
{131396265, 193419009},
{131399444, 197643260},
{140399444, 197636810},
{140399444, 199138818},
{157419464, 197643916},
{157422805, 193210743},
{153046747, 185604789},
{149044579, 185614655},
{147324399, 189850396},
{144168954, 191108901},
{141187892, 189479768},
{139917659, 185615382},
{135915724, 185598906},
},
{
},
},
{
{
{312619110, 154485844},
{309601817, 157488332},
{309599764, 203494810},
{313109244, 207010010},
{352900849, 207019221},
{359629120, 200302405},
{359638705, 159501827},
{354621096, 154487830},
{312619110, 154485844},
},
{
},
},
{
{
{313120315, 98984639},
{309609100, 102486971},
{309596977, 148492024},
{312591195, 151510010},
{354608772, 151524494},
{359629120, 146515788},
{359638123, 105715491},
{352907860, 98987790},
{313120315, 98984639},
},
{
},
},
{
{
{657746643, 86246732},
{651722477, 92270881},
{651720052, 131280884},
{653947196, 131280884},
{659746643, 125487816},
{659746643, 119273826},
{663742413, 112352691},
{671726623, 112352691},
{675733721, 119283349},
{684745297, 119298573},
{689758503, 114263168},
{689752066, 91272158},
{684746643, 86260871},
{657746643, 86246732},
},
{
},
},
{
{
{653940791, 39260871},
{651720052, 39260871},
{651726623, 78280611},
{657746631, 84295035},
{684746643, 84280891},
{689752066, 79269604},
{689746643, 56247942},
{684745283, 51243184},
{675733721, 51258413},
{671726623, 58189071},
{663742413, 58189071},
{659746643, 51267936},
{659746643, 45053950},
{653940791, 39260871},
},
{
},
},
{
{
{442365208, 3053303},
{436408500, 5694021},
{434342552, 11072741},
{436986326, 17009033},
{442365367, 19073360},
{448299202, 16431441},
{450365150, 11052721},
{448299202, 5694021},
{442365208, 3053303},
},
{
},
},
};

View File

@@ -4,9 +4,37 @@
#include <vector>
#include <clipper.hpp>
#ifndef CLIPPER_BACKEND_HPP
namespace ClipperLib {
using PointImpl = IntPoint;
using PathImpl = Path;
using HoleStore = std::vector<PathImpl>;
struct PolygonImpl {
PathImpl Contour;
HoleStore Holes;
inline PolygonImpl() {}
inline explicit PolygonImpl(const PathImpl& cont): Contour(cont) {}
inline explicit PolygonImpl(const HoleStore& holes):
Holes(holes) {}
inline PolygonImpl(const Path& cont, const HoleStore& holes):
Contour(cont), Holes(holes) {}
inline explicit PolygonImpl(PathImpl&& cont): Contour(std::move(cont)) {}
inline explicit PolygonImpl(HoleStore&& holes): Holes(std::move(holes)) {}
inline PolygonImpl(Path&& cont, HoleStore&& holes):
Contour(std::move(cont)), Holes(std::move(holes)) {}
};
}
#endif
using TestData = std::vector<ClipperLib::Path>;
using TestDataEx = std::vector<ClipperLib::PolygonImpl>;
extern const TestData PRINTER_PART_POLYGONS;
extern const TestData STEGOSAUR_POLYGONS;
extern const TestDataEx PRINTER_PART_POLYGONS_EX;
#endif // PRINTER_PARTS_H

View File

@@ -1,114 +0,0 @@
#ifndef SVGTOOLS_HPP
#define SVGTOOLS_HPP
#include <iostream>
#include <fstream>
#include <string>
#include <libnest2d.h>
#include <libnest2d/geometries_io.hpp>
namespace libnest2d { namespace svg {
class SVGWriter {
public:
enum OrigoLocation {
TOPLEFT,
BOTTOMLEFT
};
struct Config {
OrigoLocation origo_location;
Coord mm_in_coord_units;
double width, height;
Config():
origo_location(BOTTOMLEFT), mm_in_coord_units(1000000),
width(500), height(500) {}
};
private:
Config conf_;
std::vector<std::string> svg_layers_;
bool finished_ = false;
public:
SVGWriter(const Config& conf = Config()):
conf_(conf) {}
void setSize(const Box& box) {
conf_.height = static_cast<double>(box.height()) /
conf_.mm_in_coord_units;
conf_.width = static_cast<double>(box.width()) /
conf_.mm_in_coord_units;
}
void writeItem(const Item& item) {
if(svg_layers_.empty()) addLayer();
Item tsh(item.transformedShape());
if(conf_.origo_location == BOTTOMLEFT)
for(unsigned i = 0; i < tsh.vertexCount(); i++) {
auto v = tsh.vertex(i);
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(),
1.0/conf_.mm_in_coord_units) + "\n";
}
void writePackGroup(const PackGroup& result) {
for(auto r : result) {
addLayer();
for(Item& sh : r) {
writeItem(sh);
}
finishLayer();
}
}
void addLayer() {
svg_layers_.emplace_back(header());
finished_ = false;
}
void finishLayer() {
currentLayer() += "\n</svg>\n";
finished_ = true;
}
void save(const std::string& filepath) {
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) : "") +
".svg", std::fstream::out);
if(out.is_open()) out << lyr;
if(lyrc == last && !finished_) out << "\n</svg>\n";
out.flush(); out.close(); lyrc++;
};
}
private:
std::string& currentLayer() { return svg_layers_.back(); }
const std::string header() const {
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=")raw";
svg_header += std::to_string(conf_.height) + "\" width=\"" + std::to_string(conf_.width) + "\" ";
svg_header += R"raw(xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">)raw";
return svg_header;
}
};
}
}
#endif // SVGTOOLS_HPP

View File

@@ -3,8 +3,8 @@
#include <libnest2d.h>
#include "printer_parts.h"
#include <libnest2d/geometries_io.hpp>
#include <libnest2d/geometries_nfp.hpp>
#include <libnest2d/geometry_traits_nfp.hpp>
//#include "../tools/libnfpglue.hpp"
std::vector<libnest2d::Item>& prusaParts() {
static std::vector<libnest2d::Item> ret;
@@ -622,26 +622,65 @@ std::vector<ItemPair> nfp_testdata = {
}
};
}
std::vector<ItemPair> nfp_concave_testdata = {
{ // ItemPair
{
{
{533726, 142141},
{532359, 143386},
{530141, 142155},
{528649, 160091},
{533659, 157607},
{538669, 160091},
{537178, 142155},
{534959, 143386},
{533726, 142141},
}
},
{
{
{118305, 11603},
{118311, 26616},
{113311, 26611},
{109311, 29604},
{109300, 44608},
{109311, 49631},
{113300, 52636},
{118311, 52636},
{118308, 103636},
{223830, 103636},
{236845, 90642},
{236832, 11630},
{232825, 11616},
{210149, 11616},
{211308, 13625},
{209315, 17080},
{205326, 17080},
{203334, 13629},
{204493, 11616},
{118305, 11603},
}
},
}
};
TEST(GeometryAlgorithms, nfpConvexConvex) {
template<NfpLevel lvl, Coord SCALE>
void testNfp(const std::vector<ItemPair>& testdata) {
using namespace libnest2d;
const Coord SCALE = 1000000;
Box bin(210*SCALE, 250*SCALE);
int testcase = 0;
auto& exportfun = exportSVG<1, Box>;
auto& exportfun = exportSVG<SCALE, Box>;
auto onetest = [&](Item& orbiter, Item& stationary){
testcase++;
orbiter.translate({210*SCALE, 0});
auto&& nfp = Nfp::noFitPolygon(stationary.rawShape(),
orbiter.transformedShape());
auto&& nfp = Nfp::noFitPolygon<lvl>(stationary.rawShape(),
orbiter.transformedShape());
auto v = ShapeLike::isValid(nfp);
@@ -667,11 +706,9 @@ TEST(GeometryAlgorithms, nfpConvexConvex) {
tmp.translate({dx, dy});
bool notinside = !tmp.isInside(stationary);
bool notintersecting = !Item::intersects(tmp, stationary) ||
Item::touches(tmp, stationary);
bool touching = Item::touches(tmp, stationary);
if(!(notinside && notintersecting)) {
if(!touching) {
std::vector<std::reference_wrapper<Item>> inp = {
std::ref(stationary), std::ref(tmp), std::ref(infp)
};
@@ -679,23 +716,31 @@ TEST(GeometryAlgorithms, nfpConvexConvex) {
exportfun(inp, bin, testcase*i++);
}
ASSERT_TRUE(notintersecting);
ASSERT_TRUE(notinside);
ASSERT_TRUE(touching);
}
};
for(auto& td : nfp_testdata) {
for(auto& td : testdata) {
auto orbiter = td.orbiter;
auto stationary = td.stationary;
onetest(orbiter, stationary);
}
for(auto& td : nfp_testdata) {
for(auto& td : testdata) {
auto orbiter = td.stationary;
auto stationary = td.orbiter;
onetest(orbiter, stationary);
}
}
}
TEST(GeometryAlgorithms, nfpConvexConvex) {
testNfp<NfpLevel::CONVEX_ONLY, 1>(nfp_testdata);
}
//TEST(GeometryAlgorithms, nfpConcaveConcave) {
// testNfp<NfpLevel::BOTH_CONCAVE, 1000>(nfp_concave_testdata);
//}
TEST(GeometryAlgorithms, pointOnPolygonContour) {
using namespace libnest2d;
@@ -718,6 +763,29 @@ TEST(GeometryAlgorithms, pointOnPolygonContour) {
}
}
TEST(GeometryAlgorithms, mergePileWithPolygon) {
using namespace libnest2d;
Rectangle rect1(10, 15);
Rectangle rect2(15, 15);
Rectangle rect3(20, 15);
rect2.translate({10, 0});
rect3.translate({25, 0});
ShapeLike::Shapes<PolygonImpl> pile;
pile.push_back(rect1.transformedShape());
pile.push_back(rect2.transformedShape());
auto result = Nfp::merge(pile, rect3.transformedShape());
ASSERT_EQ(result.size(), 1);
Rectangle ref(45, 15);
ASSERT_EQ(ShapeLike::area(result.front()), ref.area());
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();