Ported more Slic3r::GCode methods to XS
This commit is contained in:
parent
801f629fdc
commit
b4019bb438
@ -8,13 +8,6 @@ use Slic3r::ExtrusionPath ':roles';
|
|||||||
use Slic3r::Geometry qw(epsilon scale unscale PI X Y B);
|
use Slic3r::Geometry qw(epsilon scale unscale PI X Y B);
|
||||||
use Slic3r::Geometry::Clipper qw(union_ex);
|
use Slic3r::Geometry::Clipper qw(union_ex);
|
||||||
|
|
||||||
sub apply_print_config {
|
|
||||||
my ($self, $print_config) = @_;
|
|
||||||
|
|
||||||
$self->writer->apply_print_config($print_config);
|
|
||||||
$self->config->apply_print_config($print_config);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub set_extruders {
|
sub set_extruders {
|
||||||
my ($self, $extruder_ids) = @_;
|
my ($self, $extruder_ids) = @_;
|
||||||
|
|
||||||
@ -24,34 +17,6 @@ sub set_extruders {
|
|||||||
$self->wipe->set_enable(defined first { $self->config->get_at('wipe', $_) } @$extruder_ids);
|
$self->wipe->set_enable(defined first { $self->config->get_at('wipe', $_) } @$extruder_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub set_origin {
|
|
||||||
my ($self, $pointf) = @_;
|
|
||||||
|
|
||||||
# if origin increases (goes towards right), last_pos decreases because it goes towards left
|
|
||||||
my @translate = (
|
|
||||||
scale ($self->origin->x - $pointf->x),
|
|
||||||
scale ($self->origin->y - $pointf->y), #-
|
|
||||||
);
|
|
||||||
$self->last_pos->translate(@translate);
|
|
||||||
$self->wipe->path->translate(@translate) if $self->wipe->has_path;
|
|
||||||
|
|
||||||
$self->_set_origin($pointf);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub preamble {
|
|
||||||
my ($self) = @_;
|
|
||||||
|
|
||||||
my $gcode = $self->writer->preamble;
|
|
||||||
|
|
||||||
# Perform a *silent* move to z_offset: we need this to initialize the Z
|
|
||||||
# position of our writer object so that any initial lift taking place
|
|
||||||
# before the first layer change will raise the extruder from the correct
|
|
||||||
# initial Z instead of 0.
|
|
||||||
$self->writer->travel_to_z($self->config->z_offset, '');
|
|
||||||
|
|
||||||
return $gcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub change_layer {
|
sub change_layer {
|
||||||
my ($self, $layer) = @_;
|
my ($self, $layer) = @_;
|
||||||
|
|
||||||
@ -348,7 +313,7 @@ sub travel_to {
|
|||||||
if ($needs_retraction
|
if ($needs_retraction
|
||||||
&& $self->config->avoid_crossing_perimeters
|
&& $self->config->avoid_crossing_perimeters
|
||||||
&& !$self->avoid_crossing_perimeters->disable_once) {
|
&& !$self->avoid_crossing_perimeters->disable_once) {
|
||||||
$travel = $self->avoid_crossing_perimeters->travel_to($point, $self->origin, $self->last_pos);
|
$travel = $self->avoid_crossing_perimeters->travel_to($self, $point);
|
||||||
|
|
||||||
# check again whether the new travel path still needs a retraction
|
# check again whether the new travel path still needs a retraction
|
||||||
$needs_retraction = $self->needs_retraction($travel, $role);
|
$needs_retraction = $self->needs_retraction($travel, $role);
|
||||||
@ -404,51 +369,6 @@ sub needs_retraction {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub retract {
|
|
||||||
my ($self, $toolchange) = @_;
|
|
||||||
|
|
||||||
return "" if !defined $self->writer->extruder;
|
|
||||||
|
|
||||||
my $gcode = "";
|
|
||||||
|
|
||||||
# wipe (if it's enabled for this extruder and we have a stored wipe path)
|
|
||||||
if ($self->config->get_at('wipe', $self->writer->extruder->id) && $self->wipe->has_path) {
|
|
||||||
$gcode .= $self->wipe->wipe($self, $toolchange);
|
|
||||||
}
|
|
||||||
|
|
||||||
# The parent class will decide whether we need to perform an actual retraction
|
|
||||||
# (the extruder might be already retracted fully or partially). We call these
|
|
||||||
# methods even if we performed wipe, since this will ensure the entire retraction
|
|
||||||
# length is honored in case wipe path was too short.p
|
|
||||||
$gcode .= $toolchange ? $self->writer->retract_for_toolchange : $self->writer->retract;
|
|
||||||
|
|
||||||
$gcode .= $self->writer->reset_e;
|
|
||||||
$gcode .= $self->writer->lift
|
|
||||||
if $self->writer->extruder->retract_length > 0 || $self->config->use_firmware_retraction;
|
|
||||||
|
|
||||||
return $gcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub unretract {
|
|
||||||
my ($self) = @_;
|
|
||||||
|
|
||||||
my $gcode = "";
|
|
||||||
$gcode .= $self->writer->unlift;
|
|
||||||
$gcode .= $self->writer->unretract;
|
|
||||||
return $gcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
# convert a model-space scaled point into G-code coordinates
|
|
||||||
sub point_to_gcode {
|
|
||||||
my ($self, $point) = @_;
|
|
||||||
|
|
||||||
my $extruder_offset = $self->config->get_at('extruder_offset', $self->writer->extruder->id);
|
|
||||||
return Slic3r::Pointf->new(
|
|
||||||
($point->x * &Slic3r::SCALING_FACTOR) + $self->origin->x - $extruder_offset->x,
|
|
||||||
($point->y * &Slic3r::SCALING_FACTOR) + $self->origin->y - $extruder_offset->y, #**
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub set_extruder {
|
sub set_extruder {
|
||||||
my ($self, $extruder_id) = @_;
|
my ($self, $extruder_id) = @_;
|
||||||
|
|
||||||
@ -535,63 +455,4 @@ sub post_toolchange {
|
|||||||
return $gcode;
|
return $gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
package Slic3r::GCode::Wipe;
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
|
|
||||||
use Slic3r::Geometry qw(scale);
|
|
||||||
|
|
||||||
sub wipe {
|
|
||||||
my ($self, $gcodegen, $toolchange) = @_;
|
|
||||||
|
|
||||||
my $gcode = "";
|
|
||||||
|
|
||||||
# Reduce feedrate a bit; travel speed is often too high to move on existing material.
|
|
||||||
# Too fast = ripping of existing material; too slow = short wipe path, thus more blob.
|
|
||||||
my $wipe_speed = $gcodegen->writer->config->get('travel_speed') * 0.8;
|
|
||||||
|
|
||||||
# get the retraction length
|
|
||||||
my $length = $toolchange
|
|
||||||
? $gcodegen->writer->extruder->retract_length_toolchange
|
|
||||||
: $gcodegen->writer->extruder->retract_length;
|
|
||||||
|
|
||||||
if ($length) {
|
|
||||||
# Calculate how long we need to travel in order to consume the required
|
|
||||||
# amount of retraction. In other words, how far do we move in XY at $wipe_speed
|
|
||||||
# for the time needed to consume retract_length at retract_speed?
|
|
||||||
my $wipe_dist = scale($length / $gcodegen->writer->extruder->retract_speed * $wipe_speed);
|
|
||||||
|
|
||||||
# Take the stored wipe path and replace first point with the current actual position
|
|
||||||
# (they might be different, for example, in case of loop clipping).
|
|
||||||
my $wipe_path = Slic3r::Polyline->new(
|
|
||||||
$gcodegen->last_pos,
|
|
||||||
@{$self->path}[1..$#{$self->path}],
|
|
||||||
);
|
|
||||||
#
|
|
||||||
$wipe_path->clip_end($wipe_path->length - $wipe_dist);
|
|
||||||
|
|
||||||
# subdivide the retraction in segments
|
|
||||||
my $retracted = 0;
|
|
||||||
foreach my $line (@{$wipe_path->lines}) {
|
|
||||||
my $segment_length = $line->length;
|
|
||||||
# Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one
|
|
||||||
# due to rounding (TODO: test and/or better math for this)
|
|
||||||
my $dE = $length * ($segment_length / $wipe_dist) * 0.95;
|
|
||||||
$gcode .= $gcodegen->writer->set_speed($wipe_speed*60);
|
|
||||||
$gcode .= $gcodegen->writer->extrude_to_xy(
|
|
||||||
$gcodegen->point_to_gcode($line->b),
|
|
||||||
-$dE,
|
|
||||||
'wipe and retract' . ($gcodegen->enable_cooling_markers ? ';_WIPE' : ''),
|
|
||||||
);
|
|
||||||
$retracted += $dE;
|
|
||||||
}
|
|
||||||
$gcodegen->writer->extruder->set_retracted($gcodegen->writer->extruder->retracted + $retracted);
|
|
||||||
|
|
||||||
# prevent wiping again on same path
|
|
||||||
$self->reset_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $gcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -192,7 +192,7 @@ use Slic3r::Test;
|
|||||||
push @z_steps, $info->{dist_Z}
|
push @z_steps, $info->{dist_Z}
|
||||||
if $started_extruding && $info->{dist_Z} > 0;
|
if $started_extruding && $info->{dist_Z} > 0;
|
||||||
$travel_moves_after_first_extrusion++
|
$travel_moves_after_first_extrusion++
|
||||||
if $info->{travel} && $started_extruding && !exists $args->{Z};
|
if $info->{travel} && $info->{dist_XY} > 0 && $started_extruding && !exists $args->{Z};
|
||||||
} elsif ($cmd eq 'M104') {
|
} elsif ($cmd eq 'M104') {
|
||||||
$first_layer_temperature_set = 1 if $args->{S} == 205;
|
$first_layer_temperature_set = 1 if $args->{S} == 205;
|
||||||
$temperature_set = 1 if $args->{S} == 200;
|
$temperature_set = 1 if $args->{S} == 200;
|
||||||
@ -271,7 +271,7 @@ use Slic3r::Test;
|
|||||||
foreach my $segment (@this_layer) {
|
foreach my $segment (@this_layer) {
|
||||||
# check that segment's dist_Z is proportioned to its dist_XY
|
# check that segment's dist_Z is proportioned to its dist_XY
|
||||||
$all_layer_segments_have_same_slope = 1
|
$all_layer_segments_have_same_slope = 1
|
||||||
if abs($segment->[0]*$total_dist_XY/$config->layer_height - $segment->[1]) > 0.1;
|
if abs($segment->[0]*$total_dist_XY/$config->layer_height - $segment->[1]) > 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@this_layer = ();
|
@this_layer = ();
|
||||||
|
@ -1752,6 +1752,7 @@ t/17_boundingbox.t
|
|||||||
t/18_motionplanner.t
|
t/18_motionplanner.t
|
||||||
t/19_model.t
|
t/19_model.t
|
||||||
t/20_print.t
|
t/20_print.t
|
||||||
|
t/21_gcode.t
|
||||||
xsp/BoundingBox.xsp
|
xsp/BoundingBox.xsp
|
||||||
xsp/BridgeDetector.xsp
|
xsp/BridgeDetector.xsp
|
||||||
xsp/Clipper.xsp
|
xsp/Clipper.xsp
|
||||||
|
@ -36,16 +36,15 @@ AvoidCrossingPerimeters::init_layer_mp(const ExPolygons &islands)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Polyline
|
Polyline
|
||||||
AvoidCrossingPerimeters::travel_to(Point point, const Pointf &gcodegen_origin,
|
AvoidCrossingPerimeters::travel_to(GCode &gcodegen, Point point)
|
||||||
const Point &gcodegen_last_pos)
|
|
||||||
{
|
{
|
||||||
if (this->use_external_mp || this->use_external_mp_once) {
|
if (this->use_external_mp || this->use_external_mp_once) {
|
||||||
// get current origin set in gcodegen
|
// get current origin set in gcodegen
|
||||||
// (the one that will be used to translate the G-code coordinates by)
|
// (the one that will be used to translate the G-code coordinates by)
|
||||||
Point scaled_origin = Point::new_scale(gcodegen_origin.x, gcodegen_origin.y);
|
Point scaled_origin = Point::new_scale(gcodegen.origin.x, gcodegen.origin.y);
|
||||||
|
|
||||||
// represent last_pos in absolute G-code coordinates
|
// represent last_pos in absolute G-code coordinates
|
||||||
Point last_pos = gcodegen_last_pos;
|
Point last_pos = gcodegen.last_pos();
|
||||||
last_pos.translate(scaled_origin);
|
last_pos.translate(scaled_origin);
|
||||||
|
|
||||||
// represent point in absolute G-code coordinates
|
// represent point in absolute G-code coordinates
|
||||||
@ -59,7 +58,7 @@ AvoidCrossingPerimeters::travel_to(Point point, const Pointf &gcodegen_origin,
|
|||||||
travel.translate(scaled_origin.negative());
|
travel.translate(scaled_origin.negative());
|
||||||
return travel;
|
return travel;
|
||||||
} else {
|
} else {
|
||||||
return this->_layer_mp->shortest_path(gcodegen_last_pos, point);
|
return this->_layer_mp->shortest_path(gcodegen.last_pos(), point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +92,62 @@ Wipe::reset_path()
|
|||||||
this->path = Polyline();
|
this->path = Polyline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
Wipe::wipe(GCode &gcodegen, bool toolchange)
|
||||||
|
{
|
||||||
|
std::string gcode;
|
||||||
|
|
||||||
|
/* Reduce feedrate a bit; travel speed is often too high to move on existing material.
|
||||||
|
Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */
|
||||||
|
double wipe_speed = gcodegen.writer.config.travel_speed.value * 0.8;
|
||||||
|
|
||||||
|
// get the retraction length
|
||||||
|
double length = toolchange
|
||||||
|
? gcodegen.writer.extruder()->retract_length_toolchange()
|
||||||
|
: gcodegen.writer.extruder()->retract_length();
|
||||||
|
|
||||||
|
if (length > 0) {
|
||||||
|
/* Calculate how long we need to travel in order to consume the required
|
||||||
|
amount of retraction. In other words, how far do we move in XY at wipe_speed
|
||||||
|
for the time needed to consume retract_length at retract_speed? */
|
||||||
|
double wipe_dist = scale_(length / gcodegen.writer.extruder()->retract_speed() * wipe_speed);
|
||||||
|
|
||||||
|
/* Take the stored wipe path and replace first point with the current actual position
|
||||||
|
(they might be different, for example, in case of loop clipping). */
|
||||||
|
Polyline wipe_path;
|
||||||
|
wipe_path.append(gcodegen.last_pos());
|
||||||
|
wipe_path.append(
|
||||||
|
this->path.points.begin() + 1,
|
||||||
|
this->path.points.end()
|
||||||
|
);
|
||||||
|
|
||||||
|
wipe_path.clip_end(wipe_path.length() - wipe_dist);
|
||||||
|
|
||||||
|
// subdivide the retraction in segments
|
||||||
|
double retracted = 0;
|
||||||
|
Lines lines = wipe_path.lines();
|
||||||
|
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||||
|
double segment_length = line->length();
|
||||||
|
/* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one
|
||||||
|
due to rounding (TODO: test and/or better math for this) */
|
||||||
|
double dE = length * (segment_length / wipe_dist) * 0.95;
|
||||||
|
gcode += gcodegen.writer.set_speed(wipe_speed*60);
|
||||||
|
gcode += gcodegen.writer.extrude_to_xy(
|
||||||
|
gcodegen.point_to_gcode(line->b),
|
||||||
|
-dE,
|
||||||
|
(std::string)"wipe and retract" + (gcodegen.enable_cooling_markers ? ";_WIPE" : "")
|
||||||
|
);
|
||||||
|
retracted += dE;
|
||||||
|
}
|
||||||
|
gcodegen.writer.extruder()->retracted += retracted;
|
||||||
|
|
||||||
|
// prevent wiping again on same path
|
||||||
|
this->reset_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
return gcode;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
REGISTER_CLASS(Wipe, "GCode::Wipe");
|
REGISTER_CLASS(Wipe, "GCode::Wipe");
|
||||||
#endif
|
#endif
|
||||||
@ -100,10 +155,110 @@ REGISTER_CLASS(Wipe, "GCode::Wipe");
|
|||||||
GCode::GCode()
|
GCode::GCode()
|
||||||
: enable_loop_clipping(true), enable_cooling_markers(false), layer_count(0),
|
: enable_loop_clipping(true), enable_cooling_markers(false), layer_count(0),
|
||||||
layer_index(-1), first_layer(false), elapsed_time(0), volumetric_speed(0),
|
layer_index(-1), first_layer(false), elapsed_time(0), volumetric_speed(0),
|
||||||
last_pos_defined(false)
|
_last_pos_defined(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point&
|
||||||
|
GCode::last_pos()
|
||||||
|
{
|
||||||
|
return this->_last_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCode::set_last_pos(const Point &pos)
|
||||||
|
{
|
||||||
|
this->_last_pos = pos;
|
||||||
|
this->_last_pos_defined = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GCode::last_pos_defined() const
|
||||||
|
{
|
||||||
|
return this->_last_pos_defined;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCode::apply_print_config(const PrintConfig &print_config)
|
||||||
|
{
|
||||||
|
this->writer.apply_print_config(print_config);
|
||||||
|
this->config.apply(print_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCode::set_origin(const Pointf &pointf)
|
||||||
|
{
|
||||||
|
// if origin increases (goes towards right), last_pos decreases because it goes towards left
|
||||||
|
Point translate(
|
||||||
|
scale_(this->origin.x - pointf.x),
|
||||||
|
scale_(this->origin.y - pointf.y)
|
||||||
|
);
|
||||||
|
this->_last_pos.translate(translate);
|
||||||
|
this->wipe.path.translate(translate);
|
||||||
|
|
||||||
|
this->origin = pointf;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GCode::preamble()
|
||||||
|
{
|
||||||
|
std::string gcode = this->writer.preamble();
|
||||||
|
|
||||||
|
/* Perform a *silent* move to z_offset: we need this to initialize the Z
|
||||||
|
position of our writer object so that any initial lift taking place
|
||||||
|
before the first layer change will raise the extruder from the correct
|
||||||
|
initial Z instead of 0. */
|
||||||
|
this->writer.travel_to_z(this->config.z_offset.value);
|
||||||
|
|
||||||
|
return gcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GCode::retract(bool toolchange)
|
||||||
|
{
|
||||||
|
std::string gcode;
|
||||||
|
|
||||||
|
if (this->writer.extruder() == NULL)
|
||||||
|
return gcode;
|
||||||
|
|
||||||
|
// wipe (if it's enabled for this extruder and we have a stored wipe path)
|
||||||
|
if (this->config.wipe.get_at(this->writer.extruder()->id) && this->wipe.has_path()) {
|
||||||
|
gcode += this->wipe.wipe(*this, toolchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The parent class will decide whether we need to perform an actual retraction
|
||||||
|
(the extruder might be already retracted fully or partially). We call these
|
||||||
|
methods even if we performed wipe, since this will ensure the entire retraction
|
||||||
|
length is honored in case wipe path was too short. */
|
||||||
|
gcode += toolchange ? this->writer.retract_for_toolchange() : this->writer.retract();
|
||||||
|
|
||||||
|
gcode += this->writer.reset_e();
|
||||||
|
if (this->writer.extruder()->retract_length() > 0 || this->config.use_firmware_retraction)
|
||||||
|
gcode += this->writer.lift();
|
||||||
|
|
||||||
|
return gcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GCode::unretract()
|
||||||
|
{
|
||||||
|
std::string gcode;
|
||||||
|
gcode += this->writer.unlift();
|
||||||
|
gcode += this->writer.unretract();
|
||||||
|
return gcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert a model-space scaled point into G-code coordinates
|
||||||
|
Pointf
|
||||||
|
GCode::point_to_gcode(const Point &point)
|
||||||
|
{
|
||||||
|
Pointf extruder_offset = this->config.extruder_offset.get_at(this->writer.extruder()->id);
|
||||||
|
return Pointf(
|
||||||
|
unscale(point.x) + this->origin.x - extruder_offset.x,
|
||||||
|
unscale(point.y) + this->origin.y - extruder_offset.y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
REGISTER_CLASS(GCode, "GCode");
|
REGISTER_CLASS(GCode, "GCode");
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
// draft for a binary representation of a G-code line
|
class GCode;
|
||||||
|
|
||||||
class AvoidCrossingPerimeters {
|
class AvoidCrossingPerimeters {
|
||||||
public:
|
public:
|
||||||
@ -31,10 +31,7 @@ class AvoidCrossingPerimeters {
|
|||||||
~AvoidCrossingPerimeters();
|
~AvoidCrossingPerimeters();
|
||||||
void init_external_mp(const ExPolygons &islands);
|
void init_external_mp(const ExPolygons &islands);
|
||||||
void init_layer_mp(const ExPolygons &islands);
|
void init_layer_mp(const ExPolygons &islands);
|
||||||
|
Polyline travel_to(GCode &gcodegen, Point point);
|
||||||
//Polyline travel_to(GCode &gcodegen, const Point &point);
|
|
||||||
Polyline travel_to(Point point, const Pointf &gcodegen_origin,
|
|
||||||
const Point &gcodegen_last_pos);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MotionPlanner* _external_mp;
|
MotionPlanner* _external_mp;
|
||||||
@ -57,7 +54,7 @@ class Wipe {
|
|||||||
Wipe();
|
Wipe();
|
||||||
bool has_path();
|
bool has_path();
|
||||||
void reset_path();
|
void reset_path();
|
||||||
//std::string wipe(GCode &gcodegen, bool toolchange = false);
|
std::string wipe(GCode &gcodegen, bool toolchange = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
class GCode {
|
class GCode {
|
||||||
@ -81,11 +78,22 @@ class GCode {
|
|||||||
std::map<PrintObject*,Point> _seam_position;
|
std::map<PrintObject*,Point> _seam_position;
|
||||||
bool first_layer; // this flag triggers first layer speeds
|
bool first_layer; // this flag triggers first layer speeds
|
||||||
unsigned int elapsed_time; // seconds
|
unsigned int elapsed_time; // seconds
|
||||||
Point last_pos;
|
|
||||||
bool last_pos_defined;
|
|
||||||
double volumetric_speed;
|
double volumetric_speed;
|
||||||
|
|
||||||
GCode();
|
GCode();
|
||||||
|
Point& last_pos();
|
||||||
|
void set_last_pos(const Point &pos);
|
||||||
|
bool last_pos_defined() const;
|
||||||
|
void apply_print_config(const PrintConfig &print_config);
|
||||||
|
void set_origin(const Pointf &pointf);
|
||||||
|
std::string preamble();
|
||||||
|
std::string retract(bool toolchange = false);
|
||||||
|
std::string unretract();
|
||||||
|
Pointf point_to_gcode(const Point &point);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Point _last_pos;
|
||||||
|
bool _last_pos_defined;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,24 @@ MultiPoint::remove_duplicate_points()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MultiPoint::append(const Point &point)
|
||||||
|
{
|
||||||
|
this->points.push_back(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MultiPoint::append(const Points &points)
|
||||||
|
{
|
||||||
|
this->append(points.begin(), points.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MultiPoint::append(const Points::const_iterator &begin, const Points::const_iterator &end)
|
||||||
|
{
|
||||||
|
this->points.insert(this->points.end(), begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
Points
|
Points
|
||||||
MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
|
MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,9 @@ class MultiPoint
|
|||||||
bool has_boundary_point(const Point &point) const;
|
bool has_boundary_point(const Point &point) const;
|
||||||
BoundingBox bounding_box() const;
|
BoundingBox bounding_box() const;
|
||||||
void remove_duplicate_points();
|
void remove_duplicate_points();
|
||||||
|
void append(const Point &point);
|
||||||
|
void append(const Points &points);
|
||||||
|
void append(const Points::const_iterator &begin, const Points::const_iterator &end);
|
||||||
|
|
||||||
static Points _douglas_peucker(const Points &points, const double tolerance);
|
static Points _douglas_peucker(const Points &points, const double tolerance);
|
||||||
|
|
||||||
|
17
xs/t/21_gcode.t
Normal file
17
xs/t/21_gcode.t
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Slic3r::XS;
|
||||||
|
use Test::More tests => 2;
|
||||||
|
|
||||||
|
{
|
||||||
|
my $gcodegen = Slic3r::GCode->new;
|
||||||
|
$gcodegen->set_origin(Slic3r::Pointf->new(10,0));
|
||||||
|
is_deeply $gcodegen->origin->pp, [10,0], 'set_origin';
|
||||||
|
$gcodegen->origin->translate(5,5);
|
||||||
|
is_deeply $gcodegen->origin->pp, [15,5], 'origin returns reference to point';
|
||||||
|
}
|
||||||
|
|
||||||
|
__END__
|
@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
void init_external_mp(ExPolygons islands);
|
void init_external_mp(ExPolygons islands);
|
||||||
void init_layer_mp(ExPolygons islands);
|
void init_layer_mp(ExPolygons islands);
|
||||||
Clone<Polyline> travel_to(Point* point, Pointf* gcodegen_origin, Point* gcodegen_last_pos)
|
Clone<Polyline> travel_to(GCode* gcode, Point* point)
|
||||||
%code{% RETVAL = THIS->travel_to(*point, *gcodegen_origin, *gcodegen_last_pos); %};
|
%code{% RETVAL = THIS->travel_to(*gcode, *point); %};
|
||||||
|
|
||||||
bool use_external_mp()
|
bool use_external_mp()
|
||||||
%code{% RETVAL = THIS->use_external_mp; %};
|
%code{% RETVAL = THIS->use_external_mp; %};
|
||||||
@ -51,6 +51,8 @@
|
|||||||
|
|
||||||
bool has_path();
|
bool has_path();
|
||||||
void reset_path();
|
void reset_path();
|
||||||
|
std::string wipe(GCode* gcodegen, bool toolchange = false)
|
||||||
|
%code{% RETVAL = THIS->wipe(*gcodegen, toolchange); %};
|
||||||
|
|
||||||
bool enable()
|
bool enable()
|
||||||
%code{% RETVAL = THIS->enable; %};
|
%code{% RETVAL = THIS->enable; %};
|
||||||
@ -69,8 +71,6 @@
|
|||||||
|
|
||||||
Ref<Pointf> origin()
|
Ref<Pointf> origin()
|
||||||
%code{% RETVAL = &(THIS->origin); %};
|
%code{% RETVAL = &(THIS->origin); %};
|
||||||
void _set_origin(Pointf* value)
|
|
||||||
%code{% THIS->origin = *value; %};
|
|
||||||
|
|
||||||
Ref<FullPrintConfig> config()
|
Ref<FullPrintConfig> config()
|
||||||
%code{% RETVAL = &(THIS->config); %};
|
%code{% RETVAL = &(THIS->config); %};
|
||||||
@ -136,15 +136,24 @@
|
|||||||
void set_elapsed_time(unsigned int value)
|
void set_elapsed_time(unsigned int value)
|
||||||
%code{% THIS->elapsed_time = value; %};
|
%code{% THIS->elapsed_time = value; %};
|
||||||
|
|
||||||
bool last_pos_defined()
|
bool last_pos_defined();
|
||||||
%code{% RETVAL = THIS->last_pos_defined; %};
|
|
||||||
Ref<Point> last_pos()
|
Ref<Point> last_pos()
|
||||||
%code{% RETVAL = &(THIS->last_pos); %};
|
%code{% RETVAL = &(THIS->last_pos()); %};
|
||||||
void set_last_pos(Point* value)
|
void set_last_pos(Point* pos)
|
||||||
%code{% THIS->last_pos = *value; THIS->last_pos_defined = true; %};
|
%code{% THIS->set_last_pos(*pos); %};
|
||||||
|
|
||||||
double volumetric_speed()
|
double volumetric_speed()
|
||||||
%code{% RETVAL = THIS->volumetric_speed; %};
|
%code{% RETVAL = THIS->volumetric_speed; %};
|
||||||
void set_volumetric_speed(double value)
|
void set_volumetric_speed(double value)
|
||||||
%code{% THIS->volumetric_speed = value; %};
|
%code{% THIS->volumetric_speed = value; %};
|
||||||
|
|
||||||
|
void apply_print_config(PrintConfig* print_config)
|
||||||
|
%code{% THIS->apply_print_config(*print_config); %};
|
||||||
|
void set_origin(Pointf* pointf)
|
||||||
|
%code{% THIS->set_origin(*pointf); %};
|
||||||
|
std::string preamble();
|
||||||
|
std::string retract(bool toolchange = false);
|
||||||
|
std::string unretract();
|
||||||
|
Clone<Pointf> point_to_gcode(Point* point)
|
||||||
|
%code{% RETVAL = THIS->point_to_gcode(*point); %};
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user