diff options
author | Vojtech Bubnik <bubnikv@gmail.com> | 2021-05-27 17:10:58 +0300 |
---|---|---|
committer | Vojtech Bubnik <bubnikv@gmail.com> | 2021-05-27 17:12:34 +0300 |
commit | 818cb703ede34495cb8405f224d39dfe6d3462ca (patch) | |
tree | 41465b7352946ca37755232830523f4065a73d41 | |
parent | f1754e538e7a97675346336403bfe381ac0f71e4 (diff) |
Refactored the ModelVolume bounding box to Eigen::AlignedBox<float>,
separated splitting of LayerRegions by MMU segmentation to its own
function.
-rw-r--r-- | src/libslic3r/Print.hpp | 12 | ||||
-rw-r--r-- | src/libslic3r/PrintApply.cpp | 77 | ||||
-rw-r--r-- | src/libslic3r/PrintObjectSlice.cpp | 246 |
3 files changed, 177 insertions, 158 deletions
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 073779ae6..01b866870 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -16,6 +16,8 @@ #include "libslic3r.h" +#include <Eigen/Geometry> + #include <functional> #include <set> @@ -164,9 +166,12 @@ class PrintObjectRegions public: // Bounding box of a ModelVolume transformed into the working space of a PrintObject, possibly // clipped by a layer range modifier. + // Only Eigen types of Nx16 size are vectorized. This bounding box will not be vectorized. + static_assert(sizeof(Eigen::AlignedBox<float, 3>) == 24, "Eigen::AlignedBox<float, 3> is not being vectorized, thus it does not need to be aligned"); + using BoundingBox = Eigen::AlignedBox<float, 3>; struct VolumeExtents { - ObjectID volume_id; - BoundingBoxf3 bbox; + ObjectID volume_id; + BoundingBox bbox; }; struct VolumeRegion @@ -178,7 +183,7 @@ public: // Pointer to PrintObjectRegions::all_regions, null for a negative volume. PrintRegion *region { nullptr }; // Pointer to VolumeExtents::bbox. - const BoundingBoxf3 *bbox { nullptr }; + const BoundingBox *bbox { nullptr }; // To speed up merging of same regions. const VolumeRegion *prev_same_region { nullptr }; }; @@ -307,6 +312,7 @@ public: const PrintRegion& printing_region(size_t idx) const throw() { return *m_shared_regions->all_regions[idx].get(); } //FIXME returing all possible regions before slicing, thus some of the regions may not be slicing at the end. std::vector<std::reference_wrapper<const PrintRegion>> all_regions() const; + const PrintObjectRegions* shared_regions() const throw() { return m_shared_regions; } bool has_support() const { return m_config.support_material || m_config.support_material_enforce_layers > 0; } bool has_raft() const { return m_config.raft_layers > 0; } diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 46af1fee8..ea1598afe 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -484,32 +484,40 @@ static inline bool trafos_differ_in_rotation_by_z_and_mirroring_by_xy_only(const return std::abs(d * d) < EPSILON * lx2 * ly2; } -static BoundingBoxf3 transformed_its_bbox2d(const indexed_triangle_set &its, const Transform3f &m, float offset) +static PrintObjectRegions::BoundingBox transformed_its_bbox2d(const indexed_triangle_set &its, const Transform3f &m, float offset) { - BoundingBoxf3 bbox; + assert(! its.indices.empty()); + + PrintObjectRegions::BoundingBox bbox(m * its.vertices[its.indices.front()(0)]); for (const stl_triangle_vertex_indices &tri : its.indices) for (int i = 0; i < 3; ++ i) - bbox.merge((m * its.vertices[tri(i)]).cast<double>()); - bbox.min.x() -= offset; - bbox.min.y() -= offset; - bbox.min.x() += offset; - bbox.min.y() += offset; + bbox.extend(m * its.vertices[tri(i)]); + bbox.min() -= Vec3f(offset, offset, float(EPSILON)); + bbox.max() += Vec3f(offset, offset, float(EPSILON)); return bbox; } static void transformed_its_bboxes_in_z_ranges( - const indexed_triangle_set &its, - const Transform3f &m, - const std::vector<t_layer_height_range> &z_ranges, - std::vector<BoundingBoxf3> &bboxes, - const float offset) + const indexed_triangle_set &its, + const Transform3f &m, + const std::vector<t_layer_height_range> &z_ranges, + std::vector<std::pair<PrintObjectRegions::BoundingBox, bool>> &bboxes, + const float offset) { - bboxes.assign(z_ranges.size(), BoundingBoxf3()); + bboxes.assign(z_ranges.size(), std::make_pair(PrintObjectRegions::BoundingBox, false)); for (const stl_triangle_vertex_indices &tri : its.indices) { const Vec3f pts[3] = { m * its.vertices[tri(0)], m * its.vertices[tri(1)], m * its.vertices[tri(2)] }; for (size_t irange = 0; irange < z_ranges.size(); ++ irange) { - const t_layer_height_range &z_range = z_ranges[irange]; - BoundingBoxf3 &bbox = bboxes[irange]; + const t_layer_height_range &z_range = z_ranges[irange]; + std::pair<PrintObjectRegions::BoundingBox, bool> &bbox = bboxes[irange]; + auto bbox_extend = [&bbox](const Vec3f& p) { + if (bbox.second) { + bbox.first.extend(p); + } else { + bbox.first.min() = bbox.first.max() = p; + bbox.second = true; + } + }; int iprev = 2; for (int iedge = 0; iedge < 3; ++ iedge) { const Vec3f *p1 = &pts[iprev]; @@ -527,36 +535,34 @@ static void transformed_its_bboxes_in_z_ranges( float t2 = (z_range.second - p1->z()) / zspan; Vec2f p = to_2d(*p1); Vec2f v(p2->x() - p1->x(), p2->y() - p1->y()); - bbox.merge((to_3d((p + v * t1).eval(), float(z_range.first))).cast<double>()); - bbox.merge((to_3d((p + v * t2).eval(), float(z_range.second))).cast<double>()); + bbox_extend(to_3d((p + v * t1).eval(), float(z_range.first))); + bbox_extend(to_3d((p + v * t2).eval(), float(z_range.second))); } else { // Single intersection with the lower limit. float t = (z_range.first - p1->z()) / (p2->z() - p1->z()); Vec2f v(p2->x() - p1->x(), p2->y() - p1->y()); - bbox.merge((to_3d((to_2d(*p1) + v * t).eval(), float(z_range.first))).cast<double>()); - bbox.merge(p2->cast<double>()); + bbox_extend(to_3d((to_2d(*p1) + v * t).eval(), float(z_range.first))); + bbox_extend(*p2); } } else if (p2->z() > z_range.second) { // Single intersection with the upper limit. float t = (z_range.second - p1->z()) / (p2->z() - p1->z()); Vec2f v(p2->x() - p1->x(), p2->y() - p1->y()); - bbox.merge((to_3d((to_2d(*p1) + v * t).eval(), float(z_range.second)).cast<double>())); - bbox.merge(p1->cast<double>()); + bbox_extend(to_3d((to_2d(*p1) + v * t).eval(), float(z_range.second))); + bbox_extend(*p1); } else { // Both points are inside. - bbox.merge(p1->cast<double>()); - bbox.merge(p2->cast<double>()); + bbox_extend(*p1); + bbox_extend(*p2); } iprev = iedge; } } } - for (BoundingBoxf3 &bbox : bboxes) { - bbox.min.x() -= offset; - bbox.min.y() -= offset; - bbox.min.x() += offset; - bbox.min.y() += offset; + for (std::pair<PrintObjectRegions::BoundingBox, bool> &bbox : bboxes) { + bbox.first.min() -= Vec3f(offset, offset, float(EPSILON)); + bbox.first.max() += Vec3f(offset, offset, float(EPSILON)); } } @@ -590,7 +596,7 @@ void print_objects_regions_invalidate_keep_some_volumes(PrintObjectRegions &prin print_object_regions.cached_volume_ids.erase(print_object_regions.cached_volume_ids.begin() + last, print_object_regions.cached_volume_ids.end()); } -const BoundingBoxf3* find_volume_extents(const PrintObjectRegions::LayerRangeRegions &layer_range, const ModelVolume &volume) +const PrintObjectRegions::BoundingBox* find_volume_extents(const PrintObjectRegions::LayerRangeRegions &layer_range, const ModelVolume &volume) { auto it = lower_bound_by_predicate(layer_range.volumes.begin(), layer_range.volumes.end(), [&volume](const PrintObjectRegions::VolumeExtents &l){ return l.volume_id < volume.id(); }); return it != layer_range.volumes.end() && it->volume_id == volume.id() ? &it->bbox : nullptr; @@ -727,8 +733,8 @@ void update_volume_bboxes( volumes_old.emplace_back(std::move(layer_range.volumes)); } - std::vector<BoundingBoxf3> bboxes; - std::vector<t_layer_height_range> ranges; + std::vector<std::pair<PrintObjectRegions::BoundingBox, bool>> bboxes; + std::vector<t_layer_height_range> ranges; ranges.reserve(layer_ranges.size()); for (const PrintObjectRegions::LayerRangeRegions &layer_range : layer_ranges) { t_layer_height_range r = layer_range.layer_height_range; @@ -748,7 +754,8 @@ void update_volume_bboxes( } else { transformed_its_bboxes_in_z_ranges(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix(false)), ranges, bboxes, offset); for (PrintObjectRegions::LayerRangeRegions &layer_range : layer_ranges) - layer_range.volumes.push_back({ model_volume->id(), bboxes[&layer_range - layer_ranges.data()] }); + if (auto &bbox = bboxes[&layer_range - layer_ranges.data()]; bbox.second) + layer_range.volumes.push_back({ model_volume->id(), bbox.first }); } } } @@ -820,7 +827,7 @@ static PrintObjectRegions* generate_print_object_regions( const ModelVolume &volume = *model_volumes[volume_id]; if (model_volume_solid_or_modifier(volume)) { for (PrintObjectRegions::LayerRangeRegions &layer_range : layer_ranges_regions) - if (const BoundingBoxf3 *bbox = find_volume_extents(layer_range, volume); bbox) { + if (const PrintObjectRegions::BoundingBox *bbox = find_volume_extents(layer_range, volume); bbox) { if (volume.is_model_part()) { // Add a model volume, assign an existing region or generate a new one. layer_range.volume_regions.push_back({ @@ -837,9 +844,9 @@ static PrintObjectRegions* generate_print_object_regions( for (int parent_region_id = int(layer_range.volume_regions.size()) - 1; parent_region_id >= 0; -- parent_region_id) if (const PrintObjectRegions::VolumeRegion &parent_region = layer_range.volume_regions[parent_region_id]; parent_region.model_volume->is_model_part() || parent_region.model_volume->is_modifier()) { - const BoundingBoxf3 *parent_bbox = find_volume_extents(layer_range, *parent_region.model_volume); + const PrintObjectRegions::BoundingBox *parent_bbox = find_volume_extents(layer_range, *parent_region.model_volume); assert(parent_bbox != nullptr); - if (parent_bbox->overlap(*bbox)) + if (parent_bbox->intersects(*bbox)) layer_range.volume_regions.push_back({ &volume, parent_region_id, get_create_region(region_config_from_model_volume(parent_region.region->config(), nullptr, volume, num_extruders)), diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index f44d6fdbf..1499e1c70 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -220,11 +220,10 @@ static inline VolumeSlices& volume_slices_find_by_id(std::vector<VolumeSlices> & return *it; } -static inline bool overlap_in_xy(const BoundingBoxf3 &l, const BoundingBoxf3 &r) +static inline bool overlap_in_xy(const PrintObjectRegions::BoundingBox &l, const PrintObjectRegions::BoundingBox &r) { - assert(l.defined && r.defined); - return ! (l.max.x() < r.min.x() || l.min.x() > r.max.x() || - l.max.y() < r.min.y() || l.min.y() > r.max.y()); + return ! (l.max().x() < r.min().x() || l.min().x() > r.max().x() || + l.max().y() < r.min().y() || l.min().y() > r.max().y()); } static std::vector<PrintObjectRegions::LayerRangeRegions>::const_iterator layer_range_first(const std::vector<PrintObjectRegions::LayerRangeRegions> &layer_ranges, double z) @@ -288,14 +287,14 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions( bool complex = false; for (int idx_region = 0; idx_region < int(layer_range.volume_regions.size()); ++ idx_region) { const PrintObjectRegions::VolumeRegion ®ion = layer_range.volume_regions[idx_region]; - if (region.bbox->min.z() <= z && region.bbox->max.z() >= z) { + if (region.bbox->min().z() <= z && region.bbox->max().z() >= z) { if (idx_first_printable_region == -1 && region.model_volume->is_model_part()) idx_first_printable_region = idx_region; else if (idx_first_printable_region != -1) { // Test for overlap with some other region. for (int idx_region2 = idx_first_printable_region; idx_region2 < idx_region; ++ idx_region2) { const PrintObjectRegions::VolumeRegion ®ion2 = layer_range.volume_regions[idx_region2]; - if (region2.bbox->min.z() <= z && region2.bbox->max.z() >= z && overlap_in_xy(*region.bbox, *region2.bbox)) { + if (region2.bbox->min().z() <= z && region2.bbox->max().z() >= z && overlap_in_xy(*region.bbox, *region2.bbox)) { complex = true; break; } @@ -552,6 +551,123 @@ void PrintObject::slice() this->set_done(posSlice); } +template<typename ThrowOnCancel> +static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCancel throw_on_cancel) +{ + // 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); + assert(segmentation.size() == print_object.layer_count()); + tbb::parallel_for( + tbb::blocked_range<size_t>(0, segmentation.size(), std::max(segmentation.size() / 128, size_t(1))), + [&print_object, &segmentation, throw_on_cancel](const tbb::blocked_range<size_t> &range) { + const auto &layer_ranges = print_object.shared_regions()->layer_ranges; + double z = print_object.get_layer(range.begin())->slice_z; + auto it_layer_range = layer_range_first(layer_ranges, z); + const size_t num_extruders = print_object.print()->config().nozzle_diameter.size(); + struct ByExtruder { + ExPolygons expolygons; + BoundingBox bbox; + }; + std::vector<ByExtruder> by_extruder; + struct ByRegion { + ExPolygons expolygons; + bool needs_merge { false }; + }; + std::vector<ByRegion> by_region; + for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { + throw_on_cancel(); + Layer *layer = print_object.get_layer(layer_id); + it_layer_range = layer_range_next(layer_ranges, it_layer_range, layer->slice_z); + const PrintObjectRegions::LayerRangeRegions &layer_range = *it_layer_range; + // Gather per extruder expolygons. + by_extruder.assign(num_extruders, ByExtruder()); + by_region.assign(layer->region_count(), ByRegion()); + bool layer_split = false; + for (size_t extruder_id = 0; extruder_id < num_extruders; ++ extruder_id) { + ByExtruder ®ion = by_extruder[extruder_id]; + for (const std::pair<ExPolygon, size_t> &colored_polygon : segmentation[layer_id]) + if (colored_polygon.second == extruder_id) + region.expolygons.emplace_back(std::move(colored_polygon.first)); + if (! region.expolygons.empty()) { + region.bbox = get_extents(region.expolygons); + layer_split = true; + } + } + if (! layer_split) + continue; + // Split LayerRegions by by_extruder regions. + auto it_painted_region = layer_range.painted_regions.begin(); + for (size_t region_id = 0; region_id < layer->region_count(); ++ region_id) + if (LayerRegion &layerm = *layer->get_region(region_id); ! layerm.slices.surfaces.empty()) { + const BoundingBox bbox = get_extents(layerm.slices.surfaces); + assert(it_painted_region < layer_range.painted_regions.end()); + for (; layer_range.volume_regions[it_painted_region->parent].region->print_object_region_id() < region_id; ++ it_painted_region) + assert(it_painted_region < layer_range.painted_regions.end()); + assert(&layerm.region() == it_painted_region->region && layerm.region().print_object_region_id() == region_id); + // 1-based extruder ID + bool self_trimmed = false; + size_t self_extruder_id; + for (size_t extruder_id = 1; extruder_id <= by_extruder.size(); ++ extruder_id) + if (ByExtruder &segmented = by_extruder[extruder_id - 1]; segmented.bbox.defined && bbox.overlap(segmented.bbox)) { + // Find the target region. + for (; it_painted_region->extruder_id < extruder_id; ++ it_painted_region) + assert(it_painted_region < layer_range.painted_regions.end()); + assert(layer_range.volume_regions[it_painted_region->parent].region == &layerm.region() && it_painted_region->extruder_id == extruder_id); + //FIXME Don't trim by self, it is not reliable. + if (&layerm.region() == it_painted_region->region) { + self_extruder_id = extruder_id; + continue; + } + // Steal from this region. + int target_region_id = it_painted_region->region->print_object_region_id(); + ExPolygons stolen = intersection_ex(layerm.slices.surfaces, segmented.expolygons); + if (! stolen.empty()) { + ByRegion &dst = by_region[target_region_id]; + if (dst.expolygons.empty()) { + dst.expolygons = std::move(stolen); + } else { + append(dst.expolygons, std::move(stolen)); + dst.needs_merge = true; + } + } +#if 0 + if (&layerm.region() == it_painted_region->region) + // Slices of this LayerRegion were trimmed by a MMU region of the same PrintRegion. + self_trimmed = true; +#endif + } + if (! self_trimmed) { + // Trim slices of this LayerRegion with all the MMU regions. + Polygons mine = to_polygons(std::move(layerm.slices.surfaces)); + for (auto &segmented : by_extruder) + if (&segmented - by_extruder.data() + 1 != self_extruder_id && segmented.bbox.defined && bbox.overlap(segmented.bbox)) { + mine = diff(mine, segmented.expolygons); + if (mine.empty()) + break; + } + if (! mine.empty()) { + ByRegion &dst = by_region[layerm.region().print_object_region_id()]; + if (dst.expolygons.empty()) { + dst.expolygons = union_ex(mine); + } else { + append(dst.expolygons, union_ex(mine)); + dst.needs_merge = true; + } + } + } + } + // Re-create Surfaces of LayerRegions. + for (size_t region_id = 0; region_id < layer->region_count(); ++ region_id) { + ByRegion &src = by_region[region_id]; + if (src.needs_merge) + // Multiple regions were merged into one. + src.expolygons = offset2_ex(src.expolygons, float(scale_(EPSILON)), - float(scale_(EPSILON))); + layer->get_region(region_id)->slices.set(std::move(src.expolygons), stInternal); + } + } + }); +} + // 1) Decides Z positions of the layers, // 2) Initializes layers and their regions // 3) Slices the object meshes @@ -605,123 +721,13 @@ void PrintObject::slice_volumes() m_print->throw_if_canceled(); // Is any ModelVolume MMU painted? - if (const auto &volumes = this->model_object()->volumes; - std::find_if(volumes.begin(), volumes.end(), [](const ModelVolume *v) { return ! v->mmu_segmentation_facets.empty(); }) != volumes.end()) { + if (const auto& volumes = this->model_object()->volumes; + std::find_if(volumes.begin(), volumes.end(), [](const ModelVolume* v) { return !v->mmu_segmentation_facets.empty(); }) != volumes.end()) { BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - MMU segmentation"; - // 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(*this); - assert(segmentation.size() == m_layers.size()); - tbb::parallel_for( - tbb::blocked_range<size_t>(0, segmentation.size(), std::max(segmentation.size() / 128, size_t(1))), - [this, &segmentation](const tbb::blocked_range<size_t> &range) { - const auto &layer_ranges = this->m_shared_regions->layer_ranges; - double z = m_layers[range.begin()]->slice_z; - auto it_layer_range = layer_range_first(layer_ranges, z); - const size_t num_extruders = this->print()->config().nozzle_diameter.size(); - struct ByExtruder { - ExPolygons expolygons; - BoundingBox bbox; - }; - std::vector<ByExtruder> by_extruder; - struct ByRegion { - ExPolygons expolygons; - bool needs_merge { false }; - }; - std::vector<ByRegion> by_region; - for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { - m_print->throw_if_canceled(); - Layer *layer = m_layers[layer_id]; - it_layer_range = layer_range_next(layer_ranges, it_layer_range, layer->slice_z); - const PrintObjectRegions::LayerRangeRegions &layer_range = *it_layer_range; - // Gather per extruder expolygons. - by_extruder.assign(num_extruders, ByExtruder()); - by_region.assign(layer->m_regions.size(), ByRegion()); - bool layer_split = false; - for (size_t extruder_id = 0; extruder_id < num_extruders; ++ extruder_id) { - ByExtruder ®ion = by_extruder[extruder_id]; - for (const std::pair<ExPolygon, size_t> &colored_polygon : segmentation[layer_id]) - if (colored_polygon.second == extruder_id) - region.expolygons.emplace_back(std::move(colored_polygon.first)); - if (! region.expolygons.empty()) { - region.bbox = get_extents(region.expolygons); - layer_split = true; - } - } - if (! layer_split) - continue; - // Split LayerRegions by by_extruder regions. - auto it_painted_region = layer_range.painted_regions.begin(); - for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) - if (LayerRegion &layerm = *layer->m_regions[region_id]; ! layerm.slices.surfaces.empty()) { - const BoundingBox bbox = get_extents(layerm.slices.surfaces); - assert(it_painted_region < layer_range.painted_regions.end()); - for (; layer_range.volume_regions[it_painted_region->parent].region->print_object_region_id() < region_id; ++ it_painted_region) - assert(it_painted_region < layer_range.painted_regions.end()); - assert(&layerm.region() == it_painted_region->region && layerm.region().print_object_region_id() == region_id); - // 1-based extruder ID - bool self_trimmed = false; - size_t self_extruder_id; - for (size_t extruder_id = 1; extruder_id <= by_extruder.size(); ++ extruder_id) - if (ByExtruder &segmented = by_extruder[extruder_id - 1]; segmented.bbox.defined && bbox.overlap(segmented.bbox)) { - // Find the target region. - for (; it_painted_region->extruder_id < extruder_id; ++ it_painted_region) - assert(it_painted_region < layer_range.painted_regions.end()); - assert(layer_range.volume_regions[it_painted_region->parent].region == &layerm.region() && it_painted_region->extruder_id == extruder_id); - //FIXME Don't trim by self, it is not reliable. - if (&layerm.region() == it_painted_region->region) { - self_extruder_id = extruder_id; - continue; - } - // Steal from this region. - int target_region_id = it_painted_region->region->print_object_region_id(); - ExPolygons stolen = intersection_ex(layerm.slices.surfaces, segmented.expolygons); - if (! stolen.empty()) { - ByRegion &dst = by_region[target_region_id]; - if (dst.expolygons.empty()) { - dst.expolygons = std::move(stolen); - } else { - append(dst.expolygons, std::move(stolen)); - dst.needs_merge = true; - } - } -#if 0 - if (&layerm.region() == it_painted_region->region) - // Slices of this LayerRegion were trimmed by a MMU region of the same PrintRegion. - self_trimmed = true; -#endif - } - if (! self_trimmed) { - // Trim slices of this LayerRegion with all the MMU regions. - Polygons mine = to_polygons(std::move(layerm.slices.surfaces)); - for (auto &segmented : by_extruder) - if (&segmented - by_extruder.data() + 1 != self_extruder_id && segmented.bbox.defined && bbox.overlap(segmented.bbox)) { - mine = diff(mine, segmented.expolygons); - if (mine.empty()) - break; - } - if (! mine.empty()) { - ByRegion &dst = by_region[layerm.region().print_object_region_id()]; - if (dst.expolygons.empty()) { - dst.expolygons = union_ex(mine); - } else { - append(dst.expolygons, union_ex(mine)); - dst.needs_merge = true; - } - } - } - } - // Re-create Surfaces of LayerRegions. - for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) { - ByRegion &src = by_region[region_id]; - if (src.needs_merge) - // Multiple regions were merged into one. - src.expolygons = offset2_ex(src.expolygons, float(scale_(EPSILON)), - float(scale_(EPSILON))); - layer->m_regions[region_id]->slices.set(std::move(src.expolygons), stInternal); - } - } - }); + apply_mm_segmentation(*this, [print]() { print->throw_if_canceled(); }); } + BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - make_slices in parallel - begin"; { // Compensation value, scaled. Only applying the negative scaling here, as the positive scaling has already been applied during slicing. |