ENH: do not split top/bottom when shell param is 0

1. When detect surface type,do not detect top/bottom
surface if top/bottom shell layers is zero

jira:STUDIO-5843

Signed-off-by: XunZhangBambu <xun.zhang@bambulab.com>
Change-Id: I844b24d061f3fc9aef56dab941140c567340eeae
This commit is contained in:
XunZhangBambu 2024-03-04 15:45:28 +08:00 committed by Lane.Wei
parent c373d6b198
commit 117a2aa2d9
2 changed files with 66 additions and 56 deletions

View File

@ -349,10 +349,11 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
Surfaces new_surfaces;
{
// Merge top and bottom in a single collection.
surfaces_append(top, std::move(bottom));
// Intersect the grown surfaces with the actual fill boundaries.
Polygons bottom_polygons = to_polygons(bottom);
// Merge top and bottom in a single collection.
surfaces_append(top, std::move(bottom));
for (size_t i = 0; i < top.size(); ++ i) {
Surface &s1 = top[i];
if (s1.empty())
@ -417,6 +418,7 @@ void LayerRegion::prepare_fill_surfaces()
bool spiral_mode = this->layer()->object()->print()->config().spiral_mode;
#if 0
// if no solid layers are requested, turn top/bottom surfaces to internal
if (! spiral_mode && this->region().config().top_shell_layers == 0) {
for (Surface &surface : this->fill_surfaces.surfaces)
@ -430,6 +432,7 @@ void LayerRegion::prepare_fill_surfaces()
if (surface.is_bottom()) // (surface.surface_type == stBottom)
surface.surface_type = stInternal;
}
#endif
// turn too small internal regions into solid regions according to the user setting
if (! spiral_mode && this->region().config().sparse_infill_density.value > 0) {

View File

@ -260,16 +260,6 @@ void PrintObject::prepare_infill()
this->detect_surfaces_type();
m_print->throw_if_canceled();
// Decide what surfaces are to be filled.
// Here the stTop / stBottomBridge / stBottom infill is turned to just stInternal if zero top / bottom infill layers are configured.
// Also tiny stInternal surfaces are turned to stInternalSolid.
BOOST_LOG_TRIVIAL(info) << "Preparing fill surfaces..." << log_memory_info();
for (auto *layer : m_layers)
for (auto *region : layer->m_regions) {
region->prepare_fill_surfaces();
m_print->throw_if_canceled();
}
// this will detect bridges and reverse bridges
// and rearrange top/bottom/internal surfaces
// It produces enlarged overlapping bridging areas.
@ -316,6 +306,14 @@ void PrintObject::prepare_infill()
} // for each region
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// Also tiny stInternal surfaces are turned to stInternalSolid.
BOOST_LOG_TRIVIAL(info) << "Preparing fill surfaces..." << log_memory_info();
for (auto *layer : m_layers)
for (auto *region : layer->m_regions) {
region->prepare_fill_surfaces();
m_print->throw_if_canceled();
}
// Only active if config->infill_only_where_needed. This step trims the sparse infill,
// so it acts as an internal support. It maintains all other infill types intact.
// Here the internal surfaces and perimeters have to be supported by the sparse infill.
@ -1021,7 +1019,7 @@ void PrintObject::detect_surfaces_type()
((num_layers > 1) ? num_layers - 1 : num_layers) :
// In non-spiral vase mode, go over all layers.
m_layers.size()),
[this, region_id, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
[this, spiral_mode, region_id, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
// the support from the print.
// BBS: the above logic only applys for normal(auto) support. Complete logic:
@ -1047,63 +1045,72 @@ void PrintObject::detect_surfaces_type()
// collapse very narrow parts (using the safety offset in the diff is not enough)
float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
bool detect_top = spiral_mode || layerm->region().config().top_shell_layers;
bool detect_bottom = spiral_mode || layerm->region().config().bottom_shell_layers;
// find top surfaces (difference between current surfaces
// of current layer and upper one)
Surfaces top;
if (upper_layer) {
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->lslices, ApplySafetyOffset::Yes);
surfaces_append(top, opening_ex(upper_slices, offset), stTop);
} else {
// if no upper layer, all surfaces of this one are solid
// we clone surfaces because we're going to clear the slices collection
top = layerm->slices.surfaces;
for (Surface &surface : top)
surface.surface_type = stTop;
if (detect_top) {
if (upper_layer) {
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->lslices, ApplySafetyOffset::Yes);
surfaces_append(top, opening_ex(upper_slices, offset), stTop);
}
else {
// if no upper layer, all surfaces of this one are solid
// we clone surfaces because we're going to clear the slices collection
top = layerm->slices.surfaces;
for (Surface& surface : top)
surface.surface_type = stTop;
}
}
// Find bottom surfaces (difference between current surfaces of current layer and lower one).
Surfaces bottom;
if (lower_layer) {
if (detect_bottom) {
if (lower_layer) {
#if 0
//FIXME Why is this branch failing t\multi.t ?
Polygons lower_slices = interface_shells ?
to_polygons(lower_layer->get_region(region_id)->slices.surfaces) :
to_polygons(lower_layer->slices);
surfaces_append(bottom,
opening_ex(diff(layerm->slices.surfaces, lower_slices, true), offset),
surface_type_bottom_other);
//FIXME Why is this branch failing t\multi.t ?
Polygons lower_slices = interface_shells ?
to_polygons(lower_layer->get_region(region_id)->slices.surfaces) :
to_polygons(lower_layer->slices);
surfaces_append(bottom,
opening_ex(diff(layerm->slices.surfaces, lower_slices, true), offset),
surface_type_bottom_other);
#else
// Any surface lying on the void is a true bottom bridge (an overhang)
surfaces_append(
bottom,
opening_ex(
diff_ex(layerm->slices.surfaces, lower_layer->lslices, ApplySafetyOffset::Yes),
offset),
surface_type_bottom_other);
// if user requested internal shells, we need to identify surfaces
// lying on other slices not belonging to this region
if (interface_shells) {
// non-bridging bottom surfaces: any part of this layer lying
// on something else, excluding those lying on our own region
// Any surface lying on the void is a true bottom bridge (an overhang)
surfaces_append(
bottom,
opening_ex(
diff_ex(
intersection(layerm->slices.surfaces, lower_layer->lslices), // supported
lower_layer->m_regions[region_id]->slices.surfaces,
ApplySafetyOffset::Yes),
diff_ex(layerm->slices.surfaces, lower_layer->lslices, ApplySafetyOffset::Yes),
offset),
stBottom);
}
surface_type_bottom_other);
// if user requested internal shells, we need to identify surfaces
// lying on other slices not belonging to this region
if (interface_shells) {
// non-bridging bottom surfaces: any part of this layer lying
// on something else, excluding those lying on our own region
surfaces_append(
bottom,
opening_ex(
diff_ex(
intersection(layerm->slices.surfaces, lower_layer->lslices), // supported
lower_layer->m_regions[region_id]->slices.surfaces,
ApplySafetyOffset::Yes),
offset),
stBottom);
}
#endif
} else {
// if no lower layer, all surfaces of this one are solid
// we clone surfaces because we're going to clear the slices collection
bottom = layerm->slices.surfaces;
for (Surface &surface : bottom)
surface.surface_type = stBottom;
}
else {
// if no lower layer, all surfaces of this one are solid
// we clone surfaces because we're going to clear the slices collection
bottom = layerm->slices.surfaces;
for (Surface& surface : bottom)
surface.surface_type = stBottom;
}
}
// now, if the object contained a thin membrane, we could have overlapping bottom