mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 12:22:01 +08:00
Fixed clustering for threads issue - inverse comparison, lower job idx incorrectly initialized
This commit is contained in:
parent
3782d24ccf
commit
ad693532d3
@ -44,6 +44,7 @@
|
|||||||
#include <oneapi/tbb/parallel_for.h>
|
#include <oneapi/tbb/parallel_for.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <tuple>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -1633,6 +1634,13 @@ void PrintObject::bridge_over_infill()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
||||||
|
for (const auto &c : candidate_surfaces) {
|
||||||
|
debug_draw(std::to_string(c.region->layer()->id()) + "_candidate_surface_" + std::to_string(area(c.original_surface->expolygon)),
|
||||||
|
to_lines(c.region->layer()->lslices), to_lines(c.original_surface->expolygon), to_lines(c.new_polys), {});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::map<size_t, std::vector<CandidateSurface>> surfaces_by_layer;
|
std::map<size_t, std::vector<CandidateSurface>> surfaces_by_layer;
|
||||||
std::vector<std::pair<const Surface*, float>> surfaces_w_bottom_z;
|
std::vector<std::pair<const Surface*, float>> surfaces_w_bottom_z;
|
||||||
for (const CandidateSurface& c : candidate_surfaces) {
|
for (const CandidateSurface& c : candidate_surfaces) {
|
||||||
@ -1661,10 +1669,17 @@ void PrintObject::bridge_over_infill()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#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
|
// 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<std::vector<size_t>> clustered_layers_for_threads;
|
||||||
|
// note: surfaces_by_layer is ordered map
|
||||||
for (auto pair : surfaces_by_layer) {
|
for (auto pair : surfaces_by_layer) {
|
||||||
if (clustered_layers_for_threads.empty() || this->get_layer(clustered_layers_for_threads.back().back())->print_z >
|
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)->print_z -
|
||||||
this->get_layer(pair.first)->regions()[0]->flow(frSolidInfill, true).height() -
|
this->get_layer(pair.first)->regions()[0]->flow(frSolidInfill, true).height() -
|
||||||
EPSILON) {
|
EPSILON) {
|
||||||
@ -1674,6 +1689,17 @@ void PrintObject::bridge_over_infill()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
||||||
|
std::cout << "BRIDGE OVER INFILL CLUSTERED LAYERS FOR SINGLE THREAD" << std::endl;
|
||||||
|
for (auto cluster : clustered_layers_for_threads) {
|
||||||
|
std::cout << "CLUSTER: ";
|
||||||
|
for (auto l : cluster) {
|
||||||
|
std::cout << l << " ";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// LAMBDA to gather areas with sparse infill deep enough that we can fit thick bridges there.
|
// LAMBDA to gather areas with sparse infill deep enough that we can fit thick bridges there.
|
||||||
auto gather_areas_w_depth =
|
auto gather_areas_w_depth =
|
||||||
[](const PrintObject *po, int lidx, float target_flow_height) {
|
[](const PrintObject *po, int lidx, float target_flow_height) {
|
||||||
@ -1820,10 +1846,6 @@ void PrintObject::bridge_over_infill()
|
|||||||
auto anchors_and_walls_tree = AABBTreeLines::LinesDistancer<Line>{std::move(anchors)};
|
auto anchors_and_walls_tree = AABBTreeLines::LinesDistancer<Line>{std::move(anchors)};
|
||||||
auto bridged_area_tree = AABBTreeLines::LinesDistancer<Line>{to_lines(bridged_area)};
|
auto bridged_area_tree = AABBTreeLines::LinesDistancer<Line>{to_lines(bridged_area)};
|
||||||
|
|
||||||
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
|
||||||
debug_draw(std::to_string(lidx) + "sliced", to_lines(bridged_area), anchors_and_walls, vertical_lines, {});
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::vector<std::vector<Line>> polygon_sections(n_vlines);
|
std::vector<std::vector<Line>> polygon_sections(n_vlines);
|
||||||
for (size_t i = 0; i < n_vlines; i++) {
|
for (size_t i = 0; i < n_vlines; i++) {
|
||||||
auto area_intersections = bridged_area_tree.intersections_with_line<true>(vertical_lines[i]);
|
auto area_intersections = bridged_area_tree.intersections_with_line<true>(vertical_lines[i]);
|
||||||
@ -1941,15 +1963,6 @@ void PrintObject::bridge_over_infill()
|
|||||||
Polygon &new_poly = expanded_bridged_area.emplace_back(std::move(traced_poly.lows));
|
Polygon &new_poly = expanded_bridged_area.emplace_back(std::move(traced_poly.lows));
|
||||||
new_poly.points.insert(new_poly.points.end(), traced_poly.highs.rbegin(), traced_poly.highs.rend());
|
new_poly.points.insert(new_poly.points.end(), traced_poly.highs.rbegin(), traced_poly.highs.rend());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
|
||||||
Lines l{};
|
|
||||||
for (const auto &s : polygon_sections) {
|
|
||||||
l.insert(l.end(), s.begin(), s.end());
|
|
||||||
}
|
|
||||||
debug_draw(std::to_string(lidx) + "reconstructed", l, anchors_and_walls_tree.get_lines(), to_lines(expanded_bridged_area),
|
|
||||||
bridged_area_tree.get_lines());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
polygons_rotate(expanded_bridged_area, -aligning_angle);
|
polygons_rotate(expanded_bridged_area, -aligning_angle);
|
||||||
@ -1990,7 +2003,7 @@ void PrintObject::bridge_over_infill()
|
|||||||
// reason we did the clustering of layers per thread.
|
// reason we did the clustering of layers per thread.
|
||||||
double bottom_z = po->get_layer(lidx)->print_z - thick_bridges_depth - EPSILON;
|
double bottom_z = po->get_layer(lidx)->print_z - thick_bridges_depth - EPSILON;
|
||||||
if (job_idx > 0) {
|
if (job_idx > 0) {
|
||||||
for (int lower_job_idx = job_idx; lower_job_idx >= 0; lower_job_idx--) {
|
for (int lower_job_idx = job_idx - 1; lower_job_idx >= 0; lower_job_idx--) {
|
||||||
size_t lower_layer_idx = clustered_layers_for_threads[cluster_idx][lower_job_idx];
|
size_t lower_layer_idx = clustered_layers_for_threads[cluster_idx][lower_job_idx];
|
||||||
const Layer *lower_layer = po->get_layer(lower_layer_idx);
|
const Layer *lower_layer = po->get_layer(lower_layer_idx);
|
||||||
if (lower_layer->print_z >= bottom_z) {
|
if (lower_layer->print_z >= bottom_z) {
|
||||||
@ -2024,9 +2037,6 @@ void PrintObject::bridge_over_infill()
|
|||||||
|
|
||||||
Polygons boundary_area = union_(expansion_area, expand(area_to_be_bridged, flow.scaled_spacing()));
|
Polygons boundary_area = union_(expansion_area, expand(area_to_be_bridged, flow.scaled_spacing()));
|
||||||
Lines boundary_lines = to_lines(boundary_area);
|
Lines boundary_lines = to_lines(boundary_area);
|
||||||
if (boundary_lines.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
double bridging_angle = 0;
|
double bridging_angle = 0;
|
||||||
Polygons tmp_expanded_area = expand(area_to_be_bridged, 3.0 * flow.scaled_spacing());
|
Polygons tmp_expanded_area = expand(area_to_be_bridged, 3.0 * flow.scaled_spacing());
|
||||||
for (const CandidateSurface &s : expanded_surfaces) {
|
for (const CandidateSurface &s : expanded_surfaces) {
|
||||||
@ -2040,7 +2050,7 @@ void PrintObject::bridge_over_infill()
|
|||||||
bridging_angle = determine_bridging_angle(area_to_be_bridged, anchors,
|
bridging_angle = determine_bridging_angle(area_to_be_bridged, anchors,
|
||||||
candidate.region->region().config().fill_pattern.value);
|
candidate.region->region().config().fill_pattern.value);
|
||||||
} else {
|
} else {
|
||||||
// use expansion boundaries as anchors. However the current area must be removed from such filter.
|
// use expansion boundaries as anchors.
|
||||||
// Also, use Infill pattern that is neutral for angle determination, since there are no infill lines.
|
// Also, use Infill pattern that is neutral for angle determination, since there are no infill lines.
|
||||||
bridging_angle = determine_bridging_angle(area_to_be_bridged, boundary_lines, InfillPattern::ipLine);
|
bridging_angle = determine_bridging_angle(area_to_be_bridged, boundary_lines, InfillPattern::ipLine);
|
||||||
}
|
}
|
||||||
@ -2052,6 +2062,13 @@ void PrintObject::bridge_over_infill()
|
|||||||
bridged_area = opening(bridged_area, flow.scaled_spacing());
|
bridged_area = opening(bridged_area, flow.scaled_spacing());
|
||||||
expansion_area = diff(expansion_area, bridged_area);
|
expansion_area = diff(expansion_area, bridged_area);
|
||||||
|
|
||||||
|
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
||||||
|
debug_draw(std::to_string(lidx) + "_" + std::to_string(cluster_idx) + "_" + std::to_string(job_idx) +
|
||||||
|
"_expanded_bridging",
|
||||||
|
to_lines(layer->lslices), to_lines(candidate.original_surface->expolygon), to_lines(candidate.new_polys),
|
||||||
|
to_lines(bridged_area));
|
||||||
|
#endif
|
||||||
|
|
||||||
expanded_surfaces.push_back(
|
expanded_surfaces.push_back(
|
||||||
CandidateSurface(candidate.original_surface, bridged_area, candidate.region, bridging_angle));
|
CandidateSurface(candidate.original_surface, bridged_area, candidate.region, bridging_angle));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user