Ported Slic3r::GCode::AvoidCrossingPerimeters to XS

This commit is contained in:
Alessandro Ranellucci 2015-07-01 20:14:05 +02:00
parent 580d28d071
commit bf9cd1b8e6
10 changed files with 148 additions and 79 deletions

View File

@ -194,6 +194,7 @@ sub thread_cleanup {
*Slic3r::ExtrusionPath::DESTROY = sub {}; *Slic3r::ExtrusionPath::DESTROY = sub {};
*Slic3r::ExtrusionPath::Collection::DESTROY = sub {}; *Slic3r::ExtrusionPath::Collection::DESTROY = sub {};
*Slic3r::Flow::DESTROY = sub {}; *Slic3r::Flow::DESTROY = sub {};
*Slic3r::GCode::AvoidCrossingPerimeters::DESTROY = sub {};
*Slic3r::GCode::PlaceholderParser::DESTROY = sub {}; *Slic3r::GCode::PlaceholderParser::DESTROY = sub {};
*Slic3r::GCode::Writer::DESTROY = sub {}; *Slic3r::GCode::Writer::DESTROY = sub {};
*Slic3r::Geometry::BoundingBox::DESTROY = sub {}; *Slic3r::Geometry::BoundingBox::DESTROY = sub {};

View File

@ -365,15 +365,15 @@ 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($self, $point); $travel = $self->avoid_crossing_perimeters->travel_to($point, $self->origin, $self->last_pos);
# 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);
} }
# Re-allow avoid_crossing_perimeters for the next travel moves # Re-allow avoid_crossing_perimeters for the next travel moves
$self->avoid_crossing_perimeters->disable_once(0); $self->avoid_crossing_perimeters->set_disable_once(0);
$self->avoid_crossing_perimeters->use_external_mp_once(0); $self->avoid_crossing_perimeters->set_use_external_mp_once(0);
# generate G-code for the travel move # generate G-code for the travel move
my $gcode = ""; my $gcode = "";
@ -615,53 +615,4 @@ sub wipe {
return $gcode; return $gcode;
} }
package Slic3r::GCode::AvoidCrossingPerimeters;
use Moo;
has '_external_mp' => (is => 'rw');
has '_layer_mp' => (is => 'rw');
has 'use_external_mp' => (is => 'rw', default => sub {0});
has 'use_external_mp_once' => (is => 'rw', default => sub {0}); # this flag triggers the use of the external configuration space for avoid_crossing_perimeters for the next travel move
# this flag disables avoid_crossing_perimeters just for the next travel move
# we enable it by default for the first travel move in print
has 'disable_once' => (is => 'rw', default => sub {1});
sub init_external_mp {
my ($self, $islands) = @_;
$self->_external_mp(Slic3r::MotionPlanner->new($islands));
}
sub init_layer_mp {
my ($self, $islands) = @_;
$self->_layer_mp(Slic3r::MotionPlanner->new($islands));
}
sub travel_to {
my ($self, $gcodegen, $point) = @_;
if ($self->use_external_mp || $self->use_external_mp_once) {
# get current origin set in $gcodegen
# (the one that will be used to translate the G-code coordinates by)
my $scaled_origin = Slic3r::Point->new_scale(@{$gcodegen->origin});
# represent last_pos in absolute G-code coordinates
my $last_pos = $gcodegen->last_pos->clone;
$last_pos->translate(@$scaled_origin);
# represent $point in absolute G-code coordinates
$point = $point->clone;
$point->translate(@$scaled_origin);
# calculate path
my $travel = $self->_external_mp->shortest_path($last_pos, $point);
# translate the path back into the shifted coordinate system that $gcodegen
# is currently using for writing coordinates
$travel->translate(@{$scaled_origin->negative});
return $travel;
} else {
return $self->_layer_mp->shortest_path($gcodegen->last_pos, $point);
}
}
1; 1;

View File

@ -248,7 +248,7 @@ sub export {
if ($finished_objects > 0) { if ($finished_objects > 0) {
$gcodegen->set_origin(Slic3r::Pointf->new(map unscale $copy->[$_], X,Y)); $gcodegen->set_origin(Slic3r::Pointf->new(map unscale $copy->[$_], X,Y));
$gcodegen->enable_cooling_markers(0); # we're not filtering these moves through CoolingBuffer $gcodegen->enable_cooling_markers(0); # we're not filtering these moves through CoolingBuffer
$gcodegen->avoid_crossing_perimeters->use_external_mp_once(1); $gcodegen->avoid_crossing_perimeters->set_use_external_mp_once(1);
print $fh $gcodegen->retract; print $fh $gcodegen->retract;
print $fh $gcodegen->travel_to( print $fh $gcodegen->travel_to(
Slic3r::Point->new(0,0), Slic3r::Point->new(0,0),
@ -258,7 +258,7 @@ sub export {
$gcodegen->enable_cooling_markers(1); $gcodegen->enable_cooling_markers(1);
# disable motion planner when traveling to first object point # disable motion planner when traveling to first object point
$gcodegen->avoid_crossing_perimeters->disable_once(1); $gcodegen->avoid_crossing_perimeters->set_disable_once(1);
} }
my @layers = sort { $a->print_z <=> $b->print_z } @{$object->layers}, @{$object->support_layers}; my @layers = sort { $a->print_z <=> $b->print_z } @{$object->layers}, @{$object->support_layers};
@ -398,7 +398,7 @@ sub process_layer {
&& !$self->_skirt_done->{$layer->print_z} && !$self->_skirt_done->{$layer->print_z}
&& (!$layer->isa('Slic3r::Layer::Support') || $layer->id < $object->config->raft_layers)) { && (!$layer->isa('Slic3r::Layer::Support') || $layer->id < $object->config->raft_layers)) {
$self->_gcodegen->set_origin(Slic3r::Pointf->new(0,0)); $self->_gcodegen->set_origin(Slic3r::Pointf->new(0,0));
$self->_gcodegen->avoid_crossing_perimeters->use_external_mp(1); $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(1);
my @extruder_ids = map { $_->id } @{$self->_gcodegen->writer->extruders}; my @extruder_ids = map { $_->id } @{$self->_gcodegen->writer->extruders};
$gcode .= $self->_gcodegen->set_extruder($extruder_ids[0]); $gcode .= $self->_gcodegen->set_extruder($extruder_ids[0]);
# skip skirt if we have a large brim # skip skirt if we have a large brim
@ -431,12 +431,12 @@ sub process_layer {
} }
} }
$self->_skirt_done->{$layer->print_z} = 1; $self->_skirt_done->{$layer->print_z} = 1;
$self->_gcodegen->avoid_crossing_perimeters->use_external_mp(0); $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(0);
# allow a straight travel move to the first object point if this is the first layer # allow a straight travel move to the first object point if this is the first layer
# (but don't in next layers) # (but don't in next layers)
if ($layer->id == 0) { if ($layer->id == 0) {
$self->_gcodegen->avoid_crossing_perimeters->disable_once(1); $self->_gcodegen->avoid_crossing_perimeters->set_disable_once(1);
} }
} }
@ -444,19 +444,19 @@ sub process_layer {
if (!$self->_brim_done) { if (!$self->_brim_done) {
$gcode .= $self->_gcodegen->set_extruder($self->print->regions->[0]->config->perimeter_extruder-1); $gcode .= $self->_gcodegen->set_extruder($self->print->regions->[0]->config->perimeter_extruder-1);
$self->_gcodegen->set_origin(Slic3r::Pointf->new(0,0)); $self->_gcodegen->set_origin(Slic3r::Pointf->new(0,0));
$self->_gcodegen->avoid_crossing_perimeters->use_external_mp(1); $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(1);
$gcode .= $self->_gcodegen->extrude_loop($_, 'brim', $object->config->support_material_speed) $gcode .= $self->_gcodegen->extrude_loop($_, 'brim', $object->config->support_material_speed)
for @{$self->print->brim}; for @{$self->print->brim};
$self->_brim_done(1); $self->_brim_done(1);
$self->_gcodegen->avoid_crossing_perimeters->use_external_mp(0); $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(0);
# allow a straight travel move to the first object point # allow a straight travel move to the first object point
$self->_gcodegen->avoid_crossing_perimeters->disable_once(1); $self->_gcodegen->avoid_crossing_perimeters->set_disable_once(1);
} }
for my $copy (@$object_copies) { for my $copy (@$object_copies) {
# when starting a new object, use the external motion planner for the first travel move # when starting a new object, use the external motion planner for the first travel move
$self->_gcodegen->avoid_crossing_perimeters->use_external_mp_once(1) if ($self->_last_obj_copy // '') ne "$copy"; $self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp_once(1) if ($self->_last_obj_copy // '') ne "$copy";
$self->_last_obj_copy("$copy"); $self->_last_obj_copy("$copy");
$self->_gcodegen->set_origin(Slic3r::Pointf->new(map unscale $copy->[$_], X,Y)); $self->_gcodegen->set_origin(Slic3r::Pointf->new(map unscale $copy->[$_], X,Y));

View File

@ -1670,6 +1670,7 @@ src/libslic3r/ExtrusionEntityCollection.cpp
src/libslic3r/ExtrusionEntityCollection.hpp src/libslic3r/ExtrusionEntityCollection.hpp
src/libslic3r/Flow.cpp src/libslic3r/Flow.cpp
src/libslic3r/Flow.hpp src/libslic3r/Flow.hpp
src/libslic3r/GCode.cpp
src/libslic3r/GCode.hpp src/libslic3r/GCode.hpp
src/libslic3r/GCodeWriter.cpp src/libslic3r/GCodeWriter.cpp
src/libslic3r/GCodeWriter.hpp src/libslic3r/GCodeWriter.hpp
@ -1762,6 +1763,7 @@ xsp/ExtrusionEntityCollection.xsp
xsp/ExtrusionLoop.xsp xsp/ExtrusionLoop.xsp
xsp/ExtrusionPath.xsp xsp/ExtrusionPath.xsp
xsp/Flow.xsp xsp/Flow.xsp
xsp/GCode.xsp
xsp/GCodeWriter.xsp xsp/GCodeWriter.xsp
xsp/Geometry.xsp xsp/Geometry.xsp
xsp/GUI_3DScene.xsp xsp/GUI_3DScene.xsp

View File

@ -215,6 +215,7 @@ for my $class (qw(
Slic3r::ExtrusionPath Slic3r::ExtrusionPath
Slic3r::ExtrusionPath::Collection Slic3r::ExtrusionPath::Collection
Slic3r::Flow Slic3r::Flow
Slic3r::GCode::AvoidCrossingPerimeters
Slic3r::GCode::PlaceholderParser Slic3r::GCode::PlaceholderParser
Slic3r::Geometry::BoundingBox Slic3r::Geometry::BoundingBox
Slic3r::Geometry::BoundingBoxf Slic3r::Geometry::BoundingBoxf

View File

@ -0,0 +1,70 @@
#include "GCode.hpp"
namespace Slic3r {
AvoidCrossingPerimeters::AvoidCrossingPerimeters()
: use_external_mp(false), use_external_mp_once(false), disable_once(true),
_external_mp(NULL), _layer_mp(NULL)
{
}
AvoidCrossingPerimeters::~AvoidCrossingPerimeters()
{
if (this->_external_mp != NULL)
delete this->_external_mp;
if (this->_layer_mp != NULL)
delete this->_layer_mp;
}
void
AvoidCrossingPerimeters::init_external_mp(const ExPolygons &islands)
{
if (this->_external_mp != NULL)
delete this->_external_mp;
this->_external_mp = new MotionPlanner(islands);
}
void
AvoidCrossingPerimeters::init_layer_mp(const ExPolygons &islands)
{
if (this->_layer_mp != NULL)
delete this->_layer_mp;
this->_layer_mp = new MotionPlanner(islands);
}
Polyline
AvoidCrossingPerimeters::travel_to(Point point, const Pointf &gcodegen_origin,
const Point &gcodegen_last_pos)
{
if (this->use_external_mp || this->use_external_mp_once) {
// get current origin set in gcodegen
// (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);
// represent last_pos in absolute G-code coordinates
Point last_pos = gcodegen_last_pos;
last_pos.translate(scaled_origin);
// represent point in absolute G-code coordinates
point.translate(scaled_origin);
// calculate path
Polyline travel = this->_external_mp->shortest_path(last_pos, point);
// translate the path back into the shifted coordinate system that gcodegen
// is currently using for writing coordinates
travel.translate(scaled_origin.negative());
return travel;
} else {
return this->_layer_mp->shortest_path(gcodegen_last_pos, point);
}
}
#ifdef SLIC3RXS
REGISTER_CLASS(AvoidCrossingPerimeters, "GCode::AvoidCrossingPerimeters");
#endif
}

View File

@ -2,32 +2,37 @@
#define slic3r_GCode_hpp_ #define slic3r_GCode_hpp_
#include <myinit.h> #include <myinit.h>
#include "ExPolygon.hpp"
#include "MotionPlanner.hpp"
#include <string> #include <string>
namespace Slic3r { namespace Slic3r {
// draft for a binary representation of a G-code line // draft for a binary representation of a G-code line
enum GCodeCmdType { class AvoidCrossingPerimeters {
gcctSyncMotion,
gcctExtrude,
gcctResetE,
gcctSetTemp,
gcctSetTempWait,
gcctToolchange,
gcctCustom
};
class GCodeCmd {
public: public:
GCodeCmdType type;
float X, Y, Z, E, F;
unsigned short T, S;
std::string custom, comment;
float xy_dist; // cache
GCodeCmd(GCodeCmdType type) // this flag triggers the use of the external configuration space
: type(type), X(0), Y(0), Z(0), E(0), F(0), T(-1), S(0), xy_dist(-1) {}; bool use_external_mp;
bool use_external_mp_once; // just for the next travel move
// this flag disables avoid_crossing_perimeters just for the next travel move
// we enable it by default for the first travel move in print
bool disable_once;
AvoidCrossingPerimeters();
~AvoidCrossingPerimeters();
void init_external_mp(const ExPolygons &islands);
void init_layer_mp(const ExPolygons &islands);
//Polyline travel_to(GCode &gcodegen, const Point &point);
Polyline travel_to(Point point, const Pointf &gcodegen_origin,
const Point &gcodegen_last_pos);
private:
MotionPlanner* _external_mp;
MotionPlanner* _layer_mp;
}; };
} }

31
xs/xsp/GCode.xsp Normal file
View File

@ -0,0 +1,31 @@
%module{Slic3r::XS};
%{
#include <myinit.h>
#include "libslic3r/GCode.hpp"
%}
%name{Slic3r::GCode::AvoidCrossingPerimeters} class AvoidCrossingPerimeters {
AvoidCrossingPerimeters();
~AvoidCrossingPerimeters();
void init_external_mp(ExPolygons islands);
void init_layer_mp(ExPolygons islands);
Clone<Polyline> travel_to(Point* point, Pointf* gcodegen_origin, Point* gcodegen_last_pos)
%code{% RETVAL = THIS->travel_to(*point, *gcodegen_origin, *gcodegen_last_pos); %};
bool use_external_mp()
%code{% RETVAL = THIS->use_external_mp; %};
void set_use_external_mp(bool value)
%code{% THIS->use_external_mp = value; %};
bool use_external_mp_once()
%code{% RETVAL = THIS->use_external_mp_once; %};
void set_use_external_mp_once(bool value)
%code{% THIS->use_external_mp_once = value; %};
bool disable_once()
%code{% RETVAL = THIS->disable_once; %};
void set_disable_once(bool value)
%code{% THIS->disable_once = value; %};
};

View File

@ -170,6 +170,10 @@ PlaceholderParser* O_OBJECT_SLIC3R
Ref<PlaceholderParser> O_OBJECT_SLIC3R_T Ref<PlaceholderParser> O_OBJECT_SLIC3R_T
Clone<PlaceholderParser> O_OBJECT_SLIC3R_T Clone<PlaceholderParser> O_OBJECT_SLIC3R_T
AvoidCrossingPerimeters* O_OBJECT_SLIC3R
Ref<AvoidCrossingPerimeters> O_OBJECT_SLIC3R_T
Clone<AvoidCrossingPerimeters> O_OBJECT_SLIC3R_T
MotionPlanner* O_OBJECT_SLIC3R MotionPlanner* O_OBJECT_SLIC3R
Ref<MotionPlanner> O_OBJECT_SLIC3R_T Ref<MotionPlanner> O_OBJECT_SLIC3R_T
Clone<MotionPlanner> O_OBJECT_SLIC3R_T Clone<MotionPlanner> O_OBJECT_SLIC3R_T

View File

@ -125,6 +125,10 @@
%typemap{Ref<PlaceholderParser>}{simple}; %typemap{Ref<PlaceholderParser>}{simple};
%typemap{Clone<PlaceholderParser>}{simple}; %typemap{Clone<PlaceholderParser>}{simple};
%typemap{AvoidCrossingPerimeters*};
%typemap{Ref<AvoidCrossingPerimeters>}{simple};
%typemap{Clone<AvoidCrossingPerimeters>}{simple};
%typemap{Points}; %typemap{Points};
%typemap{Pointfs}; %typemap{Pointfs};