Merge branch 'master' into xs
This commit is contained in:
commit
ff795f2918
13 changed files with 175 additions and 60 deletions
26
Build.PL
26
Build.PL
|
@ -27,16 +27,28 @@ my %recommends = qw(
|
|||
Class::XSAccessor 0
|
||||
Growl::GNTP 0.15
|
||||
XML::SAX::ExpatXS 0
|
||||
Wx 0.9901
|
||||
);
|
||||
|
||||
# removed:
|
||||
# Wx 0.9901
|
||||
|
||||
my @try = (
|
||||
$ENV{CPANM} // (),
|
||||
File::Spec->catfile($Config{sitebin}, 'cpanm'),
|
||||
File::Spec->catfile($Config{installscript}, 'cpanm'),
|
||||
);
|
||||
|
||||
my $cpanm;
|
||||
if (defined $ENV{CPANM} && -x $ENV{CPANM}) {
|
||||
$cpanm = $ENV{CPANM};
|
||||
} elsif (-x (my $c = File::Spec->catfile($Config{installscript}, 'cpanm'))) {
|
||||
$cpanm = $c;
|
||||
} elsif ($^O = /^(?:darwin|linux)$/ && system(qw(which cpanm)) == 0) {
|
||||
$cpanm = 'cpanm';
|
||||
foreach my $path (@try) {
|
||||
if (-e $path) { # don't use -x because it fails on Windows
|
||||
$cpanm = $path;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if (!$cpanm) {
|
||||
if ($^O =~ /^(?:darwin|linux)$/ && system(qw(which cpanm)) == 0) {
|
||||
$cpanm = 'cpanm';
|
||||
}
|
||||
}
|
||||
die <<'EOF'
|
||||
cpanm was not found. Please install it before running this script.
|
||||
|
|
|
@ -3,8 +3,8 @@ use Moo;
|
|||
|
||||
extends 'Slic3r::Fill::Base';
|
||||
|
||||
use Slic3r::Geometry qw(scale unscale X);
|
||||
use Slic3r::Geometry::Clipper qw(offset2 union_pt traverse_pt PFT_EVENODD);
|
||||
use Slic3r::Geometry qw(scale unscale X nearest_point_index);
|
||||
use Slic3r::Geometry::Clipper qw(offset offset2 union_pt traverse_pt PFT_EVENODD);
|
||||
|
||||
sub fill_surface {
|
||||
my $self = shift;
|
||||
|
@ -27,16 +27,26 @@ sub fill_surface {
|
|||
$flow_spacing = unscale $distance;
|
||||
}
|
||||
|
||||
my @loops = my @last = @$expolygon;
|
||||
# compensate the overlap which is good for rectilinear but harmful for concentric
|
||||
# where the perimeter/infill spacing should be equal to any other loop spacing
|
||||
my @loops = my @last = offset($expolygon, -&Slic3r::INFILL_OVERLAP_OVER_SPACING * $min_spacing / 2);
|
||||
while (@last) {
|
||||
push @loops, @last = offset2(\@last, -1.5*$distance, +0.5*$distance);
|
||||
}
|
||||
|
||||
# generate paths from the outermost to the innermost, to avoid
|
||||
# adhesion problems of the first central tiny loops
|
||||
my @paths = map Slic3r::Polygon->new(@$_)->split_at_first_point,
|
||||
@loops = map Slic3r::Polygon->new(@$_),
|
||||
reverse traverse_pt( union_pt(\@loops, PFT_EVENODD) );
|
||||
|
||||
# order paths using a nearest neighbor search
|
||||
my @paths = ();
|
||||
my $last_pos = [0,0];
|
||||
foreach my $loop (@loops) {
|
||||
push @paths, $loop->split_at_index(nearest_point_index($last_pos, $loop));
|
||||
$last_pos = $paths[-1][-1];
|
||||
}
|
||||
|
||||
# clip the paths to avoid the extruder to get exactly on the first point of the loop
|
||||
my $clip_length = scale $flow_spacing * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_SPACING;
|
||||
$_->clip_end($clip_length) for @paths;
|
||||
|
|
|
@ -190,8 +190,6 @@ sub extrude_loop {
|
|||
$extrusion_path->intersect_expolygons($self->_layer_overhangs);
|
||||
|
||||
# reapply the nearest point search for starting point
|
||||
# (TODO: choose the nearest point not on an overhang - make sure wipe and
|
||||
# inwards move consider the new actual starting point)
|
||||
@paths = Slic3r::ExtrusionPath::Collection
|
||||
->new(paths => [@paths])
|
||||
->chained_path($last_pos, 1);
|
||||
|
@ -443,9 +441,16 @@ sub retract {
|
|||
$self->speed('travel');
|
||||
|
||||
# subdivide the retraction
|
||||
my $retracted = 0;
|
||||
for (1 .. $#$wipe_path) {
|
||||
my $segment_length = $wipe_path->[$_-1]->distance_to($wipe_path->[$_]);
|
||||
$gcode .= $self->G1($wipe_path->[$_], undef, $retract->[2] * ($segment_length / $total_wipe_length), $retract->[3] . ";_WIPE");
|
||||
$retracted += my $e = $retract->[2] * ($segment_length / $total_wipe_length);
|
||||
$gcode .= $self->G1($wipe_path->[$_], undef, $e, $retract->[3] . ";_WIPE");
|
||||
}
|
||||
if ($retracted > $retract->[2]) {
|
||||
# if we retracted less than we had to, retract the remainder
|
||||
# TODO: add regression test
|
||||
$gcode .= $self->G1(undef, undef, $retract->[2] - $retracted, $comment);
|
||||
}
|
||||
} else {
|
||||
$self->speed('retract');
|
||||
|
|
|
@ -12,7 +12,7 @@ our @EXPORT_OK = qw(
|
|||
point_is_on_left_of_segment polyline_lines polygon_lines nearest_point
|
||||
point_along_segment polygon_segment_having_point polygon_has_subsegment
|
||||
polygon_has_vertex polyline_length can_connect_points deg2rad rad2deg
|
||||
rotate_points move_points clip_segment_polygon
|
||||
rotate_points move_points clip_segment_polygon nearest_point_index
|
||||
sum_vectors multiply_vector subtract_vectors dot perp polygon_points_visibility
|
||||
line_intersection bounding_box bounding_box_intersect same_point same_line
|
||||
longest_segment angle3points three_points_aligned line_direction
|
||||
|
|
|
@ -62,6 +62,18 @@ sub scale {
|
|||
$self;
|
||||
}
|
||||
|
||||
sub translate {
|
||||
my $self = shift;
|
||||
my @shift = @_;
|
||||
|
||||
for my $axis (X .. $#{$self->extents}) {
|
||||
$self->extents->[$axis][MIN] += $shift[$axis];
|
||||
$self->extents->[$axis][MAX] += $shift[$axis];
|
||||
}
|
||||
|
||||
$self;
|
||||
}
|
||||
|
||||
sub size {
|
||||
my $self = shift;
|
||||
|
||||
|
|
|
@ -256,7 +256,11 @@ sub make_perimeters {
|
|||
foreach my $polynode (@nodes) {
|
||||
push @loops, $traverse->($polynode->{children}, $depth+1, $is_contour);
|
||||
|
||||
# return ccw contours and cw holes
|
||||
# GCode.pm will convert all of them to ccw, but it needs to know
|
||||
# what the holes are in order to compute the correct inwards move
|
||||
my $polygon = Slic3r::Polygon->new($polynode->{outer} // [ reverse @{$polynode->{hole}} ]);
|
||||
$polygon->reverse if !$is_contour;
|
||||
|
||||
my $role = EXTR_ROLE_PERIMETER;
|
||||
if ($is_contour ? $depth == 0 : !@{ $polynode->{children} }) {
|
||||
|
|
|
@ -6,6 +6,7 @@ use Slic3r::Geometry qw(X Y Z MIN move_points);
|
|||
|
||||
has 'materials' => (is => 'ro', default => sub { {} });
|
||||
has 'objects' => (is => 'ro', default => sub { [] });
|
||||
has '_bounding_box' => (is => 'rw');
|
||||
|
||||
sub read_from_file {
|
||||
my $class = shift;
|
||||
|
@ -57,6 +58,7 @@ sub add_object {
|
|||
|
||||
my $object = Slic3r::Model::Object->new(model => $self, @_);
|
||||
push @{$self->objects}, $object;
|
||||
$self->_bounding_box(undef);
|
||||
return $object;
|
||||
}
|
||||
|
||||
|
@ -70,11 +72,6 @@ sub set_material {
|
|||
);
|
||||
}
|
||||
|
||||
sub scale {
|
||||
my $self = shift;
|
||||
$_->scale(@_) for @{$self->objects};
|
||||
}
|
||||
|
||||
sub arrange_objects {
|
||||
my $self = shift;
|
||||
my ($config) = @_;
|
||||
|
@ -151,8 +148,9 @@ sub _arrange {
|
|||
return ($config->duplicate_grid->[X] * $config->duplicate_grid->[Y]), @positions;
|
||||
} else {
|
||||
my $total_parts = $config->duplicate * @items;
|
||||
my $partx = max(map $_->size->[X], @items);
|
||||
my $party = max(map $_->size->[Y], @items);
|
||||
my @sizes = map $_->size, @items;
|
||||
my $partx = max(map $_->[X], @sizes);
|
||||
my $party = max(map $_->[Y], @sizes);
|
||||
return $config->duplicate,
|
||||
Slic3r::Geometry::arrange
|
||||
($total_parts, $partx, $party, (map $_, @{$config->bed_size}),
|
||||
|
@ -172,12 +170,16 @@ sub used_vertices {
|
|||
|
||||
sub size {
|
||||
my $self = shift;
|
||||
return [ Slic3r::Geometry::size_3D($self->used_vertices) ];
|
||||
return $self->bounding_box->size;
|
||||
}
|
||||
|
||||
sub bounding_box {
|
||||
my $self = shift;
|
||||
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
|
||||
|
||||
if (!defined $self->_bounding_box) {
|
||||
$self->_bounding_box(Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices));
|
||||
}
|
||||
return $self->_bounding_box;
|
||||
}
|
||||
|
||||
sub align_to_origin {
|
||||
|
@ -198,9 +200,18 @@ sub align_to_origin {
|
|||
}
|
||||
}
|
||||
|
||||
sub scale {
|
||||
my $self = shift;
|
||||
$_->scale(@_) for @{$self->objects};
|
||||
$self->_bounding_box->scale(@_) if defined $self->_bounding_box;
|
||||
}
|
||||
|
||||
sub move {
|
||||
my $self = shift;
|
||||
$_->move(@_) for @{$self->objects};
|
||||
my @shift = @_;
|
||||
|
||||
$_->move(@shift) for @{$self->objects};
|
||||
$self->_bounding_box->translate(@shift) if defined $self->_bounding_box;
|
||||
}
|
||||
|
||||
# flattens everything to a single mesh
|
||||
|
@ -286,6 +297,7 @@ has 'vertices' => (is => 'ro', default => sub { [] });
|
|||
has 'volumes' => (is => 'ro', default => sub { [] });
|
||||
has 'instances' => (is => 'rw');
|
||||
has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_max, layer_height ]
|
||||
has '_bounding_box' => (is => 'rw');
|
||||
|
||||
sub add_volume {
|
||||
my $self = shift;
|
||||
|
@ -304,6 +316,8 @@ sub add_volume {
|
|||
|
||||
my $volume = Slic3r::Model::Volume->new(object => $self, %args);
|
||||
push @{$self->volumes}, $volume;
|
||||
$self->_bounding_box(undef);
|
||||
$self->model->_bounding_box(undef);
|
||||
return $volume;
|
||||
}
|
||||
|
||||
|
@ -312,6 +326,7 @@ sub add_instance {
|
|||
|
||||
$self->instances([]) if !defined $self->instances;
|
||||
push @{$self->instances}, Slic3r::Model::Instance->new(object => $self, @_);
|
||||
$self->model->_bounding_box(undef);
|
||||
return $self->instances->[-1];
|
||||
}
|
||||
|
||||
|
@ -333,7 +348,7 @@ sub used_vertices {
|
|||
|
||||
sub size {
|
||||
my $self = shift;
|
||||
return [ Slic3r::Geometry::size_3D($self->used_vertices) ];
|
||||
return $self->bounding_box->size;
|
||||
}
|
||||
|
||||
sub center {
|
||||
|
@ -343,7 +358,11 @@ sub center {
|
|||
|
||||
sub bounding_box {
|
||||
my $self = shift;
|
||||
return Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices);
|
||||
|
||||
if (!defined $self->_bounding_box) {
|
||||
$self->_bounding_box(Slic3r::Geometry::BoundingBox->new_from_points_3D($self->used_vertices));
|
||||
}
|
||||
return $self->_bounding_box;
|
||||
}
|
||||
|
||||
sub align_to_origin {
|
||||
|
@ -359,7 +378,10 @@ sub align_to_origin {
|
|||
|
||||
sub move {
|
||||
my $self = shift;
|
||||
@{$self->vertices} = move_points_3D([ @_ ], @{$self->vertices});
|
||||
my @shift = @_;
|
||||
|
||||
@{$self->vertices} = move_points_3D([ @shift ], @{$self->vertices});
|
||||
$self->_bounding_box->translate(@shift) if defined $self->_bounding_box;
|
||||
}
|
||||
|
||||
sub scale {
|
||||
|
@ -371,6 +393,8 @@ sub scale {
|
|||
foreach my $vertex (@{$self->vertices}) {
|
||||
$vertex->[$_] *= $factor for X,Y,Z;
|
||||
}
|
||||
|
||||
$self->_bounding_box->scale($factor) if defined $self->_bounding_box;
|
||||
}
|
||||
|
||||
sub rotate {
|
||||
|
@ -384,6 +408,8 @@ sub rotate {
|
|||
foreach my $vertex (@{$self->vertices}) {
|
||||
@$vertex = (@{ +(Slic3r::Geometry::rotate_points($rad, undef, [ $vertex->[X], $vertex->[Y] ]))[0] }, $vertex->[Z]);
|
||||
}
|
||||
|
||||
$self->_bounding_box(undef);
|
||||
}
|
||||
|
||||
sub materials_count {
|
||||
|
|
|
@ -7,7 +7,7 @@ use parent 'Slic3r::Polyline';
|
|||
|
||||
use Slic3r::Geometry qw(polygon_lines polygon_remove_parallel_continuous_edges
|
||||
polygon_remove_acute_vertices polygon_segment_having_point point_in_polygon
|
||||
PI X1 X2 Y1 Y2);
|
||||
PI X1 X2 Y1 Y2 epsilon);
|
||||
use Slic3r::Geometry::Clipper qw(JT_MITER);
|
||||
|
||||
sub lines {
|
||||
|
@ -159,7 +159,7 @@ sub concave_points {
|
|||
my $self = shift;
|
||||
|
||||
return map $self->[$_],
|
||||
grep Slic3r::Geometry::angle3points(@$self[$_, $_-1, $_+1]) < PI,
|
||||
grep Slic3r::Geometry::angle3points(@$self[$_, $_-1, $_+1]) < PI - epsilon,
|
||||
-1 .. ($#$self-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,12 @@ sub slice {
|
|||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
# make sure all layers contain layer region objects for all regions
|
||||
my $regions_count = $self->print->regions_count;
|
||||
foreach my $layer (@{ $self->layers }) {
|
||||
$layer->region($_) for 0 .. ($regions_count-1);
|
||||
}
|
||||
|
||||
# process facets
|
||||
for my $region_id (0 .. $#{$self->meshes}) {
|
||||
my $mesh = $self->meshes->[$region_id]; # ignore undef meshes
|
||||
|
@ -152,8 +158,7 @@ sub slice {
|
|||
my $apply_lines = sub {
|
||||
my $lines = shift;
|
||||
foreach my $layer_id (keys %$lines) {
|
||||
my $layerm = $self->layers->[$layer_id]->region($region_id);
|
||||
push @{$layerm->lines}, @{$lines->{$layer_id}};
|
||||
push @{$self->layers->[$layer_id]->regions->[$region_id]->lines}, @{$lines->{$layer_id}};
|
||||
}
|
||||
};
|
||||
Slic3r::parallelize(
|
||||
|
@ -192,9 +197,6 @@ sub slice {
|
|||
pop @{$self->layers} while @{$self->layers} && (!map @{$_->lines}, @{$self->layers->[-1]->regions});
|
||||
|
||||
foreach my $layer (@{ $self->layers }) {
|
||||
# make sure all layers contain layer region objects for all regions
|
||||
$layer->region($_) for 0 .. ($self->print->regions_count-1);
|
||||
|
||||
Slic3r::debugf "Making surfaces for layer %d (slice z = %f):\n",
|
||||
$layer->id, unscale $layer->slice_z if $Slic3r::debug;
|
||||
|
||||
|
|
|
@ -27,6 +27,13 @@ sub model {
|
|||
$facets = [
|
||||
[0,1,2], [0,2,3], [4,5,6], [4,6,7], [0,4,7], [0,7,1], [1,7,6], [1,6,2], [2,6,5], [2,5,3], [4,0,3], [4,3,5],
|
||||
],
|
||||
} elsif ($model_name eq 'cube_with_hole') {
|
||||
$vertices = [
|
||||
[0,0,0],[0,0,10],[0,20,0],[0,20,10],[20,0,0],[20,0,10],[5,5,0],[15,5,0],[5,15,0],[20,20,0],[15,15,0],[20,20,10],[5,5,10],[5,15,10],[15,5,10],[15,15,10]
|
||||
];
|
||||
$facets = [
|
||||
[0,1,2],[2,1,3],[1,0,4],[5,1,4],[6,7,4],[8,2,9],[0,2,8],[10,8,9],[0,8,6],[0,6,4],[4,7,9],[7,10,9],[2,3,9],[9,3,11],[12,1,5],[13,3,12],[14,12,5],[3,1,12],[11,3,13],[11,15,5],[11,13,15],[15,14,5],[5,4,9],[11,5,9],[8,13,12],[6,8,12],[10,15,13],[8,10,13],[15,10,14],[14,10,7],[14,7,12],[12,7,6]
|
||||
],
|
||||
} elsif ($model_name eq 'V') {
|
||||
$vertices = [
|
||||
[-14,0,20],[-14,15,20],[0,0,0],[0,15,0],[-4,0,20],[-4,15,20],[5,0,7.14286],[10,0,0],[24,0,20],[14,0,20],[10,15,0],[5,15,7.14286],[14,15,20],[24,15,20]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package Slic3r::TriangleMesh;
|
||||
use Moo;
|
||||
|
||||
use List::Util qw(reduce min max);
|
||||
use Slic3r::Geometry qw(X Y Z A B unscale same_point);
|
||||
use Slic3r::Geometry::Clipper qw(union_ex);
|
||||
use Storable;
|
||||
|
@ -37,6 +38,7 @@ sub analyze {
|
|||
$self->facets_edges([]);
|
||||
$self->edges_facets([]);
|
||||
my %table = (); # edge_coordinates => edge_id
|
||||
my $vertices = $self->vertices; # save method calls
|
||||
|
||||
for (my $facet_id = 0; $facet_id <= $#{$self->facets}; $facet_id++) {
|
||||
my $facet = $self->facets->[$facet_id];
|
||||
|
@ -46,8 +48,10 @@ sub analyze {
|
|||
# this is needed to get all intersection lines in a consistent order
|
||||
# (external on the right of the line)
|
||||
{
|
||||
my @z_order = sort { $self->vertices->[$facet->[$a]][Z] <=> $self->vertices->[$facet->[$b]][Z] } -3..-1;
|
||||
@$facet[-3..-1] = (@$facet[$z_order[0]..-1], @$facet[-3..($z_order[0]-1)]);
|
||||
my $lowest_vertex_idx = reduce {
|
||||
$vertices->[ $facet->[$a] ][Z] < $vertices->[ $facet->[$b] ][Z] ? $a : $b
|
||||
} -3 .. -1;
|
||||
@$facet[-3..-1] = (@$facet[$lowest_vertex_idx..-1], @$facet[-3..($lowest_vertex_idx-1)]);
|
||||
}
|
||||
|
||||
# ignore the normal if provided
|
||||
|
@ -420,13 +424,11 @@ sub slice_facet {
|
|||
if $Slic3r::debug;
|
||||
|
||||
# find the vertical extents of the facet
|
||||
my ($min_z, $max_z) = (99999999999, -99999999999);
|
||||
foreach my $vertex (@vertices) {
|
||||
my $vertex_z = $self->vertices->[$vertex][Z];
|
||||
$min_z = $vertex_z if $vertex_z < $min_z;
|
||||
$max_z = $vertex_z if $vertex_z > $max_z;
|
||||
}
|
||||
Slic3r::debugf "z: min = %.0f, max = %.0f\n", $min_z, $max_z;
|
||||
my @z = map $_->[Z], @{$self->vertices}[@vertices];
|
||||
my $min_z = min(@z);
|
||||
my $max_z = max(@z);
|
||||
Slic3r::debugf "z: min = %.0f, max = %.0f\n", $min_z, $max_z
|
||||
if $Slic3r::debug;
|
||||
|
||||
if ($max_z == $min_z) {
|
||||
Slic3r::debugf "Facet is horizontal; ignoring\n";
|
||||
|
@ -435,10 +437,11 @@ sub slice_facet {
|
|||
|
||||
# calculate the layer extents
|
||||
my ($min_layer, $max_layer) = $print_object->get_layer_range($min_z, $max_z);
|
||||
Slic3r::debugf "layers: min = %s, max = %s\n", $min_layer, $max_layer;
|
||||
Slic3r::debugf "layers: min = %s, max = %s\n", $min_layer, $max_layer
|
||||
if $Slic3r::debug;
|
||||
|
||||
my $lines = {}; # layer_id => [ lines ]
|
||||
for (my $layer_id = $min_layer; $layer_id <= $max_layer; $layer_id++) {
|
||||
for my $layer_id ($min_layer .. $max_layer) {
|
||||
my $layer = $print_object->layers->[$layer_id];
|
||||
$lines->{$layer_id} ||= [];
|
||||
push @{ $lines->{$layer_id} }, $self->intersect_facet($facet_id, $layer->slice_z);
|
||||
|
@ -451,25 +454,27 @@ sub intersect_facet {
|
|||
my ($facet_id, $z) = @_;
|
||||
|
||||
my @vertices_ids = @{$self->facets->[$facet_id]}[-3..-1];
|
||||
my %vertices = map { $_ => $self->vertices->[$_] } @vertices_ids; # cache vertices
|
||||
my @edge_ids = @{$self->facets_edges->[$facet_id]};
|
||||
my @edge_vertices_ids = $self->_facet_edges($facet_id);
|
||||
|
||||
my (@lines, @points, @intersection_points, @points_on_layer) = ();
|
||||
my (@points, @intersection_points, @points_on_layer) = ();
|
||||
|
||||
for my $e (0..2) {
|
||||
my $edge_id = $edge_ids[$e];
|
||||
my ($a_id, $b_id) = @{$edge_vertices_ids[$e]};
|
||||
my ($a, $b) = map $self->vertices->[$_], ($a_id, $b_id);
|
||||
my ($a, $b) = @vertices{$a_id, $b_id};
|
||||
#printf "Az = %f, Bz = %f, z = %f\n", $a->[Z], $b->[Z], $z;
|
||||
|
||||
if ($a->[Z] == $b->[Z] && $a->[Z] == $z) {
|
||||
# edge is horizontal and belongs to the current layer
|
||||
my $edge_type = (grep $self->vertices->[$_][Z] < $z, @vertices_ids) ? FE_TOP : FE_BOTTOM;
|
||||
my $edge_type = (grep $vertices{$_}[Z] < $z, @vertices_ids) ? FE_TOP : FE_BOTTOM;
|
||||
if ($edge_type == FE_TOP) {
|
||||
($a, $b) = ($b, $a);
|
||||
($a_id, $b_id) = ($b_id, $a_id);
|
||||
}
|
||||
push @lines, pack I_FMT, (
|
||||
# We assume that this method is never being called for horizontal
|
||||
# facets, so no other edge is going to be on this layer.
|
||||
return pack I_FMT, (
|
||||
$b->[X], $b->[Y], # I_B
|
||||
$a_id, # I_A_ID
|
||||
$b_id, # I_B_ID
|
||||
|
@ -499,14 +504,13 @@ sub intersect_facet {
|
|||
$b->[X] + ($a->[X] - $b->[X]) * ($z - $b->[Z]) / ($a->[Z] - $b->[Z]),
|
||||
$b->[Y] + ($a->[Y] - $b->[Y]) * ($z - $b->[Z]) / ($a->[Z] - $b->[Z]),
|
||||
undef,
|
||||
$edge_id,
|
||||
$edge_ids[$e],
|
||||
];
|
||||
push @intersection_points, $#points;
|
||||
#print "Intersects at $z!\n";
|
||||
}
|
||||
}
|
||||
|
||||
return @lines if @lines;
|
||||
if (@points_on_layer == 2 && @intersection_points == 1) {
|
||||
$points[ $points_on_layer[1] ] = undef;
|
||||
@points = grep $_, @points;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use Test::More tests => 3;
|
||||
use Test::More tests => 5;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
@ -41,6 +41,37 @@ use Slic3r::Test;
|
|||
ok !$has_cw_loops, 'all perimeters extruded ccw';
|
||||
}
|
||||
|
||||
{
|
||||
$config->set('external_perimeter_speed', 68);
|
||||
my $print = Slic3r::Test::init_print('cube_with_hole', config => $config);
|
||||
my $has_cw_loops = my $has_outwards_move = 0;
|
||||
my $cur_loop;
|
||||
my %external_loops = (); # print_z => count of external loops
|
||||
Slic3r::GCode::Reader->new(gcode => Slic3r::Test::gcode($print))->parse(sub {
|
||||
my ($self, $cmd, $args, $info) = @_;
|
||||
|
||||
if ($info->{extruding} && $info->{dist_XY} > 0) {
|
||||
$cur_loop ||= [ [$self->X, $self->Y] ];
|
||||
push @$cur_loop, [ @$info{qw(new_X new_Y)} ];
|
||||
} else {
|
||||
if ($cur_loop) {
|
||||
$has_cw_loops = 1 if !Slic3r::Geometry::Clipper::is_counter_clockwise($cur_loop);
|
||||
if ($self->F == $config->external_perimeter_speed*60) {
|
||||
my $move_dest = [ @$info{qw(new_X new_Y)} ];
|
||||
$external_loops{$self->Z}++;
|
||||
$has_outwards_move = 1
|
||||
if !Slic3r::Polygon->new(@$cur_loop)->encloses_point($move_dest)
|
||||
? ($external_loops{$self->Z} == 2) # contour should include destination
|
||||
: ($external_loops{$self->Z} == 1); # hole should not
|
||||
}
|
||||
$cur_loop = undef;
|
||||
}
|
||||
}
|
||||
});
|
||||
ok !$has_cw_loops, 'all perimeters extruded ccw';
|
||||
ok !$has_outwards_move, 'move inwards after completing external loop';
|
||||
}
|
||||
|
||||
{
|
||||
my $print = Slic3r::Test::init_print('L', config => $config);
|
||||
my $loop_starts_from_convex_point = 0;
|
||||
|
|
14
t/slice.t
14
t/slice.t
|
@ -2,7 +2,7 @@ use Test::More;
|
|||
use strict;
|
||||
use warnings;
|
||||
|
||||
plan tests => 17;
|
||||
plan tests => 16;
|
||||
|
||||
BEGIN {
|
||||
use FindBin;
|
||||
|
@ -20,11 +20,13 @@ my @points = ([3, 4], [8, 5], [1, 9]); # XY coordinates of the facet vertices
|
|||
# the first point of the intersection lines is replaced by -1 because TriangleMesh.pm
|
||||
# is saving memory and doesn't store point A anymore since it's not actually needed.
|
||||
|
||||
is_deeply lines(20, 20, 20), [
|
||||
[ -1, $points[1] ], # $points[0]
|
||||
[ -1, $points[2] ], # $points[1]
|
||||
[ -1, $points[0] ], # $points[2]
|
||||
], 'horizontal';
|
||||
# We disable this test because intersect_facet() now assumes we never feed a horizontal
|
||||
# facet to it.
|
||||
# is_deeply lines(20, 20, 20), [
|
||||
# [ -1, $points[1] ], # $points[0]
|
||||
# [ -1, $points[2] ], # $points[1]
|
||||
# [ -1, $points[0] ], # $points[2]
|
||||
# ], 'horizontal';
|
||||
|
||||
is_deeply lines(22, 20, 20), [ [ -1, $points[2] ] ], 'lower edge on layer'; # $points[1]
|
||||
is_deeply lines(20, 20, 22), [ [ -1, $points[1] ] ], 'lower edge on layer'; # $points[0]
|
||||
|
|
Loading…
Reference in a new issue