2012-04-29 10:51:20 +00:00
|
|
|
package Slic3r::Print::Object;
|
2016-09-13 09:24:55 +00:00
|
|
|
# extends c++ class Slic3r::PrintObject (Print.xsp)
|
2014-06-10 14:01:57 +00:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
2012-04-29 10:51:20 +00:00
|
|
|
|
2013-07-29 18:49:54 +00:00
|
|
|
use List::Util qw(min max sum first);
|
2013-12-31 13:33:03 +00:00
|
|
|
use Slic3r::Flow ':roles';
|
2017-07-19 08:45:39 +00:00
|
|
|
use Slic3r::Geometry qw(scale epsilon);
|
2013-07-29 18:49:54 +00:00
|
|
|
use Slic3r::Geometry::Clipper qw(diff diff_ex intersection intersection_ex union union_ex
|
2017-07-19 08:45:39 +00:00
|
|
|
offset offset2 offset_ex offset2_ex JT_MITER);
|
2013-12-19 17:54:24 +00:00
|
|
|
use Slic3r::Print::State ':steps';
|
2012-05-19 14:04:33 +00:00
|
|
|
use Slic3r::Surface ':types';
|
2012-04-29 10:51:20 +00:00
|
|
|
|
2014-05-06 08:07:18 +00:00
|
|
|
sub layers {
|
2013-05-19 09:35:41 +00:00
|
|
|
my $self = shift;
|
2014-05-06 08:07:18 +00:00
|
|
|
return [ map $self->get_layer($_), 0..($self->layer_count - 1) ];
|
2013-05-19 09:35:41 +00:00
|
|
|
}
|
|
|
|
|
2014-05-06 08:07:18 +00:00
|
|
|
sub support_layers {
|
|
|
|
my $self = shift;
|
|
|
|
return [ map $self->get_support_layer($_), 0..($self->support_layer_count - 1) ];
|
2013-05-19 09:35:41 +00:00
|
|
|
}
|
|
|
|
|
2016-09-13 09:24:55 +00:00
|
|
|
# 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.
|
|
|
|
#
|
2013-12-15 15:17:12 +00:00
|
|
|
# this should be idempotent
|
2012-04-30 12:56:01 +00:00
|
|
|
sub slice {
|
|
|
|
my $self = shift;
|
2014-06-13 18:05:18 +00:00
|
|
|
|
|
|
|
return if $self->step_done(STEP_SLICE);
|
|
|
|
$self->set_step_started(STEP_SLICE);
|
|
|
|
$self->print->status_cb->(10, "Processing triangulated mesh");
|
2012-04-30 12:56:01 +00:00
|
|
|
|
2016-12-12 16:56:37 +00:00
|
|
|
$self->_slice;
|
2017-03-08 10:56:42 +00:00
|
|
|
|
|
|
|
my $warning = $self->_fix_slicing_errors;
|
|
|
|
warn $warning if (defined($warning) && $warning ne '');
|
|
|
|
|
2013-12-19 14:23:10 +00:00
|
|
|
# simplify slices if required
|
2017-03-08 14:08:40 +00:00
|
|
|
$self->_simplify_slices(scale($self->print->config->resolution))
|
2017-03-08 12:43:49 +00:00
|
|
|
if ($self->print->config->resolution);
|
2014-06-13 18:05:18 +00:00
|
|
|
|
2015-11-04 18:27:58 +00:00
|
|
|
die "No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n"
|
2014-06-13 18:05:18 +00:00
|
|
|
if !@{$self->layers};
|
|
|
|
|
|
|
|
$self->set_step_done(STEP_SLICE);
|
2012-04-30 12:56:01 +00:00
|
|
|
}
|
|
|
|
|
2016-11-17 22:22:59 +00:00
|
|
|
# 1) Merges typed region slices into stInternal type.
|
|
|
|
# 2) Increases an "extra perimeters" counter at region slices where needed.
|
|
|
|
# 3) Generates perimeters, gap fills and fill regions (fill regions of type stInternal).
|
2012-05-05 14:36:10 +00:00
|
|
|
sub make_perimeters {
|
2016-11-26 11:28:39 +00:00
|
|
|
my ($self) = @_;
|
2012-05-05 14:36:10 +00:00
|
|
|
|
2014-06-13 18:05:18 +00:00
|
|
|
# prerequisites
|
|
|
|
$self->slice;
|
2017-03-03 11:53:05 +00:00
|
|
|
|
2017-03-28 15:27:05 +00:00
|
|
|
if (! $self->step_done(STEP_PERIMETERS)) {
|
|
|
|
$self->print->status_cb->(20, "Generating perimeters");
|
|
|
|
$self->_make_perimeters;
|
|
|
|
}
|
2014-06-13 18:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub prepare_infill {
|
|
|
|
my ($self) = @_;
|
|
|
|
|
|
|
|
# prerequisites
|
|
|
|
$self->make_perimeters;
|
|
|
|
|
|
|
|
return if $self->step_done(STEP_PREPARE_INFILL);
|
|
|
|
$self->set_step_started(STEP_PREPARE_INFILL);
|
|
|
|
$self->print->status_cb->(30, "Preparing infill");
|
|
|
|
|
2017-08-02 12:24:32 +00:00
|
|
|
$self->_prepare_infill;
|
2016-09-26 11:56:24 +00:00
|
|
|
|
2014-06-13 18:05:18 +00:00
|
|
|
$self->set_step_done(STEP_PREPARE_INFILL);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub infill {
|
|
|
|
my ($self) = @_;
|
|
|
|
|
|
|
|
# prerequisites
|
|
|
|
$self->prepare_infill;
|
2016-11-26 11:28:39 +00:00
|
|
|
$self->_infill;
|
2014-06-13 18:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub generate_support_material {
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# prerequisites
|
|
|
|
$self->slice;
|
|
|
|
|
|
|
|
return if $self->step_done(STEP_SUPPORTMATERIAL);
|
|
|
|
$self->set_step_started(STEP_SUPPORTMATERIAL);
|
|
|
|
|
|
|
|
$self->clear_support_layers;
|
|
|
|
|
2016-12-20 11:19:13 +00:00
|
|
|
if (($self->config->support_material || $self->config->raft_layers > 0) && scalar(@{$self->layers}) > 1) {
|
|
|
|
$self->print->status_cb->(85, "Generating support material");
|
2017-01-30 18:56:46 +00:00
|
|
|
# New supports, C++ implementation.
|
|
|
|
$self->_generate_support_material;
|
2014-06-13 18:18:34 +00:00
|
|
|
}
|
2015-01-19 08:52:24 +00:00
|
|
|
|
|
|
|
$self->set_step_done(STEP_SUPPORTMATERIAL);
|
2017-02-22 11:01:31 +00:00
|
|
|
my $stats = sprintf "Weight: %.1fg, Cost: %.1f" , $self->print->total_weight, $self->print->total_cost;
|
2017-01-16 07:00:05 +00:00
|
|
|
$self->print->status_cb->(85, $stats);
|
2015-01-19 08:52:24 +00:00
|
|
|
}
|
|
|
|
|
2012-04-29 10:51:20 +00:00
|
|
|
1;
|