From 49a9492ad21021ee5defed48563e80a9b703c5a7 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 21 Dec 2016 20:32:57 +0100 Subject: [PATCH] Allow any layer height and limit it to the smallest nozzle diameter. #2706 --- lib/Slic3r/Config.pm | 2 +- lib/Slic3r/Print/Object.pm | 10 ++++++-- xs/src/libslic3r/Print.cpp | 41 ++++---------------------------- xs/src/libslic3r/Print.hpp | 2 ++ xs/src/libslic3r/PrintObject.cpp | 22 +++++++++++++++++ xs/xsp/Print.xsp | 16 +++++++++++++ 6 files changed, 53 insertions(+), 40 deletions(-) diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 031edaf37..a399a8333 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -325,7 +325,7 @@ sub validate { my $max_nozzle_diameter = max(@{ $self->nozzle_diameter }); die "Invalid extrusion width (too large)\n" if defined first { $_ > 10 * $max_nozzle_diameter } - map $self->get_abs_value_over("${_}_extrusion_width", $self->layer_height), + map $self->get_abs_value_over("${_}_extrusion_width", $max_nozzle_diameter), qw(perimeter infill solid_infill top_infill support_material first_layer); } diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 168f78bb3..9b9e99e9f 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -49,6 +49,13 @@ sub slice { $self->set_step_started(STEP_SLICE); $self->print->status_cb->(10, "Processing triangulated mesh"); + { + my @nozzle_diameters = map $self->print->config->get_at('nozzle_diameter', $_), + @{$self->print->object_extruders}; + + $self->config->set('layer_height', min(@nozzle_diameters, $self->config->layer_height)); + } + # init layers { $self->clear_layers; @@ -73,8 +80,7 @@ sub slice { { my @nozzle_diameters = ( map $self->print->config->get_at('nozzle_diameter', $_), - $self->config->support_material_extruder-1, - $self->config->support_material_interface_extruder-1, + @{$self->support_material_extruders}, ); $support_material_layer_height = 0.75 * min(@nozzle_diameters); } diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 5dee986bc..9dec28e9f 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -667,42 +667,9 @@ Print::validate() const return "The Spiral Vase option can only be used when printing single material objects."; } - { - // find the smallest nozzle diameter - std::set extruders = this->extruders(); - if (extruders.empty()) - return "The supplied settings will cause an empty print."; - - std::set nozzle_diameters; - for (std::set::iterator it = extruders.begin(); it != extruders.end(); ++it) - nozzle_diameters.insert(this->config.nozzle_diameter.get_at(*it)); - double min_nozzle_diameter = *std::min_element(nozzle_diameters.begin(), nozzle_diameters.end()); - - FOREACH_OBJECT(this, i_object) { - PrintObject* object = *i_object; - - // validate first_layer_height - double first_layer_height = object->config.get_abs_value("first_layer_height"); - double first_layer_min_nozzle_diameter; - if (object->config.raft_layers > 0) { - // if we have raft layers, only support material extruder is used on first layer - size_t first_layer_extruder = object->config.raft_layers == 1 - ? object->config.support_material_interface_extruder-1 - : object->config.support_material_extruder-1; - first_layer_min_nozzle_diameter = this->config.nozzle_diameter.get_at(first_layer_extruder); - } else { - // if we don't have raft layers, any nozzle diameter is potentially used in first layer - first_layer_min_nozzle_diameter = min_nozzle_diameter; - } - if (first_layer_height > first_layer_min_nozzle_diameter) - return "First layer height can't be greater than nozzle diameter"; - - // validate layer_height - if (object->config.layer_height.value > min_nozzle_diameter) - return "Layer height can't be greater than nozzle diameter"; - } - } - + if (this->extruders().empty()) + return "The supplied settings will cause an empty print."; + return std::string(); } @@ -917,7 +884,7 @@ Print::_make_brim() } std::auto_ptr filler(Fill::new_from_type(ipRectilinear)); - filler->spacing = flow.spacing(); + filler->min_spacing = flow.spacing(); filler->dont_adjust = true; filler->density = 1; diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 65f61f3fb..5ec3653ed 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -109,6 +109,8 @@ class PrintObject bool set_copies(const Points &points); bool reload_model_instances(); BoundingBox bounding_box() const; + std::set extruders() const; + std::set support_material_extruders() const; // adds region_id, too, if necessary void add_region_volume(int region_id, int volume_id); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index ff3f80969..8002ab0be 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -115,6 +115,28 @@ PrintObject::bounding_box() const return BoundingBox(pp); } +// returns 0-based indices of used extruders +std::set +PrintObject::extruders() const +{ + std::set extruders = this->_print->extruders(); + std::set sm_extruders = this->support_material_extruders(); + extruders.insert(sm_extruders.begin(), sm_extruders.end()); + return extruders; +} + +// returns 0-based indices of used extruders +std::set +PrintObject::support_material_extruders() const +{ + std::set extruders; + if (this->has_support_material()) { + extruders.insert(this->config.support_material_extruder - 1); + extruders.insert(this->config.support_material_interface_extruder - 1); + } + return extruders; +} + void PrintObject::add_region_volume(int region_id, int volume_id) { diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 0cd8e01f4..fbd4c3765 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -63,6 +63,22 @@ _constant() Clone bounding_box(); Ref _copies_shift() %code%{ RETVAL = &THIS->_copies_shift; %}; + std::vector support_material_extruders() + %code%{ + std::set extruders = THIS->support_material_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(); + RETVAL.reserve(extruders.size()); + for (std::set::const_iterator e = extruders.begin(); e != extruders.end(); ++e) { + RETVAL.push_back(*e); + } + %}; bool typed_slices() %code%{ RETVAL = THIS->typed_slices; %};