This commit is contained in:
Lukáš Hejl 2021-05-28 17:36:56 +02:00
parent f5c7d14e85
commit 726a48383f
4 changed files with 32 additions and 30 deletions

View file

@ -1125,11 +1125,14 @@ static void remove_multiple_edges_in_vertices(MMU_Graph &graph, const std::vecto
} }
} }
template<typename ThrowOnCancel> static void cut_segmented_layers(const std::vector<ExPolygons> &input_expolygons,
static void cut_segmented_layers(const std::vector<ExPolygons> &input_expolygons, std::vector<std::vector<std::pair<ExPolygon, size_t>>> &segmented_regions, const float cut_width, ThrowOnCancel throw_on_cancel) { std::vector<std::vector<std::pair<ExPolygon, size_t>>> &segmented_regions,
const float cut_width,
const std::function<void()> &throw_on_cancel_callback)
{
tbb::parallel_for(tbb::blocked_range<size_t>(0, segmented_regions.size()),[&](const tbb::blocked_range<size_t>& range) { tbb::parallel_for(tbb::blocked_range<size_t>(0, segmented_regions.size()),[&](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
throw_on_cancel(); throw_on_cancel_callback();
std::vector<std::pair<ExPolygon, size_t>> segmented_regions_cuts; std::vector<std::pair<ExPolygon, size_t>> segmented_regions_cuts;
for (const std::pair<ExPolygon, size_t> &colored_expoly : segmented_regions[layer_idx]) { for (const std::pair<ExPolygon, size_t> &colored_expoly : segmented_regions[layer_idx]) {
ExPolygons cut_colored_expoly = diff_ex(colored_expoly.first, offset_ex(input_expolygons[layer_idx], cut_width)); ExPolygons cut_colored_expoly = diff_ex(colored_expoly.first, offset_ex(input_expolygons[layer_idx], cut_width));
@ -1143,8 +1146,9 @@ static void cut_segmented_layers(const std::vector<ExPolygons> &input_expolygons
} }
// Returns MMU segmentation of top and bottom layers based on painting in MMU segmentation gizmo // Returns MMU segmentation of top and bottom layers based on painting in MMU segmentation gizmo
template<typename ThrowOnCancel> static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bottom_layers(const PrintObject &print_object,
static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bottom_layers(const PrintObject &print_object, const std::vector<ExPolygons> &input_expolygons, ThrowOnCancel throw_on_cancel) const std::vector<ExPolygons> &input_expolygons,
const std::function<void()> &throw_on_cancel_callback)
{ {
const size_t num_extruders = print_object.print()->config().nozzle_diameter.size(); const size_t num_extruders = print_object.print()->config().nozzle_diameter.size();
const ConstLayerPtrsAdaptor layers = print_object.layers(); const ConstLayerPtrsAdaptor layers = print_object.layers();
@ -1152,7 +1156,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
triangles_by_color.assign(num_extruders, std::vector<ExPolygons>(layers.size())); triangles_by_color.assign(num_extruders, std::vector<ExPolygons>(layers.size()));
for (const ModelVolume *mv : print_object.model_object()->volumes) { for (const ModelVolume *mv : print_object.model_object()->volumes) {
for (size_t extruder_idx = 0; extruder_idx < num_extruders; ++extruder_idx) { for (size_t extruder_idx = 0; extruder_idx < num_extruders; ++extruder_idx) {
throw_on_cancel(); throw_on_cancel_callback();
const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx)); const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx));
if (!mv->is_model_part() || custom_facets.indices.empty()) if (!mv->is_model_part() || custom_facets.indices.empty())
continue; continue;
@ -1232,7 +1236,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
top_layers.back() = input_expolygons.back(); top_layers.back() = input_expolygons.back();
tbb::parallel_for(tbb::blocked_range<size_t>(1, input_expolygons.size()), [&](const tbb::blocked_range<size_t> &range) { tbb::parallel_for(tbb::blocked_range<size_t>(1, input_expolygons.size()), [&](const tbb::blocked_range<size_t> &range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
throw_on_cancel(); throw_on_cancel_callback();
float extrusion_width = 0.1f * float(scale_(get_extrusion_width(layer_idx))); float extrusion_width = 0.1f * float(scale_(get_extrusion_width(layer_idx)));
top_layers[layer_idx - 1] = diff_ex(input_expolygons[layer_idx - 1], offset_ex(input_expolygons[layer_idx], extrusion_width)); top_layers[layer_idx - 1] = diff_ex(input_expolygons[layer_idx - 1], offset_ex(input_expolygons[layer_idx], extrusion_width));
} }
@ -1242,7 +1246,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
bottom_layers.front() = input_expolygons.front(); bottom_layers.front() = input_expolygons.front();
tbb::parallel_for(tbb::blocked_range<size_t>(0, input_expolygons.size() - 1), [&](const tbb::blocked_range<size_t> &range) { tbb::parallel_for(tbb::blocked_range<size_t>(0, input_expolygons.size() - 1), [&](const tbb::blocked_range<size_t> &range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
throw_on_cancel(); throw_on_cancel_callback();
float extrusion_width = 0.1f * float(scale_(get_extrusion_width(layer_idx))); float extrusion_width = 0.1f * float(scale_(get_extrusion_width(layer_idx)));
bottom_layers[layer_idx + 1] = diff_ex(input_expolygons[layer_idx + 1], offset_ex(input_expolygons[layer_idx], extrusion_width)); bottom_layers[layer_idx + 1] = diff_ex(input_expolygons[layer_idx + 1], offset_ex(input_expolygons[layer_idx], extrusion_width));
} }
@ -1250,7 +1254,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
tbb::parallel_for(tbb::blocked_range<size_t>(0, input_expolygons.size()), [&](const tbb::blocked_range<size_t> &range) { tbb::parallel_for(tbb::blocked_range<size_t>(0, input_expolygons.size()), [&](const tbb::blocked_range<size_t> &range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
throw_on_cancel(); throw_on_cancel_callback();
float extrusion_width = 0.1f * float(scale_(get_extrusion_width(layer_idx))); float extrusion_width = 0.1f * float(scale_(get_extrusion_width(layer_idx)));
for (std::vector<ExPolygons> &triangles : triangles_by_color) { for (std::vector<ExPolygons> &triangles : triangles_by_color) {
if (!triangles[layer_idx].empty() && (!top_layers[layer_idx].empty() || !bottom_layers[layer_idx].empty())) { if (!triangles[layer_idx].empty() && (!top_layers[layer_idx].empty() || !bottom_layers[layer_idx].empty())) {
@ -1277,7 +1281,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
continue; continue;
for (size_t color_idx = 0; color_idx < triangles_by_color.size(); ++color_idx) { for (size_t color_idx = 0; color_idx < triangles_by_color.size(); ++color_idx) {
throw_on_cancel(); throw_on_cancel_callback();
if (triangles_by_color[color_idx][layer_idx].empty()) if (triangles_by_color[color_idx][layer_idx].empty())
continue; continue;
ExPolygons intersection_poly = intersection_ex(triangles_by_color[color_idx][layer_idx], top_expolygon); ExPolygons intersection_poly = intersection_ex(triangles_by_color[color_idx][layer_idx], top_expolygon);
@ -1312,7 +1316,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
continue; continue;
for (size_t color_idx = 0; color_idx < triangles_by_color.size(); ++color_idx) { for (size_t color_idx = 0; color_idx < triangles_by_color.size(); ++color_idx) {
throw_on_cancel(); throw_on_cancel_callback();
if (triangles_by_color[color_idx][layer_idx].empty()) if (triangles_by_color[color_idx][layer_idx].empty())
continue; continue;
@ -1340,7 +1344,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
std::vector<std::vector<ExPolygons>> triangles_by_color_merged(num_extruders); std::vector<std::vector<ExPolygons>> triangles_by_color_merged(num_extruders);
triangles_by_color_merged.assign(num_extruders, std::vector<ExPolygons>(input_expolygons.size())); triangles_by_color_merged.assign(num_extruders, std::vector<ExPolygons>(input_expolygons.size()));
for (size_t layer_idx = 0; layer_idx < input_expolygons.size(); ++layer_idx) { for (size_t layer_idx = 0; layer_idx < input_expolygons.size(); ++layer_idx) {
throw_on_cancel(); throw_on_cancel_callback();
for (size_t color_idx = 0; color_idx < triangles_by_color_merged.size(); ++color_idx) { for (size_t color_idx = 0; color_idx < triangles_by_color_merged.size(); ++color_idx) {
auto &self = triangles_by_color_merged[color_idx][layer_idx]; auto &self = triangles_by_color_merged[color_idx][layer_idx];
append(self, std::move(triangles_by_color_bottom[color_idx][layer_idx])); append(self, std::move(triangles_by_color_bottom[color_idx][layer_idx]));
@ -1358,9 +1362,10 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
return triangles_by_color_merged; return triangles_by_color_merged;
} }
template<typename ThrowOnCancel>
static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_layers( static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_layers(
const std::vector<std::vector<std::pair<ExPolygon, size_t>>> &segmented_regions, std::vector<std::vector<ExPolygons>> &&top_and_bottom_layers, ThrowOnCancel throw_on_cancel) const std::vector<std::vector<std::pair<ExPolygon, size_t>>> &segmented_regions,
std::vector<std::vector<ExPolygons>> &&top_and_bottom_layers,
const std::function<void()> &throw_on_cancel_callback)
{ {
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged(segmented_regions.size()); std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged(segmented_regions.size());
@ -1368,7 +1373,7 @@ static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_la
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - merging region: " << layer_idx; BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - merging region: " << layer_idx;
for (const std::pair<ExPolygon, size_t> &colored_expoly : segmented_regions[layer_idx]) { for (const std::pair<ExPolygon, size_t> &colored_expoly : segmented_regions[layer_idx]) {
throw_on_cancel(); throw_on_cancel_callback();
ExPolygons cut_colored_expoly = {colored_expoly.first}; ExPolygons cut_colored_expoly = {colored_expoly.first};
for (const std::vector<ExPolygons> &top_and_bottom_layer : top_and_bottom_layers) for (const std::vector<ExPolygons> &top_and_bottom_layer : top_and_bottom_layers)
cut_colored_expoly = diff_ex(cut_colored_expoly, top_and_bottom_layer[layer_idx]); cut_colored_expoly = diff_ex(cut_colored_expoly, top_and_bottom_layer[layer_idx]);
@ -1385,7 +1390,7 @@ static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_la
return segmented_regions_merged; return segmented_regions_merged;
} }
std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object) std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{ {
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions(print_object.layers().size()); std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions(print_object.layers().size());
std::vector<std::vector<PaintedLine>> painted_lines(print_object.layers().size()); std::vector<std::vector<PaintedLine>> painted_lines(print_object.layers().size());
@ -1394,12 +1399,12 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
std::vector<ExPolygons> input_expolygons(layers.size()); std::vector<ExPolygons> input_expolygons(layers.size());
std::vector<Polygons> input_polygons(layers.size()); std::vector<Polygons> input_polygons(layers.size());
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
// Merge all regions and remove small holes // Merge all regions and remove small holes
tbb::parallel_for(tbb::blocked_range<size_t>(0, layers.size()), [&](const tbb::blocked_range<size_t> &range) { tbb::parallel_for(tbb::blocked_range<size_t>(0, layers.size()), [&](const tbb::blocked_range<size_t> &range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
ExPolygons ex_polygons; ExPolygons ex_polygons;
for (LayerRegion *region : layers[layer_idx]->regions()) for (LayerRegion *region : layers[layer_idx]->regions())
for (const Surface &surface : region->slices.surfaces) for (const Surface &surface : region->slices.surfaces)
@ -1422,7 +1427,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
}); // end of parallel_for }); // end of parallel_for
for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) { for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) {
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
BoundingBox bbox(get_extents(input_expolygons[layer_idx])); BoundingBox bbox(get_extents(input_expolygons[layer_idx]));
bbox.offset(SCALED_EPSILON); bbox.offset(SCALED_EPSILON);
edge_grids[layer_idx].set_bbox(bbox); edge_grids[layer_idx].set_bbox(bbox);
@ -1432,7 +1437,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
for (const ModelVolume *mv : print_object.model_object()->volumes) { for (const ModelVolume *mv : print_object.model_object()->volumes) {
const size_t num_extruders = print_object.print()->config().nozzle_diameter.size(); const size_t num_extruders = print_object.print()->config().nozzle_diameter.size();
for (size_t extruder_idx = 1; extruder_idx < num_extruders; ++extruder_idx) { for (size_t extruder_idx = 1; extruder_idx < num_extruders; ++extruder_idx) {
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx)); const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx));
if (!mv->is_model_part() || custom_facets.indices.empty()) if (!mv->is_model_part() || custom_facets.indices.empty())
continue; continue;
@ -1501,7 +1506,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
tbb::parallel_for(tbb::blocked_range<size_t>(0, print_object.layers().size()), [&](const tbb::blocked_range<size_t> &range) { tbb::parallel_for(tbb::blocked_range<size_t>(0, print_object.layers().size()), [&](const tbb::blocked_range<size_t> &range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
// for(size_t layer_idx = 0; layer_idx < print_object.layers().size(); ++layer_idx) { // for(size_t layer_idx = 0; layer_idx < print_object.layers().size(); ++layer_idx) {
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation of layer: " << layer_idx; BOOST_LOG_TRIVIAL(debug) << "MMU segmentation of layer: " << layer_idx;
auto comp = [&edge_grids, layer_idx](const PaintedLine &first, const PaintedLine &second) { auto comp = [&edge_grids, layer_idx](const PaintedLine &first, const PaintedLine &second) {
@ -1528,20 +1533,19 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
} }
} }
}); // end of parallel_for }); // end of parallel_for
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
const auto throw_on_cancel_callback = std::function<void()>([&print_object]() { print_object.print()->throw_if_canceled(); });
if (auto w = print_object.config().mmu_segmented_region_max_width; w > 0.f) { if (auto w = print_object.config().mmu_segmented_region_max_width; w > 0.f) {
cut_segmented_layers(input_expolygons, segmented_regions, float(-scale_(w)), throw_on_cancel_callback); cut_segmented_layers(input_expolygons, segmented_regions, float(-scale_(w)), throw_on_cancel_callback);
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
} }
// return segmented_regions; // return segmented_regions;
std::vector<std::vector<ExPolygons>> top_and_bottom_layers = mmu_segmentation_top_and_bottom_layers(print_object, input_expolygons, throw_on_cancel_callback); std::vector<std::vector<ExPolygons>> top_and_bottom_layers = mmu_segmentation_top_and_bottom_layers(print_object, input_expolygons, throw_on_cancel_callback);
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged = merge_segmented_layers(segmented_regions, std::move(top_and_bottom_layers), throw_on_cancel_callback); std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged = merge_segmented_layers(segmented_regions, std::move(top_and_bottom_layers), throw_on_cancel_callback);
print_object.print()->throw_if_canceled(); throw_on_cancel_callback();
return segmented_regions_merged; return segmented_regions_merged;
} }

View file

@ -11,7 +11,7 @@ class PrintObject;
class ExPolygon; class ExPolygon;
// Returns MMU segmentation based on painting in MMU segmentation gizmo // Returns MMU segmentation based on painting in MMU segmentation gizmo
std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object); std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
} // namespace Slic3r } // namespace Slic3r

View file

@ -628,8 +628,6 @@ private:
friend class GCode; friend class GCode;
// Allow PrintObject to access m_mutex and m_cancel_callback. // Allow PrintObject to access m_mutex and m_cancel_callback.
friend class PrintObject; friend class PrintObject;
// Allow multi_material_segmentation_by_painting() to access m_cancel_callback.
friend std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object);
}; };
} /* slic3r_Print_hpp_ */ } /* slic3r_Print_hpp_ */

View file

@ -556,7 +556,7 @@ template<typename ThrowOnCancel>
static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCancel throw_on_cancel) static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCancel throw_on_cancel)
{ {
// Returns MMU segmentation based on painting in MMU segmentation gizmo // Returns MMU segmentation based on painting in MMU segmentation gizmo
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmentation = multi_material_segmentation_by_painting(print_object); std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmentation = multi_material_segmentation_by_painting(print_object, throw_on_cancel);
assert(segmentation.size() == print_object.layer_count()); assert(segmentation.size() == print_object.layer_count());
tbb::parallel_for( tbb::parallel_for(
tbb::blocked_range<size_t>(0, segmentation.size(), std::max(segmentation.size() / 128, size_t(1))), tbb::blocked_range<size_t>(0, segmentation.size(), std::max(segmentation.size() / 128, size_t(1))),