diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 6c34572f6..4eb3c1ad3 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -340,32 +340,14 @@ sub extrude_path { # extrude arc or line $gcode .= ";_BRIDGE_FAN_START\n" if $path->is_bridge; - my $path_length = 0; + my $path_length = unscale $path->length; { - my $local_F = $F; - foreach my $line (@{$path->lines}) { - $path_length += my $line_length = unscale $line->length; - - # calculate extrusion length for this line - my $E = 0; - $E = $self->extruder->extrude($e * $line_length) if $e; - - # compose G-code line - my $point = $line->b; - $gcode .= sprintf "G1 X%.3f Y%.3f", - ($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]; #** - $gcode .= sprintf(" %s%.5f", $self->_extrusion_axis, $E) - if $E; - $gcode .= " F$local_F" - if $local_F; - $gcode .= " ; $description" - if $self->print_config->gcode_comments; - $gcode .= "\n"; - - # only include F in the first line - $local_F = 0; - } + $gcode .= $path->gcode($self->extruder, $e, $F, + $self->shift_x - $self->extruder->extruder_offset->[X], + $self->shift_y - $self->extruder->extruder_offset->[Y], + $self->_extrusion_axis, + $self->print_config->gcode_comments ? " ; $description" : ""); + if ($self->enable_wipe) { $self->wipe_path($path->polyline->clone); $self->wipe_path->reverse; diff --git a/xs/src/ExtrusionEntity.cpp b/xs/src/ExtrusionEntity.cpp index bc491736a..7e63a6215 100644 --- a/xs/src/ExtrusionEntity.cpp +++ b/xs/src/ExtrusionEntity.cpp @@ -1,3 +1,4 @@ +#include #include "ExtrusionEntity.hpp" #include "ExtrusionEntityCollection.hpp" #include "ExPolygonCollection.hpp" @@ -100,6 +101,67 @@ ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCo } } +#ifdef SLIC3RXS +std::string +ExtrusionPath::gcode(SV* extruder, double e, double F, + double xofs, double yofs, std::string extrusion_axis, + std::string gcode_line_suffix) const +{ + dSP; + + std::stringstream stream; + stream.setf(std::ios::fixed); + + double local_F = F; + + Lines lines = this->polyline.lines(); + for (Lines::const_iterator line_it = lines.begin(); + line_it != lines.end(); ++line_it) + { + 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; + } + + // compose G-code line + + Point point = line_it->b; + const double x = point.x * SCALING_FACTOR + xofs; + const double y = point.y * SCALING_FACTOR + yofs; + stream.precision(3); + stream << "G1 X" << x << " Y" << y; + + if (E != 0) { + stream.precision(5); + stream << " " << extrusion_axis << E; + } + + if (local_F != 0) { + stream.precision(3); + stream << " F" << local_F; + local_F = 0; + } + + stream << gcode_line_suffix; + stream << "\n"; + } + + return stream.str(); +} +#endif + ExtrusionLoop* ExtrusionLoop::clone() const { diff --git a/xs/src/ExtrusionEntity.hpp b/xs/src/ExtrusionEntity.hpp index 2c01da503..f5c7a19ce 100644 --- a/xs/src/ExtrusionEntity.hpp +++ b/xs/src/ExtrusionEntity.hpp @@ -55,6 +55,13 @@ class ExtrusionPath : public ExtrusionEntity void clip_end(double distance); void simplify(double tolerance); double length() const; + + #ifdef SLIC3RXS + std::string gcode(SV* extruder, double e, double F, + double xofs, double yofs, std::string extrusion_axis, + std::string gcode_line_suffix) const; + #endif + private: void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const; }; diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index ba5f5a157..36b5fdae8 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -27,6 +27,9 @@ bool is_perimeter(); bool is_fill(); bool is_bridge(); + std::string gcode(SV* extruder, double e, double F, + double xofs, double yofs, std::string extrusion_axis, + std::string gcode_line_suffix); %{ ExtrusionPath*