mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-01 03:01:59 +08:00
Ported PrintObject::slice() to C++
This commit is contained in:
parent
2bbb089a4f
commit
f7509f2a3f
@ -34,95 +34,6 @@ sub support_layers {
|
|||||||
return [ map $self->get_support_layer($_), 0..($self->support_layer_count - 1) ];
|
return [ map $self->get_support_layer($_), 0..($self->support_layer_count - 1) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
# 1) Decides Z positions of the layers,
|
|
||||||
# 2) Initializes layers and their regions
|
|
||||||
# 3) Slices the object meshes
|
|
||||||
# 4) Slices the modifier meshes and reclassifies the slices of the object meshes by the slices of the modifier meshes
|
|
||||||
# 5) Applies size compensation (offsets the slices in XY plane)
|
|
||||||
# 6) Replaces bad slices by the slices reconstructed from the upper/lower layer
|
|
||||||
# Resulting expolygons of layer regions are marked as Internal.
|
|
||||||
#
|
|
||||||
# this should be idempotent
|
|
||||||
sub slice {
|
|
||||||
my $self = shift;
|
|
||||||
|
|
||||||
return if $self->step_done(STEP_SLICE);
|
|
||||||
$self->set_step_started(STEP_SLICE);
|
|
||||||
$self->print->status_cb->(10, "Processing triangulated mesh");
|
|
||||||
|
|
||||||
$self->_slice;
|
|
||||||
|
|
||||||
# detect slicing errors
|
|
||||||
my $warning_thrown = 0;
|
|
||||||
for my $i (0 .. ($self->layer_count - 1)) {
|
|
||||||
my $layer = $self->get_layer($i);
|
|
||||||
next unless $layer->slicing_errors;
|
|
||||||
if (!$warning_thrown) {
|
|
||||||
warn "The model has overlapping or self-intersecting facets. I tried to repair it, "
|
|
||||||
. "however you might want to check the results or repair the input file and retry.\n";
|
|
||||||
$warning_thrown = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# try to repair the layer surfaces by merging all contours and all holes from
|
|
||||||
# neighbor layers
|
|
||||||
Slic3r::debugf "Attempting to repair layer %d\n", $i;
|
|
||||||
|
|
||||||
foreach my $region_id (0 .. ($layer->region_count - 1)) {
|
|
||||||
my $layerm = $layer->region($region_id);
|
|
||||||
|
|
||||||
my (@upper_surfaces, @lower_surfaces);
|
|
||||||
for (my $j = $i+1; $j < $self->layer_count; $j++) {
|
|
||||||
if (!$self->get_layer($j)->slicing_errors) {
|
|
||||||
@upper_surfaces = @{$self->get_layer($j)->region($region_id)->slices};
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (my $j = $i-1; $j >= 0; $j--) {
|
|
||||||
if (!$self->get_layer($j)->slicing_errors) {
|
|
||||||
@lower_surfaces = @{$self->get_layer($j)->region($region_id)->slices};
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my $union = union_ex([
|
|
||||||
map $_->expolygon->contour, @upper_surfaces, @lower_surfaces,
|
|
||||||
]);
|
|
||||||
my $diff = diff_ex(
|
|
||||||
[ map @$_, @$union ],
|
|
||||||
[ map @{$_->expolygon->holes}, @upper_surfaces, @lower_surfaces, ],
|
|
||||||
);
|
|
||||||
|
|
||||||
$layerm->slices->clear;
|
|
||||||
$layerm->slices->append($_)
|
|
||||||
for map Slic3r::Surface->new
|
|
||||||
(expolygon => $_, surface_type => S_TYPE_INTERNAL),
|
|
||||||
@$diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
# update layer slices after repairing the single regions
|
|
||||||
$layer->make_slices;
|
|
||||||
}
|
|
||||||
|
|
||||||
# remove empty layers from bottom
|
|
||||||
while (@{$self->layers} && !@{$self->get_layer(0)->slices}) {
|
|
||||||
$self->delete_layer(0);
|
|
||||||
for (my $i = 0; $i <= $#{$self->layers}; $i++) {
|
|
||||||
$self->get_layer($i)->set_id( $self->get_layer($i)->id-1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# simplify slices if required
|
|
||||||
if ($self->print->config->resolution) {
|
|
||||||
$self->_simplify_slices(scale($self->print->config->resolution));
|
|
||||||
}
|
|
||||||
|
|
||||||
die "No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n"
|
|
||||||
if !@{$self->layers};
|
|
||||||
|
|
||||||
$self->set_typed_slices(0);
|
|
||||||
$self->set_step_done(STEP_SLICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub make_perimeters {
|
sub make_perimeters {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ class ExPolygonCollection
|
|||||||
/// ExPolygons and check if at least one contains the point.
|
/// ExPolygons and check if at least one contains the point.
|
||||||
bool contains(const Point &point) const;
|
bool contains(const Point &point) const;
|
||||||
|
|
||||||
|
bool empty() const { return expolygons.empty(); }
|
||||||
size_t size() const { return expolygons.size(); }
|
size_t size() const { return expolygons.size(); }
|
||||||
ExPolygons::iterator begin() { return expolygons.begin(); }
|
ExPolygons::iterator begin() { return expolygons.begin(); }
|
||||||
ExPolygons::iterator end() { return expolygons.end(); }
|
ExPolygons::iterator end() { return expolygons.end(); }
|
||||||
|
@ -956,6 +956,17 @@ PrintObject::make_perimeters()
|
|||||||
this->_make_perimeters();
|
this->_make_perimeters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1) Decides Z positions of the layers,
|
||||||
|
2) Initializes layers and their regions
|
||||||
|
3) Slices the object meshes
|
||||||
|
4) Slices the modifier meshes and reclassifies the slices of the object meshes by the slices of the modifier meshes
|
||||||
|
5) Applies size compensation (offsets the slices in XY plane)
|
||||||
|
6) Replaces bad slices by the slices reconstructed from the upper/lower layer
|
||||||
|
Resulting expolygons of layer regions are marked as Internal.
|
||||||
|
|
||||||
|
This should be idempotent.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
PrintObject::slice()
|
PrintObject::slice()
|
||||||
{
|
{
|
||||||
@ -964,8 +975,7 @@ PrintObject::slice()
|
|||||||
if (_print->status_cb != nullptr) {
|
if (_print->status_cb != nullptr) {
|
||||||
_print->status_cb(10, "Processing triangulated mesh");
|
_print->status_cb(10, "Processing triangulated mesh");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this->_slice();
|
this->_slice();
|
||||||
|
|
||||||
// detect slicing errors
|
// detect slicing errors
|
||||||
@ -975,12 +985,75 @@ PrintObject::slice()
|
|||||||
<< "I tried to repair it, however you might want to check "
|
<< "I tried to repair it, however you might want to check "
|
||||||
<< "the results or repair the input file and retry.\n";
|
<< "the results or repair the input file and retry.\n";
|
||||||
|
|
||||||
if (this->layers.size() == 0) {
|
bool warning_thrown = false;
|
||||||
|
for (size_t i = 0; i < this->layer_count(); ++i) {
|
||||||
|
Layer* layer{ this->get_layer(i) };
|
||||||
|
if (!layer->slicing_errors) continue;
|
||||||
|
if (!warning_thrown) {
|
||||||
|
Slic3r::Log::warn("PrintObject") << "The model has overlapping or self-intersecting facets. "
|
||||||
|
<< "I tried to repair it, however you might want to check "
|
||||||
|
<< "the results or repair the input file and retry.\n";
|
||||||
|
warning_thrown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to repair the layer surfaces by merging all contours and all holes from
|
||||||
|
// neighbor layers
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
std::cout << "Attempting to repair layer " << i << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (size_t region_id = 0; region_id < layer->region_count(); ++region_id) {
|
||||||
|
LayerRegion* layerm{ layer->get_region(region_id) };
|
||||||
|
|
||||||
|
ExPolygons slices;
|
||||||
|
for (size_t j = i+1; j < this->layer_count(); ++j) {
|
||||||
|
const Layer* upper = this->get_layer(j);
|
||||||
|
if (!upper->slicing_errors) {
|
||||||
|
append_to(slices, (ExPolygons)upper->get_region(region_id)->slices);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = i-1; j >= 0; --j) {
|
||||||
|
const Layer* lower = this->get_layer(j);
|
||||||
|
if (!lower->slicing_errors) {
|
||||||
|
append_to(slices, (ExPolygons)lower->get_region(region_id)->slices);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do we actually need to split contours and holes before performing the diff?
|
||||||
|
Polygons contours, holes;
|
||||||
|
for (ExPolygon ex : slices)
|
||||||
|
contours.push_back(ex.contour);
|
||||||
|
for (ExPolygon ex : slices)
|
||||||
|
append_to(holes, ex.holes);
|
||||||
|
|
||||||
|
const ExPolygons diff = diff_ex(contours, holes);
|
||||||
|
|
||||||
|
layerm->slices.clear();
|
||||||
|
layerm->slices.append(diff, stInternal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update layer slices after repairing the single regions
|
||||||
|
layer->make_slices();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove empty layers from bottom
|
||||||
|
while (!this->layers.empty() && this->get_layer(0)->slices.empty()) {
|
||||||
|
this->delete_layer(0);
|
||||||
|
for (Layer* layer : this->layers)
|
||||||
|
layer->set_id(layer->id()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// simplify slices if required
|
||||||
|
if (this->_print->config.resolution() > 0)
|
||||||
|
this->_simplify_slices(scale_(this->_print->config.resolution()));
|
||||||
|
|
||||||
|
if (this->layers.empty()) {
|
||||||
Slic3r::Log::error("PrintObject") << "slice(): " << "No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n";
|
Slic3r::Log::error("PrintObject") << "slice(): " << "No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n";
|
||||||
return; // make this throw an exception instead?
|
return; // make this throw an exception instead?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this->typed_slices = false;
|
this->typed_slices = false;
|
||||||
this->state.set_done(posSlice);
|
this->state.set_done(posSlice);
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,7 @@ _constant()
|
|||||||
void combine_infill();
|
void combine_infill();
|
||||||
void discover_horizontal_shells();
|
void discover_horizontal_shells();
|
||||||
void clip_fill_surfaces();
|
void clip_fill_surfaces();
|
||||||
|
void slice();
|
||||||
void _slice();
|
void _slice();
|
||||||
SV* _slice_region(size_t region_id, std::vector<double> z, bool modifier)
|
SV* _slice_region(size_t region_id, std::vector<double> z, bool modifier)
|
||||||
%code%{
|
%code%{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user