Usable workaround for missing items when filling the bed

This commit is contained in:
tamasmeszaros 2023-07-21 21:21:07 +02:00
parent 9c7fd4f692
commit e90f9e7088
2 changed files with 46 additions and 1 deletions

View File

@ -107,6 +107,30 @@ template<class ArrItem> int raise_priority(ArrItem &itm)
return ret;
}
template<class ArrItem> int reduce_priority(ArrItem &itm)
{
int ret = get_priority(itm) - 1;
set_priority(itm, ret);
return ret;
}
template<class It> int lowest_priority(const Range<It> &item_range)
{
auto minp_it = std::min_element(item_range.begin(),
item_range.end(),
[](auto &itm1, auto &itm2) {
return get_priority(itm1) <
get_priority(itm2);
});
int min_priority = 0;
if (minp_it != item_range.end())
min_priority = get_priority(*minp_it);
return min_priority;
}
}} // namespace Slic3r::arr2
#endif // WRITABLEITEMTRAITS_HPP

View File

@ -66,6 +66,17 @@ void extract(FillBedTask<ArrItem> &task,
if (!task.prototype_item)
return;
// Workaround for missing items when arranging the same geometry only:
// Injecting a number of items but with slightly shrinked shape, so that
// they can fill the emerging holes. Priority is set to lowest so that
// these filler items will only be inserted as the last ones.
ArrItem prototype_item_shrinked;
scene.model().visit_arrangeable(selected_ids.front(),
[&prototype_item_shrinked, &itm_conv](const Arrangeable &arrbl) {
if (arrbl.is_printable())
prototype_item_shrinked = itm_conv.convert(arrbl, -SCALED_EPSILON);
});
set_bed_index(*task.prototype_item, Unarranged);
auto collect_task_items = [&prototype_geometry_id, &task,
@ -82,6 +93,10 @@ void extract(FillBedTask<ArrItem> &task,
}
};
// Set the lowest priority to the shrinked prototype (hole filler) item
set_priority(prototype_item_shrinked,
lowest_priority(range(task.selected)) - 1);
scene.model().for_each_arrangeable(collect_task_items);
int needed_items = calculate_items_needed_to_fill_bed(task.bed,
@ -93,6 +108,11 @@ void extract(FillBedTask<ArrItem> &task,
task.selected.reserve(task.selected.size() + needed_items);
std::fill_n(std::back_inserter(task.selected), needed_items,
*task.prototype_item);
// Add as many filler items as there are needed items. Most of them will
// be discarded anyways.
std::fill_n(std::back_inserter(task.selected), needed_items,
prototype_item_shrinked);
}
@ -143,7 +163,8 @@ std::unique_ptr<FillBedTaskResult> FillBedTask<ArrItem>::process_native(
void on_packed(ArrItem &itm) override
{
do_stop = get_bed_index(itm) > PhysicalBedId && get_priority(itm) == 0;
// Stop at the first filler that is not on the physical bed
do_stop = get_bed_index(itm) > PhysicalBedId && get_priority(itm) < 0;
}
} subctl(ctl, *this);