From 556204fddc55f787a1539828deacc53fe5a3dc47 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Nov 2016 16:04:15 +0100 Subject: [PATCH 1/4] support_material_synchronize_layers configuration value for synchronization of object layers with print layers. --- lib/Slic3r/GUI/Tab.pm | 5 +++-- xs/src/libslic3r/PrintConfig.cpp | 7 +++++++ xs/src/libslic3r/PrintConfig.hpp | 2 ++ xs/src/libslic3r/PrintObject.cpp | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index f91f273f9..b87dfa852 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -532,7 +532,7 @@ sub build { brim_width support_material support_material_threshold support_material_enforce_layers raft_layers - support_material_pattern support_material_with_sheath support_material_spacing support_material_angle + support_material_pattern support_material_with_sheath support_material_spacing support_material_synchronize_layers support_material_angle support_material_interface_layers support_material_interface_spacing support_material_contact_distance support_material_buildplate_only dont_support_bridges notes @@ -648,6 +648,7 @@ sub build { $optgroup->append_single_option_line('support_material_interface_spacing'); $optgroup->append_single_option_line('support_material_buildplate_only'); $optgroup->append_single_option_line('dont_support_bridges'); + $optgroup->append_single_option_line('support_material_synchronize_layers'); } } @@ -910,7 +911,7 @@ sub _update { my $have_support_interface = $config->support_material_interface_layers > 0; $self->get_field($_)->toggle($have_support_material) for qw(support_material_threshold support_material_pattern support_material_with_sheath - support_material_spacing support_material_angle + support_material_spacing support_material_synchronize_layers support_material_angle support_material_interface_layers dont_support_bridges support_material_extrusion_width support_material_contact_distance); $self->get_field($_)->toggle($have_support_material && $have_support_interface) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 59dcea879..a56bdcdce 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1247,6 +1247,13 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->default_value = new ConfigOptionFloat(60); + def = this->add("support_material_synchronize_layers", coBool); + def->label = "Synchronize with object layers"; + def->category = "Support material"; + def->tooltip = "Synchronize support layers with the object print layers. This is useful with multi-material printers, where the extruder switch is expensive."; + def->cli = "support-material-synchronize-layers!"; + def->default_value = new ConfigOptionBool(true); + def = this->add("support_material_threshold", coInt); def->label = "Overhang threshold"; def->category = "Support material"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index f4e6cb8c4..f908812fc 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -160,6 +160,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig ConfigOptionEnum support_material_pattern; ConfigOptionFloat support_material_spacing; ConfigOptionFloat support_material_speed; + ConfigOptionBool support_material_synchronize_layers; ConfigOptionInt support_material_threshold; ConfigOptionBool support_material_with_sheath; ConfigOptionFloat xy_size_compensation; @@ -194,6 +195,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig OPT_PTR(support_material_pattern); OPT_PTR(support_material_spacing); OPT_PTR(support_material_speed); + OPT_PTR(support_material_synchronize_layers); OPT_PTR(support_material_threshold); OPT_PTR(support_material_with_sheath); OPT_PTR(xy_size_compensation); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 3808a545e..9dcd73d39 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -203,6 +203,7 @@ PrintObject::invalidate_state_by_config_options(const std::vector Date: Wed, 30 Nov 2016 16:06:12 +0100 Subject: [PATCH 2/4] support_material_synchronize_layers implementation --- lib/Slic3r/Print/SupportMaterial.pm | 62 +++++++++++++++++------------ t/support.t | 2 +- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 9dbfe4003..5aad19cad 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -45,6 +45,7 @@ sub generate { # We now know the upper and lower boundaries for our support material object # (@$contact_z and @$top_z), so we can generate intermediate layers. my $support_z = $self->support_layers_z( + $object, [ sort keys %$contact ], [ sort keys %$top ], max(map $_->height, @{$object->layers}) @@ -384,7 +385,7 @@ sub object_top { } sub support_layers_z { - my ($self, $contact_z, $top_z, $max_object_layer_height) = @_; + my ($self, $object, $contact_z, $top_z, $max_object_layer_height) = @_; # quick table to check whether a given Z is a top surface my %top = map { $_ => 1 } @$top_z; @@ -397,13 +398,18 @@ sub support_layers_z { my $contact_distance = $self->contact_distance($support_material_height, $nozzle_diameter); # initialize known, fixed, support layers - my @z = sort { $a <=> $b } - @$contact_z, - # TODO: why we have this? - # Vojtech: To detect the bottom interface layers by finding a Z value in the $top_z. - @$top_z, - # Top surfaces of the bottom interface layers. - (map $_ + $contact_distance, @$top_z); + my @z = @$contact_z; + my $synchronize = $self->object_config->support_material_synchronize_layers; + if (! $synchronize) { + push @z, + # TODO: why we have this? + # Vojtech: To detect the bottom interface layers by finding a Z value in the $top_z. + @$top_z; + push @z, + # Top surfaces of the bottom interface layers. + (map $_ + $contact_distance, @$top_z); + } + @z = sort { $a <=> $b } @z; # enforce first layer height my $first_layer_height = $self->object_config->get_value('first_layer_height'); @@ -423,23 +429,29 @@ sub support_layers_z { 1..($self->object_config->raft_layers - 2); } - # create other layers (skip raft layers as they're already done and use thicker layers) - for (my $i = $#z; $i >= $self->object_config->raft_layers; $i--) { - my $target_height = $support_material_height; - if ($i > 0 && $top{ $z[$i-1] }) { - # Bridge flow? - #FIXME We want to enforce not only the bridge flow height, but also the interface gap! - # This will introduce an additional layer if the gap is set to an extreme value! - $target_height = $nozzle_diameter; - } - - # enforce first layer height - #FIXME better to split the layers regularly, than to bite a constant height one at a time, - # and then be left with a very thin layer at the end. - if (($i == 0 && $z[$i] > $target_height + $first_layer_height) - || ($z[$i] - $z[$i-1] > $target_height + Slic3r::Geometry::epsilon)) { - splice @z, $i, 0, ($z[$i] - $target_height); - $i++; + if ($synchronize) { + @z = splice @z, $self->object_config->raft_layers; +# if ($self->object_config->raft_layers > scalar(@z)); + push @z, map $_->print_z, @{$object->layers}; + } else { + # create other layers (skip raft layers as they're already done and use thicker layers) + for (my $i = $#z; $i >= $self->object_config->raft_layers; $i--) { + my $target_height = $support_material_height; + if ($i > 0 && $top{ $z[$i-1] }) { + # Bridge flow? + #FIXME We want to enforce not only the bridge flow height, but also the interface gap! + # This will introduce an additional layer if the gap is set to an extreme value! + $target_height = $nozzle_diameter; + } + + # enforce first layer height + #FIXME better to split the layers regularly, than to bite a constant height one at a time, + # and then be left with a very thin layer at the end. + if (($i == 0 && $z[$i] > $target_height + $first_layer_height) + || ($z[$i] - $z[$i-1] > $target_height + Slic3r::Geometry::epsilon)) { + splice @z, $i, 0, ($z[$i] - $target_height); + $i++; + } } } diff --git a/t/support.t b/t/support.t index 3eba6e64b..303f77088 100644 --- a/t/support.t +++ b/t/support.t @@ -28,7 +28,7 @@ use Slic3r::Test; interface_flow => $flow, first_layer_flow => $flow, ); - my $support_z = $support->support_layers_z(\@contact_z, \@top_z, $config->layer_height); + my $support_z = $support->support_layers_z($print->print->objects->[0], \@contact_z, \@top_z, $config->layer_height); my $expected_top_spacing = $support->contact_distance($config->layer_height, $config->nozzle_diameter->[0]); is $support_z->[0], $config->first_layer_height, From 26a8017e99c75d1d334a2a20e545696ce7a2d8e2 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Nov 2016 17:33:55 +0100 Subject: [PATCH 3/4] Made the support interface contact loops configurable. --- lib/Slic3r/GUI/Tab.pm | 5 +++-- lib/Slic3r/Print/SupportMaterial.pm | 7 +++++-- xs/src/libslic3r/PrintConfig.cpp | 9 ++++++++- xs/src/libslic3r/PrintConfig.hpp | 2 ++ xs/src/libslic3r/PrintObject.cpp | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index b87dfa852..a744b4c47 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -533,7 +533,7 @@ sub build { support_material support_material_threshold support_material_enforce_layers raft_layers support_material_pattern support_material_with_sheath support_material_spacing support_material_synchronize_layers support_material_angle - support_material_interface_layers support_material_interface_spacing + support_material_interface_layers support_material_interface_spacing support_material_interface_contact_loops support_material_contact_distance support_material_buildplate_only dont_support_bridges notes complete_objects extruder_clearance_radius extruder_clearance_height @@ -646,6 +646,7 @@ sub build { $optgroup->append_single_option_line('support_material_angle'); $optgroup->append_single_option_line('support_material_interface_layers'); $optgroup->append_single_option_line('support_material_interface_spacing'); + $optgroup->append_single_option_line('support_material_interface_contact_loops'); $optgroup->append_single_option_line('support_material_buildplate_only'); $optgroup->append_single_option_line('dont_support_bridges'); $optgroup->append_single_option_line('support_material_synchronize_layers'); @@ -916,7 +917,7 @@ sub _update { support_material_extrusion_width support_material_contact_distance); $self->get_field($_)->toggle($have_support_material && $have_support_interface) for qw(support_material_interface_spacing support_material_interface_extruder - support_material_interface_speed); + support_material_interface_speed support_material_interface_contact_loops); $self->get_field('perimeter_extrusion_width')->toggle($have_perimeters || $have_skirt || $have_brim); $self->get_field('support_material_extruder')->toggle($have_support_material || $have_skirt); diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 5aad19cad..522b4fd54 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -640,7 +640,7 @@ sub generate_toolpaths { my $interface_flow = $self->interface_flow; # shape of contact area - my $contact_loops = 1; + my $contact_loops = $self->object_config->support_material_interface_contact_loops ? 1 : 0; my $circle_radius = 1.5 * $interface_flow->scaled_width; my $circle_distance = 3 * $circle_radius; my $circle = Slic3r::Polygon->new(map [ $circle_radius * cos $_, $circle_radius * sin $_ ], @@ -704,7 +704,10 @@ sub generate_toolpaths { # if no interface layers were requested we treat the contact layer # exactly as a generic base layer push @$base, @$contact; - } elsif (@$contact && $contact_loops > 0) { + } elsif ($contact_loops == 0) { + # No contact loops, but some interface layers. Print the contact layer as a normal interface layer. + push @$interface, @$contact; + } elsif (@$contact) { # generate the outermost loop # find centerline of the external loop (or any other kind of extrusions should the loop be skipped) diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index a56bdcdce..a2a9973de 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1177,6 +1177,13 @@ PrintConfigDef::PrintConfigDef() def->cli = "support-material-extrusion-width=s"; def->default_value = new ConfigOptionFloatOrPercent(0, false); + def = this->add("support_material_interface_contact_loops", coBool); + def->label = "Interface circles"; + def->category = "Support material"; + def->tooltip = "Cover the top most interface layer with contact loops"; + def->cli = "support-material-interface-contact-loops!"; + def->default_value = new ConfigOptionBool(true); + def = this->add("support_material_interface_extruder", coInt); def->label = "Support material/raft interface extruder"; def->category = "Extruders"; @@ -1252,7 +1259,7 @@ PrintConfigDef::PrintConfigDef() def->category = "Support material"; def->tooltip = "Synchronize support layers with the object print layers. This is useful with multi-material printers, where the extruder switch is expensive."; def->cli = "support-material-synchronize-layers!"; - def->default_value = new ConfigOptionBool(true); + def->default_value = new ConfigOptionBool(false); def = this->add("support_material_threshold", coInt); def->label = "Overhang threshold"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index f908812fc..8e66d1482 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -153,6 +153,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig ConfigOptionInt support_material_enforce_layers; ConfigOptionInt support_material_extruder; ConfigOptionFloatOrPercent support_material_extrusion_width; + ConfigOptionBool support_material_interface_contact_loops; ConfigOptionInt support_material_interface_extruder; ConfigOptionInt support_material_interface_layers; ConfigOptionFloat support_material_interface_spacing; @@ -186,6 +187,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig OPT_PTR(support_material_buildplate_only); OPT_PTR(support_material_contact_distance); OPT_PTR(support_material_enforce_layers); + OPT_PTR(support_material_interface_contact_loops); OPT_PTR(support_material_extruder); OPT_PTR(support_material_extrusion_width); OPT_PTR(support_material_interface_extruder); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 9dcd73d39..e0a287f75 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -197,6 +197,7 @@ PrintObject::invalidate_state_by_config_options(const std::vector Date: Wed, 30 Nov 2016 18:54:19 +0100 Subject: [PATCH 4/4] Print the supports before the object layer at the same height. --- lib/Slic3r/Print/GCode.pm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/Print/GCode.pm b/lib/Slic3r/Print/GCode.pm index d1b0009ad..f7fdf1a4e 100644 --- a/lib/Slic3r/Print/GCode.pm +++ b/lib/Slic3r/Print/GCode.pm @@ -262,7 +262,10 @@ sub export { $gcodegen->avoid_crossing_perimeters->set_disable_once(1); } - my @layers = sort { $a->print_z <=> $b->print_z } @{$object->layers}, @{$object->support_layers}; + # Order layers by print_z, support layers preceding the object layers. + my @layers = sort + { ($a->print_z == $b->print_z) ? ($a->isa('Slic3r::Layer::Support') ? -1 : 0) : $a->print_z <=> $b->print_z } + @{$object->layers}, @{$object->support_layers}; for my $layer (@layers) { # if we are printing the bottom layer of an object, and we have already finished # another one, set first layer temperatures. this happens before the Z move @@ -289,7 +292,8 @@ sub export { my %layers = (); # print_z => [ [layers], [layers], [layers] ] by obj_idx foreach my $obj_idx (0 .. ($self->print->object_count - 1)) { my $object = $self->objects->[$obj_idx]; - foreach my $layer (@{$object->layers}, @{$object->support_layers}) { + # Collect the object layers by z, support layers first, object layers second. + foreach my $layer (@{$object->support_layers}, @{$object->layers}) { $layers{ $layer->print_z } ||= []; $layers{ $layer->print_z }[$obj_idx] ||= []; push @{$layers{ $layer->print_z }[$obj_idx]}, $layer;