Do not generate other than sparse infill lines

Split jobs if candidates bounding boxes do not overlap - otherwise it can become completely linearized and very slow
Improve formatting
This commit is contained in:
PavelMikus 2023-03-10 15:35:11 +01:00 committed by Pavel Mikuš
parent ad693532d3
commit d223eef38d
2 changed files with 121 additions and 81 deletions

View File

@ -649,6 +649,10 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
Polylines sparse_infill_polylines{};
for (SurfaceFill &surface_fill : surface_fills) {
if (surface_fill.surface.surface_type != stInternal) {
continue;
}
switch (surface_fill.params.pattern) {
case ipLightning: {
auto polylines = to_polylines(shrink_ex(surface_fill.expolygons, 5.0 * surface_fill.params.flow.scaled_spacing()));

View File

@ -1595,8 +1595,11 @@ void PrintObject::bridge_over_infill()
double bridge_angle;
};
tbb::concurrent_vector<CandidateSurface> candidate_surfaces;
std::map<size_t, std::vector<CandidateSurface>> surfaces_by_layer;
// SECTION to gather and filter surfaces for expanding, and then cluster them by layer
{
tbb::concurrent_vector<CandidateSurface> candidate_surfaces;
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = static_cast<const PrintObject *>(this),
&candidate_surfaces](tbb::blocked_range<size_t> r) {
for (size_t lidx = r.begin(); lidx < r.end(); lidx++) {
@ -1641,16 +1644,22 @@ void PrintObject::bridge_over_infill()
}
#endif
std::map<size_t, std::vector<CandidateSurface>> surfaces_by_layer;
std::vector<std::pair<const Surface*, float>> surfaces_w_bottom_z;
for (const CandidateSurface &c : candidate_surfaces) {
surfaces_by_layer[c.region->layer()->id()].push_back(c);
}
}
std::map<size_t, Polylines> infill_lines;
// SECTION to generate infill polylines
{
std::vector<std::pair<const Surface *, float>> surfaces_w_bottom_z;
for (const auto &pair : surfaces_by_layer) {
for (const CandidateSurface &c : pair.second) {
surfaces_w_bottom_z.emplace_back(c.original_surface, c.region->m_layer->bottom_z());
}
}
this->adaptive_fill_octrees = this->prepare_adaptive_infill_data(surfaces_w_bottom_z);
std::map<size_t, Polylines> infill_lines;
std::vector<size_t> layers_to_generate_infill;
for (const auto &pair : surfaces_by_layer) {
assert(pair.first > 0);
@ -1668,21 +1677,47 @@ void PrintObject::bridge_over_infill()
po->adaptive_fill_octrees.second.get());
}
});
#ifdef DEBUG_BRIDGE_OVER_INFILL
for (const auto &il : infill_lines) {
debug_draw(std::to_string(il.first) + "_infill_lines", to_lines(get_layer(il.first)->lslices), to_lines(il.second), {}, {});
}
#endif
}
// cluster layers by depth needed for thick bridges. Each cluster is to be processed by single thread sequentially, so that bridges cannot appear one on another
std::vector<std::vector<size_t>> clustered_layers_for_threads;
{
std::vector<size_t> layers_with_candidates;
std::map<size_t, Polygons> layer_area_covered_by_candidates;
for (const auto& pair : surfaces_by_layer) {
layers_with_candidates.push_back(pair.first);
layer_area_covered_by_candidates[pair.first] = {};
}
tbb::parallel_for(tbb::blocked_range<size_t>(0, layers_with_candidates.size()), [&layers_with_candidates, &surfaces_by_layer,
&layer_area_covered_by_candidates](
tbb::blocked_range<size_t> r) {
for (size_t job_idx = r.begin(); job_idx < r.end(); job_idx++) {
size_t lidx = layers_with_candidates[job_idx];
for (const auto &candidate : surfaces_by_layer.at(lidx)) {
Polygon candiate_inflated_aabb = get_extents(candidate.new_polys)
.inflated(candidate.region->flow(frSolidInfill, true).scaled_spacing() * 5)
.polygon();
layer_area_covered_by_candidates.at(lidx) = union_(layer_area_covered_by_candidates.at(lidx),
Polygons{candiate_inflated_aabb});
}
}
});
// note: surfaces_by_layer is ordered map
for (auto pair : surfaces_by_layer) {
if (clustered_layers_for_threads.empty() || this->get_layer(clustered_layers_for_threads.back().back())->print_z <
this->get_layer(pair.first)->print_z -
this->get_layer(pair.first)->regions()[0]->flow(frSolidInfill, true).height() -
EPSILON) {
if (clustered_layers_for_threads.empty() ||
this->get_layer(clustered_layers_for_threads.back().back())->print_z <
this->get_layer(pair.first)->print_z - this->get_layer(pair.first)->regions()[0]->flow(frSolidInfill, true).height() -
EPSILON ||
intersection(layer_area_covered_by_candidates[clustered_layers_for_threads.back().back()],
layer_area_covered_by_candidates[pair.first])
.empty()) {
clustered_layers_for_threads.push_back({pair.first});
} else {
clustered_layers_for_threads.back().push_back(pair.first);
@ -1699,6 +1734,7 @@ void PrintObject::bridge_over_infill()
std::cout << std::endl;
}
#endif
}
// LAMBDA to gather areas with sparse infill deep enough that we can fit thick bridges there.
auto gather_areas_w_depth =