FIX: fix slicing error of more than 1 empty first layers

Jira: STUDIO-656
Change-Id: I582e432ac14b823656780147ec585ae7a7499517
This commit is contained in:
arthur 2022-08-09 21:46:21 +08:00 committed by Lane.Wei
parent 7e01006db7
commit 1e0301dbde
2 changed files with 27 additions and 31 deletions

View File

@ -474,7 +474,8 @@ void ToolOrdering::reorder_extruders(std::vector<unsigned int> tool_order_layer0
if (m_layer_tools.empty()) if (m_layer_tools.empty())
return; return;
assert(!tool_order_layer0.empty()); if (tool_order_layer0.empty())
return;
// Reorder the extruders of first layer // Reorder the extruders of first layer
{ {

View File

@ -474,8 +474,6 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std
if (layers[idx_layer]->slicing_errors) { if (layers[idx_layer]->slicing_errors) {
buggy_layers.push_back(idx_layer); buggy_layers.push_back(idx_layer);
//BBS
error_msg = L("Empty layers around bottom are replaced by nearest normal layers.");
} }
else else
break; // only detect empty layers near bed break; // only detect empty layers near bed
@ -484,14 +482,15 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - fixing slicing errors in parallel - begin"; BOOST_LOG_TRIVIAL(debug) << "Slicing objects - fixing slicing errors in parallel - begin";
tbb::parallel_for( tbb::parallel_for(
tbb::blocked_range<size_t>(0, buggy_layers.size()), tbb::blocked_range<size_t>(0, buggy_layers.size()),
[&layers, &throw_if_canceled, &buggy_layers](const tbb::blocked_range<size_t>& range) { [&layers, &throw_if_canceled, &buggy_layers, &error_msg](const tbb::blocked_range<size_t>& range) {
for (size_t buggy_layer_idx = range.begin(); buggy_layer_idx < range.end(); ++ buggy_layer_idx) { for (size_t buggy_layer_idx = range.begin(); buggy_layer_idx < range.end(); ++ buggy_layer_idx) {
throw_if_canceled(); throw_if_canceled();
size_t idx_layer = buggy_layers[buggy_layer_idx]; size_t idx_layer = buggy_layers[buggy_layer_idx];
// BBS: only replace empty first layer // BBS: only replace empty layers lower than 1mm
if (idx_layer > 0) const coordf_t thresh_empty_layer_height = 1;
continue;
Layer* layer = layers[idx_layer]; Layer* layer = layers[idx_layer];
if (layer->print_z>= thresh_empty_layer_height)
continue;
assert(layer->slicing_errors); assert(layer->slicing_errors);
// Try to repair the layer surfaces by merging all contours and all holes from neighbor layers. // Try to repair the layer surfaces by merging all contours and all holes from neighbor layers.
// BOOST_LOG_TRIVIAL(trace) << "Attempting to repair layer" << idx_layer; // BOOST_LOG_TRIVIAL(trace) << "Attempting to repair layer" << idx_layer;
@ -500,42 +499,39 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std
// Find the first valid layer below / above the current layer. // Find the first valid layer below / above the current layer.
const Surfaces *upper_surfaces = nullptr; const Surfaces *upper_surfaces = nullptr;
const Surfaces *lower_surfaces = nullptr; const Surfaces *lower_surfaces = nullptr;
//BBS: only repair first layer if the 2nd layer is Good //BBS: only repair empty layers lowers than 1mm
for (size_t j = idx_layer + 1; j < /*layers.size()*/2; ++ j) for (size_t j = idx_layer + 1; j < layers.size(); ++j) {
if (!layers[j]->slicing_errors) { if (!layers[j]->slicing_errors) {
upper_surfaces = &layers[j]->regions()[region_id]->slices.surfaces; upper_surfaces = &layers[j]->regions()[region_id]->slices.surfaces;
break; break;
} }
for (int j = /*int(idx_layer) -*/ 1; j >= 0; -- j) if (layers[j]->print_z >= thresh_empty_layer_height) break;
}
for (int j = int(idx_layer) - 1; j >= 0; --j) {
if (layers[j]->print_z >= thresh_empty_layer_height) continue;
if (!layers[j]->slicing_errors) { if (!layers[j]->slicing_errors) {
lower_surfaces = &layers[j]->regions()[region_id]->slices.surfaces; lower_surfaces = &layers[j]->regions()[region_id]->slices.surfaces;
break; break;
} }
}
// Collect outer contours and holes from the valid layers above & below. // Collect outer contours and holes from the valid layers above & below.
Polygons outer; ExPolygons expolys;
outer.reserve( expolys.reserve(
((upper_surfaces == nullptr) ? 0 : upper_surfaces->size()) + ((upper_surfaces == nullptr) ? 0 : upper_surfaces->size()) +
((lower_surfaces == nullptr) ? 0 : lower_surfaces->size())); ((lower_surfaces == nullptr) ? 0 : lower_surfaces->size()));
size_t num_holes = 0;
if (upper_surfaces) if (upper_surfaces)
for (const auto &surface : *upper_surfaces) { for (const auto &surface : *upper_surfaces) {
outer.push_back(surface.expolygon.contour); expolys.emplace_back(surface.expolygon);
num_holes += surface.expolygon.holes.size();
} }
if (lower_surfaces) if (lower_surfaces)
for (const auto &surface : *lower_surfaces) { for (const auto &surface : *lower_surfaces) {
outer.push_back(surface.expolygon.contour); expolys.emplace_back(surface.expolygon);
num_holes += surface.expolygon.holes.size(); }
if (!expolys.empty()) {
//BBS
error_msg = L("Empty layers around bottom are replaced by nearest normal layers.");
layerm->slices.set(union_ex(expolys), stInternal);
} }
Polygons holes;
holes.reserve(num_holes);
if (upper_surfaces)
for (const auto &surface : *upper_surfaces)
polygons_append(holes, surface.expolygon.holes);
if (lower_surfaces)
for (const auto &surface : *lower_surfaces)
polygons_append(holes, surface.expolygon.holes);
layerm->slices.set(diff_ex(union_(outer), holes), stInternal);
} }
// Update layer slices after repairing the single regions. // Update layer slices after repairing the single regions.
layer->make_slices(); layer->make_slices();
@ -555,8 +551,7 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std
//BBS //BBS
if(error_msg.empty() && !buggy_layers.empty()) if(error_msg.empty() && !buggy_layers.empty())
error_msg = L("The model has overlapping or self-intersecting facets. I tried to repair it, " error_msg = L("The model has too many empty layers.");
"however you might want to check the results or repair the input file and retry.");
return error_msg; return error_msg;
} }