Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojtech Bubnik <bubnikv@gmail.com>2021-05-27 17:10:58 +0300
committerVojtech Bubnik <bubnikv@gmail.com>2021-05-27 17:12:34 +0300
commit818cb703ede34495cb8405f224d39dfe6d3462ca (patch)
tree41465b7352946ca37755232830523f4065a73d41
parentf1754e538e7a97675346336403bfe381ac0f71e4 (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.hpp12
-rw-r--r--src/libslic3r/PrintApply.cpp77
-rw-r--r--src/libslic3r/PrintObjectSlice.cpp246
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 &region = 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 &region2 = 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 &region = 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 &region = 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.