Fix layer path order when multi-layer elephant compensation is used (#2443)

This commit is contained in:
Noisyfox 2023-10-19 06:57:53 -05:00 committed by GitHub
parent 075a08bca8
commit 56fdbf5310
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1080,12 +1080,13 @@ void PrintObject::slice_volumes()
// Only enable Elephant foot compensation if printing directly on the print bed. // Only enable Elephant foot compensation if printing directly on the print bed.
float(scale_(m_config.elefant_foot_compensation.value)) : float(scale_(m_config.elefant_foot_compensation.value)) :
0.f; 0.f;
// Uncompensated slices for the first layer in case the Elephant foot compensation is applied. // Uncompensated slices for the layers in case the Elephant foot compensation is applied.
ExPolygons lslices_1st_layer; std::vector<ExPolygons> lslices_elfoot_uncompensated;
lslices_elfoot_uncompensated.resize(elephant_foot_compensation_scaled > 0 ? std::min(m_config.elefant_foot_compensation_layers.value, (int)m_layers.size()) : 0);
//BBS: this part has been changed a lot to support seperated contour and hole size compensation //BBS: this part has been changed a lot to support seperated contour and hole size compensation
tbb::parallel_for( tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()), tbb::blocked_range<size_t>(0, m_layers.size()),
[this, xy_hole_scaled, xy_contour_scaled, elephant_foot_compensation_scaled, &lslices_1st_layer](const tbb::blocked_range<size_t>& range) { [this, xy_hole_scaled, xy_contour_scaled, elephant_foot_compensation_scaled, &lslices_elfoot_uncompensated](const tbb::blocked_range<size_t>& range) {
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
m_print->throw_if_canceled(); m_print->throw_if_canceled();
Layer *layer = m_layers[layer_id]; Layer *layer = m_layers[layer_id];
@ -1098,21 +1099,22 @@ void PrintObject::slice_volumes()
// Single region, growing or shrinking. // Single region, growing or shrinking.
LayerRegion *layerm = layer->m_regions.front(); LayerRegion *layerm = layer->m_regions.front();
if (elfoot > 0) { if (elfoot > 0) {
// Apply the elephant foot compensation and store the 1st layer slices without the Elephant foot compensation applied. // Apply the elephant foot compensation and store the original layer slices without the Elephant foot compensation applied.
lslices_1st_layer = to_expolygons(std::move(layerm->slices.surfaces)); ExPolygons expolygons_to_compensate = to_expolygons(std::move(layerm->slices.surfaces));
if (xy_contour_scaled > 0 || xy_hole_scaled > 0) { if (xy_contour_scaled > 0 || xy_hole_scaled > 0) {
lslices_1st_layer = _shrink_contour_holes(std::max(0.f, xy_contour_scaled), expolygons_to_compensate = _shrink_contour_holes(std::max(0.f, xy_contour_scaled),
std::max(0.f, xy_hole_scaled), std::max(0.f, xy_hole_scaled),
lslices_1st_layer); expolygons_to_compensate);
} }
if (xy_contour_scaled < 0 || xy_hole_scaled < 0) { if (xy_contour_scaled < 0 || xy_hole_scaled < 0) {
lslices_1st_layer = _shrink_contour_holes(std::min(0.f, xy_contour_scaled), expolygons_to_compensate = _shrink_contour_holes(std::min(0.f, xy_contour_scaled),
std::min(0.f, xy_hole_scaled), std::min(0.f, xy_hole_scaled),
lslices_1st_layer); expolygons_to_compensate);
} }
lslices_elfoot_uncompensated[layer_id] = expolygons_to_compensate;
layerm->slices.set( layerm->slices.set(
union_ex( union_ex(
Slic3r::elephant_foot_compensation(lslices_1st_layer, Slic3r::elephant_foot_compensation(expolygons_to_compensate,
layerm->flow(frExternalPerimeter), unscale<double>(elfoot))), layerm->flow(frExternalPerimeter), unscale<double>(elfoot))),
stInternal); stInternal);
} else { } else {
@ -1166,8 +1168,9 @@ void PrintObject::slice_volumes()
ExPolygons trimming; ExPolygons trimming;
static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5); static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5);
if (elfoot > 0.f) { if (elfoot > 0.f) {
lslices_1st_layer = offset_ex(layer->merged(eps), -eps); ExPolygons expolygons_to_compensate = offset_ex(layer->merged(eps), -eps);
trimming = Slic3r::elephant_foot_compensation(lslices_1st_layer, lslices_elfoot_uncompensated[layer_id] = expolygons_to_compensate;
trimming = Slic3r::elephant_foot_compensation(expolygons_to_compensate,
layer->m_regions.front()->flow(frExternalPerimeter), unscale<double>(elfoot)); layer->m_regions.front()->flow(frExternalPerimeter), unscale<double>(elfoot));
} else { } else {
trimming = layer->merged(float(SCALED_EPSILON)); trimming = layer->merged(float(SCALED_EPSILON));
@ -1190,22 +1193,24 @@ void PrintObject::slice_volumes()
} }
}); });
if (elephant_foot_compensation_scaled > 0.f && ! m_layers.empty()) { if (elephant_foot_compensation_scaled > 0.f && ! m_layers.empty()) {
// The Elephant foot has been compensated, therefore the 1st layer's lslices are shrank with the Elephant foot compensation value. // The Elephant foot has been compensated, therefore the elefant_foot_compensation_layers layer's lslices are shrank with the Elephant foot compensation value.
// Store the uncompensated value there. // Store the uncompensated value there.
assert(m_layers.front()->id() == 0); assert(m_layers.front()->id() == 0);
//BBS: sort the lslices_1st_layer according to shortest path before saving //BBS: sort the lslices_elfoot_uncompensated according to shortest path before saving
//Otherwise the travel of first layer would be mess. //Otherwise the travel of the layer layer would be mess.
for (int i = 0; i < lslices_elfoot_uncompensated.size(); i++) {
ExPolygons &expolygons_uncompensated = lslices_elfoot_uncompensated[i];
Points ordering_points; Points ordering_points;
ordering_points.reserve(lslices_1st_layer.size()); ordering_points.reserve(expolygons_uncompensated.size());
for (const ExPolygon& ex : lslices_1st_layer) for (const ExPolygon &ex : expolygons_uncompensated)
ordering_points.push_back(ex.contour.first_point()); ordering_points.push_back(ex.contour.first_point());
std::vector<Points::size_type> order = chain_points(ordering_points); std::vector<Points::size_type> order = chain_points(ordering_points);
ExPolygons lslices_1st_layer_sorted; ExPolygons lslices_sorted;
lslices_1st_layer_sorted.reserve(lslices_1st_layer.size()); lslices_sorted.reserve(expolygons_uncompensated.size());
for (size_t i : order) for (size_t i : order)
lslices_1st_layer_sorted.emplace_back(std::move(lslices_1st_layer[i])); lslices_sorted.emplace_back(std::move(expolygons_uncompensated[i]));
m_layers[i]->lslices = std::move(lslices_sorted);
m_layers.front()->lslices = std::move(lslices_1st_layer_sorted); }
} }
} }