Fix of Random placment of top fill throughout model #7442
For this particular model, ClipperLib numerical instability causes one of the internal surfaces to turn into bridging surfaces on reslicing. The issue was fixed by reverting to untyped slices if possible.
This commit is contained in:
parent
175a6369fd
commit
c9727b5a57
@ -92,6 +92,25 @@ void Layer::restore_untyped_slices()
|
||||
}
|
||||
}
|
||||
|
||||
// Similar to Layer::restore_untyped_slices()
|
||||
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
|
||||
// Only resetting layerm->slices if Slice::extra_perimeters is always zero or it will not be used anymore
|
||||
// after the perimeter generator.
|
||||
void Layer::restore_untyped_slices_no_extra_perimeters()
|
||||
{
|
||||
if (layer_needs_raw_backup(this)) {
|
||||
for (LayerRegion *layerm : m_regions)
|
||||
if (layerm->region().config().extra_perimeters.value <= 0)
|
||||
layerm->slices.set(layerm->raw_slices, stInternal);
|
||||
} else {
|
||||
assert(m_regions.size() == 1);
|
||||
LayerRegion *layerm = m_regions.front();
|
||||
// This optimization is correct, as extra_perimeters are only reused by prepare_infill() with multi-regions.
|
||||
//if (layerm->region().config().extra_perimeters.value <= 0)
|
||||
layerm->slices.set(this->lslices, stInternal);
|
||||
}
|
||||
}
|
||||
|
||||
ExPolygons Layer::merged(float offset_scaled) const
|
||||
{
|
||||
assert(offset_scaled >= 0.f);
|
||||
@ -179,7 +198,7 @@ void Layer::make_perimeters()
|
||||
// group slices (surfaces) according to number of extra perimeters
|
||||
std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
|
||||
for (LayerRegion *layerm : layerms) {
|
||||
for (Surface &surface : layerm->slices.surfaces)
|
||||
for (const Surface &surface : layerm->slices.surfaces)
|
||||
slices[surface.extra_perimeters].emplace_back(surface);
|
||||
if (layerm->region().config().fill_density > layerm_config->region().config().fill_density)
|
||||
layerm_config = layerm;
|
||||
|
@ -137,6 +137,8 @@ public:
|
||||
//FIXME Review whether not to simplify the code by keeping the raw_slices all the time.
|
||||
void backup_untyped_slices();
|
||||
void restore_untyped_slices();
|
||||
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
|
||||
void restore_untyped_slices_no_extra_perimeters();
|
||||
// Slices merged into islands, to be used by the elephant foot compensation to trim the individual surfaces with the shrunk merged slices.
|
||||
ExPolygons merged(float offset) const;
|
||||
template <class T> bool any_internal_region_slice_contains(const T &item) const {
|
||||
|
@ -51,8 +51,7 @@ void LayerRegion::slices_to_fill_surfaces_clipped()
|
||||
// so we're safe. This guarantees idempotence of prepare_infill() also in case
|
||||
// that combine_infill() turns some fill_surface into VOID surfaces.
|
||||
// Collect polygons per surface type.
|
||||
std::vector<SurfacesPtr> by_surface;
|
||||
by_surface.assign(size_t(stCount), SurfacesPtr());
|
||||
std::array<SurfacesPtr, size_t(stCount)> by_surface;
|
||||
for (Surface &surface : this->slices.surfaces)
|
||||
by_surface[size_t(surface.surface_type)].emplace_back(&surface);
|
||||
// Trim surfaces by the fill_boundaries.
|
||||
|
@ -227,6 +227,17 @@ void PrintObject::prepare_infill()
|
||||
|
||||
m_print->set_status(30, L("Preparing infill"));
|
||||
|
||||
if (m_typed_slices) {
|
||||
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
|
||||
// The preceding step (perimeter generator) only modifies extra_perimeters and the extra perimeters are only used by discover_vertical_shells()
|
||||
// with more than a single region. If this step does not use Surface::extra_perimeters or Surface::extra_perimeters is always zero, it is safe
|
||||
// to reset to the untyped slices before re-runnning detect_surfaces_type().
|
||||
for (Layer* layer : m_layers) {
|
||||
layer->restore_untyped_slices_no_extra_perimeters();
|
||||
m_print->throw_if_canceled();
|
||||
}
|
||||
}
|
||||
|
||||
// This will assign a type (top/bottom/internal) to $layerm->slices.
|
||||
// Then the classifcation of $layerm->slices is transfered onto
|
||||
// the $layerm->fill_surfaces by clipping $layerm->fill_surfaces
|
||||
|
Loading…
Reference in New Issue
Block a user