From 0ad4296aaffef41d14f074a1c2689fca9a43e565 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 2 Jul 2015 19:33:08 +0200 Subject: [PATCH] Ported GCode::set_extruders() and GCode::change_layer() to XS --- lib/Slic3r/GCode.pm | 45 -------------------------------- xs/src/libslic3r/GCode.cpp | 53 +++++++++++++++++++++++++++++++++++++- xs/src/libslic3r/GCode.hpp | 4 ++- xs/src/perlglue.hpp | 1 + xs/xsp/GCode.xsp | 3 +++ 5 files changed, 59 insertions(+), 47 deletions(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 2b50f8f9c..9e344fbd6 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -8,51 +8,6 @@ use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(epsilon scale unscale PI X Y B); use Slic3r::Geometry::Clipper qw(union_ex); -sub set_extruders { - my ($self, $extruder_ids) = @_; - - $self->writer->set_extruders($extruder_ids); - - # enable wipe path generation if any extruder has wipe enabled - $self->wipe->set_enable(defined first { $self->config->get_at('wipe', $_) } @$extruder_ids); -} - -sub change_layer { - my ($self, $layer) = @_; - - { - my $l = $layer->isa('Slic3r::Layer::Support') - ? $layer->as_layer - : $layer; - $self->set_layer($l); - } - $self->set_layer_index($self->layer_index + 1); - $self->set_first_layer($layer->id == 0); - - # avoid computing islands and overhangs if they're not needed - if ($self->config->avoid_crossing_perimeters) { - $self->avoid_crossing_perimeters->init_layer_mp( - union_ex([ map @$_, @{$layer->slices} ], 1), - ); - } - - my $gcode = ""; - if ($self->layer_count > 0) { - $gcode .= $self->writer->update_progress($self->layer_index, $self->layer_count); - } - - my $z = $layer->print_z + $self->config->z_offset; # in unscaled coordinates - if ($self->config->get_at('retract_layer_change', $self->writer->extruder->id) && $self->writer->will_move_z($z)) { - $gcode .= $self->retract; - } - $gcode .= $self->writer->travel_to_z($z, 'move to next layer (' . $self->layer_index . ')'); - - # forget last wiping path as wiping after raising Z is pointless - $self->wipe->reset_path; - - return $gcode; -} - sub extrude { my $self = shift; diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 60145a6ab..f153b96f7 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -240,6 +240,22 @@ GCode::apply_print_config(const PrintConfig &print_config) this->config.apply(print_config); } +void +GCode::set_extruders(const std::vector &extruder_ids) +{ + this->writer.set_extruders(extruder_ids); + + // enable wipe path generation if any extruder has wipe enabled + this->wipe.enable = false; + for (std::vector::const_iterator it = extruder_ids.begin(); + it != extruder_ids.end(); ++it) { + if (this->config.wipe.get_at(*it)) { + this->wipe.enable = true; + break; + } + } +} + void GCode::set_origin(const Pointf &pointf) { @@ -268,6 +284,41 @@ GCode::preamble() return gcode; } +std::string +GCode::change_layer(const Layer &layer) +{ + this->layer = &layer; + this->layer_index++; + this->first_layer = (layer.id() == 0); + + // avoid computing islands and overhangs if they're not needed + if (this->config.avoid_crossing_perimeters) { + ExPolygons islands; + union_(layer.slices, &islands, true); + this->avoid_crossing_perimeters.init_layer_mp(islands); + } + + std::string gcode; + if (this->layer_count > 0) { + gcode += this->writer.update_progress(this->layer_index, this->layer_count); + } + + coordf_t z = layer.print_z + this->config.z_offset.value; // in unscaled coordinates + if (EXTRUDER_CONFIG(retract_layer_change) && this->writer.will_move_z(z)) { + gcode += this->retract(); + } + { + std::ostringstream comment; + comment << "move to next layer (" << this->layer_index << ")"; + gcode += this->writer.travel_to_z(z, comment.str()); + } + + // forget last wiping path as wiping after raising Z is pointless + this->wipe.reset_path(); + + return gcode; +} + std::string GCode::extrude_path(const ExtrusionPath &path, std::string description, double speed) { @@ -438,7 +489,7 @@ GCode::needs_retraction(const Polyline &travel, ExtrusionRole role) } if (role == erSupportMaterial) { - SupportLayer* support_layer = dynamic_cast(this->layer); + const SupportLayer* support_layer = dynamic_cast(this->layer); if (support_layer != NULL && support_layer->support_islands.contains(travel)) { // skip retraction if this is a travel move inside a support material island return false; diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index 0af91b661..de391e491 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -79,7 +79,7 @@ class GCode { bool enable_cooling_markers; size_t layer_count; int layer_index; // just a counter - Layer* layer; + const Layer* layer; std::map _seam_position; bool first_layer; // this flag triggers first layer speeds unsigned int elapsed_time; // seconds @@ -90,8 +90,10 @@ class GCode { void set_last_pos(const Point &pos); bool last_pos_defined() const; void apply_print_config(const PrintConfig &print_config); + void set_extruders(const std::vector &extruder_ids); void set_origin(const Pointf &pointf); std::string preamble(); + std::string change_layer(const Layer &layer); std::string extrude_path(const ExtrusionPath &path, std::string description = "", double speed = -1); std::string _extrude_path(ExtrusionPath path, std::string description = "", double speed = -1); std::string travel_to(const Point &point, ExtrusionRole role, std::string comment); diff --git a/xs/src/perlglue.hpp b/xs/src/perlglue.hpp index 84c9a7ae9..b10cbcf11 100644 --- a/xs/src/perlglue.hpp +++ b/xs/src/perlglue.hpp @@ -44,6 +44,7 @@ class Ref { public: Ref() : val(NULL) {} Ref(T* t) : val(t) {} + Ref(const T* t) : val(const_cast(t)) {} operator T*() const { return val; } static const char* CLASS() { return ClassTraits::name_ref; } }; diff --git a/xs/xsp/GCode.xsp b/xs/xsp/GCode.xsp index 1aa1dfdad..63cccfc22 100644 --- a/xs/xsp/GCode.xsp +++ b/xs/xsp/GCode.xsp @@ -154,9 +154,12 @@ void apply_print_config(PrintConfig* print_config) %code{% THIS->apply_print_config(*print_config); %}; + void set_extruders(std::vector extruder_ids); void set_origin(Pointf* pointf) %code{% THIS->set_origin(*pointf); %}; std::string preamble(); + std::string change_layer(Layer* layer) + %code{% RETVAL = THIS->change_layer(*layer); %}; std::string extrude_path(ExtrusionPath* path, std::string description = "", double speed = -1) %code{% RETVAL = THIS->extrude_path(*path, description, speed); %}; std::string _extrude_path(ExtrusionPath* path, std::string description = "", double speed = -1)