mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 18:29:05 +08:00
parent
708f58949d
commit
b2a2710128
@ -93,6 +93,11 @@ template<class ArrItem> bool is_fixed(const ArrItem &ap)
|
||||
return get_bed_index(ap) >= PhysicalBedId;
|
||||
}
|
||||
|
||||
template<class ArrItem> bool is_on_physical_bed(const ArrItem &ap)
|
||||
{
|
||||
return get_bed_index(ap) == PhysicalBedId;
|
||||
}
|
||||
|
||||
template<class ArrItem> void translate(ArrItem &ap, const Vec2crd &t)
|
||||
{
|
||||
set_translation(ap, get_translation(ap) + t);
|
||||
|
@ -19,6 +19,36 @@ struct CenterAlignmentFn {
|
||||
}
|
||||
};
|
||||
|
||||
template<class ArrItem>
|
||||
struct RectangleOverfitPackingContext : public DefaultPackingContext<ArrItem>
|
||||
{
|
||||
BoundingBox limits;
|
||||
int bed_index;
|
||||
PostAlignmentFn post_alignment_fn;
|
||||
|
||||
explicit RectangleOverfitPackingContext(const BoundingBox limits,
|
||||
int bedidx,
|
||||
PostAlignmentFn alignfn = CenterAlignmentFn{})
|
||||
: limits{limits}, bed_index{bedidx}, post_alignment_fn{alignfn}
|
||||
{}
|
||||
|
||||
void align_pile()
|
||||
{
|
||||
// Here, the post alignment can be safely done. No throwing
|
||||
// functions are called!
|
||||
if (fixed_items_range(*this).empty()) {
|
||||
auto itms = packed_items_range(*this);
|
||||
auto pilebb = bounding_box(itms);
|
||||
|
||||
for (auto &itm : itms) {
|
||||
translate(itm, post_alignment_fn(limits, pilebb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~RectangleOverfitPackingContext() { align_pile(); }
|
||||
};
|
||||
|
||||
// With rectange bed, and no fixed items, an infinite bed with
|
||||
// RectangleOverfitKernelWrapper can produce better results than a pure
|
||||
// RectangleBed with inner-fit polygon calculation.
|
||||
@ -29,31 +59,7 @@ struct RectangleOverfitPackingStrategy {
|
||||
PostAlignmentFn post_alignment_fn = CenterAlignmentFn{};
|
||||
|
||||
template<class ArrItem>
|
||||
struct Context: public DefaultPackingContext<ArrItem> {
|
||||
BoundingBox limits;
|
||||
int bed_index;
|
||||
PostAlignmentFn post_alignment_fn;
|
||||
|
||||
explicit Context(const BoundingBox limits,
|
||||
int bedidx,
|
||||
PostAlignmentFn alignfn = CenterAlignmentFn{})
|
||||
: limits{limits}, bed_index{bedidx}, post_alignment_fn{alignfn}
|
||||
{}
|
||||
|
||||
~Context()
|
||||
{
|
||||
// Here, the post alignment can be safely done. No throwing
|
||||
// functions are called!
|
||||
if (fixed_items_range(*this).empty()) {
|
||||
auto itms = packed_items_range(*this);
|
||||
auto pilebb = bounding_box(itms);
|
||||
|
||||
for (auto &itm : itms) {
|
||||
translate(itm, post_alignment_fn(limits, pilebb));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
using Context = RectangleOverfitPackingContext<ArrItem>;
|
||||
|
||||
RectangleOverfitPackingStrategy(PackStrategyNFP<Args...> s,
|
||||
PostAlignmentFn post_align_fn)
|
||||
@ -89,6 +95,19 @@ struct PackStrategyTraits_<RectangleOverfitPackingStrategy<Args...>> {
|
||||
}
|
||||
};
|
||||
|
||||
template<class ArrItem>
|
||||
struct PackingContextTraits_<RectangleOverfitPackingContext<ArrItem>>
|
||||
: public PackingContextTraits_<DefaultPackingContext<ArrItem>>
|
||||
{
|
||||
static void add_packed_item(RectangleOverfitPackingContext<ArrItem> &ctx, ArrItem &itm)
|
||||
{
|
||||
ctx.add_packed_item(itm);
|
||||
|
||||
// to prevent coords going out of range
|
||||
ctx.align_pile();
|
||||
}
|
||||
};
|
||||
|
||||
template<class Strategy, class ArrItem, class Bed, class RemIt>
|
||||
bool pack(Strategy &strategy,
|
||||
const Bed &bed,
|
||||
|
@ -54,6 +54,20 @@ std::unique_ptr<ArrangeTask<ArrItem>> ArrangeTask<ArrItem>::create(
|
||||
return task;
|
||||
}
|
||||
|
||||
// Remove all items on the physical bed (not occupyable for unprintable items)
|
||||
// and shift all items to the next lower bed index, so that arrange will think
|
||||
// that logical bed no. 1 is the physical one
|
||||
template<class ItemCont>
|
||||
void prepare_fixed_unselected(ItemCont &items, int shift)
|
||||
{
|
||||
for (auto &itm : items)
|
||||
set_bed_index(itm, get_bed_index(itm) - shift);
|
||||
|
||||
items.erase(std::remove_if(items.begin(), items.end(),
|
||||
[](auto &itm) { return !is_arranged(itm); }),
|
||||
items.end());
|
||||
}
|
||||
|
||||
template<class ArrItem>
|
||||
std::unique_ptr<ArrangeTaskResult>
|
||||
ArrangeTask<ArrItem>::process_native(Ctl &ctl)
|
||||
@ -78,8 +92,15 @@ ArrangeTask<ArrItem>::process_native(Ctl &ctl)
|
||||
|
||||
} subctl{ctl, *this};
|
||||
|
||||
arranger->arrange(printable.selected, printable.unselected, bed, subctl);
|
||||
arranger->arrange(unprintable.selected, unprintable.unselected, bed, ctl);
|
||||
auto fixed_items = printable.unselected;
|
||||
|
||||
// static (unselected) unprintable objects should not be overlapped by
|
||||
// movable and printable objects
|
||||
std::copy(unprintable.unselected.begin(),
|
||||
unprintable.unselected.end(),
|
||||
std::back_inserter(fixed_items));
|
||||
|
||||
arranger->arrange(printable.selected, fixed_items, bed, subctl);
|
||||
|
||||
// Unprintable items should go to the first bed not containing any printable
|
||||
// items
|
||||
@ -89,6 +110,10 @@ ArrangeTask<ArrItem>::process_native(Ctl &ctl)
|
||||
// If there are no printables, leave the physical bed empty
|
||||
beds = std::max(beds, size_t{1});
|
||||
|
||||
prepare_fixed_unselected(unprintable.unselected, beds);
|
||||
|
||||
arranger->arrange(unprintable.selected, unprintable.unselected, bed, ctl);
|
||||
|
||||
result->add_items(crange(printable.selected));
|
||||
|
||||
for (auto &itm : unprintable.selected) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user