mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-17 10:32:20 +00:00
Merge branch 'printcpp' of github.com:sapir/Slic3r into sapir-printcpp
Conflicts: lib/Slic3r/GCode.pm lib/Slic3r/Print.pm lib/Slic3r/Print/Object.pm lib/Slic3r/Print/Region.pm
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
package Slic3r::Print::Object;
|
||||
use Moo;
|
||||
|
||||
use List::Util qw(min max sum first);
|
||||
use Slic3r::Flow ':roles';
|
||||
@@ -9,56 +8,38 @@ use Slic3r::Geometry::Clipper qw(diff diff_ex intersection intersection_ex union
|
||||
use Slic3r::Print::State ':steps';
|
||||
use Slic3r::Surface ':types';
|
||||
|
||||
has 'print' => (is => 'ro', weak_ref => 1, required => 1);
|
||||
has 'model_object' => (is => 'ro', required => 1); # caller is responsible for holding the Model object
|
||||
has 'region_volumes' => (is => 'rw', default => sub { [] }); # by region_id
|
||||
has 'copies' => (is => 'ro'); # Slic3r::Point objects in scaled G-code coordinates
|
||||
has 'config' => (is => 'ro', default => sub { Slic3r::Config::PrintObject->new });
|
||||
has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ]
|
||||
|
||||
has 'size' => (is => 'rw'); # XYZ in scaled coordinates
|
||||
has '_copies_shift' => (is => 'rw'); # scaled coordinates to add to copies (to compensate for the alignment operated when creating the object but still preserving a coherent API for external callers)
|
||||
has '_shifted_copies' => (is => 'rw'); # Slic3r::Point objects in scaled G-code coordinates in our coordinates
|
||||
has 'layers' => (is => 'rw', default => sub { [] });
|
||||
has 'support_layers' => (is => 'rw', default => sub { [] });
|
||||
has 'fill_maker' => (is => 'lazy');
|
||||
has '_state' => (is => 'ro', default => sub { Slic3r::Print::State->new });
|
||||
|
||||
sub BUILD {
|
||||
my ($self) = @_;
|
||||
|
||||
# Compute the translation to be applied to our meshes so that we work with smaller coordinates
|
||||
{
|
||||
my $bb = $self->model_object->bounding_box;
|
||||
|
||||
# Translate meshes so that our toolpath generation algorithms work with smaller
|
||||
# XY coordinates; this translation is an optimization and not strictly required.
|
||||
# A cloned mesh will be aligned to 0 before slicing in _slice_region() since we
|
||||
# don't assume it's already aligned and we don't alter the original position in model.
|
||||
# We store the XY translation so that we can place copies correctly in the output G-code
|
||||
# (copies are expressed in G-code coordinates and this translation is not publicly exposed).
|
||||
$self->_copies_shift(Slic3r::Point->new_scale($bb->x_min, $bb->y_min));
|
||||
$self->_trigger_copies;
|
||||
|
||||
# Scale the object size and store it
|
||||
my $scaled_bb = $bb->clone;
|
||||
$scaled_bb->scale(1 / &Slic3r::SCALING_FACTOR);
|
||||
$self->size($scaled_bb->size);
|
||||
}
|
||||
}
|
||||
|
||||
sub _build_fill_maker {
|
||||
# TODO: lazy
|
||||
sub fill_maker {
|
||||
my $self = shift;
|
||||
return Slic3r::Fill->new(bounding_box => $self->bounding_box);
|
||||
}
|
||||
|
||||
sub region_volumes {
|
||||
my $self = shift;
|
||||
return [ map $self->get_region_volumes($_), 0..($self->region_count - 1) ];
|
||||
}
|
||||
|
||||
sub layers {
|
||||
my $self = shift;
|
||||
return [ map $self->get_layer($_), 0..($self->layer_count - 1) ];
|
||||
}
|
||||
|
||||
sub support_layers {
|
||||
my $self = shift;
|
||||
return [ map $self->get_support_layer($_), 0..($self->support_layer_count - 1) ];
|
||||
}
|
||||
|
||||
# TODO: translate to C++, then call it from constructor (see also
|
||||
# Print->add_model_object)
|
||||
sub _trigger_copies {
|
||||
my $self = shift;
|
||||
|
||||
# TODO: should this mean point is 0,0?
|
||||
return if !defined $self->_copies_shift;
|
||||
|
||||
# order copies with a nearest neighbor search and translate them by _copies_shift
|
||||
$self->_shifted_copies([
|
||||
$self->set_shifted_copies([
|
||||
map {
|
||||
my $c = $_->clone;
|
||||
$c->translate(@{ $self->_copies_shift });
|
||||
@@ -73,28 +54,32 @@ sub _trigger_copies {
|
||||
# in unscaled coordinates
|
||||
sub add_copy {
|
||||
my ($self, $x, $y) = @_;
|
||||
push @{$self->copies}, Slic3r::Point->new_scale($x, $y);
|
||||
my @copies = $self->copies;
|
||||
push @copies, Slic3r::Point->new_scale($x, $y);
|
||||
$self->set_copies(\@copies);
|
||||
$self->_trigger_copies;
|
||||
}
|
||||
|
||||
sub delete_last_copy {
|
||||
my ($self) = @_;
|
||||
pop @{$self->copies};
|
||||
my @copies = $self->copies;
|
||||
pop @copies;
|
||||
$self->set_copies(\@copies);
|
||||
$self->_trigger_copies;
|
||||
}
|
||||
|
||||
sub delete_all_copies {
|
||||
my ($self) = @_;
|
||||
@{$self->copies} = ();
|
||||
$self->set_copies([]);
|
||||
$self->_trigger_copies;
|
||||
}
|
||||
|
||||
# this is the *total* layer count
|
||||
# this is the *total* layer count (including support layers)
|
||||
# this value is not supposed to be compared with $layer->id
|
||||
# since they have different semantics
|
||||
sub layer_count {
|
||||
sub total_layer_count {
|
||||
my $self = shift;
|
||||
return scalar @{ $self->layers } + scalar @{ $self->support_layers };
|
||||
return $self->layer_count + $self->support_layer_count;
|
||||
}
|
||||
|
||||
sub bounding_box {
|
||||
@@ -114,7 +99,7 @@ sub slice {
|
||||
|
||||
# init layers
|
||||
{
|
||||
@{$self->layers} = ();
|
||||
$self->clear_layers;
|
||||
|
||||
# make layers taking custom heights into account
|
||||
my $print_z = my $slice_z = my $height = my $id = 0;
|
||||
@@ -167,16 +152,10 @@ sub slice {
|
||||
|
||||
### Slic3r::debugf "Layer %d: height = %s; slice_z = %s; print_z = %s\n", $id, $height, $slice_z, $print_z;
|
||||
|
||||
push @{$self->layers}, Slic3r::Layer->new(
|
||||
object => $self,
|
||||
id => $id,
|
||||
height => $height,
|
||||
print_z => $print_z,
|
||||
slice_z => $slice_z,
|
||||
);
|
||||
$self->add_layer($id, $height, $print_z, $slice_z);
|
||||
if (@{$self->layers} >= 2) {
|
||||
$self->layers->[-2]->upper_layer($self->layers->[-1]);
|
||||
$self->layers->[-1]->lower_layer($self->layers->[-2]);
|
||||
$self->layers->[-2]->set_upper_layer($self->layers->[-1]);
|
||||
$self->layers->[-1]->set_lower_layer($self->layers->[-2]);
|
||||
}
|
||||
$id++;
|
||||
|
||||
@@ -194,7 +173,7 @@ sub slice {
|
||||
my @z = map $_->slice_z, @{$self->layers};
|
||||
|
||||
# slice all non-modifier volumes
|
||||
for my $region_id (0..$#{$self->region_volumes}) {
|
||||
for my $region_id (0..($self->region_count - 1)) {
|
||||
my $expolygons_by_layer = $self->_slice_region($region_id, \@z, 0);
|
||||
for my $layer_id (0..$#$expolygons_by_layer) {
|
||||
my $layerm = $self->layers->[$layer_id]->regions->[$region_id];
|
||||
@@ -209,12 +188,12 @@ sub slice {
|
||||
}
|
||||
|
||||
# then slice all modifier volumes
|
||||
if (@{$self->region_volumes} > 1) {
|
||||
for my $region_id (0..$#{$self->region_volumes}) {
|
||||
if ($self->region_count > 1) {
|
||||
for my $region_id (0..$self->region_count) {
|
||||
my $expolygons_by_layer = $self->_slice_region($region_id, \@z, 1);
|
||||
|
||||
# loop through the other regions and 'steal' the slices belonging to this one
|
||||
for my $other_region_id (0..$#{$self->region_volumes}) {
|
||||
for my $other_region_id (0..$self->region_count) {
|
||||
next if $other_region_id == $region_id;
|
||||
|
||||
for my $layer_id (0..$#$expolygons_by_layer) {
|
||||
@@ -248,7 +227,8 @@ sub slice {
|
||||
}
|
||||
|
||||
# remove last layer(s) if empty
|
||||
pop @{$self->layers} while @{$self->layers} && (!map @{$_->slices}, @{$self->layers->[-1]->regions});
|
||||
$self->delete_layer($self->layer_count - 1)
|
||||
while $self->layer_count && (!map @{$_->slices}, @{$self->layers->[-1]->regions});
|
||||
|
||||
foreach my $layer (@{ $self->layers }) {
|
||||
# apply size compensation
|
||||
@@ -310,7 +290,7 @@ sub slice {
|
||||
|
||||
# detect slicing errors
|
||||
my $warning_thrown = 0;
|
||||
for my $i (0 .. $#{$self->layers}) {
|
||||
for my $i (0 .. ($self->layer_count - 1)) {
|
||||
my $layer = $self->layers->[$i];
|
||||
next unless $layer->slicing_errors;
|
||||
if (!$warning_thrown) {
|
||||
@@ -323,11 +303,11 @@ sub slice {
|
||||
# neighbor layers
|
||||
Slic3r::debugf "Attempting to repair layer %d\n", $i;
|
||||
|
||||
foreach my $region_id (0 .. $#{$layer->regions}) {
|
||||
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->layers}; $j++) {
|
||||
for (my $j = $i+1; $j < $self->layer_count; $j++) {
|
||||
if (!$self->layers->[$j]->slicing_errors) {
|
||||
@upper_surfaces = @{$self->layers->[$j]->region($region_id)->slices};
|
||||
last;
|
||||
@@ -377,11 +357,11 @@ sub slice {
|
||||
sub _slice_region {
|
||||
my ($self, $region_id, $z, $modifier) = @_;
|
||||
|
||||
return [] if !defined $self->region_volumes->[$region_id];
|
||||
|
||||
return [] if !@{$self->get_region_volumes($region_id)};
|
||||
|
||||
# compose mesh
|
||||
my $mesh;
|
||||
foreach my $volume_id (@{$self->region_volumes->[$region_id]}) {
|
||||
foreach my $volume_id (@{ $self->get_region_volumes($region_id) }) {
|
||||
my $volume = $self->model_object->volumes->[$volume_id];
|
||||
next if $volume->modifier && !$modifier;
|
||||
next if !$volume->modifier && $modifier;
|
||||
@@ -421,7 +401,7 @@ sub make_perimeters {
|
||||
my $region_perimeters = $region->config->perimeters;
|
||||
|
||||
if ($region->config->extra_perimeters && $region_perimeters > 0 && $region->config->fill_density > 0) {
|
||||
for my $i (0 .. $#{$self->layers}-1) {
|
||||
for my $i (0 .. ($self->layer_count - 2)) {
|
||||
my $layerm = $self->layers->[$i]->regions->[$region_id];
|
||||
my $upper_layerm = $self->layers->[$i+1]->regions->[$region_id];
|
||||
my $perimeter_spacing = $layerm->flow(FLOW_ROLE_PERIMETER)->scaled_spacing;
|
||||
@@ -471,7 +451,7 @@ sub make_perimeters {
|
||||
|
||||
Slic3r::parallelize(
|
||||
threads => $self->print->config->threads,
|
||||
items => sub { 0 .. $#{$self->layers} },
|
||||
items => sub { 0 .. ($self->layer_count - 1) },
|
||||
thread_cb => sub {
|
||||
my $q = shift;
|
||||
while (defined (my $i = $q->dequeue)) {
|
||||
@@ -495,7 +475,7 @@ sub detect_surfaces_type {
|
||||
Slic3r::debugf "Detecting solid surfaces...\n";
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for my $i (0 .. $#{$self->layers}) {
|
||||
for my $i (0 .. ($self->layer_count - 1)) {
|
||||
my $layerm = $self->layers->[$i]->regions->[$region_id];
|
||||
|
||||
# prepare a reusable subroutine to make surface differences
|
||||
@@ -623,7 +603,7 @@ sub clip_fill_surfaces {
|
||||
my $additional_margin = scale 3*0;
|
||||
|
||||
my $overhangs = []; # arrayref of polygons
|
||||
for my $layer_id (reverse 0..$#{$self->layers}) {
|
||||
for my $layer_id (reverse 0..($self->layer_count - 1)) {
|
||||
my $layer = $self->layers->[$layer_id];
|
||||
my @layer_internal = (); # arrayref of Surface objects
|
||||
my @new_internal = (); # arrayref of Surface objects
|
||||
@@ -672,11 +652,11 @@ sub clip_fill_surfaces {
|
||||
sub bridge_over_infill {
|
||||
my $self = shift;
|
||||
|
||||
for my $region_id (0..$#{$self->print->regions}) {
|
||||
for my $region_id (0..($self->print->region_count - 1)) {
|
||||
my $fill_density = $self->print->regions->[$region_id]->config->fill_density;
|
||||
next if $fill_density == 100 || $fill_density == 0;
|
||||
|
||||
for my $layer_id (1..$#{$self->layers}) {
|
||||
for my $layer_id (1..($self->layer_count - 1)) {
|
||||
my $layer = $self->layers->[$layer_id];
|
||||
my $layerm = $layer->regions->[$region_id];
|
||||
my $lower_layer = $self->layers->[$layer_id-1];
|
||||
@@ -750,7 +730,7 @@ sub process_external_surfaces {
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
$self->layers->[0]->regions->[$region_id]->process_external_surfaces(undef);
|
||||
for my $i (1 .. $#{$self->layers}) {
|
||||
for my $i (1 .. ($self->layer_count - 1)) {
|
||||
$self->layers->[$i]->regions->[$region_id]->process_external_surfaces($self->layers->[$i-1]);
|
||||
}
|
||||
}
|
||||
@@ -762,7 +742,7 @@ sub discover_horizontal_shells {
|
||||
Slic3r::debugf "==> DISCOVERING HORIZONTAL SHELLS\n";
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for (my $i = 0; $i <= $#{$self->layers}; $i++) {
|
||||
for (my $i = 0; $i < $self->layer_count; $i++) {
|
||||
my $layerm = $self->layers->[$i]->regions->[$region_id];
|
||||
|
||||
if ($layerm->config->solid_infill_every_layers && $layerm->config->fill_density > 0
|
||||
@@ -794,7 +774,7 @@ sub discover_horizontal_shells {
|
||||
abs($n - $i) <= $solid_layers-1;
|
||||
($type == S_TYPE_TOP) ? $n-- : $n++) {
|
||||
|
||||
next if $n < 0 || $n > $#{$self->layers};
|
||||
next if $n < 0 || $n >= $self->layer_count;
|
||||
Slic3r::debugf " looking for neighbors on layer %d...\n", $n;
|
||||
|
||||
my $neighbor_layerm = $self->layers->[$n]->regions->[$region_id];
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
package Slic3r::Print::Region;
|
||||
use Moo;
|
||||
|
||||
use Slic3r::Extruder ':roles';
|
||||
use Slic3r::Flow ':roles';
|
||||
@@ -7,9 +6,6 @@ use Slic3r::Flow ':roles';
|
||||
# A Print::Region object represents a group of volumes to print
|
||||
# sharing the same config (including the same assigned extruder(s))
|
||||
|
||||
has 'print' => (is => 'ro', required => 1, weak_ref => 1);
|
||||
has 'config' => (is => 'ro', default => sub { Slic3r::Config::PrintRegion->new});
|
||||
|
||||
sub flow {
|
||||
my ($self, $role, $layer_height, $bridge, $first_layer, $width, $object) = @_;
|
||||
|
||||
@@ -51,14 +47,14 @@ sub flow {
|
||||
} else {
|
||||
die "Unknown role $role";
|
||||
}
|
||||
my $nozzle_diameter = $self->print->config->get_at('nozzle_diameter', $extruder-1);
|
||||
my $nozzle_diameter = $self->print_config->get_at('nozzle_diameter', $extruder-1);
|
||||
|
||||
return Slic3r::Flow->new_from_width(
|
||||
width => $config_width,
|
||||
role => $role,
|
||||
nozzle_diameter => $nozzle_diameter,
|
||||
layer_height => $layer_height,
|
||||
bridge_flow_ratio => ($bridge ? $self->print->config->bridge_flow_ratio : 0),
|
||||
bridge_flow_ratio => ($bridge ? $self->print_config->bridge_flow_ratio : 0),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,14 +74,14 @@ sub set_model {
|
||||
sub _before_export {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->_print->status_cb($self->status_cb);
|
||||
$self->_print->set_status_cb($self->status_cb);
|
||||
$self->_print->validate;
|
||||
}
|
||||
|
||||
sub _after_export {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->_print->status_cb(undef);
|
||||
$self->_print->set_status_cb(undef);
|
||||
}
|
||||
|
||||
sub export_gcode {
|
||||
|
||||
@@ -71,17 +71,14 @@ sub generate {
|
||||
|
||||
# Install support layers into object.
|
||||
for my $i (0 .. $#$support_z) {
|
||||
push @{$object->support_layers}, Slic3r::Layer::Support->new(
|
||||
object => $object,
|
||||
id => $i,
|
||||
height => ($i == 0) ? $support_z->[$i] : ($support_z->[$i] - $support_z->[$i-1]),
|
||||
print_z => $support_z->[$i],
|
||||
slice_z => -1,
|
||||
slices => [],
|
||||
);
|
||||
$object->add_support_layer(
|
||||
$i, # id
|
||||
($i == 0) ? $support_z->[$i] : ($support_z->[$i] - $support_z->[$i-1]), # height
|
||||
$support_z->[$i], # print_z
|
||||
-1); # slice_z
|
||||
if ($i >= 1) {
|
||||
$object->support_layers->[-2]->upper_layer($object->support_layers->[-1]);
|
||||
$object->support_layers->[-1]->lower_layer($object->support_layers->[-2]);
|
||||
$object->support_layers->[-2]->set_upper_layer($object->support_layers->[-1]);
|
||||
$object->support_layers->[-1]->set_lower_layer($object->support_layers->[-2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user