From 66d23a2416bfd9460b207e1ef8bf1dc2c8889b34 Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Tue, 8 Apr 2014 02:42:29 +0300 Subject: [PATCH 01/10] Convert Extruder object (mostly) to C++ with lots of fields. --- lib/Slic3r.pm | 1 + lib/Slic3r/Extruder.pm | 36 +++--------------- lib/Slic3r/GCode.pm | 10 ++--- xs/lib/Slic3r/XS.pm | 16 ++++++++ xs/src/Extruder.cpp | 63 +++++++++++++++++++++++++++++++ xs/src/Extruder.hpp | 59 +++++++++++++++++++++++++++++ xs/xsp/Extruder.xsp | 84 ++++++++++++++++++++++++++++++++++++++++++ xs/xsp/my.map | 2 + xs/xsp/typemap.xspt | 1 + 9 files changed, 237 insertions(+), 35 deletions(-) create mode 100644 xs/src/Extruder.cpp create mode 100644 xs/src/Extruder.hpp create mode 100644 xs/xsp/Extruder.xsp diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 39fa85ab1..999e450bb 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -140,6 +140,7 @@ sub thread_cleanup { *Slic3r::Config::PrintRegion::DESTROY = sub {}; *Slic3r::ExPolygon::DESTROY = sub {}; *Slic3r::ExPolygon::Collection::DESTROY = sub {}; + *Slic3r::Extruder::DESTROY = sub {}; *Slic3r::ExtrusionLoop::DESTROY = sub {}; *Slic3r::ExtrusionPath::DESTROY = sub {}; *Slic3r::ExtrusionPath::Collection::DESTROY = sub {}; diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index e2334c65e..cfe608c26 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -1,5 +1,6 @@ package Slic3r::Extruder; -use Moo; +use strict; +use warnings; require Exporter; our @ISA = qw(Exporter); @@ -16,16 +17,8 @@ use constant OPTIONS => [qw( retract_layer_change retract_length_toolchange retract_restart_extra_toolchange wipe )]; -has 'id' => (is => 'rw', required => 1); -has $_ => (is => 'ro', required => 1) for @{&OPTIONS}; -has 'use_relative_e_distances' => (is => 'ro', default => sub {0}); - -has 'E' => (is => 'rw', default => sub {0} ); -has 'absolute_E' => (is => 'rw', default => sub {0} ); -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 'e_per_mm3' => (is => 'lazy'); +# has 'retract_speed_mm_min' => (is => 'lazy'); use constant EXTRUDER_ROLE_PERIMETER => 1; use constant EXTRUDER_ROLE_INFILL => 2; @@ -45,25 +38,16 @@ sub new_from_config { return $class->new(%conf); } -sub _build_e_per_mm3 { +sub e_per_mm3 { my $self = shift; return $self->extrusion_multiplier * (4 / (($self->filament_diameter ** 2) * PI)); } -sub _build_retract_speed_mm_min { +sub retract_speed_mm_min { my $self = shift; 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) = @_; @@ -74,14 +58,6 @@ sub scaled_wipe_distance { return scale($self->retract_length / $self->retract_speed * $travel_speed * 0.8); } -sub extrude { - my ($self, $E) = @_; - - $self->E(0) if $self->use_relative_e_distances; - $self->absolute_E($self->absolute_E + $E); - return $self->E($self->E + $E); -} - sub extruded_volume { my ($self, $E) = @_; return $E * ($self->filament_diameter**2) * PI/4; diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 564266dc0..aef280fc1 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -508,8 +508,8 @@ sub retract { $gcode .= $self->G1(@$lift); } } - $self->extruder->retracted($self->extruder->retracted + $length); - $self->extruder->restart_extra($restart_extra); + $self->extruder->set_retracted($self->extruder->retracted + $length); + $self->extruder->set_restart_extra($restart_extra); $self->lifted($self->_retract_lift) if $lift; # reset extrusion distance during retracts @@ -547,8 +547,8 @@ sub unretract { $gcode .= " ; compensate retraction" if $self->print_config->gcode_comments; $gcode .= "\n"; } - $self->extruder->retracted(0); - $self->extruder->restart_extra(0); + $self->extruder->set_retracted(0); + $self->extruder->set_restart_extra(0); } return $gcode; @@ -558,7 +558,7 @@ sub reset_e { my ($self) = @_; return "" if $self->print_config->gcode_flavor =~ /^(?:mach3|makerware|sailfish)$/; - $self->extruder->E(0) if $self->extruder; + $self->extruder->set_E(0) if $self->extruder; return sprintf "G92 %s0%s\n", $self->_extrusion_axis, ($self->print_config->gcode_comments ? ' ; reset extrusion distance' : '') if $self->_extrusion_axis && !$self->print_config->use_relative_e_distances; } diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index 6188a8bef..18add2e82 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -221,4 +221,20 @@ use overload '@{}' => sub { $_[0]->arrayref }, 'fallback' => 1; +package Slic3r::Extruder; + +sub new { + my ($class, %args) = @_; + + $args{extruder_offset} = Slic3r::Point->new($args{extruder_offset}); + + return $class->_new(@args{qw( + id use_relative_e_distances + extruder_offset + nozzle_diameter filament_diameter extrusion_multiplier temperature + first_layer_temperature retract_length retract_lift retract_speed + retract_restart_extra retract_before_travel retract_layer_change + retract_length_toolchange retract_restart_extra_toolchange wipe)}); +} + 1; diff --git a/xs/src/Extruder.cpp b/xs/src/Extruder.cpp new file mode 100644 index 000000000..501de98b0 --- /dev/null +++ b/xs/src/Extruder.cpp @@ -0,0 +1,63 @@ +#include "Extruder.hpp" + +namespace Slic3r { + +Extruder::Extruder(int id, bool use_relative_e_distances, + const Point *extruder_offset, + double nozzle_diameter, + double filament_diameter, + double extrusion_multiplier, + int temperature, + int first_layer_temperature, + double retract_length, + double retract_lift, + int retract_speed, + double retract_restart_extra, + double retract_before_travel, + bool retract_layer_change, + double retract_length_toolchange, + double retract_restart_extra_toolchange, + double wipe) +: id(id), + use_relative_e_distances(use_relative_e_distances), + extruder_offset(*extruder_offset), + nozzle_diameter(nozzle_diameter), + filament_diameter(filament_diameter), + extrusion_multiplier(extrusion_multiplier), + temperature(temperature), + first_layer_temperature(first_layer_temperature), + retract_length(retract_length), + retract_lift(retract_lift), + retract_speed(retract_speed), + retract_restart_extra(retract_restart_extra), + retract_before_travel(retract_before_travel), + retract_layer_change(retract_layer_change), + retract_length_toolchange(retract_length_toolchange), + retract_restart_extra_toolchange(retract_restart_extra_toolchange), + wipe(wipe) +{ + reset(); +} + +void +Extruder::reset() +{ + this->E = 0; + this->absolute_E = 0; + this->retracted = 0; + this->restart_extra = 0; +} + +double +Extruder::extrude(double dE) +{ + if (use_relative_e_distances) { + this->E = 0; + } + + this->E += dE; + this->absolute_E += dE; + return this->E; +} + +} diff --git a/xs/src/Extruder.hpp b/xs/src/Extruder.hpp new file mode 100644 index 000000000..db7f159b5 --- /dev/null +++ b/xs/src/Extruder.hpp @@ -0,0 +1,59 @@ +#ifndef slic3r_Extruder_hpp_ +#define slic3r_Extruder_hpp_ + +#include +#include "Point.hpp" + +namespace Slic3r { + +class Extruder +{ + public: + Extruder(int id, bool use_relative_e_distances, + const Point *extruder_offset, + double nozzle_diameter, + double filament_diameter, + double extrusion_multiplier, + int temperature, + int first_layer_temperature, + double retract_length, + double retract_lift, + int retract_speed, + double retract_restart_extra, + double retract_before_travel, + bool retract_layer_change, + double retract_length_toolchange, + double retract_restart_extra_toolchange, + double wipe); + virtual ~Extruder() {} + void reset(); + double extrude(double dE); + + int id; + bool use_relative_e_distances; + double E; + double absolute_E; + double retracted; + double restart_extra; + + // options: + Point extruder_offset; + double nozzle_diameter; + double filament_diameter; + double extrusion_multiplier; + int temperature; + int first_layer_temperature; + double retract_length; + double retract_lift; + int retract_speed; + double retract_restart_extra; + double retract_before_travel; + bool retract_layer_change; + double retract_length_toolchange; + double retract_restart_extra_toolchange; + double wipe; +}; + +} + +#endif diff --git a/xs/xsp/Extruder.xsp b/xs/xsp/Extruder.xsp new file mode 100644 index 000000000..84b3a754c --- /dev/null +++ b/xs/xsp/Extruder.xsp @@ -0,0 +1,84 @@ +%module{Slic3r::XS}; + +%{ +#include +#include "Extruder.hpp" +%} + +%name{Slic3r::Extruder} class Extruder { + %name{_new} Extruder(int id, bool use_relative_e_distances, + Point *extruder_offset, + double nozzle_diameter, + double filament_diameter, + double extrusion_multiplier, + int temperature, + int first_layer_temperature, + double retract_length, + double retract_lift, + int retract_speed, + double retract_restart_extra, + double retract_before_travel, + bool retract_layer_change, + double retract_length_toolchange, + double retract_restart_extra_toolchange, + double wipe); + + ~Extruder(); + void reset(); + double extrude(double dE); + + int id() const + %code%{ RETVAL = THIS->id; %}; + + double E() const + %code%{ RETVAL = THIS->E; %}; + double set_E(double val) const + %code%{ RETVAL = THIS->E = val; %}; + double absolute_E() const + %code%{ RETVAL = THIS->absolute_E; %}; + double set_absolute_E(double val) const + %code%{ RETVAL = THIS->absolute_E = val; %}; + double retracted() const + %code%{ RETVAL = THIS->retracted; %}; + double set_retracted(double val) const + %code%{ RETVAL = THIS->retracted = val; %}; + double restart_extra() const + %code%{ RETVAL = THIS->restart_extra; %}; + double set_restart_extra(double val) const + %code%{ RETVAL = THIS->restart_extra = val; %}; + + Point *extruder_offset() const + %code%{ + const char *CLASS = "Slic3r::Point"; + RETVAL = new Point(THIS->extruder_offset); + %}; + + double nozzle_diameter() const + %code%{ RETVAL = THIS->nozzle_diameter; %}; + double filament_diameter() const + %code%{ RETVAL = THIS->filament_diameter; %}; + double extrusion_multiplier() const + %code%{ RETVAL = THIS->extrusion_multiplier; %}; + int temperature() const + %code%{ RETVAL = THIS->temperature; %}; + int first_layer_temperature() const + %code%{ RETVAL = THIS->first_layer_temperature; %}; + double retract_length() const + %code%{ RETVAL = THIS->retract_length; %}; + double retract_lift() const + %code%{ RETVAL = THIS->retract_lift; %}; + int retract_speed() const + %code%{ RETVAL = THIS->retract_speed; %}; + double retract_restart_extra() const + %code%{ RETVAL = THIS->retract_restart_extra; %}; + double retract_before_travel() const + %code%{ RETVAL = THIS->retract_before_travel; %}; + bool retract_layer_change() const + %code%{ RETVAL = THIS->retract_layer_change; %}; + double retract_length_toolchange() const + %code%{ RETVAL = THIS->retract_length_toolchange; %}; + double retract_restart_extra_toolchange() const + %code%{ RETVAL = THIS->retract_restart_extra_toolchange; %}; + double wipe() const + %code%{ RETVAL = THIS->wipe; %}; +}; diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 306158396..1bd3b4205 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -77,6 +77,8 @@ Clone O_OBJECT_SLIC3R_T SurfaceCollection* O_OBJECT_SLIC3R +Extruder* O_OBJECT_SLIC3R + ExtrusionRole T_UV FlowRole T_UV PrintStep T_UV diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index 2c3667096..b666cdcff 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -70,6 +70,7 @@ %typemap{Surfaces}; %typemap{Polygons*}; %typemap{TriangleMeshPtrs}; +%typemap{Extruder*}; %typemap{SurfaceType}{parsed}{ %cpp_type{SurfaceType}; From 04fad70cbf64e1fa7c1c02669b4349270bd09ade Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Tue, 8 Apr 2014 02:43:02 +0300 Subject: [PATCH 02/10] Make C++ gcode generator use C++ Extruder object directly. --- xs/src/ExtrusionEntity.cpp | 17 +++-------------- xs/src/ExtrusionEntity.hpp | 3 ++- xs/xsp/ExtrusionPath.xsp | 2 +- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/xs/src/ExtrusionEntity.cpp b/xs/src/ExtrusionEntity.cpp index 3865df877..0e023577e 100644 --- a/xs/src/ExtrusionEntity.cpp +++ b/xs/src/ExtrusionEntity.cpp @@ -2,6 +2,7 @@ #include "ExtrusionEntityCollection.hpp" #include "ExPolygonCollection.hpp" #include "ClipperUtils.hpp" +#include "Extruder.hpp" #include #ifdef SLIC3RXS #include "perlglue.hpp" @@ -109,7 +110,7 @@ ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCo REGISTER_CLASS(ExtrusionPath, "ExtrusionPath"); std::string -ExtrusionPath::gcode(SV* extruder, double e, double F, +ExtrusionPath::gcode(Extruder* extruder, double e, double F, double xofs, double yofs, std::string extrusion_axis, std::string gcode_line_suffix) const { @@ -127,19 +128,7 @@ ExtrusionPath::gcode(SV* extruder, double e, double F, const double line_length = line_it->length() * SCALING_FACTOR; // calculate extrusion length for this line - double E = 0; - if (e != 0) { - PUSHMARK(SP); - XPUSHs(extruder); - XPUSHs(sv_2mortal(newSVnv(e * line_length))); - PUTBACK; - - const int count = call_method("extrude", G_SCALAR); - SPAGAIN; - - // TODO: check that count is 1 - E = POPn; - } + double E = (e == 0) ? 0 : extruder->extrude(e * line_length); // compose G-code line diff --git a/xs/src/ExtrusionEntity.hpp b/xs/src/ExtrusionEntity.hpp index cab5be7d9..0e3c71ea7 100644 --- a/xs/src/ExtrusionEntity.hpp +++ b/xs/src/ExtrusionEntity.hpp @@ -9,6 +9,7 @@ namespace Slic3r { class ExPolygonCollection; class ExtrusionEntityCollection; +class Extruder; enum ExtrusionRole { erPerimeter, @@ -57,7 +58,7 @@ class ExtrusionPath : public ExtrusionEntity double length() const; #ifdef SLIC3RXS - std::string gcode(SV* extruder, double e, double F, + std::string gcode(Extruder* extruder, double e, double F, double xofs, double yofs, std::string extrusion_axis, std::string gcode_line_suffix) const; #endif diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index 5c013b182..2926f2eda 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -25,7 +25,7 @@ bool is_perimeter(); bool is_fill(); bool is_bridge(); - std::string gcode(SV* extruder, double e, double F, + std::string gcode(Extruder* extruder, double e, double F, double xofs, double yofs, std::string extrusion_axis, std::string gcode_line_suffix); %{ From 717d099ae1634ae92819793861b61b337f36c30d Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Tue, 8 Apr 2014 02:47:38 +0300 Subject: [PATCH 03/10] Add XS Extruder files to manifest. --- xs/MANIFEST | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xs/MANIFEST b/xs/MANIFEST index 0ad4cd8c1..0381ee4e6 100644 --- a/xs/MANIFEST +++ b/xs/MANIFEST @@ -1660,6 +1660,8 @@ src/ExPolygon.cpp src/ExPolygon.hpp src/ExPolygonCollection.cpp src/ExPolygonCollection.hpp +src/Extruder.cpp +src/Extruder.hpp src/ExtrusionEntity.cpp src/ExtrusionEntity.hpp src/ExtrusionEntityCollection.cpp @@ -1721,6 +1723,7 @@ xsp/Clipper.xsp xsp/Config.xsp xsp/ExPolygon.xsp xsp/ExPolygonCollection.xsp +xsp/Extruder.xsp xsp/ExtrusionEntityCollection.xsp xsp/ExtrusionLoop.xsp xsp/ExtrusionPath.xsp From b319dc9361727efba91df01318ae3064e9a397c8 Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Tue, 8 Apr 2014 03:36:39 +0300 Subject: [PATCH 04/10] Correctly convert extruder_offset to Point object before passing to C++ code. --- xs/lib/Slic3r/XS.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index 18add2e82..4ad9bb29f 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -226,7 +226,7 @@ package Slic3r::Extruder; sub new { my ($class, %args) = @_; - $args{extruder_offset} = Slic3r::Point->new($args{extruder_offset}); + $args{extruder_offset} = Slic3r::Point->new(@{$args{extruder_offset}}); return $class->_new(@args{qw( id use_relative_e_distances From 2565d8067978caaf6341af145bbcd0f7a305cec3 Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Sun, 27 Apr 2014 00:28:32 +0300 Subject: [PATCH 05/10] Replace multitude of Extruder fields with querying a PrintConfig object by id. --- lib/Slic3r/Extruder.pm | 20 ++++++++-------- lib/Slic3r/GCode.pm | 2 +- lib/Slic3r/Print.pm | 2 +- xs/lib/Slic3r/XS.pm | 17 +++----------- xs/src/Extruder.cpp | 45 ++++++++++------------------------- xs/src/Extruder.hpp | 39 +++++-------------------------- xs/xsp/Extruder.xsp | 53 ++++-------------------------------------- 7 files changed, 38 insertions(+), 140 deletions(-) diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index cfe608c26..d05143ed6 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -25,19 +25,19 @@ 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}) { - $conf{$opt_key} = $config->get_at($opt_key, $extruder_id); + +# generate accessors +{ + no strict 'refs'; + for my $opt_key (@{&Slic3r::Extruder::OPTIONS}) { + *{$opt_key} = sub { + my $self = shift; + $self->config->get_at($opt_key, $self->id); + }; } - return $class->new(%conf); } + sub e_per_mm3 { my $self = shift; return $self->extrusion_multiplier * (4 / (($self->filament_diameter ** 2) * PI)); diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index aef280fc1..a4471c470 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -53,7 +53,7 @@ sub set_extruders { my ($self, $extruder_ids) = @_; foreach my $i (@$extruder_ids) { - $self->extruders->{$i} = my $e = Slic3r::Extruder->new_from_config($self->print_config, $i); + $self->extruders->{$i} = my $e = Slic3r::Extruder->new($i, $self->print_config); $self->enable_wipe(1) if $e->wipe; } diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 34216271b..18678e391 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -714,7 +714,7 @@ sub make_skirt { if ($self->config->min_skirt_length > 0) { $extruded_length[$extruder_idx] ||= 0; if (!$extruders_e_per_mm[$extruder_idx]) { - my $extruder = Slic3r::Extruder->new_from_config($self->config, $extruder_idx); + my $extruder = Slic3r::Extruder->new($extruder_idx, $self->config); $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]; diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index 4ad9bb29f..2c6a985b7 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -221,20 +221,9 @@ use overload '@{}' => sub { $_[0]->arrayref }, 'fallback' => 1; -package Slic3r::Extruder; +package Slic3r::Config::Print::Ref; +our @ISA = 'Slic3r::Config::Print'; -sub new { - my ($class, %args) = @_; - - $args{extruder_offset} = Slic3r::Point->new(@{$args{extruder_offset}}); - - return $class->_new(@args{qw( - id use_relative_e_distances - extruder_offset - nozzle_diameter filament_diameter extrusion_multiplier temperature - first_layer_temperature retract_length retract_lift retract_speed - retract_restart_extra retract_before_travel retract_layer_change - retract_length_toolchange retract_restart_extra_toolchange wipe)}); -} +sub DESTROY {} 1; diff --git a/xs/src/Extruder.cpp b/xs/src/Extruder.cpp index 501de98b0..8194f7149 100644 --- a/xs/src/Extruder.cpp +++ b/xs/src/Extruder.cpp @@ -2,39 +2,9 @@ namespace Slic3r { -Extruder::Extruder(int id, bool use_relative_e_distances, - const Point *extruder_offset, - double nozzle_diameter, - double filament_diameter, - double extrusion_multiplier, - int temperature, - int first_layer_temperature, - double retract_length, - double retract_lift, - int retract_speed, - double retract_restart_extra, - double retract_before_travel, - bool retract_layer_change, - double retract_length_toolchange, - double retract_restart_extra_toolchange, - double wipe) +Extruder::Extruder(int id, PrintConfig *config) : id(id), - use_relative_e_distances(use_relative_e_distances), - extruder_offset(*extruder_offset), - nozzle_diameter(nozzle_diameter), - filament_diameter(filament_diameter), - extrusion_multiplier(extrusion_multiplier), - temperature(temperature), - first_layer_temperature(first_layer_temperature), - retract_length(retract_length), - retract_lift(retract_lift), - retract_speed(retract_speed), - retract_restart_extra(retract_restart_extra), - retract_before_travel(retract_before_travel), - retract_layer_change(retract_layer_change), - retract_length_toolchange(retract_length_toolchange), - retract_restart_extra_toolchange(retract_restart_extra_toolchange), - wipe(wipe) + config(*config) // make a copy { reset(); } @@ -51,7 +21,7 @@ Extruder::reset() double Extruder::extrude(double dE) { - if (use_relative_e_distances) { + if (this->use_relative_e_distances()) { this->E = 0; } @@ -60,4 +30,13 @@ Extruder::extrude(double dE) return this->E; } +bool +Extruder::use_relative_e_distances() const +{ + // TODO: figure out way to avoid static_cast to access hidden const method + const ConfigOption *opt = static_cast(&this->config) + ->option("use_relative_e_distances"); + return *static_cast(opt); +} + } diff --git a/xs/src/Extruder.hpp b/xs/src/Extruder.hpp index db7f159b5..8fd70ee53 100644 --- a/xs/src/Extruder.hpp +++ b/xs/src/Extruder.hpp @@ -3,55 +3,28 @@ #include #include "Point.hpp" +#include "PrintConfig.hpp" namespace Slic3r { class Extruder { public: - Extruder(int id, bool use_relative_e_distances, - const Point *extruder_offset, - double nozzle_diameter, - double filament_diameter, - double extrusion_multiplier, - int temperature, - int first_layer_temperature, - double retract_length, - double retract_lift, - int retract_speed, - double retract_restart_extra, - double retract_before_travel, - bool retract_layer_change, - double retract_length_toolchange, - double retract_restart_extra_toolchange, - double wipe); + Extruder(int id, PrintConfig *config); virtual ~Extruder() {} void reset(); double extrude(double dE); + bool use_relative_e_distances() const; + int id; - bool use_relative_e_distances; double E; double absolute_E; double retracted; double restart_extra; - // options: - Point extruder_offset; - double nozzle_diameter; - double filament_diameter; - double extrusion_multiplier; - int temperature; - int first_layer_temperature; - double retract_length; - double retract_lift; - int retract_speed; - double retract_restart_extra; - double retract_before_travel; - bool retract_layer_change; - double retract_length_toolchange; - double retract_restart_extra_toolchange; - double wipe; + // TODO: maybe better to keep a reference to an existing object than copy it + PrintConfig config; }; } diff --git a/xs/xsp/Extruder.xsp b/xs/xsp/Extruder.xsp index 84b3a754c..ad19daf11 100644 --- a/xs/xsp/Extruder.xsp +++ b/xs/xsp/Extruder.xsp @@ -6,22 +6,7 @@ %} %name{Slic3r::Extruder} class Extruder { - %name{_new} Extruder(int id, bool use_relative_e_distances, - Point *extruder_offset, - double nozzle_diameter, - double filament_diameter, - double extrusion_multiplier, - int temperature, - int first_layer_temperature, - double retract_length, - double retract_lift, - int retract_speed, - double retract_restart_extra, - double retract_before_travel, - bool retract_layer_change, - double retract_length_toolchange, - double retract_restart_extra_toolchange, - double wipe); + Extruder(int id, PrintConfig *config); ~Extruder(); void reset(); @@ -30,6 +15,7 @@ int id() const %code%{ RETVAL = THIS->id; %}; + double E() const %code%{ RETVAL = THIS->E; %}; double set_E(double val) const @@ -47,38 +33,9 @@ double set_restart_extra(double val) const %code%{ RETVAL = THIS->restart_extra = val; %}; - Point *extruder_offset() const + PrintConfig *config() %code%{ - const char *CLASS = "Slic3r::Point"; - RETVAL = new Point(THIS->extruder_offset); + const char *CLASS = "Slic3r::Config::Print::Ref"; + RETVAL = &THIS->config; %}; - - double nozzle_diameter() const - %code%{ RETVAL = THIS->nozzle_diameter; %}; - double filament_diameter() const - %code%{ RETVAL = THIS->filament_diameter; %}; - double extrusion_multiplier() const - %code%{ RETVAL = THIS->extrusion_multiplier; %}; - int temperature() const - %code%{ RETVAL = THIS->temperature; %}; - int first_layer_temperature() const - %code%{ RETVAL = THIS->first_layer_temperature; %}; - double retract_length() const - %code%{ RETVAL = THIS->retract_length; %}; - double retract_lift() const - %code%{ RETVAL = THIS->retract_lift; %}; - int retract_speed() const - %code%{ RETVAL = THIS->retract_speed; %}; - double retract_restart_extra() const - %code%{ RETVAL = THIS->retract_restart_extra; %}; - double retract_before_travel() const - %code%{ RETVAL = THIS->retract_before_travel; %}; - bool retract_layer_change() const - %code%{ RETVAL = THIS->retract_layer_change; %}; - double retract_length_toolchange() const - %code%{ RETVAL = THIS->retract_length_toolchange; %}; - double retract_restart_extra_toolchange() const - %code%{ RETVAL = THIS->retract_restart_extra_toolchange; %}; - double wipe() const - %code%{ RETVAL = THIS->wipe; %}; }; From c2b249d059e6351f60a91cc67b7413ef82e18122 Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Sun, 27 Apr 2014 23:44:10 +0300 Subject: [PATCH 06/10] Add REGISTER_CLASS call for Extruder class. --- xs/src/Extruder.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xs/src/Extruder.cpp b/xs/src/Extruder.cpp index 8194f7149..3dce80ea7 100644 --- a/xs/src/Extruder.cpp +++ b/xs/src/Extruder.cpp @@ -1,4 +1,7 @@ #include "Extruder.hpp" +#ifdef SLIC3RXS +#include "perlglue.hpp" +#endif namespace Slic3r { @@ -39,4 +42,8 @@ Extruder::use_relative_e_distances() const return *static_cast(opt); } +#ifdef SLIC3RXS +REGISTER_CLASS(Extruder, "Extruder"); +#endif + } From d824de61683f76087c27bee00616fc6bb1225d26 Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Mon, 28 Apr 2014 00:03:22 +0300 Subject: [PATCH 07/10] Keep pointer to PrintConfig instead of copying it. --- xs/src/Extruder.cpp | 4 ++-- xs/src/Extruder.hpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/xs/src/Extruder.cpp b/xs/src/Extruder.cpp index 3dce80ea7..2f5a82469 100644 --- a/xs/src/Extruder.cpp +++ b/xs/src/Extruder.cpp @@ -7,7 +7,7 @@ namespace Slic3r { Extruder::Extruder(int id, PrintConfig *config) : id(id), - config(*config) // make a copy + config(config) { reset(); } @@ -37,7 +37,7 @@ bool Extruder::use_relative_e_distances() const { // TODO: figure out way to avoid static_cast to access hidden const method - const ConfigOption *opt = static_cast(&this->config) + const ConfigOption *opt = static_cast(this->config) ->option("use_relative_e_distances"); return *static_cast(opt); } diff --git a/xs/src/Extruder.hpp b/xs/src/Extruder.hpp index 8fd70ee53..1ab7fd16e 100644 --- a/xs/src/Extruder.hpp +++ b/xs/src/Extruder.hpp @@ -23,8 +23,7 @@ class Extruder double retracted; double restart_extra; - // TODO: maybe better to keep a reference to an existing object than copy it - PrintConfig config; + PrintConfig *config; }; } From 71b0b211ecb3f12905c6a413f827f82b16f1a733 Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Mon, 28 Apr 2014 00:19:03 +0300 Subject: [PATCH 08/10] Constify ConfigOptionVector::get_at. --- xs/src/Config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/Config.hpp b/xs/src/Config.hpp index 4d6446dc9..452f602d4 100644 --- a/xs/src/Config.hpp +++ b/xs/src/Config.hpp @@ -33,7 +33,7 @@ class ConfigOptionVector virtual ~ConfigOptionVector() {}; std::vector values; - T get_at(size_t i) { + T get_at(size_t i) const { try { return this->values.at(i); } catch (const std::out_of_range& oor) { From e005ff32c40f9f1b70e6351ae764507b9e4a1775 Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Mon, 28 Apr 2014 00:49:05 +0300 Subject: [PATCH 09/10] Replace Extruder::config accessor with Perl wrapper, with C++ option accessors. --- lib/Slic3r/Extruder.pm | 19 -------- xs/src/Extruder.cpp | 104 +++++++++++++++++++++++++++++++++++++++++ xs/src/Extruder.hpp | 23 +++++++++ xs/xsp/Extruder.xsp | 20 ++++++-- xs/xsp/my.map | 4 ++ xs/xsp/typemap.xspt | 3 ++ 6 files changed, 149 insertions(+), 24 deletions(-) diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index d05143ed6..51e7ad2a6 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -10,13 +10,6 @@ our %EXPORT_TAGS = (roles => \@EXPORT_OK); use Slic3r::Geometry qw(PI scale); -use constant OPTIONS => [qw( - extruder_offset - nozzle_diameter filament_diameter extrusion_multiplier temperature first_layer_temperature - retract_length retract_lift retract_speed retract_restart_extra retract_before_travel - retract_layer_change retract_length_toolchange retract_restart_extra_toolchange wipe -)]; - # has 'e_per_mm3' => (is => 'lazy'); # has 'retract_speed_mm_min' => (is => 'lazy'); @@ -26,18 +19,6 @@ use constant EXTRUDER_ROLE_SUPPORT_MATERIAL => 3; use constant EXTRUDER_ROLE_SUPPORT_MATERIAL_INTERFACE => 4; -# generate accessors -{ - no strict 'refs'; - for my $opt_key (@{&Slic3r::Extruder::OPTIONS}) { - *{$opt_key} = sub { - my $self = shift; - $self->config->get_at($opt_key, $self->id); - }; - } -} - - sub e_per_mm3 { my $self = shift; return $self->extrusion_multiplier * (4 / (($self->filament_diameter ** 2) * PI)); diff --git a/xs/src/Extruder.cpp b/xs/src/Extruder.cpp index 2f5a82469..c7a04941f 100644 --- a/xs/src/Extruder.cpp +++ b/xs/src/Extruder.cpp @@ -33,15 +33,119 @@ Extruder::extrude(double dE) return this->E; } +template Val +Extruder::get_config(const char *name) const +{ + // TODO: figure out way to avoid static_cast to access hidden const method + const ConfigOption *opt = static_cast(this->config) + ->option(name); + return dynamic_cast(opt)->get_at(this->id); +} + bool Extruder::use_relative_e_distances() const { + // not using get_config because use_relative_e_distances is global + // for all extruders + // TODO: figure out way to avoid static_cast to access hidden const method const ConfigOption *opt = static_cast(this->config) ->option("use_relative_e_distances"); return *static_cast(opt); } +Pointf +Extruder::extruder_offset() const +{ + return get_config("extruder_offset"); +} + +double +Extruder::nozzle_diameter() const +{ + return get_config("nozzle_diameter"); +} + +double +Extruder::filament_diameter() const +{ + return get_config("filament_diameter"); +} + +double +Extruder::extrusion_multiplier() const +{ + return get_config("extrusion_multiplier"); +} + +int +Extruder::temperature() const +{ + return get_config("temperature"); +} + +int +Extruder::first_layer_temperature() const +{ + return get_config("first_layer_temperature"); +} + +double +Extruder::retract_length() const +{ + return get_config("retract_length"); +} + +double +Extruder::retract_lift() const +{ + return get_config("retract_lift"); +} + +int +Extruder::retract_speed() const +{ + return get_config("retract_speed"); +} + +double +Extruder::retract_restart_extra() const +{ + return get_config("retract_restart_extra"); +} + +double +Extruder::retract_before_travel() const +{ + return get_config("retract_before_travel"); +} + +bool +Extruder::retract_layer_change() const +{ + return get_config("retract_layer_change"); +} + +double +Extruder::retract_length_toolchange() const +{ + return get_config("retract_length_toolchange"); +} + +double +Extruder::retract_restart_extra_toolchange() const +{ + return get_config( + "retract_restart_extra_toolchange"); +} + +bool +Extruder::wipe() const +{ + return get_config("wipe"); +} + + #ifdef SLIC3RXS REGISTER_CLASS(Extruder, "Extruder"); #endif diff --git a/xs/src/Extruder.hpp b/xs/src/Extruder.hpp index 1ab7fd16e..7302e42a3 100644 --- a/xs/src/Extruder.hpp +++ b/xs/src/Extruder.hpp @@ -15,7 +15,23 @@ class Extruder void reset(); double extrude(double dE); + bool use_relative_e_distances() const; + Pointf extruder_offset() const; + double nozzle_diameter() const; + double filament_diameter() const; + double extrusion_multiplier() const; + int temperature() const; + int first_layer_temperature() const; + double retract_length() const; + double retract_lift() const; + int retract_speed() const; + double retract_restart_extra() const; + double retract_before_travel() const; + bool retract_layer_change() const; + double retract_length_toolchange() const; + double retract_restart_extra_toolchange() const; + bool wipe() const; int id; double E; @@ -24,6 +40,13 @@ class Extruder double restart_extra; PrintConfig *config; + + + private: + + // get value from a ConfigOptionVector subtype, indexed by extruder id + template + Val get_config(const char *name) const; }; } diff --git a/xs/xsp/Extruder.xsp b/xs/xsp/Extruder.xsp index ad19daf11..47b5c0fa2 100644 --- a/xs/xsp/Extruder.xsp +++ b/xs/xsp/Extruder.xsp @@ -33,9 +33,19 @@ double set_restart_extra(double val) const %code%{ RETVAL = THIS->restart_extra = val; %}; - PrintConfig *config() - %code%{ - const char *CLASS = "Slic3r::Config::Print::Ref"; - RETVAL = &THIS->config; - %}; + Clone extruder_offset() const; + double nozzle_diameter() const; + double filament_diameter() const; + double extrusion_multiplier() const; + int temperature() const; + int first_layer_temperature() const; + double retract_length() const; + double retract_lift() const; + int retract_speed() const; + double retract_restart_extra() const; + double retract_before_travel() const; + bool retract_layer_change() const; + double retract_length_toolchange() const; + double retract_restart_extra_toolchange() const; + bool wipe() const; }; diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 1bd3b4205..27afe53bb 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -25,6 +25,10 @@ Point* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T Clone O_OBJECT_SLIC3R_T +Pointf* O_OBJECT_SLIC3R +Ref O_OBJECT_SLIC3R_T +Clone O_OBJECT_SLIC3R_T + Pointf3* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T Clone O_OBJECT_SLIC3R_T diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index b666cdcff..3aed02f7a 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -12,6 +12,9 @@ %typemap{Point*}; %typemap{Ref}{simple}; %typemap{Clone}{simple}; +%typemap{Pointf*}; +%typemap{Ref}{simple}; +%typemap{Clone}{simple}; %typemap{Pointf3*}; %typemap{Ref}{simple}; %typemap{Clone}{simple}; From ad03a88733ce0f5e687a22609df6cf9dd54b3a9b Mon Sep 17 00:00:00 2001 From: "Y. Sapir" Date: Mon, 28 Apr 2014 01:13:50 +0300 Subject: [PATCH 10/10] Add xsp wrapper for Pointf class. --- lib/Slic3r/GCode.pm | 2 +- xs/lib/Slic3r/XS.pm | 5 +++++ xs/xsp/Point.xsp | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index a4471c470..37eed4797 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -587,7 +587,7 @@ sub _G0_G1 { if ($point) { $gcode .= sprintf " X%.3f Y%.3f", - ($point->x * &Slic3r::SCALING_FACTOR) + $self->shift_x - $self->extruder->extruder_offset->[X], + ($point->x * &Slic3r::SCALING_FACTOR) + $self->shift_x - $self->extruder->extruder_offset->[X], ($point->y * &Slic3r::SCALING_FACTOR) + $self->shift_y - $self->extruder->extruder_offset->[Y]; #** $self->last_pos($point->clone); } diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index 2c6a985b7..d30f84299 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -28,6 +28,11 @@ our @ISA = 'Slic3r::Point'; sub DESTROY {} +package Slic3r::Pointf; +use overload + '@{}' => sub { [ $_[0]->x, $_[0]->y ] }, #, + 'fallback' => 1; + package Slic3r::Pointf3; use overload '@{}' => sub { [ $_[0]->x, $_[0]->y, $_[0]->z ] }, #, diff --git a/xs/xsp/Point.xsp b/xs/xsp/Point.xsp index f2c1a699f..952cd161f 100644 --- a/xs/xsp/Point.xsp +++ b/xs/xsp/Point.xsp @@ -56,6 +56,17 @@ Point::coincides_with(point_sv) }; +%name{Slic3r::Pointf} class Pointf { + Pointf(double _x = 0, double _y = 0); + ~Pointf(); + Clone clone() + %code{% RETVAL = THIS; %}; + double x() + %code{% RETVAL = THIS->x; %}; + double y() + %code{% RETVAL = THIS->y; %}; +}; + %name{Slic3r::Pointf3} class Pointf3 { Pointf3(double _x = 0, double _y = 0, double _z = 0); ~Pointf3();