From d8ee9dd5f50700651dd1adbca3309caca5af0adf Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 9 Mar 2015 19:27:57 +0100 Subject: [PATCH] Limit first object layer height correctly when using a larger support material extruder. #2722 --- lib/Slic3r/Print/Object.pm | 11 ++++++++--- t/support.t | 29 +++++++++++++++++++++++++++-- xs/src/libslic3r/Print.cpp | 13 ++++++++++++- xs/src/libslic3r/Print.hpp | 1 + xs/xsp/Print.xsp | 8 ++++++++ 5 files changed, 56 insertions(+), 6 deletions(-) diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index aa24eedf35..537817f52e 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -59,9 +59,14 @@ sub slice { $print_z += $first_layer_height; $print_z += $self->config->layer_height * ($self->config->raft_layers - 1); - # at this stage we don't know which nozzles are actually used for the first layer - # so we compute the average of all of them - my $nozzle_diameter = sum(@{$self->print->config->nozzle_diameter})/@{$self->print->config->nozzle_diameter}; + # compute the average of all nozzles used for printing the object + my $nozzle_diameter; + { + my @nozzle_diameters = ( + map $self->print->config->get_at('nozzle_diameter', $_), @{$self->print->object_extruders} + ); + $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters; + } my $distance = $self->_support_material->contact_distance($first_layer_height, $nozzle_diameter); # force first layer print_z according to the contact distance diff --git a/t/support.t b/t/support.t index 2091b4432a..5967d5c693 100644 --- a/t/support.t +++ b/t/support.t @@ -1,4 +1,4 @@ -use Test::More tests => 25; +use Test::More tests => 26; use strict; use warnings; @@ -221,12 +221,37 @@ use Slic3r::Test; { my $config = Slic3r::Config->new_from_defaults; + $config->set('skirts', 0); + $config->set('start_gcode', ''); $config->set('raft_layers', 3); $config->set('nozzle_diameter', [0.4, 1]); + $config->set('layer_height', 0.3); $config->set('first_layer_height', 0.8); $config->set('support_material_extruder', 2); + $config->set('support_material_interface_extruder', 2); + $config->set('support_material_contact_distance', 0); my $print = Slic3r::Test::init_print('20mm_cube', config => $config); - ok Slic3r::Test::gcode($print), 'first_layer_height is validated with support material extruder nozzle diameter when using raft layers'; + ok my $gcode = Slic3r::Test::gcode($print), 'first_layer_height is validated with support material extruder nozzle diameter when using raft layers'; + + my $tool = undef; + my @z = (0); + my %layer_heights_by_tool = (); # tool => [ lh, lh... ] + Slic3r::GCode::Reader->new->parse($gcode, sub { + my ($self, $cmd, $args, $info) = @_; + + if ($cmd =~ /^T(\d+)/) { + $tool = $1; + } elsif ($cmd eq 'G1' && exists $args->{Z} && $args->{Z} != $self->Z) { + push @z, $args->{Z}; + } elsif ($info->{extruding} && $info->{dist_XY} > 0) { + $layer_heights_by_tool{$tool} ||= []; + push @{ $layer_heights_by_tool{$tool} }, $z[-1] - $z[-2] if $tool == 0; + } + }); + + ok !defined(first { $_ > $config->nozzle_diameter->[0] + epsilon } + @{ $layer_heights_by_tool{$config->perimeter_extruder-1} }), + 'no object layer is thicker than nozzle diameter'; } __END__ diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index d3bb43b3c7..0dab8e70b3 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -300,7 +300,7 @@ Print::step_done(PrintObjectStep step) const // returns 0-based indices of used extruders std::set -Print::extruders() const +Print::object_extruders() const { std::set extruders; @@ -316,6 +316,17 @@ Print::extruders() const if ((*region)->config.top_solid_layers.value > 0 || (*region)->config.bottom_solid_layers.value > 0) extruders.insert((*region)->config.solid_infill_extruder - 1); } + + return extruders; +} + +// returns 0-based indices of used extruders +std::set +Print::extruders() const +{ + std::set extruders = this->object_extruders(); + + // add support material extruder(s) FOREACH_OBJECT(this, object) { if ((*object)->has_support_material()) { extruders.insert((*object)->config.support_material_extruder - 1); diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 53c28833b5..489eebc08a 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -198,6 +198,7 @@ class Print Flow brim_flow() const; Flow skirt_flow() const; + std::set object_extruders() const; std::set extruders() const; void _simplify_slices(double distance); double max_allowed_layer_height() const; diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index e1329c4490..1a6635c30a 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -161,6 +161,14 @@ _constant() void set_step_started(PrintStep step) %code%{ THIS->state.set_started(step); %}; + std::vector object_extruders() + %code%{ + std::set extruders = THIS->object_extruders(); + RETVAL.reserve(extruders.size()); + for (std::set::const_iterator e = extruders.begin(); e != extruders.end(); ++e) { + RETVAL.push_back(*e); + } + %}; std::vector extruders() %code%{ std::set extruders = THIS->extruders();