Some more work on wireframe
This commit is contained in:
parent
c21a254480
commit
7253dc699a
7 changed files with 107 additions and 37 deletions
|
@ -344,7 +344,7 @@ sub travel_to {
|
||||||
if ($travel->length < scale $self->config->get_at('retract_before_travel', $self->writer->extruder->id)
|
if ($travel->length < scale $self->config->get_at('retract_before_travel', $self->writer->extruder->id)
|
||||||
|| ($self->config->only_retract_when_crossing_perimeters
|
|| ($self->config->only_retract_when_crossing_perimeters
|
||||||
&& $self->config->fill_density > 0
|
&& $self->config->fill_density > 0
|
||||||
&& $self->layer->any_internal_region_slice_contains_line($travel))
|
&& defined($self->layer) && $self->layer->any_internal_region_slice_contains_line($travel))
|
||||||
|| (defined $role && $role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands->contains_line($travel))
|
|| (defined $role && $role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands->contains_line($travel))
|
||||||
) {
|
) {
|
||||||
# Just perform a straight travel move without any retraction.
|
# Just perform a straight travel move without any retraction.
|
||||||
|
|
|
@ -11,13 +11,14 @@ BEGIN {
|
||||||
}
|
}
|
||||||
|
|
||||||
use Getopt::Long qw(:config no_auto_abbrev);
|
use Getopt::Long qw(:config no_auto_abbrev);
|
||||||
use PDF::API2;
|
|
||||||
use Slic3r;
|
use Slic3r;
|
||||||
use Slic3r::ExtrusionPath ':roles';
|
use Slic3r::ExtrusionPath ':roles';
|
||||||
use Slic3r::Geometry qw(scale unscale X Y);
|
use Slic3r::Geometry qw(scale unscale X Y PI);
|
||||||
|
|
||||||
my %opt = (
|
my %opt = (
|
||||||
step_height => 10,
|
step_height => 5,
|
||||||
|
nozzle_angle => 30,
|
||||||
|
nozzle_width => 10,
|
||||||
first_layer_height => 0.3,
|
first_layer_height => 0.3,
|
||||||
);
|
);
|
||||||
{
|
{
|
||||||
|
@ -30,13 +31,15 @@ my %opt = (
|
||||||
'first-layer-height=f' => \$opt{first_layer_height},
|
'first-layer-height=f' => \$opt{first_layer_height},
|
||||||
);
|
);
|
||||||
GetOptions(%options) or usage(1);
|
GetOptions(%options) or usage(1);
|
||||||
$opt{output_file} or usage(1);ì
|
$opt{output_file} or usage(1);
|
||||||
$ARGV[0] or usage(1);
|
$ARGV[0] or usage(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
# load model
|
# load model
|
||||||
my $model = Slic3r::Model->read_from_file($ARGV[0]);
|
my $model = Slic3r::Model->read_from_file($ARGV[0]);
|
||||||
|
$model->add_default_instances;
|
||||||
|
$model->center_instances_around_point(Slic3r::Pointf->new(100,100));
|
||||||
my $mesh = $model->mesh;
|
my $mesh = $model->mesh;
|
||||||
$mesh->translate(0, 0, -$mesh->bounding_box->z_min);
|
$mesh->translate(0, 0, -$mesh->bounding_box->z_min);
|
||||||
|
|
||||||
|
@ -46,6 +49,7 @@ my %opt = (
|
||||||
for (my $z = $opt{first_layer_height}; $z <= $z_max; $z += $opt{step_height}) {
|
for (my $z = $opt{first_layer_height}; $z <= $z_max; $z += $opt{step_height}) {
|
||||||
push @z, $z;
|
push @z, $z;
|
||||||
}
|
}
|
||||||
|
my @slices = @{$mesh->slice(\@z)};
|
||||||
|
|
||||||
my $flow = Slic3r::Flow->new(
|
my $flow = Slic3r::Flow->new(
|
||||||
width => 0.35,
|
width => 0.35,
|
||||||
|
@ -54,45 +58,96 @@ my %opt = (
|
||||||
bridge => 1,
|
bridge => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
my $section;
|
my $config = Slic3r::Config::Print->new;
|
||||||
|
$config->set('gcode_comments', 1);
|
||||||
# build a square section
|
|
||||||
{
|
|
||||||
my $dist = 2 * $opt{step_height}; # horizontal step
|
|
||||||
my $side_modules = 3;
|
|
||||||
my @points = (
|
|
||||||
[0,0],
|
|
||||||
(map [$_*$dist, 0], 1..$side_modules),
|
|
||||||
(map [$side_modules*$dist, $_*$dist], 1..$side_modules),
|
|
||||||
(map [($_-1)*$dist, $side_modules*$dist], reverse 1..$side_modules),
|
|
||||||
(map [0, ($_-1)*$dist], reverse 1..$side_modules),
|
|
||||||
);
|
|
||||||
pop @points; # prevent coinciding endpoints
|
|
||||||
$section = Slic3r::Polygon->new_scale(@points);
|
|
||||||
}
|
|
||||||
my $section_loop = Slic3r::ExtrusionLoop->new_from_paths(
|
|
||||||
Slic3r::ExtrusionPath->new(
|
|
||||||
polyline => $section->split_at_first_point,
|
|
||||||
role => EXTR_ROLE_BRIDGE,
|
|
||||||
mm3_per_mm => $flow->mm3_per_mm,
|
|
||||||
width => $flow->width,
|
|
||||||
height => $flow->height,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
my $vertical_steps = 3;
|
|
||||||
|
|
||||||
open my $fh, '>', $opt{output_file};
|
open my $fh, '>', $opt{output_file};
|
||||||
my $gcodegen = Slic3r::GCode->new(
|
my $gcodegen = Slic3r::GCode->new(
|
||||||
enable_loop_clipping => 0, # better bonding
|
enable_loop_clipping => 0, # better bonding
|
||||||
);
|
);
|
||||||
|
$gcodegen->apply_print_config($config);
|
||||||
$gcodegen->set_extruders([0]);
|
$gcodegen->set_extruders([0]);
|
||||||
print $fh $gcodegen->set_extruder(0);
|
print $fh $gcodegen->set_extruder(0);
|
||||||
print $fh $gcodegen->writer->preamble;
|
print $fh $gcodegen->writer->preamble;
|
||||||
|
|
||||||
foreach my $z (map $_*$opt{step_height}, 0..($vertical_steps-1)) {
|
my $e = $gcodegen->writer->extruder->e_per_mm3 * $flow->mm3_per_mm;
|
||||||
print $fh $gcodegen->writer->travel_to_z($z + $flow->height);
|
|
||||||
print $fh $gcodegen->extrude_loop($section_loop, "contour");
|
foreach my $layer_id (0..$#z) {
|
||||||
|
my $z = $z[$layer_id];
|
||||||
|
|
||||||
|
foreach my $island (@{$slices[$layer_id]}) {
|
||||||
|
foreach my $polygon (@$island) {
|
||||||
|
if ($layer_id > 0) {
|
||||||
|
# find the lower polygon that we want to connect to this one
|
||||||
|
my $lower = $slices[$layer_id-1]->[0]->contour; # 't was easy, wasn't it?
|
||||||
|
my $lower_z = $z[$layer_id-1];
|
||||||
|
|
||||||
|
{
|
||||||
|
my @points = ();
|
||||||
|
|
||||||
|
# keep all points with strong angles
|
||||||
|
{
|
||||||
|
my @pp = @$polygon;
|
||||||
|
foreach my $i (0..$#pp) {
|
||||||
|
push @points, $pp[$i-1] if abs($pp[$i-1]->ccw_angle($pp[$i-2], $pp[$i]) - PI) > PI/3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$polygon = Slic3r::Polygon->new(@points);
|
||||||
|
}
|
||||||
|
#$polygon = Slic3r::Polygon->new(@{$polygon->split_at_first_point->equally_spaced_points(scale $opt{nozzle_width})});
|
||||||
|
|
||||||
|
# find vertical lines
|
||||||
|
my @vertical = ();
|
||||||
|
foreach my $point (@{$polygon}) {
|
||||||
|
push @vertical, Slic3r::Line->new($point->projection_onto_polygon($lower), $point);
|
||||||
|
}
|
||||||
|
|
||||||
|
next if !@vertical;
|
||||||
|
|
||||||
|
my @points = ();
|
||||||
|
foreach my $line (@vertical) {
|
||||||
|
push @points, Slic3r::Pointf3->new(
|
||||||
|
unscale($line->a->x),
|
||||||
|
unscale($line->a->y), #))
|
||||||
|
$lower_z,
|
||||||
|
);
|
||||||
|
push @points, Slic3r::Pointf3->new(
|
||||||
|
unscale($line->b->x),
|
||||||
|
unscale($line->b->y), #))
|
||||||
|
$z,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# reappend first point as destination of the last diagonal segment
|
||||||
|
push @points, Slic3r::Pointf3->new(
|
||||||
|
unscale($vertical[0]->a->x),
|
||||||
|
unscale($vertical[0]->a->y), #))
|
||||||
|
$lower_z,
|
||||||
|
);
|
||||||
|
|
||||||
|
# move to the position of the first vertical line
|
||||||
|
print $fh $gcodegen->writer->travel_to_xyz(shift @points);
|
||||||
|
|
||||||
|
# extrude segments
|
||||||
|
foreach my $point (@points) {
|
||||||
|
print $fh $gcodegen->writer->extrude_to_xyz($point, $e * $gcodegen->writer->get_position->distance_to($point));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print $fh $gcodegen->writer->travel_to_z($z);
|
||||||
|
foreach my $polygon (@$island) {
|
||||||
|
#my $polyline = $polygon->split_at_vertex(Slic3r::Point->new_scale(@{$gcodegen->writer->get_position}[0,1]));
|
||||||
|
my $polyline = $polygon->split_at_first_point;
|
||||||
|
print $fh $gcodegen->writer->travel_to_xy(Slic3r::Pointf->new_unscale(@{ $polyline->first_point }), "move to first contour point");
|
||||||
|
|
||||||
|
foreach my $line (@{$polyline->lines}) {
|
||||||
|
my $point = Slic3r::Pointf->new_unscale(@{ $line->b });
|
||||||
|
print $fh $gcodegen->writer->extrude_to_xy($point, $e * unscale($line->length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close $fh;
|
close $fh;
|
||||||
|
|
|
@ -491,6 +491,12 @@ GCodeWriter::unlift()
|
||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pointf3
|
||||||
|
GCodeWriter::get_position() const
|
||||||
|
{
|
||||||
|
return this->_pos;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
REGISTER_CLASS(GCodeWriter, "GCode::Writer");
|
REGISTER_CLASS(GCodeWriter, "GCode::Writer");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,6 +45,7 @@ class GCodeWriter {
|
||||||
std::string unretract();
|
std::string unretract();
|
||||||
std::string lift();
|
std::string lift();
|
||||||
std::string unlift();
|
std::string unlift();
|
||||||
|
Pointf3 get_position() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string _extrusion_axis;
|
std::string _extrusion_axis;
|
||||||
|
|
|
@ -161,10 +161,15 @@ Point::ccw(const Line &line) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the CCW angle between this-p1 and this-p2
|
// returns the CCW angle between this-p1 and this-p2
|
||||||
|
// i.e. this assumes a CCW rotation from p1 to p2 around this
|
||||||
double
|
double
|
||||||
Point::ccw_angle(const Point &p1, const Point &p2) const
|
Point::ccw_angle(const Point &p1, const Point &p2) const
|
||||||
{
|
{
|
||||||
return Line(*this, p1).orientation() - Line(*this, p2).orientation();
|
double angle = atan2(p1.x - this->x, p1.y - this->y)
|
||||||
|
- atan2(p2.x - this->x, p2.y - this->y);
|
||||||
|
|
||||||
|
// we only want to return only positive angles
|
||||||
|
return angle <= 0 ? angle + 2*PI : angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point
|
Point
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
std::string unretract();
|
std::string unretract();
|
||||||
std::string lift();
|
std::string lift();
|
||||||
std::string unlift();
|
std::string unlift();
|
||||||
|
Clone<Pointf3> get_position() const;
|
||||||
%{
|
%{
|
||||||
|
|
||||||
SV*
|
SV*
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
%code{% RETVAL = THIS->distance_to(*line); %};
|
%code{% RETVAL = THIS->distance_to(*line); %};
|
||||||
double ccw(Point* p1, Point* p2)
|
double ccw(Point* p1, Point* p2)
|
||||||
%code{% RETVAL = THIS->ccw(*p1, *p2); %};
|
%code{% RETVAL = THIS->ccw(*p1, *p2); %};
|
||||||
|
double ccw_angle(Point* p1, Point* p2)
|
||||||
|
%code{% RETVAL = THIS->ccw_angle(*p1, *p2); %};
|
||||||
Clone<Point> projection_onto_polygon(Polygon* polygon)
|
Clone<Point> projection_onto_polygon(Polygon* polygon)
|
||||||
%code{% RETVAL = new Point(THIS->projection_onto(*polygon)); %};
|
%code{% RETVAL = new Point(THIS->projection_onto(*polygon)); %};
|
||||||
Clone<Point> projection_onto_polyline(Polyline* polyline)
|
Clone<Point> projection_onto_polyline(Polyline* polyline)
|
||||||
|
|
Loading…
Reference in a new issue