Fix of weird double extrusions with multiple regions and their
parameters being changed between slicing runs.
This commit is contained in:
parent
38d06d57a0
commit
a9fc39491e
@ -112,72 +112,82 @@ void Layer::make_perimeters()
|
|||||||
// keep track of regions whose perimeters we have already generated
|
// keep track of regions whose perimeters we have already generated
|
||||||
std::vector<unsigned char> done(m_regions.size(), false);
|
std::vector<unsigned char> done(m_regions.size(), false);
|
||||||
|
|
||||||
for (LayerRegionPtrs::iterator layerm = m_regions.begin(); layerm != m_regions.end(); ++ layerm) {
|
for (LayerRegionPtrs::iterator layerm = m_regions.begin(); layerm != m_regions.end(); ++ layerm)
|
||||||
size_t region_id = layerm - m_regions.begin();
|
if ((*layerm)->slices.empty()) {
|
||||||
if (done[region_id])
|
(*layerm)->perimeters.clear();
|
||||||
continue;
|
(*layerm)->fills.clear();
|
||||||
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
|
(*layerm)->thin_fills.clear();
|
||||||
done[region_id] = true;
|
} else {
|
||||||
const PrintRegionConfig &config = (*layerm)->region()->config();
|
size_t region_id = layerm - m_regions.begin();
|
||||||
|
if (done[region_id])
|
||||||
// find compatible regions
|
continue;
|
||||||
LayerRegionPtrs layerms;
|
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
|
||||||
layerms.push_back(*layerm);
|
done[region_id] = true;
|
||||||
for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it) {
|
const PrintRegionConfig &config = (*layerm)->region()->config();
|
||||||
LayerRegion* other_layerm = *it;
|
|
||||||
const PrintRegionConfig &other_config = other_layerm->region()->config();
|
// find compatible regions
|
||||||
if (config.perimeter_extruder == other_config.perimeter_extruder
|
LayerRegionPtrs layerms;
|
||||||
&& config.perimeters == other_config.perimeters
|
layerms.push_back(*layerm);
|
||||||
&& config.perimeter_speed == other_config.perimeter_speed
|
for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it)
|
||||||
&& config.external_perimeter_speed == other_config.external_perimeter_speed
|
if (! (*it)->slices.empty()) {
|
||||||
&& config.gap_fill_speed == other_config.gap_fill_speed
|
LayerRegion* other_layerm = *it;
|
||||||
&& config.overhangs == other_config.overhangs
|
const PrintRegionConfig &other_config = other_layerm->region()->config();
|
||||||
&& config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width")
|
if (config.perimeter_extruder == other_config.perimeter_extruder
|
||||||
&& config.thin_walls == other_config.thin_walls
|
&& config.perimeters == other_config.perimeters
|
||||||
&& config.external_perimeters_first == other_config.external_perimeters_first
|
&& config.perimeter_speed == other_config.perimeter_speed
|
||||||
&& config.infill_overlap == other_config.infill_overlap) {
|
&& config.external_perimeter_speed == other_config.external_perimeter_speed
|
||||||
layerms.push_back(other_layerm);
|
&& config.gap_fill_speed == other_config.gap_fill_speed
|
||||||
done[it - m_regions.begin()] = true;
|
&& config.overhangs == other_config.overhangs
|
||||||
}
|
&& config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width")
|
||||||
}
|
&& config.thin_walls == other_config.thin_walls
|
||||||
|
&& config.external_perimeters_first == other_config.external_perimeters_first
|
||||||
if (layerms.size() == 1) { // optimization
|
&& config.infill_overlap == other_config.infill_overlap)
|
||||||
(*layerm)->fill_surfaces.surfaces.clear();
|
{
|
||||||
(*layerm)->make_perimeters((*layerm)->slices, &(*layerm)->fill_surfaces);
|
other_layerm->perimeters.clear();
|
||||||
(*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
|
other_layerm->fills.clear();
|
||||||
} else {
|
other_layerm->thin_fills.clear();
|
||||||
SurfaceCollection new_slices;
|
layerms.push_back(other_layerm);
|
||||||
// Use the region with highest infill rate, as the make_perimeters() function below decides on the gap fill based on the infill existence.
|
done[it - m_regions.begin()] = true;
|
||||||
LayerRegion *layerm_config = layerms.front();
|
}
|
||||||
{
|
}
|
||||||
// group slices (surfaces) according to number of extra perimeters
|
|
||||||
std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
|
if (layerms.size() == 1) { // optimization
|
||||||
for (LayerRegion *layerm : layerms) {
|
(*layerm)->fill_surfaces.surfaces.clear();
|
||||||
for (Surface &surface : layerm->slices.surfaces)
|
(*layerm)->make_perimeters((*layerm)->slices, &(*layerm)->fill_surfaces);
|
||||||
slices[surface.extra_perimeters].emplace_back(surface);
|
(*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
|
||||||
if (layerm->region()->config().fill_density > layerm_config->region()->config().fill_density)
|
} else {
|
||||||
layerm_config = layerm;
|
SurfaceCollection new_slices;
|
||||||
}
|
// Use the region with highest infill rate, as the make_perimeters() function below decides on the gap fill based on the infill existence.
|
||||||
// merge the surfaces assigned to each group
|
LayerRegion *layerm_config = layerms.front();
|
||||||
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
|
{
|
||||||
new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front());
|
// group slices (surfaces) according to number of extra perimeters
|
||||||
}
|
std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
|
||||||
|
for (LayerRegion *layerm : layerms) {
|
||||||
// make perimeters
|
for (Surface &surface : layerm->slices.surfaces)
|
||||||
SurfaceCollection fill_surfaces;
|
slices[surface.extra_perimeters].emplace_back(surface);
|
||||||
layerm_config->make_perimeters(new_slices, &fill_surfaces);
|
if (layerm->region()->config().fill_density > layerm_config->region()->config().fill_density)
|
||||||
|
layerm_config = layerm;
|
||||||
|
}
|
||||||
|
// merge the surfaces assigned to each group
|
||||||
|
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
|
||||||
|
new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
// make perimeters
|
||||||
|
SurfaceCollection fill_surfaces;
|
||||||
|
layerm_config->make_perimeters(new_slices, &fill_surfaces);
|
||||||
|
|
||||||
// assign fill_surfaces to each layer
|
// assign fill_surfaces to each layer
|
||||||
if (!fill_surfaces.surfaces.empty()) {
|
if (!fill_surfaces.surfaces.empty()) {
|
||||||
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
||||||
// Separate the fill surfaces.
|
// Separate the fill surfaces.
|
||||||
ExPolygons expp = intersection_ex(to_polygons(fill_surfaces), (*l)->slices);
|
ExPolygons expp = intersection_ex(to_polygons(fill_surfaces), (*l)->slices);
|
||||||
(*l)->fill_expolygons = expp;
|
(*l)->fill_expolygons = expp;
|
||||||
(*l)->fill_surfaces.set(std::move(expp), fill_surfaces.surfaces.front());
|
(*l)->fill_surfaces.set(std::move(expp), fill_surfaces.surfaces.front());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << " - Done";
|
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << " - Done";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user