mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 15:59:01 +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;
|
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)
|
template<class ArrItem> void translate(ArrItem &ap, const Vec2crd &t)
|
||||||
{
|
{
|
||||||
set_translation(ap, get_translation(ap) + 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
|
// With rectange bed, and no fixed items, an infinite bed with
|
||||||
// RectangleOverfitKernelWrapper can produce better results than a pure
|
// RectangleOverfitKernelWrapper can produce better results than a pure
|
||||||
// RectangleBed with inner-fit polygon calculation.
|
// RectangleBed with inner-fit polygon calculation.
|
||||||
@ -29,31 +59,7 @@ struct RectangleOverfitPackingStrategy {
|
|||||||
PostAlignmentFn post_alignment_fn = CenterAlignmentFn{};
|
PostAlignmentFn post_alignment_fn = CenterAlignmentFn{};
|
||||||
|
|
||||||
template<class ArrItem>
|
template<class ArrItem>
|
||||||
struct Context: public DefaultPackingContext<ArrItem> {
|
using Context = RectangleOverfitPackingContext<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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RectangleOverfitPackingStrategy(PackStrategyNFP<Args...> s,
|
RectangleOverfitPackingStrategy(PackStrategyNFP<Args...> s,
|
||||||
PostAlignmentFn post_align_fn)
|
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>
|
template<class Strategy, class ArrItem, class Bed, class RemIt>
|
||||||
bool pack(Strategy &strategy,
|
bool pack(Strategy &strategy,
|
||||||
const Bed &bed,
|
const Bed &bed,
|
||||||
|
@ -54,6 +54,20 @@ std::unique_ptr<ArrangeTask<ArrItem>> ArrangeTask<ArrItem>::create(
|
|||||||
return task;
|
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>
|
template<class ArrItem>
|
||||||
std::unique_ptr<ArrangeTaskResult>
|
std::unique_ptr<ArrangeTaskResult>
|
||||||
ArrangeTask<ArrItem>::process_native(Ctl &ctl)
|
ArrangeTask<ArrItem>::process_native(Ctl &ctl)
|
||||||
@ -78,8 +92,15 @@ ArrangeTask<ArrItem>::process_native(Ctl &ctl)
|
|||||||
|
|
||||||
} subctl{ctl, *this};
|
} subctl{ctl, *this};
|
||||||
|
|
||||||
arranger->arrange(printable.selected, printable.unselected, bed, subctl);
|
auto fixed_items = printable.unselected;
|
||||||
arranger->arrange(unprintable.selected, unprintable.unselected, bed, ctl);
|
|
||||||
|
// 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
|
// Unprintable items should go to the first bed not containing any printable
|
||||||
// items
|
// items
|
||||||
@ -89,6 +110,10 @@ ArrangeTask<ArrItem>::process_native(Ctl &ctl)
|
|||||||
// If there are no printables, leave the physical bed empty
|
// If there are no printables, leave the physical bed empty
|
||||||
beds = std::max(beds, size_t{1});
|
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));
|
result->add_items(crange(printable.selected));
|
||||||
|
|
||||||
for (auto &itm : unprintable.selected) {
|
for (auto &itm : unprintable.selected) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user