mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-01 03:11: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) ];
|
||||
}
|
||||
|
||||
# 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 {
|
||||
my ($self) = @_;
|
||||
|
||||
|
@ -41,6 +41,7 @@ class ExPolygonCollection
|
||||
/// ExPolygons and check if at least one contains the point.
|
||||
bool contains(const Point &point) const;
|
||||
|
||||
bool empty() const { return expolygons.empty(); }
|
||||
size_t size() const { return expolygons.size(); }
|
||||
ExPolygons::iterator begin() { return expolygons.begin(); }
|
||||
ExPolygons::iterator end() { return expolygons.end(); }
|
||||
|
@ -956,6 +956,17 @@ PrintObject::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
|
||||
PrintObject::slice()
|
||||
{
|
||||
@ -965,7 +976,6 @@ PrintObject::slice()
|
||||
_print->status_cb(10, "Processing triangulated mesh");
|
||||
}
|
||||
|
||||
|
||||
this->_slice();
|
||||
|
||||
// detect slicing errors
|
||||
@ -975,12 +985,75 @@ PrintObject::slice()
|
||||
<< "I tried to repair it, however you might want to check "
|
||||
<< "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";
|
||||
return; // make this throw an exception instead?
|
||||
}
|
||||
|
||||
|
||||
this->typed_slices = false;
|
||||
this->state.set_done(posSlice);
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ _constant()
|
||||
void combine_infill();
|
||||
void discover_horizontal_shells();
|
||||
void clip_fill_surfaces();
|
||||
void slice();
|
||||
void _slice();
|
||||
SV* _slice_region(size_t region_id, std::vector<double> z, bool modifier)
|
||||
%code%{
|
||||
|
Loading…
x
Reference in New Issue
Block a user