From 9857f7384b958aa0fa0e6844c39d099164617be1 Mon Sep 17 00:00:00 2001 From: miaoxin Date: Tue, 6 Dec 2022 17:10:35 +0800 Subject: [PATCH] ENH: auto-arrange uses inner NFP to simplify fixed_overfit 1. Add inner nfp algo.The final nfp result is inner nfp subtract outer nfp. 2. Leave 5(scaled) room in inflation to allow numeric float eps. Change-Id: I6be0b205c9811af24a238352b256bf1399ee3716 (cherry picked from commit dbab96efc7bfa16afd9db9607b862886606b0aa0) --- .../backends/libslic3r/geometries.hpp | 2 ++ .../include/libnest2d/geometry_traits_nfp.hpp | 36 +++++++++++++++++++ .../include/libnest2d/placers/nfpplacer.hpp | 7 ++-- src/libslic3r/Arrange.cpp | 8 ++--- src/slic3r/GUI/Jobs/ArrangeJob.cpp | 10 +++--- 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/libnest2d/include/libnest2d/backends/libslic3r/geometries.hpp b/src/libnest2d/include/libnest2d/backends/libslic3r/geometries.hpp index 14b075b19..63ed1c277 100644 --- a/src/libnest2d/include/libnest2d/backends/libslic3r/geometries.hpp +++ b/src/libnest2d/include/libnest2d/backends/libslic3r/geometries.hpp @@ -261,6 +261,8 @@ inline TMultiShape merge(const TMultiShape& shapes) return Slic3r::union_ex(shapes); } +inline TMultiShape subtract(const TMultiShape &outerBinNfp, const TMultiShape &shapes) { return Slic3r::diff_ex(outerBinNfp, shapes); } + } // namespace nfp } // namespace libnest2d diff --git a/src/libnest2d/include/libnest2d/geometry_traits_nfp.hpp b/src/libnest2d/include/libnest2d/geometry_traits_nfp.hpp index 70b300ef6..ab5f7678f 100644 --- a/src/libnest2d/include/libnest2d/geometry_traits_nfp.hpp +++ b/src/libnest2d/include/libnest2d/geometry_traits_nfp.hpp @@ -179,6 +179,42 @@ inline TPoint referenceVertex(const RawShape& sh) return rightmostUpVertex(sh); } +template inline NfpResult nfpInnerRectBed(const RawBox &bed, const RawShape &other) +{ + using Vertex = TPoint; + using Edge = _Segment; + namespace sl = shapelike; + + auto sbox = sl::boundingBox(other); + auto sheight = sbox.height(); + auto swidth = sbox.width(); + Vertex slidingTop = rightmostUpVertex(other); + auto leftOffset = slidingTop.x() - sbox.minCorner().x(); + auto rightOffset = slidingTop.x() - sbox.maxCorner().x(); + auto topOffset = 0; + auto bottomOffset = sheight; + + + auto boxWidth = bed.width(); + auto boxHeight = bed.height(); + + auto bedMinx = bed.minCorner().x(); + auto bedMiny = bed.minCorner().y(); + auto bedMaxx = bed.maxCorner().x(); + auto bedMaxy = bed.maxCorner().y(); + + RawShape innerNfp{{bedMinx + leftOffset, bedMaxy + topOffset}, + {bedMaxx + rightOffset, bedMaxy + topOffset}, + {bedMaxx + rightOffset, bedMiny + bottomOffset}, + {bedMinx + leftOffset, bedMiny + bottomOffset}, + {bedMinx + leftOffset, bedMaxy + topOffset}}; + if (sheight > boxHeight || swidth > boxWidth) { + return {{}, {0, 0}}; + } else { + return {innerNfp, {0, 0}}; + } +} + /** * The "trivial" Cuninghame-Green implementation of NFP for convex polygons. * diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp index 7272d4b01..08afd130b 100644 --- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp +++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp @@ -565,7 +565,7 @@ private: using Shapes = TMultiShape; - Shapes calcnfp(const Item &trsh, Lvl) + Shapes calcnfp(const Item &trsh, const Box& bed ,Lvl) { using namespace nfp; @@ -598,7 +598,8 @@ private: nfps[n] = subnfp_r.first; }); - return nfp::merge(nfps); + RawShape innerNfp = nfpInnerRectBed(bed, trsh.transformedShape()).first; + return nfp::subtract({innerNfp}, nfps); } @@ -738,7 +739,7 @@ private: // it is disjunct from the current merged pile placeOutsideOfBin(item); - nfps = calcnfp(item, Lvl()); + nfps = calcnfp(item, binbb, Lvl()); auto iv = item.referenceVertex(); diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 568d1a4d1..df7678f63 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -554,11 +554,11 @@ public: // 对于屏蔽区域,摆入的对象仍然是可以向右上滑动的; // 对挤出料塔,摆入的对象不能滑动(必须围绕料塔) bool pack_around_wipe_tower = std::any_of(packed_items.begin(), packed_items.end(), [](Item& itm) { return itm.is_wipe_tower; }); - if(pack_around_wipe_tower) + //if(pack_around_wipe_tower) return fixed_overfit(objfunc(item, starting_point), binbb); - else { - return fixed_overfit_topright_sliding(objfunc(item, starting_point), binbb, m_excluded_and_extruCali_regions); - } + //else { + // return fixed_overfit_topright_sliding(objfunc(item, starting_point), binbb, m_excluded_and_extruCali_regions); + //} }; }; diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 0fee1cc04..fc7b6025a 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -539,11 +539,11 @@ void ArrangeJob::process() std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon &ap) { ap.inflation = params.min_obj_distance / 2; BoundingBox apbb = ap.poly.contour.bounding_box(); - coord_t diffx = bedbb.size().x() - apbb.size().x(); - coord_t diffy = bedbb.size().y() - apbb.size().y(); - if (diffx > 0 && diffy > 0) { - coord_t min_diff = std::min(diffx, diffy); - ap.inflation = std::min(min_diff / 2, ap.inflation); + auto diffx = bedbb.size().x() - apbb.size().x() - 5; + auto diffy = bedbb.size().y() - apbb.size().y() - 5; + if (diffx > 0 && diffy > 0) { + auto min_diff = std::min(diffx, diffy); + ap.inflation = std::min(min_diff / 2, ap.inflation); } }); // For occulusion regions, inflation should be larger to prevent genrating brim on them.