mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-17 04:35:59 +08:00
SPE-2486: Implement segmentation of layers based on fuzzy skin painting.
This commit is contained in:
parent
2c06c81159
commit
800b742b95
@ -152,9 +152,10 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Modifying m_slices
|
// Modifying m_slices
|
||||||
friend std::string fix_slicing_errors(LayerPtrs&, const std::function<void()>&);
|
|
||||||
template<typename ThrowOnCancel>
|
template<typename ThrowOnCancel>
|
||||||
friend void apply_mm_segmentation(PrintObject& print_object, ThrowOnCancel throw_on_cancel);
|
friend void apply_mm_segmentation(PrintObject &print_object, ThrowOnCancel throw_on_cancel);
|
||||||
|
template<typename ThrowOnCancel>
|
||||||
|
friend void apply_fuzzy_skin_segmentation(PrintObject &print_object, ThrowOnCancel throw_on_cancel);
|
||||||
|
|
||||||
Layer *m_layer;
|
Layer *m_layer;
|
||||||
const PrintRegion *m_region;
|
const PrintRegion *m_region;
|
||||||
|
@ -1762,5 +1762,21 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co
|
|||||||
return final_path;
|
return final_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrintRegion *PrintObjectRegions::FuzzySkinPaintedRegion::parent_print_object_region(const LayerRangeRegions &layer_range) const
|
||||||
|
{
|
||||||
|
using FuzzySkinParentType = PrintObjectRegions::FuzzySkinPaintedRegion::ParentType;
|
||||||
|
|
||||||
|
if (this->parent_type == FuzzySkinParentType::PaintedRegion) {
|
||||||
|
return layer_range.painted_regions[this->parent].region;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(this->parent_type == FuzzySkinParentType::VolumeRegion);
|
||||||
|
return layer_range.volume_regions[this->parent].region;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PrintObjectRegions::FuzzySkinPaintedRegion::parent_print_object_region_id(const LayerRangeRegions &layer_range) const
|
||||||
|
{
|
||||||
|
return this->parent_print_object_region(layer_range)->print_object_region_id();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -150,8 +150,6 @@ using SpanOfConstPtrs = tcb::span<const T* const>;
|
|||||||
using LayerPtrs = std::vector<Layer*>;
|
using LayerPtrs = std::vector<Layer*>;
|
||||||
using SupportLayerPtrs = std::vector<SupportLayer*>;
|
using SupportLayerPtrs = std::vector<SupportLayer*>;
|
||||||
|
|
||||||
class BoundingBoxf3; // TODO: for temporary constructor parameter
|
|
||||||
|
|
||||||
// Single instance of a PrintObject.
|
// Single instance of a PrintObject.
|
||||||
// As multiple PrintObjects may be generated for a single ModelObject (their instances differ in rotation around Z),
|
// As multiple PrintObjects may be generated for a single ModelObject (their instances differ in rotation around Z),
|
||||||
// ModelObject's instancess will be distributed among these multiple PrintObjects.
|
// ModelObject's instancess will be distributed among these multiple PrintObjects.
|
||||||
@ -204,6 +202,22 @@ public:
|
|||||||
PrintRegion *region { nullptr };
|
PrintRegion *region { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LayerRangeRegions;
|
||||||
|
|
||||||
|
struct FuzzySkinPaintedRegion
|
||||||
|
{
|
||||||
|
enum class ParentType { VolumeRegion, PaintedRegion };
|
||||||
|
|
||||||
|
ParentType parent_type { ParentType::VolumeRegion };
|
||||||
|
// Index of a parent VolumeRegion or PaintedRegion.
|
||||||
|
int parent { -1 };
|
||||||
|
// Pointer to PrintObjectRegions::all_regions.
|
||||||
|
PrintRegion *region { nullptr };
|
||||||
|
|
||||||
|
PrintRegion *parent_print_object_region(const LayerRangeRegions &layer_range) const;
|
||||||
|
int parent_print_object_region_id(const LayerRangeRegions &layer_range) const;
|
||||||
|
};
|
||||||
|
|
||||||
// One slice over the PrintObject (possibly the whole PrintObject) and a list of ModelVolumes and their bounding boxes
|
// One slice over the PrintObject (possibly the whole PrintObject) and a list of ModelVolumes and their bounding boxes
|
||||||
// possibly clipped by the layer_height_range.
|
// possibly clipped by the layer_height_range.
|
||||||
struct LayerRangeRegions
|
struct LayerRangeRegions
|
||||||
@ -216,8 +230,9 @@ public:
|
|||||||
std::vector<VolumeExtents> volumes;
|
std::vector<VolumeExtents> volumes;
|
||||||
|
|
||||||
// Sorted in the order of their source ModelVolumes, thus reflecting the order of region clipping, modifier overrides etc.
|
// Sorted in the order of their source ModelVolumes, thus reflecting the order of region clipping, modifier overrides etc.
|
||||||
std::vector<VolumeRegion> volume_regions;
|
std::vector<VolumeRegion> volume_regions;
|
||||||
std::vector<PaintedRegion> painted_regions;
|
std::vector<PaintedRegion> painted_regions;
|
||||||
|
std::vector<FuzzySkinPaintedRegion> fuzzy_skin_painted_regions;
|
||||||
|
|
||||||
bool has_volume(const ObjectID id) const {
|
bool has_volume(const ObjectID id) const {
|
||||||
auto it = lower_bound_by_predicate(this->volumes.begin(), this->volumes.end(), [id](const VolumeExtents &l) { return l.volume_id < id; });
|
auto it = lower_bound_by_predicate(this->volumes.begin(), this->volumes.end(), [id](const VolumeExtents &l) { return l.volume_id < id; });
|
||||||
@ -340,6 +355,8 @@ public:
|
|||||||
bool has_support_material() const { return this->has_support() || this->has_raft(); }
|
bool has_support_material() const { return this->has_support() || this->has_raft(); }
|
||||||
// Checks if the model object is painted using the multi-material painting gizmo.
|
// Checks if the model object is painted using the multi-material painting gizmo.
|
||||||
bool is_mm_painted() const { return this->model_object()->is_mm_painted(); }
|
bool is_mm_painted() const { return this->model_object()->is_mm_painted(); }
|
||||||
|
// Checks if the model object is painted using the fuzzy skin painting gizmo.
|
||||||
|
bool is_fuzzy_skin_painted() const { return this->model_object()->is_fuzzy_skin_painted(); }
|
||||||
|
|
||||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||||
std::vector<unsigned int> object_extruders() const;
|
std::vector<unsigned int> object_extruders() const;
|
||||||
|
@ -683,7 +683,6 @@ bool verify_update_print_object_regions(
|
|||||||
ModelVolumePtrs model_volumes,
|
ModelVolumePtrs model_volumes,
|
||||||
const PrintRegionConfig &default_region_config,
|
const PrintRegionConfig &default_region_config,
|
||||||
size_t num_extruders,
|
size_t num_extruders,
|
||||||
const std::vector<unsigned int> &painting_extruders,
|
|
||||||
PrintObjectRegions &print_object_regions,
|
PrintObjectRegions &print_object_regions,
|
||||||
const std::function<void(const PrintRegionConfig&, const PrintRegionConfig&, const t_config_option_keys&)> &callback_invalidate)
|
const std::function<void(const PrintRegionConfig&, const PrintRegionConfig&, const t_config_option_keys&)> &callback_invalidate)
|
||||||
{
|
{
|
||||||
@ -757,7 +756,7 @@ bool verify_update_print_object_regions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify and / or update PrintRegions produced by color painting.
|
// Verify and / or update PrintRegions produced by color painting.
|
||||||
for (const PrintObjectRegions::LayerRangeRegions &layer_range : print_object_regions.layer_ranges)
|
for (const PrintObjectRegions::LayerRangeRegions &layer_range : print_object_regions.layer_ranges)
|
||||||
for (const PrintObjectRegions::PaintedRegion ®ion : layer_range.painted_regions) {
|
for (const PrintObjectRegions::PaintedRegion ®ion : layer_range.painted_regions) {
|
||||||
const PrintObjectRegions::VolumeRegion &parent_region = layer_range.volume_regions[region.parent];
|
const PrintObjectRegions::VolumeRegion &parent_region = layer_range.volume_regions[region.parent];
|
||||||
@ -781,6 +780,29 @@ bool verify_update_print_object_regions(
|
|||||||
print_region_ref_inc(*region.region);
|
print_region_ref_inc(*region.region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify and / or update PrintRegions produced by fuzzy skin painting.
|
||||||
|
for (const PrintObjectRegions::LayerRangeRegions &layer_range : print_object_regions.layer_ranges) {
|
||||||
|
for (const PrintObjectRegions::FuzzySkinPaintedRegion ®ion : layer_range.fuzzy_skin_painted_regions) {
|
||||||
|
const PrintRegion &parent_print_region = *region.parent_print_object_region(layer_range);
|
||||||
|
PrintRegionConfig cfg = parent_print_region.config();
|
||||||
|
cfg.fuzzy_skin.value = FuzzySkinType::All;
|
||||||
|
if (cfg != region.region->config()) {
|
||||||
|
// Region configuration changed.
|
||||||
|
if (print_region_ref_cnt(*region.region) == 0) {
|
||||||
|
// Region is referenced for the first time. Just change its parameters.
|
||||||
|
// Stop the background process before assigning new configuration to the regions.
|
||||||
|
t_config_option_keys diff = region.region->config().diff(cfg);
|
||||||
|
callback_invalidate(region.region->config(), cfg, diff);
|
||||||
|
region.region->config_apply_only(cfg, diff, false);
|
||||||
|
} else {
|
||||||
|
// Region is referenced multiple times, thus the region is being split. We need to reslice.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_region_ref_inc(*region.region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Lastly verify, whether some regions were not merged.
|
// Lastly verify, whether some regions were not merged.
|
||||||
{
|
{
|
||||||
std::vector<const PrintRegion*> regions;
|
std::vector<const PrintRegion*> regions;
|
||||||
@ -884,7 +906,8 @@ static PrintObjectRegions* generate_print_object_regions(
|
|||||||
const Transform3d &trafo,
|
const Transform3d &trafo,
|
||||||
size_t num_extruders,
|
size_t num_extruders,
|
||||||
const float xy_size_compensation,
|
const float xy_size_compensation,
|
||||||
const std::vector<unsigned int> &painting_extruders)
|
const std::vector<unsigned int> &painting_extruders,
|
||||||
|
const bool has_painted_fuzzy_skin)
|
||||||
{
|
{
|
||||||
// Reuse the old object or generate a new one.
|
// Reuse the old object or generate a new one.
|
||||||
auto out = print_object_regions_old ? std::unique_ptr<PrintObjectRegions>(print_object_regions_old) : std::make_unique<PrintObjectRegions>();
|
auto out = print_object_regions_old ? std::unique_ptr<PrintObjectRegions>(print_object_regions_old) : std::make_unique<PrintObjectRegions>();
|
||||||
@ -906,6 +929,7 @@ static PrintObjectRegions* generate_print_object_regions(
|
|||||||
r.config = range.config;
|
r.config = range.config;
|
||||||
r.volume_regions.clear();
|
r.volume_regions.clear();
|
||||||
r.painted_regions.clear();
|
r.painted_regions.clear();
|
||||||
|
r.fuzzy_skin_painted_regions.clear();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out->trafo_bboxes = trafo;
|
out->trafo_bboxes = trafo;
|
||||||
@ -987,13 +1011,42 @@ static PrintObjectRegions* generate_print_object_regions(
|
|||||||
cfg.infill_extruder.value = painted_extruder_id;
|
cfg.infill_extruder.value = painted_extruder_id;
|
||||||
layer_range.painted_regions.push_back({ painted_extruder_id, parent_region_id, get_create_region(std::move(cfg))});
|
layer_range.painted_regions.push_back({ painted_extruder_id, parent_region_id, get_create_region(std::move(cfg))});
|
||||||
}
|
}
|
||||||
// Sort the regions by parent region::print_object_region_id() and extruder_id to help the slicing algorithm when applying MMU segmentation.
|
// Sort the regions by parent region::print_object_region_id() and extruder_id to help the slicing algorithm when applying MM segmentation.
|
||||||
std::sort(layer_range.painted_regions.begin(), layer_range.painted_regions.end(), [&layer_range](auto &l, auto &r) {
|
std::sort(layer_range.painted_regions.begin(), layer_range.painted_regions.end(), [&layer_range](auto &l, auto &r) {
|
||||||
int lid = layer_range.volume_regions[l.parent].region->print_object_region_id();
|
int lid = layer_range.volume_regions[l.parent].region->print_object_region_id();
|
||||||
int rid = layer_range.volume_regions[r.parent].region->print_object_region_id();
|
int rid = layer_range.volume_regions[r.parent].region->print_object_region_id();
|
||||||
return lid < rid || (lid == rid && l.extruder_id < r.extruder_id); });
|
return lid < rid || (lid == rid && l.extruder_id < r.extruder_id); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_painted_fuzzy_skin) {
|
||||||
|
using FuzzySkinParentType = PrintObjectRegions::FuzzySkinPaintedRegion::ParentType;
|
||||||
|
|
||||||
|
for (PrintObjectRegions::LayerRangeRegions &layer_range : layer_ranges_regions) {
|
||||||
|
// FuzzySkinPaintedRegion can override different parts of the Layer than PaintedRegions,
|
||||||
|
// so FuzzySkinPaintedRegion has to point to both VolumeRegion and PaintedRegion.
|
||||||
|
for (int parent_volume_region_id = 0; parent_volume_region_id < int(layer_range.volume_regions.size()); ++parent_volume_region_id) {
|
||||||
|
if (const PrintObjectRegions::VolumeRegion &parent_volume_region = layer_range.volume_regions[parent_volume_region_id]; parent_volume_region.model_volume->is_model_part() || parent_volume_region.model_volume->is_modifier()) {
|
||||||
|
PrintRegionConfig cfg = parent_volume_region.region->config();
|
||||||
|
cfg.fuzzy_skin.value = FuzzySkinType::All;
|
||||||
|
layer_range.fuzzy_skin_painted_regions.push_back({FuzzySkinParentType::VolumeRegion, parent_volume_region_id, get_create_region(std::move(cfg))});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int parent_painted_regions_id = 0; parent_painted_regions_id < int(layer_range.painted_regions.size()); ++parent_painted_regions_id) {
|
||||||
|
const PrintObjectRegions::PaintedRegion &parent_painted_region = layer_range.painted_regions[parent_painted_regions_id];
|
||||||
|
|
||||||
|
PrintRegionConfig cfg = parent_painted_region.region->config();
|
||||||
|
cfg.fuzzy_skin.value = FuzzySkinType::All;
|
||||||
|
layer_range.fuzzy_skin_painted_regions.push_back({FuzzySkinParentType::PaintedRegion, parent_painted_regions_id, get_create_region(std::move(cfg))});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the regions by parent region::print_object_region_id() to help the slicing algorithm when applying fuzzy skin segmentation.
|
||||||
|
std::sort(layer_range.fuzzy_skin_painted_regions.begin(), layer_range.fuzzy_skin_painted_regions.end(), [&layer_range](auto &l, auto &r) {
|
||||||
|
return l.parent_print_object_region_id(layer_range) < r.parent_print_object_region_id(layer_range);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return out.release();
|
return out.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1450,7 +1503,6 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
print_object.model_object()->volumes,
|
print_object.model_object()->volumes,
|
||||||
m_default_region_config,
|
m_default_region_config,
|
||||||
num_extruders,
|
num_extruders,
|
||||||
painting_extruders,
|
|
||||||
*print_object_regions,
|
*print_object_regions,
|
||||||
[it_print_object, it_print_object_end, &update_apply_status](const PrintRegionConfig &old_config, const PrintRegionConfig &new_config, const t_config_option_keys &diff_keys) {
|
[it_print_object, it_print_object_end, &update_apply_status](const PrintRegionConfig &old_config, const PrintRegionConfig &new_config, const t_config_option_keys &diff_keys) {
|
||||||
for (auto it = it_print_object; it != it_print_object_end; ++it)
|
for (auto it = it_print_object; it != it_print_object_end; ++it)
|
||||||
@ -1477,7 +1529,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
model_object_status.print_instances.front().trafo,
|
model_object_status.print_instances.front().trafo,
|
||||||
num_extruders,
|
num_extruders,
|
||||||
print_object.is_mm_painted() ? 0.f : float(print_object.config().xy_size_compensation.value),
|
print_object.is_mm_painted() ? 0.f : float(print_object.config().xy_size_compensation.value),
|
||||||
painting_extruders);
|
painting_extruders,
|
||||||
|
print_object.is_fuzzy_skin_painted());
|
||||||
}
|
}
|
||||||
for (auto it = it_print_object; it != it_print_object_end; ++it)
|
for (auto it = it_print_object; it != it_print_object_end; ++it)
|
||||||
if ((*it)->m_shared_regions) {
|
if ((*it)->m_shared_regions) {
|
||||||
@ -1540,7 +1593,7 @@ void Print::cleanup()
|
|||||||
auto this_objects = SpanOfConstPtrs<PrintObject>(const_cast<const PrintObject* const* const>(&(*it_begin)), it - it_begin);
|
auto this_objects = SpanOfConstPtrs<PrintObject>(const_cast<const PrintObject* const* const>(&(*it_begin)), it - it_begin);
|
||||||
if (! Print::is_shared_print_object_step_valid_unguarded(this_objects, posSupportSpotsSearch))
|
if (! Print::is_shared_print_object_step_valid_unguarded(this_objects, posSupportSpotsSearch))
|
||||||
shared_regions->generated_support_points.reset();
|
shared_regions->generated_support_points.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Print::is_shared_print_object_step_valid_unguarded(SpanOfConstPtrs<PrintObject> print_objects, PrintObjectStep print_object_step)
|
bool Print::is_shared_print_object_step_valid_unguarded(SpanOfConstPtrs<PrintObject> print_objects, PrintObjectStep print_object_step)
|
||||||
|
@ -731,6 +731,114 @@ void apply_mm_segmentation(PrintObject &print_object, ThrowOnCancel throw_on_can
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ThrowOnCancel>
|
||||||
|
void apply_fuzzy_skin_segmentation(PrintObject &print_object, ThrowOnCancel throw_on_cancel)
|
||||||
|
{
|
||||||
|
// Returns fuzzy skin segmentation based on painting in the fuzzy skin painting gizmo.
|
||||||
|
std::vector<std::vector<ExPolygons>> segmentation = fuzzy_skin_segmentation_by_painting(print_object, throw_on_cancel);
|
||||||
|
assert(segmentation.size() == print_object.layer_count());
|
||||||
|
|
||||||
|
struct ByRegion
|
||||||
|
{
|
||||||
|
ExPolygons expolygons;
|
||||||
|
bool needs_merge { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
auto it_layer_range = layer_range_first(layer_ranges, print_object.get_layer(int(range.begin()))->slice_z);
|
||||||
|
|
||||||
|
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||||
|
throw_on_cancel();
|
||||||
|
|
||||||
|
Layer &layer = *print_object.get_layer(int(layer_idx));
|
||||||
|
it_layer_range = layer_range_next(layer_ranges, it_layer_range, layer.slice_z);
|
||||||
|
const PrintObjectRegions::LayerRangeRegions &layer_range = *it_layer_range;
|
||||||
|
|
||||||
|
assert(segmentation[layer_idx].size() == 1);
|
||||||
|
const ExPolygons &fuzzy_skin_segmentation = segmentation[layer_idx][0];
|
||||||
|
const BoundingBox fuzzy_skin_segmentation_bbox = get_extents(fuzzy_skin_segmentation);
|
||||||
|
if (fuzzy_skin_segmentation.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Split LayerRegions by painted fuzzy skin regions.
|
||||||
|
// layer_range.fuzzy_skin_painted_regions are sorted by parent PrintObject region ID.
|
||||||
|
std::vector<ByRegion> by_region(layer.region_count());
|
||||||
|
auto it_fuzzy_skin_region_begin = layer_range.fuzzy_skin_painted_regions.cbegin();
|
||||||
|
for (int parent_layer_region_idx = 0; parent_layer_region_idx < layer.region_count(); ++parent_layer_region_idx) {
|
||||||
|
if (it_fuzzy_skin_region_begin == layer_range.fuzzy_skin_painted_regions.cend())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const LayerRegion &parent_layer_region = *layer.get_region(parent_layer_region_idx);
|
||||||
|
const PrintRegion &parent_print_region = parent_layer_region.region();
|
||||||
|
assert(parent_print_region.print_object_region_id() == parent_layer_region_idx);
|
||||||
|
if (parent_layer_region.slices().empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Find the first FuzzySkinPaintedRegion, which overrides the parent PrintRegion.
|
||||||
|
auto it_fuzzy_skin_region = std::find_if(it_fuzzy_skin_region_begin, layer_range.fuzzy_skin_painted_regions.cend(), [&layer_range, &parent_print_region](const auto &fuzzy_skin_region) {
|
||||||
|
return fuzzy_skin_region.parent_print_object_region_id(layer_range) == parent_print_region.print_object_region_id();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it_fuzzy_skin_region == layer_range.fuzzy_skin_painted_regions.cend())
|
||||||
|
continue; // This LayerRegion isn't overrides by any FuzzySkinPaintedRegion.
|
||||||
|
|
||||||
|
assert(it_fuzzy_skin_region->parent_print_object_region(layer_range) == &parent_print_region);
|
||||||
|
|
||||||
|
// Update the beginning FuzzySkinPaintedRegion iterator for the next iteration.
|
||||||
|
it_fuzzy_skin_region_begin = std::next(it_fuzzy_skin_region);
|
||||||
|
|
||||||
|
const BoundingBox parent_layer_region_bbox = get_extents(parent_layer_region.slices().surfaces);
|
||||||
|
Polygons layer_region_remaining_polygons = to_polygons(parent_layer_region.slices().surfaces);
|
||||||
|
// Don't trim by self, it is not reliable.
|
||||||
|
if (parent_layer_region_bbox.overlap(fuzzy_skin_segmentation_bbox) && it_fuzzy_skin_region->region != &parent_print_region) {
|
||||||
|
// Steal from this region.
|
||||||
|
const int target_region_id = it_fuzzy_skin_region->region->print_object_region_id();
|
||||||
|
ExPolygons stolen = intersection_ex(parent_layer_region.slices().surfaces, fuzzy_skin_segmentation);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim slices of this LayerRegion by the fuzzy skin region.
|
||||||
|
layer_region_remaining_polygons = diff(layer_region_remaining_polygons, fuzzy_skin_segmentation);
|
||||||
|
|
||||||
|
// Filter out unprintable polygons. Detailed explanation is inside apply_mm_segmentation.
|
||||||
|
if (!layer_region_remaining_polygons.empty()) {
|
||||||
|
layer_region_remaining_polygons = opening(union_ex(layer_region_remaining_polygons), scaled<float>(5. * EPSILON), scaled<float>(5. * EPSILON));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layer_region_remaining_polygons.empty()) {
|
||||||
|
ByRegion &dst = by_region[parent_print_region.print_object_region_id()];
|
||||||
|
if (dst.expolygons.empty()) {
|
||||||
|
dst.expolygons = union_ex(layer_region_remaining_polygons);
|
||||||
|
} else {
|
||||||
|
append(dst.expolygons, union_ex(layer_region_remaining_polygons));
|
||||||
|
dst.needs_merge = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-create Surfaces of LayerRegions.
|
||||||
|
for (int 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 = closing_ex(src.expolygons, scaled<float>(10. * EPSILON));
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.get_region(region_id)->m_slices.set(std::move(src.expolygons), stInternal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}); // end of parallel_for
|
||||||
|
}
|
||||||
|
|
||||||
// 1) Decides Z positions of the layers,
|
// 1) Decides Z positions of the layers,
|
||||||
// 2) Initializes layers and their regions
|
// 2) Initializes layers and their regions
|
||||||
// 3) Slices the object meshes
|
// 3) Slices the object meshes
|
||||||
@ -796,6 +904,21 @@ void PrintObject::slice_volumes()
|
|||||||
apply_mm_segmentation(*this, [print]() { print->throw_if_canceled(); });
|
apply_mm_segmentation(*this, [print]() { print->throw_if_canceled(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is any ModelVolume fuzzy skin painted?
|
||||||
|
if (this->model_object()->is_fuzzy_skin_painted()) {
|
||||||
|
// If XY Size compensation is also enabled, notify the user that XY Size compensation
|
||||||
|
// would not be used because the object has custom fuzzy skin painted.
|
||||||
|
if (m_config.xy_size_compensation.value != 0.f) {
|
||||||
|
this->active_step_add_warning(
|
||||||
|
PrintStateBase::WarningLevel::CRITICAL,
|
||||||
|
_u8L("An object has enabled XY Size compensation which will not be used because it is also fuzzy skin painted.\nXY Size "
|
||||||
|
"compensation cannot be combined with fuzzy skin painting.") +
|
||||||
|
"\n" + (_u8L("Object name")) + ": " + this->model_object()->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - Fuzzy skin segmentation";
|
||||||
|
apply_fuzzy_skin_segmentation(*this, [print]() { print->throw_if_canceled(); });
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - make_slices in parallel - begin";
|
BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - make_slices in parallel - begin";
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user