mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-25 15:44:12 -06:00
Change to firstfit selection because DJD needs further testing.
This commit is contained in:
parent
eefa1678db
commit
6bcd735655
31 changed files with 4317 additions and 826 deletions
182
xs/src/libnest2d/tools/libnfpglue.cpp
Normal file
182
xs/src/libnest2d/tools/libnfpglue.cpp
Normal file
|
@ -0,0 +1,182 @@
|
|||
//#ifndef NDEBUG
|
||||
//#define NFP_DEBUG
|
||||
//#endif
|
||||
|
||||
#include "libnfpglue.hpp"
|
||||
#include "tools/libnfporb/libnfporb.hpp"
|
||||
|
||||
namespace libnest2d {
|
||||
|
||||
namespace {
|
||||
inline bool vsort(const libnfporb::point_t& v1, const libnfporb::point_t& v2)
|
||||
{
|
||||
using Coord = libnfporb::coord_t;
|
||||
Coord x1 = v1.x_, x2 = v2.x_, y1 = v1.y_, y2 = v2.y_;
|
||||
auto diff = y1 - y2;
|
||||
#ifdef LIBNFP_USE_RATIONAL
|
||||
long double diffv = diff.convert_to<long double>();
|
||||
#else
|
||||
long double diffv = diff.val();
|
||||
#endif
|
||||
if(std::abs(diffv) <=
|
||||
std::numeric_limits<Coord>::epsilon())
|
||||
return x1 < x2;
|
||||
|
||||
return diff < 0;
|
||||
}
|
||||
|
||||
TCoord<PointImpl> getX(const libnfporb::point_t& p) {
|
||||
#ifdef LIBNFP_USE_RATIONAL
|
||||
return p.x_.convert_to<TCoord<PointImpl>>();
|
||||
#else
|
||||
return static_cast<TCoord<PointImpl>>(std::round(p.x_.val()));
|
||||
#endif
|
||||
}
|
||||
|
||||
TCoord<PointImpl> getY(const libnfporb::point_t& p) {
|
||||
#ifdef LIBNFP_USE_RATIONAL
|
||||
return p.y_.convert_to<TCoord<PointImpl>>();
|
||||
#else
|
||||
return static_cast<TCoord<PointImpl>>(std::round(p.y_.val()));
|
||||
#endif
|
||||
}
|
||||
|
||||
libnfporb::point_t scale(const libnfporb::point_t& p, long double factor) {
|
||||
#ifdef LIBNFP_USE_RATIONAL
|
||||
auto px = p.x_.convert_to<long double>();
|
||||
auto py = p.y_.convert_to<long double>();
|
||||
#else
|
||||
long double px = p.x_.val();
|
||||
long double py = p.y_.val();
|
||||
#endif
|
||||
return libnfporb::point_t(px*factor, py*factor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PolygonImpl _nfp(const PolygonImpl &sh, const PolygonImpl &cother)
|
||||
{
|
||||
using Vertex = PointImpl;
|
||||
|
||||
PolygonImpl ret;
|
||||
|
||||
// try {
|
||||
libnfporb::polygon_t pstat, porb;
|
||||
|
||||
boost::geometry::convert(sh, pstat);
|
||||
boost::geometry::convert(cother, porb);
|
||||
|
||||
long double factor = 0.0000001;//libnfporb::NFP_EPSILON;
|
||||
long double refactor = 1.0/factor;
|
||||
|
||||
for(auto& v : pstat.outer()) v = scale(v, factor);
|
||||
// std::string message;
|
||||
// boost::geometry::is_valid(pstat, message);
|
||||
// std::cout << message << std::endl;
|
||||
for(auto& h : pstat.inners()) for(auto& v : h) v = scale(v, factor);
|
||||
|
||||
for(auto& v : porb.outer()) v = scale(v, factor);
|
||||
// message;
|
||||
// boost::geometry::is_valid(porb, message);
|
||||
// std::cout << message << std::endl;
|
||||
for(auto& h : porb.inners()) for(auto& v : h) v = scale(v, factor);
|
||||
|
||||
|
||||
// this can throw
|
||||
auto nfp = libnfporb::generateNFP(pstat, porb, true);
|
||||
|
||||
auto &ct = ShapeLike::getContour(ret);
|
||||
ct.reserve(nfp.front().size()+1);
|
||||
for(auto v : nfp.front()) {
|
||||
v = scale(v, refactor);
|
||||
ct.emplace_back(getX(v), getY(v));
|
||||
}
|
||||
ct.push_back(ct.front());
|
||||
std::reverse(ct.begin(), ct.end());
|
||||
|
||||
auto &rholes = ShapeLike::holes(ret);
|
||||
for(size_t hidx = 1; hidx < nfp.size(); ++hidx) {
|
||||
if(nfp[hidx].size() >= 3) {
|
||||
rholes.push_back({});
|
||||
auto& h = rholes.back();
|
||||
h.reserve(nfp[hidx].size()+1);
|
||||
|
||||
for(auto& v : nfp[hidx]) {
|
||||
v = scale(v, refactor);
|
||||
h.emplace_back(getX(v), getY(v));
|
||||
}
|
||||
h.push_back(h.front());
|
||||
std::reverse(h.begin(), h.end());
|
||||
}
|
||||
}
|
||||
|
||||
auto& cmp = vsort;
|
||||
std::sort(pstat.outer().begin(), pstat.outer().end(), cmp);
|
||||
std::sort(porb.outer().begin(), porb.outer().end(), cmp);
|
||||
|
||||
// leftmost lower vertex of the stationary polygon
|
||||
auto& touch_sh = scale(pstat.outer().back(), refactor);
|
||||
// rightmost upper vertex of the orbiting polygon
|
||||
auto& touch_other = scale(porb.outer().front(), refactor);
|
||||
|
||||
// Calculate the difference and move the orbiter to the touch position.
|
||||
auto dtouch = touch_sh - touch_other;
|
||||
auto _top_other = scale(porb.outer().back(), refactor) + dtouch;
|
||||
|
||||
Vertex top_other(getX(_top_other), getY(_top_other));
|
||||
|
||||
// Get the righmost upper vertex of the nfp and move it to the RMU of
|
||||
// the orbiter because they should coincide.
|
||||
auto&& top_nfp = Nfp::rightmostUpVertex(ret);
|
||||
auto dnfp = top_other - top_nfp;
|
||||
|
||||
std::for_each(ShapeLike::begin(ret), ShapeLike::end(ret),
|
||||
[&dnfp](Vertex& v) { v+= dnfp; } );
|
||||
|
||||
for(auto& h : ShapeLike::holes(ret))
|
||||
std::for_each( h.begin(), h.end(),
|
||||
[&dnfp](Vertex& v) { v += dnfp; } );
|
||||
|
||||
// } catch(std::exception& e) {
|
||||
// std::cout << "Error: " << e.what() << "\nTrying with convex hull..." << std::endl;
|
||||
// auto ch_stat = ShapeLike::convexHull(sh);
|
||||
// auto ch_orb = ShapeLike::convexHull(cother);
|
||||
// ret = Nfp::nfpConvexOnly(ch_stat, ch_orb);
|
||||
// }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PolygonImpl Nfp::NfpImpl<PolygonImpl, NfpLevel::CONVEX_ONLY>::operator()(
|
||||
const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
|
||||
{
|
||||
return _nfp(sh, cother);//nfpConvexOnly(sh, cother);
|
||||
}
|
||||
|
||||
PolygonImpl Nfp::NfpImpl<PolygonImpl, NfpLevel::ONE_CONVEX>::operator()(
|
||||
const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
|
||||
{
|
||||
return _nfp(sh, cother);
|
||||
}
|
||||
|
||||
PolygonImpl Nfp::NfpImpl<PolygonImpl, NfpLevel::BOTH_CONCAVE>::operator()(
|
||||
const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
|
||||
{
|
||||
return _nfp(sh, cother);
|
||||
}
|
||||
|
||||
PolygonImpl
|
||||
Nfp::NfpImpl<PolygonImpl, NfpLevel::ONE_CONVEX_WITH_HOLES>::operator()(
|
||||
const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
|
||||
{
|
||||
return _nfp(sh, cother);
|
||||
}
|
||||
|
||||
PolygonImpl
|
||||
Nfp::NfpImpl<PolygonImpl, NfpLevel::BOTH_CONCAVE_WITH_HOLES>::operator()(
|
||||
const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
|
||||
{
|
||||
return _nfp(sh, cother);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue