SPE-2054: Fixed missing infills on multi-part models caused by 3cb2f5f58f952bc104260c84292411894f957552 reported in #11721.

The temporary variable used for reordering ExPolygons wasn't cleared, and it contained empty ExPolygons from previous reordering. This caused those empty ExPolygons replaced actual ExPolygons for infill.

Another issue was that m_fill_expolygons was reordered, but m_fill_expolygons_bboxes were left untouched.
This commit is contained in:
Lukáš Hejl 2024-01-03 15:35:40 +01:00
parent 285cb02d74
commit 7e889bbe7c

View File

@ -874,12 +874,14 @@ void Layer::sort_perimeters_into_islands(
int sort_region_id = -1;
// Temporary vector of fills for reordering.
ExPolygons fills_temp;
// Temporary vector of fill_bboxes for reordering.
BoundingBoxes fill_bboxes_temp;
// Vector of new positions of the above.
std::vector<int> new_positions;
do {
sort_region_id = -1;
for (size_t source_slice_idx = 0; source_slice_idx < fill_expolygons_ranges.size(); ++ source_slice_idx)
if (ExPolygonRange fill_range = fill_expolygons_ranges[source_slice_idx]; fill_range.size() > 1) {
if (const ExPolygonRange fill_range = fill_expolygons_ranges[source_slice_idx]; fill_range.size() > 1) {
// More than one expolygon exists for a single island. Check whether they are contiguous inside a single LayerRegion::fill_expolygons() vector.
uint32_t fill_idx = *fill_range.begin();
if (const int fill_regon_id = map_expolygon_to_region_and_fill[fill_idx].region_id; fill_regon_id != -1) {
@ -916,15 +918,23 @@ void Layer::sort_perimeters_into_islands(
// Not referenced by any map_expolygon_to_region_and_fill.
new_pos = last ++;
// Move just the content of m_fill_expolygons to fills_temp, but don't move the container vector.
auto &fills = layerm.m_fill_expolygons;
auto &fills = layerm.m_fill_expolygons;
auto &fill_bboxes = layerm.m_fill_expolygons_bboxes;
assert(fills.size() == fill_bboxes.size());
assert(last == int(fills.size()));
fills_temp.reserve(fills.size());
fills_temp.insert(fills_temp.end(), std::make_move_iterator(fills.begin()), std::make_move_iterator(fills.end()));
for (ExPolygon &ex : fills)
ex.clear();
// Move / reoder the expolygons back into m_fill_expolygons.
for (size_t old_pos = 0; old_pos < new_positions.size(); ++ old_pos)
fills[new_positions[old_pos]] = std::move(fills_temp[old_pos]);
fills_temp.resize(fills.size());
fills_temp.assign(std::make_move_iterator(fills.begin()), std::make_move_iterator(fills.end()));
fill_bboxes_temp.resize(fill_bboxes.size());
fill_bboxes_temp.assign(std::make_move_iterator(fill_bboxes.begin()), std::make_move_iterator(fill_bboxes.end()));
// Move / reorder the ExPolygons and BoundingBoxes back into m_fill_expolygons and m_fill_expolygons_bboxes.
for (size_t old_pos = 0; old_pos < new_positions.size(); ++old_pos) {
fills[new_positions[old_pos]] = std::move(fills_temp[old_pos]);
fill_bboxes[new_positions[old_pos]] = std::move(fill_bboxes_temp[old_pos]);
}
}
} while (sort_region_id != -1);
} else {
@ -956,7 +966,7 @@ void Layer::sort_perimeters_into_islands(
// Check whether the fill expolygons of this island were split into multiple regions.
island.fill_region_id = LayerIsland::fill_region_composite_id;
for (uint32_t fill_idx : fill_range) {
if (const int fill_regon_id = map_expolygon_to_region_and_fill[fill_idx].region_id;
if (const int fill_regon_id = map_expolygon_to_region_and_fill[fill_idx].region_id;
fill_regon_id == -1 || (island.fill_region_id != LayerIsland::fill_region_composite_id && int(island.fill_region_id) != fill_regon_id)) {
island.fill_region_id = LayerIsland::fill_region_composite_id;
break;