mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 17:39:04 +08:00
Merge branch 'tm_fix_xl_arrange_rebase_SPE-2033' into master_27x
This commit is contained in:
commit
a084471740
@ -61,7 +61,7 @@ class DefaultArrangerCtl : public Arranger<ArrItem>::Ctl {
|
|||||||
public:
|
public:
|
||||||
DefaultArrangerCtl() = default;
|
DefaultArrangerCtl() = default;
|
||||||
|
|
||||||
explicit DefaultArrangerCtl(ArrangeTaskBase::Ctl &ctl) : taskctl{&ctl} {}
|
explicit DefaultArrangerCtl(ArrangeTaskCtl &ctl) : taskctl{&ctl} {}
|
||||||
|
|
||||||
void update_status(int st) override
|
void update_status(int st) override
|
||||||
{
|
{
|
||||||
|
@ -292,7 +292,7 @@ class DefaultArranger: public Arranger<ArrItem> {
|
|||||||
|
|
||||||
firstfit::SelectionStrategy sel{cmpfn, on_arranged, stop_cond};
|
firstfit::SelectionStrategy sel{cmpfn, on_arranged, stop_cond};
|
||||||
|
|
||||||
constexpr auto ep = ex_tbb;
|
constexpr auto ep = ex_seq;
|
||||||
|
|
||||||
VariantKernel basekernel;
|
VariantKernel basekernel;
|
||||||
switch (m_settings.get_arrange_strategy()) {
|
switch (m_settings.get_arrange_strategy()) {
|
||||||
@ -328,7 +328,7 @@ class DefaultArranger: public Arranger<ArrItem> {
|
|||||||
// a pure RectangleBed with inner-fit polygon calculation.
|
// a pure RectangleBed with inner-fit polygon calculation.
|
||||||
if (!with_wipe_tower &&
|
if (!with_wipe_tower &&
|
||||||
m_settings.get_arrange_strategy() == ArrangeSettingsView::asAuto &&
|
m_settings.get_arrange_strategy() == ArrangeSettingsView::asAuto &&
|
||||||
std::is_convertible_v<Bed, RectangleBed>) {
|
IsRectangular<Bed>) {
|
||||||
PackStrategyNFP base_strategy{std::move(kernel), ep, Accuracy, stop_cond};
|
PackStrategyNFP base_strategy{std::move(kernel), ep, Accuracy, stop_cond};
|
||||||
|
|
||||||
RectangleOverfitPackingStrategy final_strategy{std::move(base_strategy)};
|
RectangleOverfitPackingStrategy final_strategy{std::move(base_strategy)};
|
||||||
|
@ -184,6 +184,12 @@ inline ExPolygons to_expolygons(const ArrangeBed &bed)
|
|||||||
|
|
||||||
ArrangeBed to_arrange_bed(const Points &bedpts);
|
ArrangeBed to_arrange_bed(const Points &bedpts);
|
||||||
|
|
||||||
|
template<class Bed, class En = void> struct IsRectangular_ : public std::false_type {};
|
||||||
|
template<> struct IsRectangular_<RectangleBed>: public std::true_type {};
|
||||||
|
template<> struct IsRectangular_<BoundingBox>: public std::true_type {};
|
||||||
|
|
||||||
|
template<class Bed> static constexpr bool IsRectangular = IsRectangular_<Bed>::value;
|
||||||
|
|
||||||
} // namespace arr2
|
} // namespace arr2
|
||||||
|
|
||||||
inline BoundingBox &bounding_box(BoundingBox &bb) { return bb; }
|
inline BoundingBox &bounding_box(BoundingBox &bb) { return bb; }
|
||||||
|
@ -54,9 +54,9 @@ protected:
|
|||||||
public:
|
public:
|
||||||
TMArrangeKernel() = default;
|
TMArrangeKernel() = default;
|
||||||
TMArrangeKernel(Vec2crd gravity_center, size_t itm_cnt, double bedarea = NaNd)
|
TMArrangeKernel(Vec2crd gravity_center, size_t itm_cnt, double bedarea = NaNd)
|
||||||
: sink{gravity_center}
|
: m_bin_area(bedarea)
|
||||||
, m_bin_area(bedarea)
|
|
||||||
, m_item_cnt{itm_cnt}
|
, m_item_cnt{itm_cnt}
|
||||||
|
, sink{gravity_center}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TMArrangeKernel(size_t itm_cnt, double bedarea = NaNd)
|
TMArrangeKernel(size_t itm_cnt, double bedarea = NaNd)
|
||||||
@ -90,18 +90,12 @@ public:
|
|||||||
// Will hold the resulting score
|
// Will hold the resulting score
|
||||||
double score = 0;
|
double score = 0;
|
||||||
|
|
||||||
// Density is the pack density: how big is the arranged pile
|
|
||||||
double density = 0;
|
|
||||||
|
|
||||||
// Distinction of cases for the arrangement scene
|
// Distinction of cases for the arrangement scene
|
||||||
enum e_cases {
|
enum e_cases {
|
||||||
// This branch is for big items in a mixed (big and small) scene
|
// This branch is for big items in a mixed (big and small) scene
|
||||||
// OR for all items in a small-only scene.
|
// OR for all items in a small-only scene.
|
||||||
BIG_ITEM,
|
BIG_ITEM,
|
||||||
|
|
||||||
// This branch is for the last big item in a mixed scene
|
|
||||||
LAST_BIG_ITEM,
|
|
||||||
|
|
||||||
// For small items in a mixed scene.
|
// For small items in a mixed scene.
|
||||||
SMALL_ITEM,
|
SMALL_ITEM,
|
||||||
|
|
||||||
@ -112,10 +106,8 @@ public:
|
|||||||
bool bigitems = is_big(envelope_area(item)) || m_rtree.empty();
|
bool bigitems = is_big(envelope_area(item)) || m_rtree.empty();
|
||||||
if (is_wt)
|
if (is_wt)
|
||||||
compute_case = WIPE_TOWER;
|
compute_case = WIPE_TOWER;
|
||||||
else if (bigitems && m_rem_cnt > 0)
|
else if (bigitems)
|
||||||
compute_case = BIG_ITEM;
|
compute_case = BIG_ITEM;
|
||||||
else if (bigitems && m_rem_cnt == 0)
|
|
||||||
compute_case = LAST_BIG_ITEM;
|
|
||||||
else
|
else
|
||||||
compute_case = SMALL_ITEM;
|
compute_case = SMALL_ITEM;
|
||||||
|
|
||||||
@ -132,20 +124,8 @@ public:
|
|||||||
Point top_left{minc.x(), maxc.y()};
|
Point top_left{minc.x(), maxc.y()};
|
||||||
Point bottom_right{maxc.x(), minc.y()};
|
Point bottom_right{maxc.x(), minc.y()};
|
||||||
|
|
||||||
// Now the distance of the gravity center will be calculated to the
|
// The smallest distance from the arranged pile center:
|
||||||
// five anchor points and the smallest will be chosen.
|
double dist = norm((itmcntr - m_pilebb.center()).template cast<double>().norm());
|
||||||
std::array<double, 5> dists;
|
|
||||||
auto cc = fullbb.center(); // The gravity center
|
|
||||||
dists[0] = (minc - cc).cast<double>().norm();
|
|
||||||
dists[1] = (maxc - cc).cast<double>().norm();
|
|
||||||
dists[2] = (itmcntr - cc).template cast<double>().norm();
|
|
||||||
dists[3] = (top_left - cc).cast<double>().norm();
|
|
||||||
dists[4] = (bottom_right - cc).cast<double>().norm();
|
|
||||||
|
|
||||||
// The smalles distance from the arranged pile center:
|
|
||||||
double dist = norm(*(std::min_element(dists.begin(), dists.end())));
|
|
||||||
double bindist = norm((ibb.center() - active_sink).template cast<double>().norm());
|
|
||||||
dist = 0.8 * dist + 0.2 * bindist;
|
|
||||||
|
|
||||||
// Prepare a variable for the alignment score.
|
// Prepare a variable for the alignment score.
|
||||||
// This will indicate: how well is the candidate item
|
// This will indicate: how well is the candidate item
|
||||||
@ -153,7 +133,7 @@ public:
|
|||||||
// with all neighbors and return the score for the best
|
// with all neighbors and return the score for the best
|
||||||
// alignment. So it is enough for the candidate to be
|
// alignment. So it is enough for the candidate to be
|
||||||
// aligned with only one item.
|
// aligned with only one item.
|
||||||
auto alignment_score = 1.0;
|
auto alignment_score = 1.;
|
||||||
|
|
||||||
auto query = bgi::intersects(ibb);
|
auto query = bgi::intersects(ibb);
|
||||||
auto& index = is_big(envelope_area(item)) ? m_rtree : m_smallsrtree;
|
auto& index = is_big(envelope_area(item)) ? m_rtree : m_smallsrtree;
|
||||||
@ -173,31 +153,23 @@ public:
|
|||||||
auto bb = p.bb;
|
auto bb = p.bb;
|
||||||
bb.merge(ibb);
|
bb.merge(ibb);
|
||||||
auto bbarea = area(bb);
|
auto bbarea = area(bb);
|
||||||
auto ascore = 1.0 - (fixed_area(item) + parea) / bbarea;
|
auto ascore = 1.0 - (area(fixed_bounding_box(item)) + area(p.bb)) / bbarea;
|
||||||
|
|
||||||
if(ascore < alignment_score)
|
if(ascore < alignment_score)
|
||||||
alignment_score = ascore;
|
alignment_score = ascore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fullbbsz = fullbb.size();
|
|
||||||
density = std::sqrt(norm(fullbbsz.x()) * norm(fullbbsz.y()));
|
|
||||||
double R = double(m_rem_cnt) / (m_item_cnt);
|
double R = double(m_rem_cnt) / (m_item_cnt);
|
||||||
|
R = std::pow(R, 1./3.);
|
||||||
|
|
||||||
// The final mix of the score is the balance between the
|
// The final mix of the score is the balance between the
|
||||||
// distance from the full pile center, the pack density and
|
// distance from the full pile center, the pack density and
|
||||||
// the alignment with the neighbors
|
// the alignment with the neighbors
|
||||||
if (result.empty())
|
|
||||||
score = 0.50 * dist + 0.50 * density;
|
|
||||||
else
|
|
||||||
// Let the density matter more when fewer objects remain
|
|
||||||
score = 0.50 * dist + (1.0 - R) * 0.20 * density +
|
|
||||||
0.30 * alignment_score;
|
|
||||||
|
|
||||||
break;
|
// Let the density matter more when fewer objects remain
|
||||||
}
|
score = 0.6 * dist + 0.1 * alignment_score + (1.0 - R) * (0.3 * dist) + R * 0.3 * alignment_score;
|
||||||
case LAST_BIG_ITEM: {
|
|
||||||
score = norm((itmcntr - m_pilebb.center()).template cast<double>().norm());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMALL_ITEM: {
|
case SMALL_ITEM: {
|
||||||
@ -239,8 +211,11 @@ public:
|
|||||||
if (m_item_cnt == 0)
|
if (m_item_cnt == 0)
|
||||||
m_item_cnt = m_rem_cnt + fixed.size() + 1;
|
m_item_cnt = m_rem_cnt + fixed.size() + 1;
|
||||||
|
|
||||||
if (std::isnan(m_bin_area))
|
if (std::isnan(m_bin_area)) {
|
||||||
m_bin_area = area(bed);
|
auto sz = bounding_box(bed).size();
|
||||||
|
|
||||||
|
m_bin_area = scaled<double>(unscaled(sz.x()) * unscaled(sz.y()));
|
||||||
|
}
|
||||||
|
|
||||||
m_norm = std::sqrt(m_bin_area);
|
m_norm = std::sqrt(m_bin_area);
|
||||||
|
|
||||||
@ -248,7 +223,7 @@ public:
|
|||||||
m_itemstats.reserve(fixed.size());
|
m_itemstats.reserve(fixed.size());
|
||||||
m_rtree.clear();
|
m_rtree.clear();
|
||||||
m_smallsrtree.clear();
|
m_smallsrtree.clear();
|
||||||
m_pilebb = {};
|
m_pilebb = {active_sink, active_sink};
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
for (auto &fixitem : fixed) {
|
for (auto &fixitem : fixed) {
|
||||||
auto fixitmbb = fixed_bounding_box(fixitem);
|
auto fixitmbb = fixed_bounding_box(fixitem);
|
||||||
|
@ -104,6 +104,10 @@ ExPolygons to_expolygons(const SegmentedRectangleBed<Args...> &bed)
|
|||||||
return to_expolygons(RectangleBed{bed.bb});
|
return to_expolygons(RectangleBed{bed.bb});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class SegB>
|
||||||
|
struct IsRectangular_<SegB, std::enable_if_t<IsSegmentedBed<SegB>, void>> : public std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
}} // namespace Slic3r::arr2
|
}} // namespace Slic3r::arr2
|
||||||
|
|
||||||
#endif // SEGMENTEDRECTANGLEBED_HPP
|
#endif // SEGMENTEDRECTANGLEBED_HPP
|
||||||
|
@ -207,7 +207,7 @@ static void check_nfp(const std::string & outfile_prefix,
|
|||||||
auto orb_ex_offs_pos_r_ch = offset_ex(orb_ex_r_ch, scaled<float>(EPSILON));
|
auto orb_ex_offs_pos_r_ch = offset_ex(orb_ex_r_ch, scaled<float>(EPSILON));
|
||||||
auto orb_ex_offs_neg_r_ch = offset_ex(orb_ex_r_ch, -scaled<float>(EPSILON));
|
auto orb_ex_offs_neg_r_ch = offset_ex(orb_ex_r_ch, -scaled<float>(EPSILON));
|
||||||
|
|
||||||
auto bedpoly_offs = offset_ex(bedpoly, SCALED_EPSILON);
|
auto bedpoly_offs = offset_ex(bedpoly, static_cast<float>(SCALED_EPSILON));
|
||||||
|
|
||||||
auto check_at_nfppos = [&](const Point &pos) {
|
auto check_at_nfppos = [&](const Point &pos) {
|
||||||
ExPolygons orb_ex = orb_ex_r;
|
ExPolygons orb_ex = orb_ex_r;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user