From 8ed738d3f7dcc5ae3d47415eff331f0f1e874da0 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Fri, 3 Jan 2014 18:27:46 +0100 Subject: [PATCH] More incomplete work for Flow/Extruder refactoring --- lib/Slic3r.pm | 1 - lib/Slic3r/Extruder.pm | 56 ++++++-------- lib/Slic3r/ExtrusionLoop.pm | 3 +- lib/Slic3r/Fill.pm | 12 +-- lib/Slic3r/Fill/Honeycomb.pm | 6 +- lib/Slic3r/Fill/Rectilinear.pm | 15 ++-- lib/Slic3r/Flow.pm | 115 ++++++++++++++++++++-------- lib/Slic3r/GCode.pm | 37 ++++----- lib/Slic3r/GCode/Layer.pm | 12 +-- lib/Slic3r/Layer/Region.pm | 19 ++--- lib/Slic3r/Print.pm | 48 +++++------- lib/Slic3r/Print/Object.pm | 4 +- lib/Slic3r/Print/Region.pm | 2 +- lib/Slic3r/Print/SupportMaterial.pm | 49 ++++++------ t/arcs.t | 6 +- t/fill.t | 4 +- xs/lib/Slic3r/XS.pm | 12 +-- xs/src/ExtrusionEntity.cpp | 3 +- xs/src/ExtrusionEntity.hpp | 3 +- xs/src/PrintConfig.hpp | 3 + xs/t/07_extrusionpath.t | 1 + xs/t/08_extrusionloop.t | 1 + xs/t/12_extrusionpathcollection.t | 6 +- xs/t/15_config.t | 15 +++- xs/xsp/Config.xsp | 2 +- xs/xsp/ExtrusionLoop.xsp | 24 ++---- xs/xsp/ExtrusionPath.xsp | 24 ++---- 27 files changed, 250 insertions(+), 233 deletions(-) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 1c5ffa74..710e33e1 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -77,7 +77,6 @@ our $build = eval "use Slic3r::Build; 1"; use constant SCALING_FACTOR => 0.000001; use constant RESOLUTION => 0.0125; use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR; -use constant OVERLAP_FACTOR => 1; use constant SMALL_PERIMETER_LENGTH => (6.5 / SCALING_FACTOR) * 2 * PI; use constant LOOP_CLIPPING_LENGTH_OVER_SPACING => 0.15; use constant INFILL_OVERLAP_OVER_SPACING => 0.45; diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index 9b8b1dc9..2a8371ce 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -26,13 +26,26 @@ has 'retracted' => (is => 'rw', default => sub {0} ); has 'restart_extra' => (is => 'rw', default => sub {0} ); has 'e_per_mm3' => (is => 'lazy'); has 'retract_speed_mm_min' => (is => 'lazy'); -has '_mm3_per_mm_cache' => (is => 'ro', default => sub {{}}); use constant EXTRUDER_ROLE_PERIMETER => 1; use constant EXTRUDER_ROLE_INFILL => 2; use constant EXTRUDER_ROLE_SUPPORT_MATERIAL => 3; use constant EXTRUDER_ROLE_SUPPORT_MATERIAL_INTERFACE => 4; +sub new_from_config { + my ($class, $config, $extruder_id) = @_; + + my %conf = ( + id => $extruder_id, + use_relative_e_distances => $config->use_relative_e_distances, + ); + foreach my $opt_key (@{&OPTIONS}) { + my $value = $config->get($opt_key); + $conf{$opt_key} = $value->[$extruder_id] // $value->[0]; + } + return $class->new(%conf); +} + sub _build_e_per_mm3 { my $self = shift; return $self->extrusion_multiplier * (4 / (($self->filament_diameter ** 2) * PI)); @@ -43,6 +56,15 @@ sub _build_retract_speed_mm_min { return $self->retract_speed * 60; } +sub reset { + my ($self) = @_; + + $self->E(0); + $self->absolute_E(0); + $self->retracted(0); + $self->restart_extra(0); +} + sub scaled_wipe_distance { my ($self, $travel_speed) = @_; @@ -66,37 +88,9 @@ sub extruded_volume { return $self->absolute_E * ($self->filament_diameter**2) * PI/4; } -sub make_flow { - my $self = shift; - return Slic3r::Flow->new(nozzle_diameter => $self->nozzle_diameter, @_); -} - -sub mm3_per_mm { - my $self = shift; - my ($s, $h) = @_; - - my $cache_key = "${s}_${h}"; - if (!exists $self->_mm3_per_mm_cache->{$cache_key}) { - my $w_threshold = $h + $self->nozzle_diameter; - my $s_threshold = $w_threshold - &Slic3r::OVERLAP_FACTOR * ($w_threshold - ($w_threshold - $h * (1 - PI/4))); - - if ($s >= $s_threshold) { - # rectangle with semicircles at the ends - my $w = $s + &Slic3r::OVERLAP_FACTOR * $h * (1 - PI/4); - $self->_mm3_per_mm_cache->{$cache_key} = $w * $h + ($h**2) / 4 * (PI - 4); - } else { - # rectangle with shrunk semicircles at the ends - my $w = ($s + $self->nozzle_diameter * &Slic3r::OVERLAP_FACTOR * (PI/4 - 1)) / (1 + &Slic3r::OVERLAP_FACTOR * (PI/4 - 1)); - $self->_mm3_per_mm_cache->{$cache_key} = $self->nozzle_diameter * $h * (1 - PI/4) + $h * $w * PI/4; - } - } - return $self->_mm3_per_mm_cache->{$cache_key}; -} - sub e_per_mm { - my $self = shift; - my ($s, $h) = @_; - return $self->mm3_per_mm($s, $h) * $self->e_per_mm3; + my ($self, $mm3_per_mm) = @_; + return $mm3_per_mm * $self->e_per_mm3; } 1; diff --git a/lib/Slic3r/ExtrusionLoop.pm b/lib/Slic3r/ExtrusionLoop.pm index 57f380ee..7123b3a7 100644 --- a/lib/Slic3r/ExtrusionLoop.pm +++ b/lib/Slic3r/ExtrusionLoop.pm @@ -8,8 +8,7 @@ sub split_at { return Slic3r::ExtrusionPath->new( polyline => $self->polygon->split_at(@_), role => $self->role, - flow_spacing => $self->flow_spacing, - height => $self->height, + mm3_per_mm => $self->mm3_per_mm, ); } diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 7969431c..45508169 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -158,20 +158,17 @@ sub make_fill { next SURFACE unless $density > 0; } - my $flow_spacing = $flow->spacing; - my $f = $self->filler($filler); $f->layer_id($layerm->id); $f->angle($layerm->config->fill_angle); my ($params, @polylines) = $f->fill_surface( $surface, - density => $density, - flow_spacing => $flow_spacing, + density => $density, + flow => $flow, ); next unless @polylines; - # ugly hack(tm) to get the right amount of flow (GCode.pm should be fixed) - $params->{flow_spacing} = $flow->width if $is_bridge; + my $mm3_per_mm = $params->{flow}->mm3_per_mm($surface->thickness); # save into layer push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new; @@ -187,8 +184,7 @@ sub make_fill { : $is_solid ? (($surface->surface_type == S_TYPE_TOP) ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL) : EXTR_ROLE_FILL), - height => $surface->thickness, - flow_spacing => $params->{flow_spacing} || (warn "Warning: no flow_spacing was returned by the infill engine, please report this to the developer\n"), + mm3_per_mm => $mm3_per_mm, ), @polylines, ); push @fills_ordering_points, $polylines[0]->first_point; diff --git a/lib/Slic3r/Fill/Honeycomb.pm b/lib/Slic3r/Fill/Honeycomb.pm index caaa1540..1e6df274 100644 --- a/lib/Slic3r/Fill/Honeycomb.pm +++ b/lib/Slic3r/Fill/Honeycomb.pm @@ -17,11 +17,11 @@ sub fill_surface { my $rotate_vector = $self->infill_direction($surface); # cache hexagons math - my $cache_id = sprintf "d%s_s%s", $params{density}, $params{flow_spacing}; + my $cache_id = sprintf "d%s_s%s", $params{density}, $params{flow}->spacing; my $m; if (!($m = $self->cache->{$cache_id})) { $m = $self->cache->{$cache_id} = {}; - my $min_spacing = scale $params{flow_spacing}; + my $min_spacing = $params{flow}->scaled_spacing; $m->{distance} = $min_spacing / $params{density}; $m->{hex_side} = $m->{distance} / (sqrt(3)/2); $m->{hex_width} = $m->{distance} * 2; # $m->{hex_width} == $m->{hex_side} * sqrt(3); @@ -120,7 +120,7 @@ sub fill_surface { )}; } - return { flow_spacing => $params{flow_spacing} }, @paths; + return { flow => $params{flow} }, @paths; } 1; diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index 335bf5b2..39fa5b94 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -17,8 +17,8 @@ sub fill_surface { my $rotate_vector = $self->infill_direction($surface); $self->rotate_points($expolygon, $rotate_vector); - my $flow_spacing = $params{flow_spacing}; - my $min_spacing = scale $params{flow_spacing}; + my $flow = $params{flow}; + my $min_spacing = $flow->scaled_spacing; my $line_spacing = $min_spacing / $params{density}; my $line_oscillation = $line_spacing - $min_spacing; my $is_line_pattern = $self->isa('Slic3r::Fill::Line'); @@ -30,7 +30,12 @@ sub fill_surface { width => $bounding_box->size->[X], distance => $line_spacing, ); - $flow_spacing = unscale $line_spacing; + $flow = Slic3r::Flow->new_from_spacing( + spacing => unscale($line_spacing), + nozzle_diameter => $flow->nozzle_diameter, + layer_height => $surface->thickness, + bridge => $flow->bridge, + ); } else { # extend bounding box so that our pattern will be aligned with other layers $bounding_box->extents->[X][MIN] -= $bounding_box->x_min % $line_spacing; @@ -62,7 +67,7 @@ sub fill_surface { # connect lines unless ($params{dont_connect} || !@polylines) { # prevent calling leftmost_point() on empty collections - my ($expolygon_off) = @{$expolygon->offset_ex(scale $params{flow_spacing}/2)}; + my ($expolygon_off) = @{$expolygon->offset_ex($min_spacing/2)}; my $collection = Slic3r::Polyline::Collection->new(@polylines); @polylines = (); @@ -97,7 +102,7 @@ sub fill_surface { # paths must be rotated back $self->rotate_points_back(\@polylines, $rotate_vector); - return { flow_spacing => $flow_spacing }, @polylines; + return { flow => $flow }, @polylines; } 1; diff --git a/lib/Slic3r/Flow.pm b/lib/Slic3r/Flow.pm index 3930dce5..5b1502a7 100644 --- a/lib/Slic3r/Flow.pm +++ b/lib/Slic3r/Flow.pm @@ -9,8 +9,10 @@ our %EXPORT_TAGS = (roles => \@EXPORT_OK); use Slic3r::Geometry qw(PI); -has 'width' => (is => 'ro'); -has 'spacing' => (is => 'ro'); +has 'width' => (is => 'ro', required => 1); +has 'spacing' => (is => 'ro', required => 1); +has 'nozzle_diameter' => (is => 'ro', required => 1); +has 'bridge' => (is => 'ro', default => sub {0}); has 'scaled_width' => (is => 'lazy'); has 'scaled_spacing' => (is => 'lazy'); @@ -21,32 +23,67 @@ use constant FLOW_ROLE_TOP_SOLID_INFILL => 4; use constant FLOW_ROLE_SUPPORT_MATERIAL => 5; use constant FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE => 6; -sub BUILDARGS { - my ($self, %args) = @_; +use constant BRIDGE_EXTRA_SPACING => 0.05; +use constant OVERLAP_FACTOR => 1; + +sub new_from_width { + my ($class, %args) = @_; - # the constructor can take two sets of arguments: - # - width (only absolute value), spacing - # - width (abs/%/0), role, nozzle_diameter, layer_height, bridge_flow_ratio - # (if bridge_flow_ratio == 0, we return a non-bridge flow) - - if (exists $args{role}) { - if ($args{width} eq '0') { - $args{width} = $self->_width(@args{qw(role nozzle_diameter layer_height bridge_flow_ratio)}); - } elsif ($args{width} =~ /^(\d+(?:\.\d+)?)%$/) { - $args{width} = $args{layer_height} * $1 / 100; - } - $args{spacing} = $self->_spacing(@args{qw(width nozzle_diameter layer_height bridge_flow_ratio)}); - %args = ( - width => $args{width}, - spacing => $args{spacing}, - ); + if ($args{width} eq '0') { + $args{width} = _width(@args{qw(role nozzle_diameter layer_height bridge_flow_ratio)}); + } elsif ($args{width} =~ /^(\d+(?:\.\d+)?)%$/) { + $args{width} = $args{layer_height} * $1 / 100; } - return {%args}; + return $class->new( + width => $args{width}, + spacing => _spacing(@args{qw(width nozzle_diameter layer_height bridge_flow_ratio)}), + nozzle_diameter => $args{nozzle_diameter}, + bridge => ($args{bridge_flow_ratio} > 0) ? 1 : 0, + ); +} + +sub new_from_spacing { + my ($class, %args) = @_; + + return $class->new( + width => _width_from_spacing(@args{qw(spacing nozzle_diameter layer_height bridge)}), + spacing => $args{spacing}, + nozzle_diameter => $args{nozzle_diameter}, + bridge => $args{bridge}, + ); +} + +sub clone { + my $self = shift; + + return (ref $self)->new( + width => $self->width, + spacing => $self->spacing, + nozzle_diameter => $self->nozzle_diameter, + bridge => $self->bridge, + ); +} + +sub mm3_per_mm { + my ($self, $h) = @_; + + my $w = $self->width; + my $s = $self->spacing; + + if ($self->bridge) { + return ($s**2) * PI/4; + } elsif ($w >= ($self->nozzle_diameter + $h)) { + # rectangle with semicircles at the ends + return $w * $h + ($h**2) / 4 * (PI - 4); + } else { + # rectangle with shrunk semicircles at the ends + return $self->nozzle_diameter * $h * (1 - PI/4) + $h * $w * PI/4; + } } sub _width { - my ($self, $role, $nozzle_diameter, $layer_height, $bridge_flow_ratio) = @_; + my ($role, $nozzle_diameter, $layer_height, $bridge_flow_ratio) = @_; if ($bridge_flow_ratio > 0) { return sqrt($bridge_flow_ratio * ($nozzle_diameter**2)); @@ -78,11 +115,30 @@ sub _width { return $width; } +sub _width_from_spacing { + my ($s, $nozzle_diameter, $h, $bridge) = @_; + + if ($bridge) { + return $s - BRIDGE_EXTRA_SPACING; + } + + my $w_threshold = $h + $nozzle_diameter; + my $s_threshold = $w_threshold - OVERLAP_FACTOR * ($w_threshold - ($w_threshold - $h * (1 - PI/4))); + + if ($s >= $s_threshold) { + # rectangle with semicircles at the ends + return $s + OVERLAP_FACTOR * $h * (1 - PI/4); + } else { + # rectangle with shrunk semicircles at the ends + return ($s + $nozzle_diameter * OVERLAP_FACTOR * (PI/4 - 1)) / (1 + OVERLAP_FACTOR * (PI/4 - 1)); + } +} + sub _spacing { - my ($self, $width, $nozzle_diameter, $layer_height, $bridge_flow_ratio) = @_; + my ($width, $nozzle_diameter, $layer_height, $bridge_flow_ratio) = @_; if ($bridge_flow_ratio > 0) { - return $width + 0.05; + return $width + BRIDGE_EXTRA_SPACING; } my $min_flow_spacing; @@ -93,16 +149,7 @@ sub _spacing { # rectangle with shrunk semicircles at the ends $min_flow_spacing = $nozzle_diameter * (1 - PI/4) + $width * PI/4; } - return $width - &Slic3r::OVERLAP_FACTOR * ($width - $min_flow_spacing); -} - -sub clone { - my $self = shift; - - return (ref $self)->new( - width => $self->width, - spacing => $self->spacing, - ); + return $width - OVERLAP_FACTOR * ($width - $min_flow_spacing); } sub _build_scaled_width { diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 66175260..a8f7526a 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -10,8 +10,6 @@ use Slic3r::Surface ':types'; has 'print_config' => (is => 'ro', default => sub { Slic3r::Config::Print->new }); has 'extra_variables' => (is => 'rw', default => sub {{}}); -has 'extruders' => (is => 'ro', required => 1); -has 'multiple_extruders' => (is => 'lazy'); has 'standby_points' => (is => 'rw'); has 'enable_loop_clipping' => (is => 'rw', default => sub {1}); has 'enable_wipe' => (is => 'lazy'); # at least one extruder has wipe enabled @@ -27,6 +25,7 @@ has 'z' => (is => 'rw'); has 'speed' => (is => 'rw'); has '_extrusion_axis' => (is => 'rw'); has '_retract_lift' => (is => 'rw'); +has 'extruders' => (is => 'ro', default => sub {[]}); has 'speeds' => (is => 'lazy'); # mm/min has 'external_mp' => (is => 'rw'); @@ -49,6 +48,14 @@ sub BUILD { $self->_retract_lift($self->print_config->retract_lift->[0]); } +sub set_extruders { + my ($self, $extruder_ids) = @_; + + foreach my $i (@$extruder_ids) { + $self->extruders->[$i] = Slic3r::Extruder->new_from_config($self->print_config, $i); + } +} + sub _build_speeds { my $self = shift; return { @@ -73,7 +80,7 @@ my %role_speeds = ( &EXTR_ROLE_GAPFILL => 'gap_fill', ); -sub _build_multiple_extruders { +sub multiple_extruders { my $self = shift; return @{$self->extruders} > 1; } @@ -320,18 +327,8 @@ sub extrude_path { $gcode .= $self->set_acceleration($acceleration) if $acceleration; } - my $area; # mm^3 of extrudate per mm of tool movement - if ($path->is_bridge) { - my $s = $path->flow_spacing; - $area = ($s**2) * PI/4; - } else { - my $s = $path->flow_spacing; - my $h = (defined $path->height && $path->height != -1) ? $path->height : $self->layer->height; - $area = $self->extruder->mm3_per_mm($s, $h); - } - # calculate extrusion length per distance unit - my $e = $self->extruder->e_per_mm3 * $area; + my $e = $self->extruder->e_per_mm3 * $path->mm3_per_mm; $e = 0 if !$self->_extrusion_axis; # set speed @@ -640,14 +637,14 @@ sub _Gx { } sub set_extruder { - my ($self, $extruder) = @_; + my ($self, $extruder_id) = @_; # return nothing if this extruder was already selected - return "" if (defined $self->extruder) && ($self->extruder->id == $extruder->id); + return "" if (defined $self->extruder) && ($self->extruder->id == $extruder_id); # if we are running a single-extruder setup, just set the extruder and return nothing if (!$self->multiple_extruders) { - $self->extruder($extruder); + $self->extruder($self->extruders->[$extruder_id]); return ""; } @@ -659,7 +656,7 @@ sub set_extruder { if (defined $self->extruder && $self->print_config->toolchange_gcode) { $gcode .= sprintf "%s\n", $self->replace_variables($self->print_config->toolchange_gcode, { previous_extruder => $self->extruder->id, - next_extruder => $extruder->id, + next_extruder => $extruder_id, }); } @@ -676,14 +673,14 @@ sub set_extruder { } # set the new extruder - $self->extruder($extruder); + $self->extruder($self->extruders->[$extruder_id]); $gcode .= sprintf "%s%d%s\n", ($self->print_config->gcode_flavor eq 'makerware' ? 'M135 T' : $self->print_config->gcode_flavor eq 'sailfish' ? 'M108 T' : 'T'), - $extruder->id, + $extruder_id, ($self->print_config->gcode_comments ? ' ; change extruder' : ''); $gcode .= $self->reset_e; diff --git a/lib/Slic3r/GCode/Layer.pm b/lib/Slic3r/GCode/Layer.pm index f64b6a1b..96029eaa 100644 --- a/lib/Slic3r/GCode/Layer.pm +++ b/lib/Slic3r/GCode/Layer.pm @@ -85,7 +85,7 @@ sub process_layer { # when printing layers > 0 ignore 'min_skirt_length' and # just use the 'skirts' setting; also just use the current extruder last if ($layer->id > 0) && ($i >= $self->print->config->skirts); - $gcode .= $self->gcodegen->set_extruder($self->extruders->[ ($i/@{$self->extruders}) % @{$self->extruders} ]) + $gcode .= $self->gcodegen->set_extruder(($i/@{$self->extruders}) % @{$self->extruders}) if $layer->id == 0; $gcode .= $self->gcodegen->extrude_loop($skirt_loops[$i], 'skirt'); } @@ -96,7 +96,7 @@ sub process_layer { # extrude brim if (!$self->brim_done) { - $gcode .= $self->gcodegen->set_extruder($self->extruders->[$self->print->objects->[0]->config->support_material_extruder-1]); + $gcode .= $self->gcodegen->set_extruder($self->print->objects->[0]->config->support_material_extruder-1); $self->gcodegen->set_shift(@{$self->shift}); $gcode .= $self->gcodegen->extrude_loop($_, 'brim') for @{$self->print->brim}; $self->brim_done(1); @@ -113,13 +113,13 @@ sub process_layer { # and also because we avoid travelling on other things when printing it if ($layer->isa('Slic3r::Layer::Support')) { if ($layer->support_interface_fills->count > 0) { - $gcode .= $self->gcodegen->set_extruder($self->extruders->[$object->config->support_material_interface_extruder-1]); + $gcode .= $self->gcodegen->set_extruder($object->config->support_material_interface_extruder-1); my %params = (speed => $object->config->support_material_speed*60); $gcode .= $self->gcodegen->extrude_path($_, 'support material interface', %params) for @{$layer->support_interface_fills->chained_path_from($self->gcodegen->last_pos, 0)}; } if ($layer->support_fills->count > 0) { - $gcode .= $self->gcodegen->set_extruder($self->extruders->[$object->config->support_material_extruder-1]); + $gcode .= $self->gcodegen->set_extruder($object->config->support_material_extruder-1); my %params = (speed => $object->config->support_material_speed*60); $gcode .= $self->gcodegen->extrude_path($_, 'support material', %params) for @{$layer->support_fills->chained_path_from($self->gcodegen->last_pos, 0)}; @@ -205,7 +205,7 @@ sub _extrude_perimeters { return "" if !@{ $island->{perimeters} }; my $gcode = ""; - $gcode .= $self->gcodegen->set_extruder($self->extruders->[$region->config->perimeter_extruder-1]); + $gcode .= $self->gcodegen->set_extruder($region->config->perimeter_extruder-1); $gcode .= $self->gcodegen->extrude($_, 'perimeter') for @{ $island->{perimeters} }; return $gcode; } @@ -217,7 +217,7 @@ sub _extrude_infill { return "" if !@{ $island->{fills} }; my $gcode = ""; - $gcode .= $self->gcodegen->set_extruder($self->extruders->[$region->config->infill_extruder-1]); + $gcode .= $self->gcodegen->set_extruder($region->config->infill_extruder-1); for my $fill (@{ $island->{fills} }) { if ($fill->isa('Slic3r::ExtrusionPath::Collection')) { $gcode .= $self->gcodegen->extrude($_, 'fill') diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index ce22d9c8..53b3834d 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -125,6 +125,7 @@ sub make_perimeters { my $self = shift; my $perimeter_flow = $self->flow(FLOW_ROLE_PERIMETER); + my $mm3_per_mm = $perimeter_flow->mm3_per_mm($self->height); my $pwidth = $perimeter_flow->scaled_width; my $pspacing = $perimeter_flow->scaled_spacing; my $ispacing = $self->flow(FLOW_ROLE_SOLID_INFILL)->scaled_spacing; @@ -264,7 +265,7 @@ sub make_perimeters { push @loops, Slic3r::ExtrusionLoop->new( polygon => $polygon, role => $role, - flow_spacing => $perimeter_flow->spacing, + mm3_per_mm => $mm3_per_mm, ); } return @loops; @@ -290,8 +291,8 @@ sub make_perimeters { for my $p (@p) { next if $p->length <= $pspacing * 2; my %params = ( - role => EXTR_ROLE_EXTERNAL_PERIMETER, - flow_spacing => $perimeter_flow->spacing, + role => EXTR_ROLE_EXTERNAL_PERIMETER, + mm3_per_mm => $mm3_per_mm, ); push @paths, $p->isa('Slic3r::Polygon') ? Slic3r::ExtrusionLoop->new(polygon => $p, %params) @@ -339,8 +340,8 @@ sub _fill_gaps { # fill gaps using dynamic extrusion width, by treating them like thin polygons, # thus generating the skeleton and using it to fill them my %path_args = ( - role => EXTR_ROLE_SOLIDFILL, - flow_spacing => $flow->spacing, + role => EXTR_ROLE_SOLIDFILL, + mm3_per_mm => $flow->mm3_per_mm($self->height), ); $self->thin_fills->append(map { $_->isa('Slic3r::Polygon') @@ -360,9 +361,10 @@ sub _fill_gaps { foreach my $expolygon (@infill) { my ($params, @paths) = $filler->fill_surface( Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNALSOLID), - density => 1, - flow_spacing => $flow->spacing, + density => 1, + flow => $flow, ); + my $mm3_per_mm = $params->{flow}->mm3_per_mm($self->height); # Split polylines into lines so that the chained_path() search # at the final stage has more freedom and will choose starting @@ -379,8 +381,7 @@ sub _fill_gaps { @paths = map Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(@$_), role => EXTR_ROLE_GAPFILL, - height => $self->height, - flow_spacing => $params->{flow_spacing}, + mm3_per_mm => $mm3_per_mm, ), @lines; $_->simplify($flow->scaled_width/3) for @paths; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index f7283954..ebaba5ce 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -305,26 +305,6 @@ sub extruders { sub init_extruders { my $self = shift; - # initialize all extruder(s) we need - for my $extruder_id (@{$self->extruders}) { - # make sure print config contains a value for all extruders - my %extruder_config = (); - foreach my $opt_key (@{&Slic3r::Extruder::OPTIONS}) { - my $value = $self->config->get($opt_key); - if (!defined $value->[$extruder_id]) { - $value->[$extruder_id] = $value->[0]; - $self->config->set($opt_key, $value); - } - $extruder_config{$opt_key} = $value->[$extruder_id]; - } - - $self->extruders->[$extruder_id] = Slic3r::Extruder->new( - id => $extruder_id, - use_relative_e_distances => $self->config->use_relative_e_distances, - %extruder_config, - ); - } - # enforce tall skirt if using ooze_prevention # FIXME: this is not idempotent (i.e. switching ooze_prevention off will not revert skirt settings) if ($self->config->ooze_prevention && @{$self->extruders} > 1) { @@ -671,7 +651,7 @@ sub make_skirt { # but loops must be aligned so can't vary width/spacing # TODO: use each extruder's own flow my $first_layer_height = $self->objects->[0]->config->get_value('first_layer_height'); - my $flow = Slic3r::Flow->new( + my $flow = Slic3r::Flow->new_from_width( width => ($self->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width), role => FLOW_ROLE_PERIMETER, nozzle_diameter => $self->config->nozzle_diameter->[0], @@ -679,6 +659,7 @@ sub make_skirt { bridge_flow_ratio => 0, ); my $spacing = $flow->spacing; + my $mm3_per_mm = $flow->mm3_per_mm($first_layer_height); my @extruders_e_per_mm = (); my $extruder_idx = 0; @@ -692,13 +673,16 @@ sub make_skirt { $self->skirt->append(Slic3r::ExtrusionLoop->new( polygon => Slic3r::Polygon->new(@$loop), role => EXTR_ROLE_SKIRT, - flow_spacing => $spacing, + mm3_per_mm => $mm3_per_mm, )); if ($self->config->min_skirt_length > 0) { - $extruded_length[$extruder_idx] ||= 0; - $extruders_e_per_mm[$extruder_idx] ||= $self->extruders->[$extruder_idx]->e_per_mm($spacing, $first_layer_height); - $extruded_length[$extruder_idx] += unscale $loop->length * $extruders_e_per_mm[$extruder_idx]; + $extruded_length[$extruder_idx] ||= 0; + if (!$extruders_e_per_mm[$extruder_idx]) { + my $extruder = Slic3r::Extruder->new_from_config($self->config, $extruder_idx); + $extruders_e_per_mm[$extruder_idx] = $extruder->e_per_mm($mm3_per_mm); + } + $extruded_length[$extruder_idx] += unscale $loop->length * $extruders_e_per_mm[$extruder_idx]; $i++ if defined first { ($extruded_length[$_] // 0) < $self->config->min_skirt_length } 0 .. $#{$self->extruders}; if ($extruded_length[$extruder_idx] >= $self->config->min_skirt_length) { if ($extruder_idx < $#{$self->extruders}) { @@ -719,13 +703,15 @@ sub make_brim { $self->brim->clear; # method must be idempotent # brim is only printed on first layer and uses support material extruder - my $flow = Slic3r::Flow->new( + my $first_layer_height = $self->objects->[0]->config->get_abs_value('first_layer_height'); + my $flow = Slic3r::Flow->new_from_width( width => ($self->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width), role => FLOW_ROLE_PERIMETER, nozzle_diameter => $self->config->nozzle_diameter->[ $self->objects->[0]->config->support_material_extruder-1 ], - layer_height => $self->objects->[0]->config->get_abs_value('first_layer_height'), + layer_height => $first_layer_height, bridge_flow_ratio => 0, ); + my $mm3_per_mm = $flow->mm3_per_mm($first_layer_height); my $grow_distance = $flow->scaled_width / 2; my @islands = (); # array of polygons @@ -768,7 +754,7 @@ sub make_brim { $self->brim->append(map Slic3r::ExtrusionLoop->new( polygon => Slic3r::Polygon->new(@$_), role => EXTR_ROLE_SKIRT, - flow_spacing => $flow->spacing, + mm3_per_mm => $mm3_per_mm, ), reverse @{union_pt_chained(\@loops)}); } @@ -816,9 +802,11 @@ sub write_gcode { my $gcodegen = Slic3r::GCode->new( print_config => $self->config, extra_variables => $self->extra_variables, - extruders => $self->extruders, # we should only pass the *used* extruders (but maintain the Tx indices right!) layer_count => $self->layer_count, ); + $gcodegen->set_extruders($self->extruders); + $gcodegen->set_extruder($self->extruders->[0]); + print $fh "G21 ; set units to millimeters\n" if $self->config->gcode_flavor ne 'makerware'; print $fh $gcodegen->set_fan(0, 1) if $self->config->cooling && $self->config->disable_fan_first_layers; @@ -833,7 +821,7 @@ sub write_gcode { return if $self->config->start_gcode =~ /M(?:109|104)/i; for my $t (0 .. $#{$self->extruders}) { - my $temp = $self->extruders->[$t]->first_layer_temperature; + my $temp = $self->config->first_layer_temperature->[$t] // $self->config->first_layer_temperature->[0]; $temp += $self->config->standby_temperature_delta if $self->config->ooze_prevention; printf $fh $gcodegen->set_temperature($temp, $wait, $t) if $temp > 0; } diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index fd07d73e..2d9e9b53 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -863,7 +863,7 @@ sub generate_support_material { return unless ($self->config->support_material || $self->config->raft_layers > 0) && $self->layer_count >= 2; - my $first_layer_flow = Slic3r::Flow->new( + my $first_layer_flow = Slic3r::Flow->new_from_width( width => ($self->config->first_layer_extrusion_width || $self->config->support_material_extrusion_width), role => FLOW_ROLE_SUPPORT_MATERIAL, nozzle_diameter => $self->print->config->nozzle_diameter->[ $self->config->support_material_extruder-1 ], @@ -900,7 +900,7 @@ sub support_material_flow { # we use a bogus layer_height because we use the same flow for all # support material layers - return Slic3r::Flow->new( + return Slic3r::Flow->new_from_width( width => $self->config->support_material_extrusion_width, role => $role, nozzle_diameter => $self->print->config->nozzle_diameter->[$extruder-1], diff --git a/lib/Slic3r/Print/Region.pm b/lib/Slic3r/Print/Region.pm index c587f515..47296847 100644 --- a/lib/Slic3r/Print/Region.pm +++ b/lib/Slic3r/Print/Region.pm @@ -48,7 +48,7 @@ sub flow { } my $nozzle_diameter = $self->print->config->nozzle_diameter->[$extruder-1]; - return Slic3r::Flow->new( + return Slic3r::Flow->new_from_width( width => $config_width, role => $role, nozzle_diameter => $nozzle_diameter, diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index b6d793ee..a88728e6 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -500,10 +500,11 @@ sub generate_toolpaths { ); # transform loops into ExtrusionPath objects + my $mm3_per_mm = $interface_flow->mm3_per_mm($layer->height); @loops = map Slic3r::ExtrusionPath->new( - polyline => $_, - role => EXTR_ROLE_SUPPORTMATERIAL, - flow_spacing => $interface_flow->spacing, + polyline => $_, + role => EXTR_ROLE_SUPPORTMATERIAL, + mm3_per_mm => $mm3_per_mm, ), @loops; $layer->support_interface_fills->append(@loops); @@ -536,16 +537,16 @@ sub generate_toolpaths { foreach my $expolygon (@{union_ex($interface)}) { my ($params, @p) = $fillers{interface}->fill_surface( Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL), - density => $interface_density, - flow_spacing => $interface_flow->spacing, - complete => 1, + density => $interface_density, + flow => $interface_flow, + complete => 1, ); + my $mm3_per_mm = $params->{flow}->mm3_per_mm($layer->height); push @paths, map Slic3r::ExtrusionPath->new( - polyline => Slic3r::Polyline->new(@$_), - role => EXTR_ROLE_SUPPORTMATERIAL, - height => undef, - flow_spacing => $params->{flow_spacing}, + polyline => Slic3r::Polyline->new(@$_), + role => EXTR_ROLE_SUPPORTMATERIAL, + mm3_per_mm => $mm3_per_mm, ), @p; } @@ -556,8 +557,8 @@ sub generate_toolpaths { if (@$base) { my $filler = $fillers{support}; $filler->angle($angles[ ($layer_id) % @angles ]); - my $density = $support_density; - my $flow_spacing = $flow->spacing; + my $density = $support_density; + my $base_flow = $flow; # TODO: use offset2_ex() my $to_infill = union_ex($base, 1); @@ -568,15 +569,15 @@ sub generate_toolpaths { $filler = $fillers{interface}; $filler->angle($self->object_config->support_material_angle + 90); $density = 0.5; - $flow_spacing = $self->first_layer_flow->spacing; + $base_flow = $self->first_layer_flow; } else { # draw a perimeter all around support infill # TODO: use brim ordering algorithm + my $mm3_per_mm = $flow->mm3_per_mm($layer->height); push @paths, map Slic3r::ExtrusionPath->new( - polyline => $_->split_at_first_point, - role => EXTR_ROLE_SUPPORTMATERIAL, - height => undef, - flow_spacing => $flow->spacing, + polyline => $_->split_at_first_point, + role => EXTR_ROLE_SUPPORTMATERIAL, + mm3_per_mm => $mm3_per_mm, ), map @$_, @$to_infill; # TODO: use offset2_ex() @@ -586,16 +587,16 @@ sub generate_toolpaths { foreach my $expolygon (@$to_infill) { my ($params, @p) = $filler->fill_surface( Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL), - density => $density, - flow_spacing => $flow_spacing, - complete => 1, + density => $density, + flow => $base_flow, + complete => 1, ); + my $mm3_per_mm = $params->{flow}->mm3_per_mm($layer->height); push @paths, map Slic3r::ExtrusionPath->new( - polyline => Slic3r::Polyline->new(@$_), - role => EXTR_ROLE_SUPPORTMATERIAL, - height => undef, - flow_spacing => $params->{flow_spacing}, + polyline => Slic3r::Polyline->new(@$_), + role => EXTR_ROLE_SUPPORTMATERIAL, + mm3_per_mm => $mm3_per_mm, ), @p; } diff --git a/t/arcs.t b/t/arcs.t index 92f83964..2eac2acf 100644 --- a/t/arcs.t +++ b/t/arcs.t @@ -21,7 +21,7 @@ use Slic3r::Geometry qw(scaled_epsilon scale X Y); [306517.1,219034.23], [286979.42,248012.49], [258001.16,267550.17], [222515.14,274714.47], [187029.11,267550.17], [158050.85,248012.49], [138513.17,219034.23], [131348.87,183548.2], [86948.77,175149.09], [119825.35,100585], - ), role => EXTR_ROLE_FILL, flow_spacing => 0.5); + ), role => EXTR_ROLE_FILL, mm3_per_mm => 0.5); my @paths = $path->detect_arcs(30); @@ -42,12 +42,12 @@ use Slic3r::Geometry qw(scaled_epsilon scale X Y); my $path1 = Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(@points), role => EXTR_ROLE_FILL, - flow_spacing => 0.5, + mm3_per_mm => 0.5, ); my $path2 = Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(reverse @points), role => EXTR_ROLE_FILL, - flow_spacing => 0.5, + mm3_per_mm => 0.5, ); my @paths1 = $path1->detect_arcs(10, scale 1); diff --git a/t/fill.t b/t/fill.t index 2be4b87c..424b206d 100644 --- a/t/fill.t +++ b/t/fill.t @@ -134,7 +134,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } { my $collection = Slic3r::ExtrusionPath::Collection->new( - map Slic3r::ExtrusionPath->new(polyline => $_, role => 0), + map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1), Slic3r::Polyline->new([0,15], [0,18], [0,20]), Slic3r::Polyline->new([0,10], [0,8], [0,5]), ); @@ -146,7 +146,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } { my $collection = Slic3r::ExtrusionPath::Collection->new( - map Slic3r::ExtrusionPath->new(polyline => $_, role => 0), + map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1), Slic3r::Polyline->new([15,0], [10,0], [4,0]), Slic3r::Polyline->new([10,5], [15,5], [20,5]), ); diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index 9f761ba9..9e0e678d 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -97,8 +97,7 @@ sub new { return $class->_new( $args{polygon}, # required $args{role}, # required - $args{height} // -1, - $args{flow_spacing} // -1, + $args{mm3_per_mm} // -1, ); } @@ -108,8 +107,7 @@ sub clone { return (ref $self)->_new( $args{polygon} // $self->polygon, $args{role} // $self->role, - $args{height} // $self->height, - $args{flow_spacing} // $self->flow_spacing, + $args{mm3_per_mm} // $self->mm3_per_mm, ); } @@ -129,8 +127,7 @@ sub new { return $class->_new( $args{polyline}, # required $args{role}, # required - $args{height} // -1, - $args{flow_spacing} // -1, + $args{mm3_per_mm} // -1, ); } @@ -140,8 +137,7 @@ sub clone { return (ref $self)->_new( $args{polyline} // $self->polyline, $args{role} // $self->role, - $args{height} // $self->height, - $args{flow_spacing} // $self->flow_spacing, + $args{mm3_per_mm} // $self->mm3_per_mm, ); } diff --git a/xs/src/ExtrusionEntity.cpp b/xs/src/ExtrusionEntity.cpp index 9c5cd5d3..c6641a71 100644 --- a/xs/src/ExtrusionEntity.cpp +++ b/xs/src/ExtrusionEntity.cpp @@ -116,8 +116,7 @@ ExtrusionLoop::split_at_index(int index) const ExtrusionPath* path = new ExtrusionPath(); path->polyline = *poly; path->role = this->role; - path->height = this->height; - path->flow_spacing = this->flow_spacing; + path->mm3_per_mm = this->mm3_per_mm; delete poly; return path; diff --git a/xs/src/ExtrusionEntity.hpp b/xs/src/ExtrusionEntity.hpp index c763ad77..381fd1fd 100644 --- a/xs/src/ExtrusionEntity.hpp +++ b/xs/src/ExtrusionEntity.hpp @@ -31,8 +31,7 @@ class ExtrusionEntity virtual ExtrusionEntity* clone() const = 0; virtual ~ExtrusionEntity() {}; ExtrusionRole role; - double height; // vertical thickness of the extrusion expressed in mm - double flow_spacing; + double mm3_per_mm; // mm^3 of plastic per mm of linear head motion virtual void reverse() = 0; virtual Point* first_point() const = 0; virtual Point* last_point() const = 0; diff --git a/xs/src/PrintConfig.hpp b/xs/src/PrintConfig.hpp index 05380ab1..c5adff7c 100644 --- a/xs/src/PrintConfig.hpp +++ b/xs/src/PrintConfig.hpp @@ -241,6 +241,7 @@ class PrintConfigDef Options["fill_pattern"].tooltip = "Fill pattern for general low-density infill."; Options["fill_pattern"].cli = "fill-pattern=s"; Options["fill_pattern"].scope = "object"; + Options["fill_pattern"].enum_keys_map = ConfigOptionEnum::get_enum_values(); Options["fill_pattern"].enum_values.push_back("rectilinear"); Options["fill_pattern"].enum_values.push_back("line"); Options["fill_pattern"].enum_values.push_back("concentric"); @@ -320,6 +321,7 @@ class PrintConfigDef Options["gcode_flavor"].label = "G-code flavor"; Options["gcode_flavor"].tooltip = "Some G/M-code commands, including temperature control and others, are not universal. Set this option to your printer's firmware to get a compatible output. The \"No extrusion\" flavor prevents Slic3r from exporting any extrusion value at all."; Options["gcode_flavor"].cli = "gcode-flavor=s"; + Options["gcode_flavor"].enum_keys_map = ConfigOptionEnum::get_enum_values(); Options["gcode_flavor"].enum_values.push_back("reprap"); Options["gcode_flavor"].enum_values.push_back("teacup"); Options["gcode_flavor"].enum_values.push_back("makerware"); @@ -613,6 +615,7 @@ class PrintConfigDef Options["solid_fill_pattern"].tooltip = "Fill pattern for top/bottom infill."; Options["solid_fill_pattern"].cli = "solid-fill-pattern=s"; Options["solid_fill_pattern"].scope = "object"; + Options["solid_fill_pattern"].enum_keys_map = ConfigOptionEnum::get_enum_values(); Options["solid_fill_pattern"].enum_values.push_back("rectilinear"); Options["solid_fill_pattern"].enum_values.push_back("concentric"); Options["solid_fill_pattern"].enum_values.push_back("hilbertcurve"); diff --git a/xs/t/07_extrusionpath.t b/xs/t/07_extrusionpath.t index 78e084cc..1c2ed3f2 100644 --- a/xs/t/07_extrusionpath.t +++ b/xs/t/07_extrusionpath.t @@ -15,6 +15,7 @@ my $points = [ my $path = Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(@$points), role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, + mm3_per_mm => 1, ); isa_ok $path->polyline, 'Slic3r::Polyline::Ref', 'path polyline'; is_deeply $path->polyline->pp, $points, 'path points roundtrip'; diff --git a/xs/t/08_extrusionloop.t b/xs/t/08_extrusionloop.t index bd729361..54ef72ca 100644 --- a/xs/t/08_extrusionloop.t +++ b/xs/t/08_extrusionloop.t @@ -16,6 +16,7 @@ my $square = [ my $loop = Slic3r::ExtrusionLoop->new( polygon => Slic3r::Polygon->new(@$square), role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, + mm3_per_mm => 1, ); isa_ok $loop->polygon, 'Slic3r::Polygon::Ref', 'loop polygon'; is_deeply $loop->polygon->pp, $square, 'polygon points roundtrip'; diff --git a/xs/t/12_extrusionpathcollection.t b/xs/t/12_extrusionpathcollection.t index e28c04b6..4d5b9c58 100644 --- a/xs/t/12_extrusionpathcollection.t +++ b/xs/t/12_extrusionpathcollection.t @@ -15,11 +15,13 @@ my $points = [ my $path = Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(@$points), role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, + mm3_per_mm => 1, ); my $loop = Slic3r::ExtrusionLoop->new( polygon => Slic3r::Polygon->new(@$points), role => Slic3r::ExtrusionPath::EXTR_ROLE_FILL, + mm3_per_mm => 1, ); my $collection = Slic3r::ExtrusionPath::Collection->new($path); @@ -49,7 +51,7 @@ is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated'; { my $collection = Slic3r::ExtrusionPath::Collection->new( - map Slic3r::ExtrusionPath->new(polyline => $_, role => 0), + map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1), Slic3r::Polyline->new([0,15], [0,18], [0,20]), Slic3r::Polyline->new([0,10], [0,8], [0,5]), ); @@ -65,7 +67,7 @@ is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated'; { my $collection = Slic3r::ExtrusionPath::Collection->new( - map Slic3r::ExtrusionPath->new(polyline => $_, role => 0), + map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1), Slic3r::Polyline->new([15,0], [10,0], [4,0]), Slic3r::Polyline->new([10,5], [15,5], [20,5]), ); diff --git a/xs/t/15_config.t b/xs/t/15_config.t index 4e8f6e68..0d208060 100644 --- a/xs/t/15_config.t +++ b/xs/t/15_config.t @@ -4,7 +4,7 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 79; +use Test::More tests => 82; foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { $config->set('layer_height', 0.3); @@ -49,6 +49,9 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { $config->set_deserialize('gcode_flavor', 'mach3'); is $config->get('gcode_flavor'), 'mach3', 'deserialize enum'; + $config->set_deserialize('fill_pattern', 'line'); + is $config->get('fill_pattern'), 'line', 'deserialize enum'; + $config->set('extruder_offset', [[10,20],[30,45]]); is_deeply $config->get('extruder_offset'), [[10,20],[30,45]], 'set/get points'; is $config->serialize('extruder_offset'), '10x20,30x45', 'serialize points'; @@ -106,4 +109,14 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { is $config2->get('perimeters'), Slic3r::Config::print_config_def()->{perimeters}{default}, 'apply_static and print_config_def'; } +{ + my $config = Slic3r::Config->new; + $config->set('fill_pattern', 'line'); + + my $config2 = Slic3r::Config->new; + $config2->set('fill_pattern', 'hilbertcurve'); + + is $config->get('fill_pattern'), 'line', 'no interferences between DynamicConfig objects'; +} + __END__ diff --git a/xs/xsp/Config.xsp b/xs/xsp/Config.xsp index 18deda29..743b38ca 100644 --- a/xs/xsp/Config.xsp +++ b/xs/xsp/Config.xsp @@ -19,7 +19,7 @@ double get_abs_value(t_config_option_key opt_key, double ratio_over); void apply(DynamicPrintConfig* other) %code{% THIS->apply(*other, true); %}; - void apply_static(PrintConfig* other) + void apply_static(FullPrintConfig* other) %code{% THIS->apply(*other, true); %}; std::vector get_keys() %code{% THIS->keys(&RETVAL); %}; diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp index 9bef01d4..fbf4dfca 100644 --- a/xs/xsp/ExtrusionLoop.xsp +++ b/xs/xsp/ExtrusionLoop.xsp @@ -28,18 +28,16 @@ %{ ExtrusionLoop* -_new(CLASS, polygon_sv, role, height, flow_spacing) +_new(CLASS, polygon_sv, role, mm3_per_mm) char* CLASS; SV* polygon_sv; ExtrusionRole role; - double height; - double flow_spacing; + double mm3_per_mm; CODE: RETVAL = new ExtrusionLoop (); RETVAL->polygon.from_SV_check(polygon_sv); RETVAL->role = role; - RETVAL->height = height; - RETVAL->flow_spacing = flow_spacing; + RETVAL->mm3_per_mm = mm3_per_mm; OUTPUT: RETVAL @@ -66,22 +64,12 @@ ExtrusionLoop::role(...) RETVAL double -ExtrusionLoop::height(...) +ExtrusionLoop::mm3_per_mm(...) CODE: if (items > 1) { - THIS->height = (double)SvNV(ST(1)); + THIS->mm3_per_mm = (double)SvNV(ST(1)); } - RETVAL = THIS->height; - OUTPUT: - RETVAL - -double -ExtrusionLoop::flow_spacing(...) - CODE: - if (items > 1) { - THIS->flow_spacing = (double)SvNV(ST(1)); - } - RETVAL = THIS->flow_spacing; + RETVAL = THIS->mm3_per_mm; OUTPUT: RETVAL diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index b4248214..9d0abd70 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -33,18 +33,16 @@ %{ ExtrusionPath* -_new(CLASS, polyline_sv, role, height, flow_spacing) +_new(CLASS, polyline_sv, role, mm3_per_mm) char* CLASS; SV* polyline_sv; ExtrusionRole role; - double height; - double flow_spacing; + double mm3_per_mm; CODE: RETVAL = new ExtrusionPath (); RETVAL->polyline.from_SV_check(polyline_sv); RETVAL->role = role; - RETVAL->height = height; - RETVAL->flow_spacing = flow_spacing; + RETVAL->mm3_per_mm = mm3_per_mm; OUTPUT: RETVAL @@ -71,22 +69,12 @@ ExtrusionPath::role(...) RETVAL double -ExtrusionPath::height(...) +ExtrusionPath::mm3_per_mm(...) CODE: if (items > 1) { - THIS->height = (double)SvNV(ST(1)); + THIS->mm3_per_mm = (double)SvNV(ST(1)); } - RETVAL = THIS->height; - OUTPUT: - RETVAL - -double -ExtrusionPath::flow_spacing(...) - CODE: - if (items > 1) { - THIS->flow_spacing = (double)SvNV(ST(1)); - } - RETVAL = THIS->flow_spacing; + RETVAL = THIS->mm3_per_mm; OUTPUT: RETVAL