mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-07 06:57:36 -06:00
Merge tiny cracks that is part of a large bottom surface into bottom surface (#9332)
* Merge tiny cracks that is part of a large bottom surface into bottom surface (SoftFever/OrcaSlicer#9329) * Revert bottom offset * Top surfaces will have perimeters around, which need to be removed from bottom surfaces so bridges not extended to visible areas
This commit is contained in:
parent
a499695c93
commit
940800b059
1 changed files with 14 additions and 7 deletions
|
@ -1309,8 +1309,7 @@ void PrintObject::detect_surfaces_type()
|
||||||
Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? m_layers[idx_layer + 1] : nullptr;
|
Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? m_layers[idx_layer + 1] : nullptr;
|
||||||
Layer *lower_layer = (idx_layer > 0) ? m_layers[idx_layer - 1] : nullptr;
|
Layer *lower_layer = (idx_layer > 0) ? m_layers[idx_layer - 1] : nullptr;
|
||||||
// collapse very narrow parts (using the safety offset in the diff is not enough)
|
// collapse very narrow parts (using the safety offset in the diff is not enough)
|
||||||
const float offset_top = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
|
const float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
|
||||||
const float offset_bottom = layerm->flow(frExternalPerimeter).scaled_width();
|
|
||||||
|
|
||||||
ExPolygons layerm_slices_surfaces = to_expolygons(layerm->slices.surfaces);
|
ExPolygons layerm_slices_surfaces = to_expolygons(layerm->slices.surfaces);
|
||||||
// no_perimeter_full_bridge allow to put bridges where there are nothing, hence adding area to slice, that's why we need to start from the result of PerimeterGenerator.
|
// no_perimeter_full_bridge allow to put bridges where there are nothing, hence adding area to slice, that's why we need to start from the result of PerimeterGenerator.
|
||||||
|
@ -1325,7 +1324,7 @@ void PrintObject::detect_surfaces_type()
|
||||||
ExPolygons upper_slices = interface_shells ?
|
ExPolygons upper_slices = interface_shells ?
|
||||||
diff_ex(layerm_slices_surfaces, upper_layer->m_regions[region_id]->slices.surfaces, ApplySafetyOffset::Yes) :
|
diff_ex(layerm_slices_surfaces, upper_layer->m_regions[region_id]->slices.surfaces, ApplySafetyOffset::Yes) :
|
||||||
diff_ex(layerm_slices_surfaces, upper_layer->lslices, ApplySafetyOffset::Yes);
|
diff_ex(layerm_slices_surfaces, upper_layer->lslices, ApplySafetyOffset::Yes);
|
||||||
surfaces_append(top, opening_ex(upper_slices, offset_top), stTop);
|
surfaces_append(top, opening_ex(upper_slices, offset), stTop);
|
||||||
} else {
|
} else {
|
||||||
// if no upper layer, all surfaces of this one are solid
|
// if no upper layer, all surfaces of this one are solid
|
||||||
// we clone surfaces because we're going to clear the slices collection
|
// we clone surfaces because we're going to clear the slices collection
|
||||||
|
@ -1351,7 +1350,7 @@ void PrintObject::detect_surfaces_type()
|
||||||
bottom,
|
bottom,
|
||||||
opening_ex(
|
opening_ex(
|
||||||
diff_ex(layerm_slices_surfaces, lower_layer->lslices, ApplySafetyOffset::Yes),
|
diff_ex(layerm_slices_surfaces, lower_layer->lslices, ApplySafetyOffset::Yes),
|
||||||
offset_bottom),
|
offset),
|
||||||
surface_type_bottom_other);
|
surface_type_bottom_other);
|
||||||
// if user requested internal shells, we need to identify surfaces
|
// if user requested internal shells, we need to identify surfaces
|
||||||
// lying on other slices not belonging to this region
|
// lying on other slices not belonging to this region
|
||||||
|
@ -1365,7 +1364,7 @@ void PrintObject::detect_surfaces_type()
|
||||||
intersection(layerm_slices_surfaces, lower_layer->lslices), // supported
|
intersection(layerm_slices_surfaces, lower_layer->lslices), // supported
|
||||||
lower_layer->m_regions[region_id]->slices.surfaces,
|
lower_layer->m_regions[region_id]->slices.surfaces,
|
||||||
ApplySafetyOffset::Yes),
|
ApplySafetyOffset::Yes),
|
||||||
offset_bottom),
|
offset),
|
||||||
stBottom);
|
stBottom);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1383,14 +1382,22 @@ void PrintObject::detect_surfaces_type()
|
||||||
if (! top.empty() && ! bottom.empty()) {
|
if (! top.empty() && ! bottom.empty()) {
|
||||||
const auto cracks = intersection_ex(top, bottom);
|
const auto cracks = intersection_ex(top, bottom);
|
||||||
if (!cracks.empty()) {
|
if (!cracks.empty()) {
|
||||||
const float small_crack_threshold = -offset_bottom;
|
const float small_crack_threshold = -layerm->flow(frExternalPerimeter).scaled_width() * 1.5;
|
||||||
|
|
||||||
for (const auto& crack : cracks) {
|
for (const auto& crack : cracks) {
|
||||||
if (offset_ex(crack, small_crack_threshold).empty()) {
|
if (offset_ex(crack, small_crack_threshold).empty()) {
|
||||||
|
// For small cracks, if it's part of a large bottom surface, then it should be added to bottom as well
|
||||||
|
if (std::any_of(bottom.begin(), bottom.end(), [&crack, small_crack_threshold](const Surface& s) {
|
||||||
|
const auto& se = s.expolygon;
|
||||||
|
return diff_ex(crack, se, ApplySafetyOffset::Yes).empty()
|
||||||
|
&& se.area() > crack.area() * 2
|
||||||
|
&& !offset_ex(diff_ex(se, crack), small_crack_threshold).empty();
|
||||||
|
})) continue;
|
||||||
|
|
||||||
// Crack too small, leave it as part of the top surface, remove it from bottom surfaces
|
// Crack too small, leave it as part of the top surface, remove it from bottom surfaces
|
||||||
Surfaces bot_tmp;
|
Surfaces bot_tmp;
|
||||||
for (auto& b : bottom) {
|
for (auto& b : bottom) {
|
||||||
surfaces_append(bot_tmp, diff_ex(b.expolygon, crack), b.surface_type);
|
surfaces_append(bot_tmp, diff_ex(b.expolygon, offset_ex(crack, -small_crack_threshold)), b.surface_type);
|
||||||
}
|
}
|
||||||
bottom = std::move(bot_tmp);
|
bottom = std::move(bot_tmp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue