Parallelized the slow discover_vertical_shells()
This commit is contained in:
parent
f200781436
commit
798bca561b
@ -579,8 +579,6 @@ PrintObject::discover_vertical_shells()
|
|||||||
|
|
||||||
BOOST_LOG_TRIVIAL(info) << "Discovering vertical shells...";
|
BOOST_LOG_TRIVIAL(info) << "Discovering vertical shells...";
|
||||||
|
|
||||||
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
|
|
||||||
|
|
||||||
for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
|
for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
|
||||||
PROFILE_BLOCK(discover_vertical_shells_region);
|
PROFILE_BLOCK(discover_vertical_shells_region);
|
||||||
|
|
||||||
@ -593,254 +591,265 @@ PrintObject::discover_vertical_shells()
|
|||||||
if (n_extra_top_layers + n_extra_bottom_layers == 0)
|
if (n_extra_top_layers + n_extra_bottom_layers == 0)
|
||||||
// Zero or 1 layer, there is no additional vertical wall thickness enforced.
|
// Zero or 1 layer, there is no additional vertical wall thickness enforced.
|
||||||
continue;
|
continue;
|
||||||
// Cyclic buffers of pre-calculated offsetted top/bottom surfaces.
|
|
||||||
std::vector<DiscoverVerticalShellsCacheEntry> cache_top_regions(n_extra_top_layers, DiscoverVerticalShellsCacheEntry());
|
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - start";
|
||||||
std::vector<DiscoverVerticalShellsCacheEntry> cache_bottom_regions(n_extra_bottom_layers, DiscoverVerticalShellsCacheEntry());
|
//FIXME Improve the heuristics for a grain size.
|
||||||
for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++ idx_layer)
|
size_t grain_size = std::max(this->layers.size() / 16, size_t(1));
|
||||||
{
|
tbb::parallel_for(
|
||||||
PROFILE_BLOCK(discover_vertical_shells_region_layer);
|
tbb::blocked_range<size_t>(0, this->layers.size(), grain_size),
|
||||||
|
[this, idx_region, n_extra_top_layers, n_extra_bottom_layers](const tbb::blocked_range<size_t>& range) {
|
||||||
|
// printf("discover_vertical_shells from %d to %d\n", range.begin(), range.end());
|
||||||
|
// Cyclic buffers of pre-calculated offsetted top/bottom surfaces.
|
||||||
|
//FIXME these caches could be maintained per thread of the thread loop.
|
||||||
|
std::vector<DiscoverVerticalShellsCacheEntry> cache_top_regions(n_extra_top_layers, DiscoverVerticalShellsCacheEntry());
|
||||||
|
std::vector<DiscoverVerticalShellsCacheEntry> cache_bottom_regions(n_extra_bottom_layers, DiscoverVerticalShellsCacheEntry());
|
||||||
|
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
|
||||||
|
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
||||||
|
PROFILE_BLOCK(discover_vertical_shells_region_layer);
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
static size_t debug_idx = 0;
|
static size_t debug_idx = 0;
|
||||||
++ debug_idx;
|
++ debug_idx;
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
Layer *layer = this->layers[idx_layer];
|
Layer *layer = this->layers[idx_layer];
|
||||||
LayerRegion *layerm = layer->get_region(idx_region);
|
LayerRegion *layerm = layer->regions[idx_region];
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells-initial");
|
layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells-initial");
|
||||||
layerm->export_region_fill_surfaces_to_svg_debug("4_discover_vertical_shells-initial");
|
layerm->export_region_fill_surfaces_to_svg_debug("4_discover_vertical_shells-initial");
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
Flow solid_infill_flow = layerm->flow(frSolidInfill);
|
Flow solid_infill_flow = layerm->flow(frSolidInfill);
|
||||||
coord_t infill_line_spacing = solid_infill_flow.scaled_spacing();
|
coord_t infill_line_spacing = solid_infill_flow.scaled_spacing();
|
||||||
// Find a union of perimeters below / above this surface to guarantee a minimum shell thickness.
|
// Find a union of perimeters below / above this surface to guarantee a minimum shell thickness.
|
||||||
Polygons shell;
|
Polygons shell;
|
||||||
Polygons holes;
|
Polygons holes;
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
ExPolygons shell_ex;
|
ExPolygons shell_ex;
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
float min_perimeter_infill_spacing = float(infill_line_spacing) * 1.05f;
|
float min_perimeter_infill_spacing = float(infill_line_spacing) * 1.05f;
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
PROFILE_BLOCK(discover_vertical_shells_region_layer_collect);
|
PROFILE_BLOCK(discover_vertical_shells_region_layer_collect);
|
||||||
#if 0
|
#if 0
|
||||||
// #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
// #ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
{
|
{
|
||||||
Slic3r::SVG svg_cummulative(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d.svg", debug_idx), this->bounding_box());
|
Slic3r::SVG svg_cummulative(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d.svg", debug_idx), this->bounding_box());
|
||||||
for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n) {
|
for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n) {
|
||||||
if (n < 0 || n >= (int)this->layers.size())
|
if (n < 0 || n >= (int)this->layers.size())
|
||||||
continue;
|
continue;
|
||||||
ExPolygons &expolys = this->layers[n]->perimeter_expolygons;
|
ExPolygons &expolys = this->layers[n]->perimeter_expolygons;
|
||||||
for (size_t i = 0; i < expolys.size(); ++ i) {
|
for (size_t i = 0; i < expolys.size(); ++ i) {
|
||||||
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d-layer%d-expoly%d.svg", debug_idx, n, i), get_extents(expolys[i]));
|
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d-layer%d-expoly%d.svg", debug_idx, n, i), get_extents(expolys[i]));
|
||||||
svg.draw(expolys[i]);
|
svg.draw(expolys[i]);
|
||||||
svg.draw_outline(expolys[i].contour, "black", scale_(0.05));
|
svg.draw_outline(expolys[i].contour, "black", scale_(0.05));
|
||||||
svg.draw_outline(expolys[i].holes, "blue", scale_(0.05));
|
svg.draw_outline(expolys[i].holes, "blue", scale_(0.05));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
|
|
||||||
svg_cummulative.draw(expolys[i]);
|
svg_cummulative.draw(expolys[i]);
|
||||||
svg_cummulative.draw_outline(expolys[i].contour, "black", scale_(0.05));
|
svg_cummulative.draw_outline(expolys[i].contour, "black", scale_(0.05));
|
||||||
svg_cummulative.draw_outline(expolys[i].holes, "blue", scale_(0.05));
|
svg_cummulative.draw_outline(expolys[i].holes, "blue", scale_(0.05));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
// Reset the top / bottom inflated regions caches of entries, which are out of the moving window.
|
// Reset the top / bottom inflated regions caches of entries, which are out of the moving window.
|
||||||
if (n_extra_top_layers > 0)
|
if (n_extra_top_layers > 0)
|
||||||
cache_top_regions[idx_layer % n_extra_top_layers].valid = false;
|
cache_top_regions[idx_layer % n_extra_top_layers].valid = false;
|
||||||
if (n_extra_bottom_layers > 0 && idx_layer > 0)
|
if (n_extra_bottom_layers > 0 && idx_layer > 0)
|
||||||
cache_bottom_regions[(idx_layer - 1) % n_extra_bottom_layers].valid = false;
|
cache_bottom_regions[(idx_layer - 1) % n_extra_bottom_layers].valid = false;
|
||||||
bool hole_first = true;
|
bool hole_first = true;
|
||||||
for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n)
|
for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n)
|
||||||
if (n >= 0 && n < (int)this->layers.size()) {
|
if (n >= 0 && n < (int)this->layers.size()) {
|
||||||
Layer &neighbor_layer = *this->layers[n];
|
Layer &neighbor_layer = *this->layers[n];
|
||||||
LayerRegion &neighbor_region = *neighbor_layer.get_region(int(idx_region));
|
LayerRegion &neighbor_region = *neighbor_layer.get_region(int(idx_region));
|
||||||
Polygons newholes;
|
Polygons newholes;
|
||||||
for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region)
|
for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region)
|
||||||
polygons_append(newholes, to_polygons(neighbor_layer.regions[idx_region]->fill_expolygons));
|
polygons_append(newholes, to_polygons(neighbor_layer.regions[idx_region]->fill_expolygons));
|
||||||
if (hole_first) {
|
if (hole_first) {
|
||||||
hole_first = false;
|
hole_first = false;
|
||||||
polygons_append(holes, std::move(newholes));
|
polygons_append(holes, std::move(newholes));
|
||||||
}
|
}
|
||||||
else if (! holes.empty()) {
|
else if (! holes.empty()) {
|
||||||
holes = intersection(holes, newholes);
|
holes = intersection(holes, newholes);
|
||||||
}
|
}
|
||||||
size_t n_shell_old = shell.size();
|
size_t n_shell_old = shell.size();
|
||||||
if (n > int(idx_layer)) {
|
if (n > int(idx_layer)) {
|
||||||
// Collect top surfaces.
|
// Collect top surfaces.
|
||||||
DiscoverVerticalShellsCacheEntry &cache = cache_top_regions[n % n_extra_top_layers];
|
DiscoverVerticalShellsCacheEntry &cache = cache_top_regions[n % n_extra_top_layers];
|
||||||
if (! cache.valid) {
|
if (! cache.valid) {
|
||||||
cache.valid = true;
|
cache.valid = true;
|
||||||
// neighbor_region.slices contain the source top regions,
|
// neighbor_region.slices contain the source top regions,
|
||||||
// so one would think that they encompass the top fill_surfaces. But the fill_surfaces could have been
|
// so one would think that they encompass the top fill_surfaces. But the fill_surfaces could have been
|
||||||
// expanded before, therefore they may protrude out of neighbor_region.slices's top surfaces.
|
// expanded before, therefore they may protrude out of neighbor_region.slices's top surfaces.
|
||||||
//FIXME one should probably use the cummulative top surfaces over all regions here.
|
//FIXME one should probably use the cummulative top surfaces over all regions here.
|
||||||
cache.slices = offset(to_expolygons(neighbor_region.slices.filter_by_type(stTop)), min_perimeter_infill_spacing);
|
cache.slices = offset(to_expolygons(neighbor_region.slices.filter_by_type(stTop)), min_perimeter_infill_spacing);
|
||||||
cache.fill_surfaces = offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_type(stTop)), min_perimeter_infill_spacing);
|
cache.fill_surfaces = offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_type(stTop)), min_perimeter_infill_spacing);
|
||||||
|
}
|
||||||
|
polygons_append(shell, cache.slices);
|
||||||
|
polygons_append(shell, cache.fill_surfaces);
|
||||||
|
}
|
||||||
|
else if (n < int(idx_layer)) {
|
||||||
|
// Collect bottom and bottom bridge surfaces.
|
||||||
|
DiscoverVerticalShellsCacheEntry &cache = cache_bottom_regions[n % n_extra_bottom_layers];
|
||||||
|
if (! cache.valid) {
|
||||||
|
cache.valid = true;
|
||||||
|
//FIXME one should probably use the cummulative top surfaces over all regions here.
|
||||||
|
cache.slices = offset(to_expolygons(neighbor_region.slices.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing);
|
||||||
|
cache.fill_surfaces = offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing);
|
||||||
|
}
|
||||||
|
polygons_append(shell, cache.slices);
|
||||||
|
polygons_append(shell, cache.fill_surfaces);
|
||||||
|
}
|
||||||
|
// Running the union_ using the Clipper library piece by piece is cheaper
|
||||||
|
// than running the union_ all at once.
|
||||||
|
if (n_shell_old < shell.size())
|
||||||
|
shell = union_(shell, false);
|
||||||
}
|
}
|
||||||
polygons_append(shell, cache.slices);
|
|
||||||
polygons_append(shell, cache.fill_surfaces);
|
|
||||||
}
|
|
||||||
else if (n < int(idx_layer)) {
|
|
||||||
// Collect bottom and bottom bridge surfaces.
|
|
||||||
DiscoverVerticalShellsCacheEntry &cache = cache_bottom_regions[n % n_extra_bottom_layers];
|
|
||||||
if (! cache.valid) {
|
|
||||||
cache.valid = true;
|
|
||||||
//FIXME one should probably use the cummulative top surfaces over all regions here.
|
|
||||||
cache.slices = offset(to_expolygons(neighbor_region.slices.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing);
|
|
||||||
cache.fill_surfaces = offset(to_expolygons(neighbor_region.fill_surfaces.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing);
|
|
||||||
}
|
|
||||||
polygons_append(shell, cache.slices);
|
|
||||||
polygons_append(shell, cache.fill_surfaces);
|
|
||||||
}
|
|
||||||
// Running the union_ using the Clipper library piece by piece is cheaper
|
|
||||||
// than running the union_ all at once.
|
|
||||||
if (n_shell_old < shell.size())
|
|
||||||
shell = union_(shell, false);
|
|
||||||
}
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
{
|
{
|
||||||
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-%d.svg", debug_idx), get_extents(shell));
|
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-%d.svg", debug_idx), get_extents(shell));
|
||||||
svg.draw(shell);
|
svg.draw(shell);
|
||||||
svg.draw_outline(shell, "black", scale_(0.05));
|
svg.draw_outline(shell, "black", scale_(0.05));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
}
|
}
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
PROFILE_BLOCK(discover_vertical_shells_region_layer_shell_);
|
PROFILE_BLOCK(discover_vertical_shells_region_layer_shell_);
|
||||||
// shell = union_(shell, true);
|
// shell = union_(shell, true);
|
||||||
shell = union_(shell, false);
|
shell = union_(shell, false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
shell_ex = union_ex(shell, true);
|
shell_ex = union_ex(shell, true);
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (shell.empty())
|
//if (shell.empty())
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
{
|
{
|
||||||
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-after-union-%d.svg", debug_idx), get_extents(shell));
|
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-after-union-%d.svg", debug_idx), get_extents(shell));
|
||||||
svg.draw(shell_ex);
|
svg.draw(shell_ex);
|
||||||
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
}
|
}
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
{
|
{
|
||||||
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-internal-wshell-%d.svg", debug_idx), get_extents(shell));
|
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-internal-wshell-%d.svg", debug_idx), get_extents(shell));
|
||||||
svg.draw(layerm->fill_surfaces.filter_by_type(stInternal), "yellow", 0.5);
|
svg.draw(layerm->fill_surfaces.filter_by_type(stInternal), "yellow", 0.5);
|
||||||
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternal), "black", "blue", scale_(0.05));
|
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternal), "black", "blue", scale_(0.05));
|
||||||
svg.draw(shell_ex, "blue", 0.5);
|
svg.draw(shell_ex, "blue", 0.5);
|
||||||
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-internalvoid-wshell-%d.svg", debug_idx), get_extents(shell));
|
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-internalvoid-wshell-%d.svg", debug_idx), get_extents(shell));
|
||||||
svg.draw(layerm->fill_surfaces.filter_by_type(stInternalVoid), "yellow", 0.5);
|
svg.draw(layerm->fill_surfaces.filter_by_type(stInternalVoid), "yellow", 0.5);
|
||||||
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternalVoid), "black", "blue", scale_(0.05));
|
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternalVoid), "black", "blue", scale_(0.05));
|
||||||
svg.draw(shell_ex, "blue", 0.5);
|
svg.draw(shell_ex, "blue", 0.5);
|
||||||
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-internalvoid-wshell-%d.svg", debug_idx), get_extents(shell));
|
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-internalvoid-wshell-%d.svg", debug_idx), get_extents(shell));
|
||||||
svg.draw(layerm->fill_surfaces.filter_by_type(stInternalVoid), "yellow", 0.5);
|
svg.draw(layerm->fill_surfaces.filter_by_type(stInternalVoid), "yellow", 0.5);
|
||||||
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternalVoid), "black", "blue", scale_(0.05));
|
svg.draw_outline(layerm->fill_surfaces.filter_by_type(stInternalVoid), "black", "blue", scale_(0.05));
|
||||||
svg.draw(shell_ex, "blue", 0.5);
|
svg.draw(shell_ex, "blue", 0.5);
|
||||||
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
svg.draw_outline(shell_ex, "black", "blue", scale_(0.05));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
}
|
}
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
// Trim the shells region by the internal & internal void surfaces.
|
// Trim the shells region by the internal & internal void surfaces.
|
||||||
const SurfaceType surfaceTypesInternal[] = { stInternal, stInternalVoid, stInternalSolid };
|
const SurfaceType surfaceTypesInternal[] = { stInternal, stInternalVoid, stInternalSolid };
|
||||||
const Polygons polygonsInternal = to_polygons(layerm->fill_surfaces.filter_by_types(surfaceTypesInternal, 3));
|
const Polygons polygonsInternal = to_polygons(layerm->fill_surfaces.filter_by_types(surfaceTypesInternal, 3));
|
||||||
shell = intersection(shell, polygonsInternal, true);
|
shell = intersection(shell, polygonsInternal, true);
|
||||||
polygons_append(shell, diff(polygonsInternal, holes));
|
polygons_append(shell, diff(polygonsInternal, holes));
|
||||||
if (shell.empty())
|
if (shell.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Append the internal solids, so they will be merged with the new ones.
|
// Append the internal solids, so they will be merged with the new ones.
|
||||||
polygons_append(shell, to_polygons(layerm->fill_surfaces.filter_by_type(stInternalSolid)));
|
polygons_append(shell, to_polygons(layerm->fill_surfaces.filter_by_type(stInternalSolid)));
|
||||||
|
|
||||||
// These regions will be filled by a rectilinear full infill. Currently this type of infill
|
// These regions will be filled by a rectilinear full infill. Currently this type of infill
|
||||||
// only fills regions, which fit at least a single line. To avoid gaps in the sparse infill,
|
// only fills regions, which fit at least a single line. To avoid gaps in the sparse infill,
|
||||||
// make sure that this region does not contain parts narrower than the infill spacing width.
|
// make sure that this region does not contain parts narrower than the infill spacing width.
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
Polygons shell_before = shell;
|
Polygons shell_before = shell;
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
#if 1
|
#if 1
|
||||||
// Intentionally inflate a bit more than how much the region has been shrunk,
|
// Intentionally inflate a bit more than how much the region has been shrunk,
|
||||||
// so there will be some overlap between this solid infill and the other infill regions (mainly the sparse infill).
|
// so there will be some overlap between this solid infill and the other infill regions (mainly the sparse infill).
|
||||||
shell = offset2(shell, - 0.5f * min_perimeter_infill_spacing, 0.8f * min_perimeter_infill_spacing, ClipperLib::jtSquare);
|
shell = offset2(shell, - 0.5f * min_perimeter_infill_spacing, 0.8f * min_perimeter_infill_spacing, ClipperLib::jtSquare);
|
||||||
if (shell.empty())
|
if (shell.empty())
|
||||||
continue;
|
continue;
|
||||||
#else
|
#else
|
||||||
// Ensure each region is at least 3x infill line width wide, so it could be filled in.
|
// Ensure each region is at least 3x infill line width wide, so it could be filled in.
|
||||||
// float margin = float(infill_line_spacing) * 3.f;
|
// float margin = float(infill_line_spacing) * 3.f;
|
||||||
float margin = float(infill_line_spacing) * 1.5f;
|
float margin = float(infill_line_spacing) * 1.5f;
|
||||||
// we use a higher miterLimit here to handle areas with acute angles
|
// we use a higher miterLimit here to handle areas with acute angles
|
||||||
// in those cases, the default miterLimit would cut the corner and we'd
|
// in those cases, the default miterLimit would cut the corner and we'd
|
||||||
// get a triangle in $too_narrow; if we grow it below then the shell
|
// get a triangle in $too_narrow; if we grow it below then the shell
|
||||||
// would have a different shape from the external surface and we'd still
|
// would have a different shape from the external surface and we'd still
|
||||||
// have the same angle, so the next shell would be grown even more and so on.
|
// have the same angle, so the next shell would be grown even more and so on.
|
||||||
Polygons too_narrow = diff(shell, offset2(shell, -margin, margin, ClipperLib::jtMiter, 5.), true);
|
Polygons too_narrow = diff(shell, offset2(shell, -margin, margin, ClipperLib::jtMiter, 5.), true);
|
||||||
if (! too_narrow.empty()) {
|
if (! too_narrow.empty()) {
|
||||||
// grow the collapsing parts and add the extra area to the neighbor layer
|
// grow the collapsing parts and add the extra area to the neighbor layer
|
||||||
// as well as to our original surfaces so that we support this
|
// as well as to our original surfaces so that we support this
|
||||||
// additional area in the next shell too
|
// additional area in the next shell too
|
||||||
// make sure our grown surfaces don't exceed the fill area
|
// make sure our grown surfaces don't exceed the fill area
|
||||||
polygons_append(shell, intersection(offset(too_narrow, margin), polygonsInternal));
|
polygons_append(shell, intersection(offset(too_narrow, margin), polygonsInternal));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ExPolygons new_internal_solid = intersection_ex(polygonsInternal, shell, false);
|
ExPolygons new_internal_solid = intersection_ex(polygonsInternal, shell, false);
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
{
|
{
|
||||||
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-regularized-%d.svg", debug_idx), get_extents(shell_before));
|
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-regularized-%d.svg", debug_idx), get_extents(shell_before));
|
||||||
// Source shell.
|
// Source shell.
|
||||||
svg.draw(union_ex(shell_before, true));
|
svg.draw(union_ex(shell_before, true));
|
||||||
// Shell trimmed to the internal surfaces.
|
// Shell trimmed to the internal surfaces.
|
||||||
svg.draw_outline(union_ex(shell, true), "black", "blue", scale_(0.05));
|
svg.draw_outline(union_ex(shell, true), "black", "blue", scale_(0.05));
|
||||||
// Regularized infill region.
|
// Regularized infill region.
|
||||||
svg.draw_outline(new_internal_solid, "red", "magenta", scale_(0.05));
|
svg.draw_outline(new_internal_solid, "red", "magenta", scale_(0.05));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
}
|
}
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
// Trim the internal & internalvoid by the shell.
|
// Trim the internal & internalvoid by the shell.
|
||||||
Slic3r::ExPolygons new_internal = diff_ex(
|
Slic3r::ExPolygons new_internal = diff_ex(
|
||||||
to_polygons(layerm->fill_surfaces.filter_by_type(stInternal)),
|
to_polygons(layerm->fill_surfaces.filter_by_type(stInternal)),
|
||||||
shell,
|
shell,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
Slic3r::ExPolygons new_internal_void = diff_ex(
|
Slic3r::ExPolygons new_internal_void = diff_ex(
|
||||||
to_polygons(layerm->fill_surfaces.filter_by_type(stInternalVoid)),
|
to_polygons(layerm->fill_surfaces.filter_by_type(stInternalVoid)),
|
||||||
shell,
|
shell,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
{
|
{
|
||||||
SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal-%d.svg", debug_idx), get_extents(shell), new_internal, "black", "blue", scale_(0.05));
|
SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal-%d.svg", debug_idx), get_extents(shell), new_internal, "black", "blue", scale_(0.05));
|
||||||
SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_void-%d.svg", debug_idx), get_extents(shell), new_internal_void, "black", "blue", scale_(0.05));
|
SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_void-%d.svg", debug_idx), get_extents(shell), new_internal_void, "black", "blue", scale_(0.05));
|
||||||
SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_solid-%d.svg", debug_idx), get_extents(shell), new_internal_solid, "black", "blue", scale_(0.05));
|
SVG::export_expolygons(debug_out_path("discover_vertical_shells-new_internal_solid-%d.svg", debug_idx), get_extents(shell), new_internal_solid, "black", "blue", scale_(0.05));
|
||||||
}
|
}
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
// Assign resulting internal surfaces to layer.
|
// Assign resulting internal surfaces to layer.
|
||||||
const SurfaceType surfaceTypesKeep[] = { stTop, stBottom, stBottomBridge };
|
const SurfaceType surfaceTypesKeep[] = { stTop, stBottom, stBottomBridge };
|
||||||
layerm->fill_surfaces.keep_types(surfaceTypesKeep, sizeof(surfaceTypesKeep)/sizeof(SurfaceType));
|
layerm->fill_surfaces.keep_types(surfaceTypesKeep, sizeof(surfaceTypesKeep)/sizeof(SurfaceType));
|
||||||
layerm->fill_surfaces.append(new_internal, stInternal);
|
layerm->fill_surfaces.append(new_internal, stInternal);
|
||||||
layerm->fill_surfaces.append(new_internal_void, stInternalVoid);
|
layerm->fill_surfaces.append(new_internal_void, stInternalVoid);
|
||||||
layerm->fill_surfaces.append(new_internal_solid, stInternalSolid);
|
layerm->fill_surfaces.append(new_internal_solid, stInternalSolid);
|
||||||
} // for each layer
|
} // for each layer
|
||||||
|
});
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - end";
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++idx_layer) {
|
for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++idx_layer) {
|
||||||
|
Loading…
Reference in New Issue
Block a user