#180 xy first layer compensation fix.

This commit is contained in:
supermerill 2020-04-20 17:18:26 +02:00
parent 473dca0884
commit 046210b0d5
2 changed files with 55 additions and 41 deletions

View File

@ -548,8 +548,9 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, double min_c
Point bbox_size = bbox.size(); Point bbox_size = bbox.size();
ExPolygon out; ExPolygon out;
if (bbox_size.x() < min_contour_width_compensated + SCALED_EPSILON || if (bbox_size.x() < min_contour_width_compensated + SCALED_EPSILON ||
bbox_size.y() < min_contour_width_compensated + SCALED_EPSILON || bbox_size.y() < min_contour_width_compensated + SCALED_EPSILON )
input_expoly.area() < min_contour_width_compensated * min_contour_width_compensated * 5.) //this is a hidden switch that will create strange behavior for the user. That's why i deactivate it.
//|| input_expoly.area() < min_contour_width_compensated * min_contour_width_compensated * 5.)
{ {
// The contour is tiny. Don't correct it. // The contour is tiny. Don't correct it.
out = input_expoly; out = input_expoly;

View File

@ -2283,10 +2283,10 @@ end:
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - begin"; BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - begin";
{ {
// Uncompensated slices for the first layer in case the Elephant foot compensation is applied. // Uncompensated slices for the first layer in case the Elephant foot compensation is applied.
ExPolygons lslices_1st_layer;
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, upscaled, clipped, &lslices_1st_layer](const tbb::blocked_range<size_t>& range) { [this, upscaled, clipped](const tbb::blocked_range<size_t>& range) {
ExPolygons expolygons_first_layer;
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];
@ -2294,21 +2294,21 @@ end:
float delta = float(scale_(m_config.xy_size_compensation.value)); float delta = float(scale_(m_config.xy_size_compensation.value));
float hole_delta = float(scale_(this->config().hole_size_compensation.value)); float hole_delta = float(scale_(this->config().hole_size_compensation.value));
//FIXME only apply the compensation if no raft is enabled. //FIXME only apply the compensation if no raft is enabled.
float elephant_foot_compensation = 0.f; float first_layer_compensation = 0.f;
if (layer_id == 0 && m_config.raft_layers == 0) { if (layer_id == 0 && m_config.raft_layers == 0 && m_config.elefant_foot_compensation.value != 0) {
// Only enable Elephant foot compensation if printing directly on the print bed. // Only enable Elephant foot compensation if printing directly on the print bed.
elephant_foot_compensation = float(scale_(m_config.elefant_foot_compensation.value)); first_layer_compensation = float(scale_(m_config.elefant_foot_compensation.value));
if (elephant_foot_compensation > 0) { if (first_layer_compensation > 0) {
delta += elephant_foot_compensation; delta += first_layer_compensation;
elephant_foot_compensation = 0; first_layer_compensation = 0;
} }
else if (delta > 0) { else if (delta > 0) {
if (-elephant_foot_compensation < delta) { if (-first_layer_compensation < delta) {
delta += elephant_foot_compensation; delta += first_layer_compensation;
elephant_foot_compensation = 0; first_layer_compensation = 0;
} }
else { else {
elephant_foot_compensation += delta; first_layer_compensation += delta;
delta = 0; delta = 0;
} }
} }
@ -2319,28 +2319,40 @@ end:
LayerRegion *layerm = layer->regions().front(); LayerRegion *layerm = layer->regions().front();
ExPolygons expolygons = to_expolygons(std::move(layerm->slices().surfaces)); ExPolygons expolygons = to_expolygons(std::move(layerm->slices().surfaces));
// Apply the XY hole compensation. // Apply the XY hole compensation.
if (hole_delta > 0) if (hole_delta > 0) {
expolygons = _offset_holes(-hole_delta, expolygons); expolygons = _offset_holes(-hole_delta, expolygons);
// Apply the XY compensation. if (layer_id == 0 && first_layer_compensation != 0)
if (delta > 0.f) expolygons_first_layer = expolygons;
expolygons = offset_ex(expolygons, delta);
// Apply the elephant foot compensation.
if (layer_id == 0 && elephant_foot_compensation != 0.f) {
expolygons = union_ex(Slic3r::elephant_foot_compensation(expolygons, layerm->flow(frExternalPerimeter), unscale<double>(-elephant_foot_compensation)));
} }
// Apply the XY compensation. // Apply the XY compensation.
if (delta < 0.f) if (delta > 0.f) {
expolygons = offset_ex(expolygons, delta); expolygons = offset_ex(expolygons, delta);
// Apply the XY hole compensation. if (layer_id == 0 && first_layer_compensation != 0)
if (hole_delta < 0) expolygons_first_layer = offset_ex(expolygons_first_layer, float(scale_(m_config.xy_size_compensation.value)));
}
// Apply the elephant foot compensation.
if (layer_id == 0 && first_layer_compensation != 0.f) {
expolygons = union_ex(Slic3r::elephant_foot_compensation(expolygons, layerm->flow(frExternalPerimeter),
unscale<double>(-first_layer_compensation)));
}
// Apply the negative XY compensation.
if (delta < 0.f) {
expolygons = offset_ex(expolygons, delta);
if (layer_id == 0 && first_layer_compensation != 0)
expolygons_first_layer = offset_ex(expolygons_first_layer, float(scale_(m_config.xy_size_compensation.value)));
}
// Apply the negative XY hole compensation.
if (hole_delta < 0) {
expolygons = _offset_holes(-hole_delta, expolygons); expolygons = _offset_holes(-hole_delta, expolygons);
if (layer_id == 0 && first_layer_compensation != 0)
expolygons_first_layer = _offset_holes(-hole_delta, expolygons_first_layer);
}
if (layer->regions().front()->region()->config().curve_smoothing_precision > 0.f) { if (layer->regions().front()->region()->config().curve_smoothing_precision > 0.f) {
//smoothing //smoothing
expolygons = _smooth_curves(expolygons, layer->regions().front()->region()->config()); expolygons = _smooth_curves(expolygons, layer->regions().front()->region()->config());
} if (layer_id == 0 && first_layer_compensation != 0)
if (layer_id == 0 && elephant_foot_compensation != 0.f) { expolygons_first_layer = _smooth_curves(expolygons_first_layer, layer->regions().front()->region()->config());
lslices_1st_layer = expolygons;
} }
layerm->m_slices.set(std::move(expolygons), stPosInternal | stDensSparse); layerm->m_slices.set(std::move(expolygons), stPosInternal | stDensSparse);
} else { } else {
@ -2364,8 +2376,8 @@ end:
slices = intersection_ex(offset_ex(slices, hole_delta), merged_poly_for_holes_growing); slices = intersection_ex(offset_ex(slices, hole_delta), merged_poly_for_holes_growing);
} }
// Apply the XY compensation if >0. // Apply the XY compensation if >0.
if (upscale || (layer_id == 0 && elephant_foot_compensation > 0)) if (upscale || (layer_id == 0 && first_layer_compensation > 0))
slices = offset_ex(std::move(slices), std::max(delta, 0.f) + std::max(elephant_foot_compensation, 0.f)); slices = offset_ex(std::move(slices), std::max(delta, 0.f) + std::max(first_layer_compensation, 0.f));
//smoothing //smoothing
if (layerm->region()->config().curve_smoothing_precision > 0.f) if (layerm->region()->config().curve_smoothing_precision > 0.f)
slices = _smooth_curves(slices, layerm->region()->config()); slices = _smooth_curves(slices, layerm->region()->config());
@ -2378,14 +2390,14 @@ end:
layerm->m_slices.set(std::move(slices), stPosInternal | stDensSparse); layerm->m_slices.set(std::move(slices), stPosInternal | stDensSparse);
} }
} }
if (delta < 0.f || elephant_foot_compensation != 0.f || hole_delta < 0.f) { if (delta < 0.f || first_layer_compensation != 0.f || hole_delta < 0.f) {
// Apply the negative XY compensation. (the ones that is <0) // Apply the negative XY compensation. (the ones that is <0)
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 (layer_id == 0 && elephant_foot_compensation < 0.f) { if (layer_id == 0 && first_layer_compensation < 0.f) {
trimming = Slic3r::elephant_foot_compensation(offset_ex(layer->merged(eps), std::min(delta, 0.f) - eps), expolygons_first_layer = offset_ex(layer->merged(eps), std::min(delta, 0.f) - eps);
layer->regions().front()->flow(frExternalPerimeter), unscale<double>(-elephant_foot_compensation)); trimming = Slic3r::elephant_foot_compensation(expolygons_first_layer,
lslices_1st_layer = trimming; layer->regions().front()->flow(frExternalPerimeter), unscale<double>(-first_layer_compensation));
} }
else if (delta != 0.f) { else if (delta != 0.f) {
trimming = offset_ex(layer->merged(float(SCALED_EPSILON)), delta - float(SCALED_EPSILON)); trimming = offset_ex(layer->merged(float(SCALED_EPSILON)), delta - float(SCALED_EPSILON));
@ -2403,13 +2415,14 @@ end:
} }
// Merge all regions' slices to get islands, chain them by a shortest path. // Merge all regions' slices to get islands, chain them by a shortest path.
layer->make_slices(); layer->make_slices();
} //FIXME: can't make it work in multi-region object, it seems useful to avoid bridge on top of first layer compensation
if (float(scale_(m_config.elefant_foot_compensation.value)) > 0.f && m_config.raft_layers == 0) { if (layer->regions().size() == 1 && layer_id == 0 && first_layer_compensation < 0 && m_config.raft_layers == 0) {
// 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 1st layer's lslices are shrank with the Elephant foot compensation value.
// Store the uncompensated value there. // Store the uncompensated value there.
assert(! m_layers.empty()); assert(! m_layers.empty());
assert(m_layers.front()->id() == 0); assert(m_layers.front()->id() == 0);
m_layers.front()->lslices = std::move(lslices_1st_layer); m_layers.front()->lslices = offset_ex(std::move(m_layers.front()->lslices), -first_layer_compensation);
}
} }
}); });
} }