mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-11-02 04:31:17 -07:00
Add the full source of BambuStudio
using version 1.0.10
This commit is contained in:
parent
30bcadab3e
commit
1555904bef
3771 changed files with 1251328 additions and 0 deletions
35
xs/t/01_trianglemesh.t
Normal file
35
xs/t/01_trianglemesh.t
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 5;
|
||||
|
||||
my $cube = {
|
||||
vertices => [ [20,20,0], [20,0,0], [0,0,0], [0,20,0], [20,20,20], [0,20,20], [0,0,20], [20,0,20] ],
|
||||
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] ],
|
||||
};
|
||||
|
||||
{
|
||||
my $m = Slic3r::TriangleMesh->new;
|
||||
$m->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
||||
my ($vertices, $facets) = ($m->vertices, $m->facets);
|
||||
|
||||
is_deeply $vertices, $cube->{vertices}, 'vertices arrayref roundtrip';
|
||||
is_deeply $facets, $cube->{facets}, 'facets arrayref roundtrip';
|
||||
|
||||
{
|
||||
my $m2 = $m->clone;
|
||||
is_deeply $m2->vertices, $cube->{vertices}, 'cloned vertices arrayref roundtrip';
|
||||
is_deeply $m2->facets, $cube->{facets}, 'cloned facets arrayref roundtrip';
|
||||
$m2->scale(3); # check that it does not affect $m
|
||||
}
|
||||
|
||||
{
|
||||
my $stats = $m->stats;
|
||||
is $stats->{number_of_facets}, scalar(@{ $cube->{facets} }), 'stats.number_of_facets';
|
||||
}
|
||||
}
|
||||
|
||||
__END__
|
||||
84
xs/t/03_point.t
Normal file
84
xs/t/03_point.t
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 24;
|
||||
|
||||
my $point = Slic3r::Point->new(10, 15);
|
||||
is_deeply [ @$point ], [10, 15], 'point roundtrip';
|
||||
|
||||
my $point2 = $point->clone;
|
||||
$point2->scale(2);
|
||||
is_deeply [ @$point2 ], [20, 30], 'scale';
|
||||
|
||||
$point2->translate(10, -15);
|
||||
is_deeply [ @$point2 ], [30, 15], 'translate';
|
||||
|
||||
ok $point->coincides_with($point->clone), 'coincides_with';
|
||||
ok !$point->coincides_with($point2), 'coincides_with';
|
||||
|
||||
{
|
||||
my $point3 = Slic3r::Point->new(4300000, -9880845);
|
||||
is $point->[0], $point->x, 'x accessor';
|
||||
is $point->[1], $point->y, 'y accessor'; #,,
|
||||
}
|
||||
|
||||
{
|
||||
my $nearest = $point->nearest_point([ $point2, Slic3r::Point->new(100, 200) ]);
|
||||
ok $nearest->coincides_with($point2), 'nearest_point';
|
||||
}
|
||||
|
||||
{
|
||||
my $line = Slic3r::Line->new([0,0], [100,0]);
|
||||
is +Slic3r::Point->new(0,0) ->distance_to_line($line), 0, 'distance_to_line()';
|
||||
is +Slic3r::Point->new(100,0)->distance_to_line($line), 0, 'distance_to_line()';
|
||||
is +Slic3r::Point->new(50,0) ->distance_to_line($line), 0, 'distance_to_line()';
|
||||
is +Slic3r::Point->new(150,0)->distance_to_line($line), 50, 'distance_to_line()';
|
||||
is +Slic3r::Point->new(0,50) ->distance_to_line($line), 50, 'distance_to_line()';
|
||||
is +Slic3r::Point->new(50,50)->distance_to_line($line), 50, 'distance_to_line()';
|
||||
is +Slic3r::Point->new(50,50) ->perp_distance_to_line($line), 50, 'perp_distance_to_line()';
|
||||
is +Slic3r::Point->new(150,50)->perp_distance_to_line($line), 50, 'perp_distance_to_line()';
|
||||
}
|
||||
|
||||
{
|
||||
my $line = Slic3r::Line->new([50,50], [125,-25]);
|
||||
cmp_ok(abs(Slic3r::Point->new(100,0)->distance_to_line($line)), '<=', 4e-15, 'distance_to_line()');
|
||||
}
|
||||
|
||||
{
|
||||
my $line = Slic3r::Line->new(
|
||||
[18335846,18335845],
|
||||
[18335846,1664160],
|
||||
);
|
||||
$point = Slic3r::Point->new(1664161,18335848);
|
||||
is $point->perp_distance_to_line($line), 16671685, 'perp_distance_to_line() does not overflow';
|
||||
}
|
||||
|
||||
{
|
||||
my $p0 = Slic3r::Point->new(76975850,89989996);
|
||||
my $p1 = Slic3r::Point->new(76989990,109989991);
|
||||
my $p2 = Slic3r::Point->new(76989987,89989994);
|
||||
ok $p0->ccw($p1, $p2) < 0, 'ccw() does not overflow';
|
||||
}
|
||||
|
||||
{
|
||||
my $point = Slic3r::Point->new(15,15);
|
||||
my $line = Slic3r::Line->new([10,10], [20,10]);
|
||||
is_deeply $point->projection_onto_line($line)->pp, [15,10], 'project_onto_line';
|
||||
|
||||
$point = Slic3r::Point->new(0, 15);
|
||||
is_deeply $point->projection_onto_line($line)->pp, [10,10], 'project_onto_line';
|
||||
|
||||
$point = Slic3r::Point->new(25, 15);
|
||||
is_deeply $point->projection_onto_line($line)->pp, [20,10], 'project_onto_line';
|
||||
|
||||
$point = Slic3r::Point->new(10,10);
|
||||
is_deeply $point->projection_onto_line($line)->pp, [10,10], 'project_onto_line';
|
||||
|
||||
$point = Slic3r::Point->new(12, 10);
|
||||
is_deeply $point->projection_onto_line($line)->pp, [12,10], 'project_onto_line';
|
||||
}
|
||||
|
||||
__END__
|
||||
108
xs/t/04_expolygon.t
Normal file
108
xs/t/04_expolygon.t
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use List::Util qw(first sum);
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 21;
|
||||
|
||||
use constant PI => 4 * atan2(1, 1);
|
||||
|
||||
my $square = [ # ccw
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
[200, 200],
|
||||
[100, 200],
|
||||
];
|
||||
my $hole_in_square = [ # cw
|
||||
[140, 140],
|
||||
[140, 160],
|
||||
[160, 160],
|
||||
[160, 140],
|
||||
];
|
||||
|
||||
my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square);
|
||||
|
||||
ok $expolygon->is_valid, 'is_valid';
|
||||
is ref($expolygon->pp), 'ARRAY', 'expolygon pp is unblessed';
|
||||
is_deeply $expolygon->pp, [$square, $hole_in_square], 'expolygon roundtrip';
|
||||
|
||||
is ref($expolygon->arrayref), 'ARRAY', 'expolygon arrayref is unblessed';
|
||||
isa_ok $expolygon->[0], 'Slic3r::Polygon::Ref', 'expolygon polygon is blessed';
|
||||
isa_ok $expolygon->contour, 'Slic3r::Polygon::Ref', 'expolygon contour is blessed';
|
||||
isa_ok $expolygon->holes->[0], 'Slic3r::Polygon::Ref', 'expolygon hole is blessed';
|
||||
isa_ok $expolygon->[0][0], 'Slic3r::Point::Ref', 'expolygon point is blessed';
|
||||
|
||||
{
|
||||
my $expolygon2 = $expolygon->clone;
|
||||
my $polygon = $expolygon2->[0];
|
||||
$polygon->scale(2);
|
||||
is $expolygon2->[0][0][0], $polygon->[0][0], 'polygons are returned by reference';
|
||||
}
|
||||
|
||||
is_deeply $expolygon->clone->pp, [$square, $hole_in_square], 'clone';
|
||||
|
||||
is $expolygon->area, 100*100-20*20, 'area';
|
||||
|
||||
{
|
||||
my $expolygon2 = $expolygon->clone;
|
||||
$expolygon2->scale(2.5);
|
||||
is_deeply $expolygon2->pp, [
|
||||
[map [ 2.5*$_->[0], 2.5*$_->[1] ], @$square],
|
||||
[map [ 2.5*$_->[0], 2.5*$_->[1] ], @$hole_in_square]
|
||||
], 'scale';
|
||||
}
|
||||
|
||||
{
|
||||
my $expolygon2 = $expolygon->clone;
|
||||
$expolygon2->translate(10, -5);
|
||||
is_deeply $expolygon2->pp, [
|
||||
[map [ $_->[0]+10, $_->[1]-5 ], @$square],
|
||||
[map [ $_->[0]+10, $_->[1]-5 ], @$hole_in_square]
|
||||
], 'translate';
|
||||
}
|
||||
|
||||
{
|
||||
my $expolygon2 = $expolygon->clone;
|
||||
$expolygon2->rotate(PI/2, Slic3r::Point->new(150,150));
|
||||
is_deeply $expolygon2->pp, [
|
||||
[ @$square[1,2,3,0] ],
|
||||
[ @$hole_in_square[3,0,1,2] ]
|
||||
], 'rotate around Point';
|
||||
}
|
||||
|
||||
{
|
||||
my $expolygon2 = $expolygon->clone;
|
||||
$expolygon2->rotate(PI/2, [150,150]);
|
||||
is_deeply $expolygon2->pp, [
|
||||
[ @$square[1,2,3,0] ],
|
||||
[ @$hole_in_square[3,0,1,2] ]
|
||||
], 'rotate around pure-Perl Point';
|
||||
}
|
||||
|
||||
{
|
||||
my $expolygon2 = $expolygon->clone;
|
||||
$expolygon2->scale(2);
|
||||
my $collection = Slic3r::ExPolygon::Collection->new($expolygon->pp, $expolygon2->pp);
|
||||
is_deeply $collection->pp, [ $expolygon->pp, $expolygon2->pp ],
|
||||
'expolygon collection (pure Perl) roundtrip';
|
||||
|
||||
my $collection2 = Slic3r::ExPolygon::Collection->new($expolygon, $expolygon2);
|
||||
is_deeply $collection->pp, $collection2->pp,
|
||||
'expolygon collection (XS) roundtrip';
|
||||
|
||||
$collection->clear;
|
||||
is scalar(@$collection), 0, 'clear collection';
|
||||
|
||||
$collection->append($expolygon);
|
||||
is scalar(@$collection), 1, 'append to collection';
|
||||
|
||||
my $exp = $collection->[0];
|
||||
$exp->scale(3);
|
||||
is $collection->[0][0][0][0], $exp->[0][0][0], 'collection items are returned by reference';
|
||||
|
||||
is_deeply $collection->[0]->clone->pp, $collection->[0]->pp, 'clone collection item';
|
||||
}
|
||||
|
||||
__END__
|
||||
76
xs/t/05_surface.t
Normal file
76
xs/t/05_surface.t
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 15;
|
||||
|
||||
my $square = [ # ccw
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
[200, 200],
|
||||
[100, 200],
|
||||
];
|
||||
my $hole_in_square = [ # cw
|
||||
[140, 140],
|
||||
[140, 160],
|
||||
[160, 160],
|
||||
[160, 140],
|
||||
];
|
||||
|
||||
my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square);
|
||||
my $surface = Slic3r::Surface->new(
|
||||
expolygon => $expolygon,
|
||||
surface_type => Slic3r::Surface::S_TYPE_INTERNAL,
|
||||
);
|
||||
|
||||
$surface = $surface->clone;
|
||||
|
||||
isa_ok $surface->expolygon, 'Slic3r::ExPolygon::Ref', 'expolygon';
|
||||
is_deeply [ @{$surface->expolygon->pp} ], [$square, $hole_in_square], 'expolygon roundtrip';
|
||||
is scalar(@{$surface->polygons}), 2, 'polygons roundtrip';
|
||||
|
||||
is $surface->surface_type, Slic3r::Surface::S_TYPE_INTERNAL, 'surface_type';
|
||||
$surface->surface_type(Slic3r::Surface::S_TYPE_BOTTOM);
|
||||
is $surface->surface_type, Slic3r::Surface::S_TYPE_BOTTOM, 'modify surface_type';
|
||||
|
||||
$surface->bridge_angle(30);
|
||||
is $surface->bridge_angle, 30, 'bridge_angle';
|
||||
|
||||
$surface->extra_perimeters(2);
|
||||
is $surface->extra_perimeters, 2, 'extra_perimeters';
|
||||
|
||||
{
|
||||
my $surface2 = $surface->clone;
|
||||
$surface2->expolygon->scale(2);
|
||||
isnt $surface2->expolygon->area, $expolygon->area, 'expolygon is returned by reference';
|
||||
}
|
||||
|
||||
{
|
||||
my $collection = Slic3r::Surface::Collection->new;
|
||||
$collection->append($_) for $surface, $surface->clone;
|
||||
is scalar(@$collection), 2, 'collection has the right number of items';
|
||||
is_deeply $collection->[0]->expolygon->pp, [$square, $hole_in_square],
|
||||
'collection returns a correct surface expolygon';
|
||||
$collection->clear;
|
||||
is scalar(@$collection), 0, 'clear collection';
|
||||
$collection->append($surface);
|
||||
is scalar(@$collection), 1, 'append to collection';
|
||||
|
||||
my $item = $collection->[0];
|
||||
isa_ok $item, 'Slic3r::Surface::Ref';
|
||||
$item->surface_type(Slic3r::Surface::S_TYPE_INTERNAL);
|
||||
is $item->surface_type, $collection->[0]->surface_type, 'collection returns items by reference';
|
||||
}
|
||||
|
||||
{
|
||||
my $collection = Slic3r::Surface::Collection->new;
|
||||
$collection->append($_) for
|
||||
Slic3r::Surface->new(expolygon => $expolygon, surface_type => Slic3r::Surface::S_TYPE_BOTTOM),
|
||||
Slic3r::Surface->new(expolygon => $expolygon, surface_type => Slic3r::Surface::S_TYPE_BOTTOM),
|
||||
Slic3r::Surface->new(expolygon => $expolygon, surface_type => Slic3r::Surface::S_TYPE_TOP);
|
||||
is scalar(@{$collection->group}), 2, 'group() returns correct number of groups';
|
||||
}
|
||||
|
||||
__END__
|
||||
21
xs/t/06_polygon.t
Normal file
21
xs/t/06_polygon.t
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 3;
|
||||
|
||||
my $square = [ # ccw
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
[200, 200],
|
||||
[100, 200],
|
||||
];
|
||||
|
||||
my $polygon = Slic3r::Polygon->new(@$square);
|
||||
is ref($polygon->arrayref), 'ARRAY', 'polygon arrayref is unblessed';
|
||||
isa_ok $polygon->[0], 'Slic3r::Point::Ref', 'polygon point is blessed';
|
||||
ok ref($polygon->first_point) eq 'Slic3r::Point', 'first_point';
|
||||
|
||||
__END__
|
||||
38
xs/t/07_extrusionpath.t
Normal file
38
xs/t/07_extrusionpath.t
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 7;
|
||||
|
||||
my $points = [
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
[200, 200],
|
||||
];
|
||||
|
||||
my $path = Slic3r::ExtrusionPath->new(
|
||||
polyline => Slic3r::Polyline->new(@$points),
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
mm3_per_mm => 1,
|
||||
);
|
||||
isa_ok $path->polyline, 'Slic3r::Polyline::Ref', 'path polyline';
|
||||
is_deeply $path->polyline->pp, $points, 'path points roundtrip';
|
||||
|
||||
$path->reverse;
|
||||
is_deeply $path->polyline->pp, [ reverse @$points ], 'reverse path';
|
||||
|
||||
$path->append([ 150, 150 ]);
|
||||
is scalar(@$path), 4, 'append to path';
|
||||
|
||||
$path->pop_back;
|
||||
is scalar(@$path), 3, 'pop_back from path';
|
||||
|
||||
ok $path->first_point->coincides_with($path->polyline->[0]), 'first_point';
|
||||
|
||||
$path = $path->clone;
|
||||
|
||||
is $path->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'role';
|
||||
|
||||
__END__
|
||||
158
xs/t/08_extrusionloop.t
Normal file
158
xs/t/08_extrusionloop.t
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use List::Util qw(sum);
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 47;
|
||||
|
||||
{
|
||||
my $square = [
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
[200, 200],
|
||||
[100, 200],
|
||||
];
|
||||
my $square_p = Slic3r::Polygon->new(@$square);
|
||||
|
||||
my $loop = Slic3r::ExtrusionLoop->new;
|
||||
$loop->append(Slic3r::ExtrusionPath->new(
|
||||
polyline => $square_p->split_at_first_point,
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
mm3_per_mm => 1,
|
||||
));
|
||||
|
||||
isa_ok $loop, 'Slic3r::ExtrusionLoop';
|
||||
isa_ok $loop->polygon, 'Slic3r::Polygon', 'loop polygon';
|
||||
is $loop->polygon->area, $square_p->area, 'polygon area';
|
||||
is $loop->length, $square_p->length(), 'loop length';
|
||||
|
||||
$loop = $loop->clone;
|
||||
|
||||
is scalar(@$loop), 1, 'loop contains one path';
|
||||
{
|
||||
my $path = $loop->[0];
|
||||
isa_ok $path, 'Slic3r::ExtrusionPath::Ref';
|
||||
is $path->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'role';
|
||||
}
|
||||
|
||||
$loop->split_at_vertex($square_p->[2]);
|
||||
is scalar(@$loop), 1, 'splitting a single-path loop results in a single path';
|
||||
is scalar(@{$loop->[0]->polyline}), 5, 'path has correct number of points';
|
||||
ok $loop->[0]->polyline->[0]->coincides_with($square_p->[2]), 'expected point order';
|
||||
ok $loop->[0]->polyline->[1]->coincides_with($square_p->[3]), 'expected point order';
|
||||
ok $loop->[0]->polyline->[2]->coincides_with($square_p->[0]), 'expected point order';
|
||||
ok $loop->[0]->polyline->[3]->coincides_with($square_p->[1]), 'expected point order';
|
||||
ok $loop->[0]->polyline->[4]->coincides_with($square_p->[2]), 'expected point order';
|
||||
}
|
||||
|
||||
{
|
||||
my $polyline1 = Slic3r::Polyline->new([100,100], [200,100], [200,200]);
|
||||
my $polyline2 = Slic3r::Polyline->new([200,200], [100,200], [100,100]);
|
||||
|
||||
my $loop = Slic3r::ExtrusionLoop->new_from_paths(
|
||||
Slic3r::ExtrusionPath->new(
|
||||
polyline => $polyline1,
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
mm3_per_mm => 1,
|
||||
),
|
||||
Slic3r::ExtrusionPath->new(
|
||||
polyline => $polyline2,
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER,
|
||||
mm3_per_mm => 1,
|
||||
),
|
||||
);
|
||||
my $tot_len = sum($polyline1->length, $polyline2->length);
|
||||
is $loop->length, $tot_len, 'length';
|
||||
is scalar(@$loop), 2, 'loop contains two paths';
|
||||
|
||||
{
|
||||
# check splitting at intermediate point
|
||||
my $loop2 = $loop->clone;
|
||||
isa_ok $loop2, 'Slic3r::ExtrusionLoop';
|
||||
$loop2->split_at_vertex($polyline1->[1]);
|
||||
is $loop2->length, $tot_len, 'length after splitting is unchanged';
|
||||
is scalar(@$loop2), 3, 'loop contains three paths after splitting';
|
||||
ok $loop2->[0]->polyline->[0]->coincides_with($polyline1->[1]), 'expected starting point';
|
||||
ok $loop2->[-1]->polyline->[-1]->coincides_with($polyline1->[1]), 'expected ending point';
|
||||
ok $loop2->[0]->polyline->[-1]->coincides_with($loop2->[1]->polyline->[0]), 'paths have common point';
|
||||
ok $loop2->[1]->polyline->[-1]->coincides_with($loop2->[2]->polyline->[0]), 'paths have common point';
|
||||
is $loop2->[0]->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'expected order after splitting';
|
||||
is $loop2->[1]->role, Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, 'expected order after splitting';
|
||||
is $loop2->[2]->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'expected order after splitting';
|
||||
is scalar(@{$loop2->[0]->polyline}), 2, 'path has correct number of points';
|
||||
is scalar(@{$loop2->[1]->polyline}), 3, 'path has correct number of points';
|
||||
is scalar(@{$loop2->[2]->polyline}), 2, 'path has correct number of points';
|
||||
|
||||
my @paths = @{$loop2->clip_end(3)};
|
||||
is sum(map $_->length, @paths), $loop2->length - 3, 'returned paths have expected length';
|
||||
}
|
||||
|
||||
{
|
||||
# check splitting at endpoint
|
||||
my $loop2 = $loop->clone;
|
||||
$loop2->split_at_vertex($polyline2->[0]);
|
||||
is $loop2->length, $tot_len, 'length after splitting is unchanged';
|
||||
is scalar(@$loop2), 2, 'loop contains two paths after splitting';
|
||||
ok $loop2->[0]->polyline->[0]->coincides_with($polyline2->[0]), 'expected starting point';
|
||||
ok $loop2->[-1]->polyline->[-1]->coincides_with($polyline2->[0]), 'expected ending point';
|
||||
ok $loop2->[0]->polyline->[-1]->coincides_with($loop2->[1]->polyline->[0]), 'paths have common point';
|
||||
ok $loop2->[1]->polyline->[-1]->coincides_with($loop2->[0]->polyline->[0]), 'paths have common point';
|
||||
is $loop2->[0]->role, Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, 'expected order after splitting';
|
||||
is $loop2->[1]->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'expected order after splitting';
|
||||
is scalar(@{$loop2->[0]->polyline}), 3, 'path has correct number of points';
|
||||
is scalar(@{$loop2->[1]->polyline}), 3, 'path has correct number of points';
|
||||
}
|
||||
|
||||
{
|
||||
my $loop2 = $loop->clone;
|
||||
my $point = Slic3r::Point->new(250,150);
|
||||
$loop2->split_at($point);
|
||||
is $loop2->length, $tot_len, 'length after splitting is unchanged';
|
||||
is scalar(@$loop2), 3, 'loop contains three paths after splitting';
|
||||
my $expected_start_point = Slic3r::Point->new(200,150);
|
||||
ok $loop2->[0]->polyline->[0]->coincides_with($expected_start_point), 'expected starting point';
|
||||
ok $loop2->[-1]->polyline->[-1]->coincides_with($expected_start_point), 'expected ending point';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my @polylines = (
|
||||
Slic3r::Polyline->new([59312736,4821067],[64321068,4821067],[64321068,4821067],[64321068,9321068],[59312736,9321068]),
|
||||
Slic3r::Polyline->new([59312736,9321068],[9829401,9321068]),
|
||||
Slic3r::Polyline->new([9829401,9321068],[4821067,9321068],[4821067,4821067],[9829401,4821067]),
|
||||
Slic3r::Polyline->new([9829401,4821067],[59312736,4821067]),
|
||||
);
|
||||
my $loop = Slic3r::ExtrusionLoop->new;
|
||||
$loop->append($_) for (
|
||||
Slic3r::ExtrusionPath->new(polyline => $polylines[0], role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1),
|
||||
Slic3r::ExtrusionPath->new(polyline => $polylines[1], role => Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, mm3_per_mm => 1),
|
||||
Slic3r::ExtrusionPath->new(polyline => $polylines[2], role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1),
|
||||
Slic3r::ExtrusionPath->new(polyline => $polylines[3], role => Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, mm3_per_mm => 1),
|
||||
);
|
||||
my $len = $loop->length;
|
||||
my $point = Slic3r::Point->new(4821067,9321068);
|
||||
$loop->split_at_vertex($point) or $loop->split_at($point);
|
||||
is $loop->length, $len, 'total length is preserved after splitting';
|
||||
is_deeply [ map $_->role, @$loop ], [
|
||||
Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER,
|
||||
Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER,
|
||||
Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
], 'order is correctly preserved after splitting';
|
||||
}
|
||||
|
||||
{
|
||||
my $loop = Slic3r::ExtrusionLoop->new;
|
||||
$loop->append(Slic3r::ExtrusionPath->new(
|
||||
polyline => Slic3r::Polyline->new([15896783,15868739],[24842049,12117558],[33853238,15801279],[37591780,24780128],[37591780,24844970],[33853231,33825297],[24842049,37509013],[15896798,33757841],[12211841,24812544],[15896783,15868739]),
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1
|
||||
));
|
||||
my $len = $loop->length;
|
||||
$loop->split_at(Slic3r::Point->new(15896783,15868739));
|
||||
is $loop->length, $len, 'split_at() preserves total length';
|
||||
}
|
||||
|
||||
__END__
|
||||
128
xs/t/09_polyline.t
Normal file
128
xs/t/09_polyline.t
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 18;
|
||||
|
||||
my $points = [
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
[200, 200],
|
||||
];
|
||||
|
||||
my $polyline = Slic3r::Polyline->new(@$points);
|
||||
|
||||
is_deeply $polyline->pp, $points, 'polyline roundtrip';
|
||||
|
||||
is ref($polyline->arrayref), 'ARRAY', 'polyline arrayref is unblessed';
|
||||
isa_ok $polyline->[0], 'Slic3r::Point::Ref', 'polyline point is blessed';
|
||||
|
||||
my $lines = $polyline->lines;
|
||||
is_deeply [ map $_->pp, @$lines ], [
|
||||
[ [100, 100], [200, 100] ],
|
||||
[ [200, 100], [200, 200] ],
|
||||
], 'polyline lines';
|
||||
|
||||
$polyline->append_polyline($polyline->clone);
|
||||
is_deeply $polyline->pp, [ @$points, @$points ], 'append_polyline';
|
||||
|
||||
{
|
||||
my $len = $polyline->length;
|
||||
$polyline->clip_end($len/3);
|
||||
ok abs($polyline->length - ($len-($len/3))) < 1, 'clip_end';
|
||||
}
|
||||
|
||||
{
|
||||
my $polyline = Slic3r::Polyline->new(
|
||||
[0,0], [20,0], [50,0], [80,0], [100,0],
|
||||
);
|
||||
$polyline->simplify(2);
|
||||
is_deeply $polyline->pp, [ [0,0], [100,0] ], 'Douglas-Peucker';
|
||||
}
|
||||
|
||||
{
|
||||
my $polyline = Slic3r::Polyline->new(
|
||||
[0,0], [50,50], [100,0], [125,-25], [150,50],
|
||||
);
|
||||
$polyline->simplify(25);
|
||||
is_deeply $polyline->pp, [ [0, 0], [50, 50], [125, -25], [150, 50] ], 'Douglas-Peucker';
|
||||
}
|
||||
|
||||
{
|
||||
my $polyline = Slic3r::Polyline->new(
|
||||
[0,0], [100,0], [50,10],
|
||||
);
|
||||
$polyline->simplify(25);
|
||||
is_deeply $polyline->pp, [ [0,0], [100,0], [50,10] ], 'Douglas-Peucker uses shortest distance instead of perpendicular distance';
|
||||
}
|
||||
|
||||
{
|
||||
my $polyline = Slic3r::Polyline->new(@$points);
|
||||
is $polyline->length, 100*2, 'length';
|
||||
$polyline->extend_end(50);
|
||||
is $polyline->length, 100*2 + 50, 'extend_end';
|
||||
$polyline->extend_start(50);
|
||||
is $polyline->length, 100*2 + 50 + 50, 'extend_start';
|
||||
}
|
||||
|
||||
{
|
||||
my $polyline = Slic3r::Polyline->new(@$points);
|
||||
my $p1 = Slic3r::Polyline->new;
|
||||
my $p2 = Slic3r::Polyline->new;
|
||||
my $point = Slic3r::Point->new(150, 100);
|
||||
$polyline->split_at($point, $p1, $p2);
|
||||
is scalar(@$p1), 2, 'split_at';
|
||||
is scalar(@$p2), 3, 'split_at';
|
||||
ok $p1->last_point->coincides_with($point), 'split_at';
|
||||
ok $p2->first_point->coincides_with($point), 'split_at';
|
||||
}
|
||||
|
||||
{
|
||||
my $polyline = Slic3r::Polyline->new(@$points[0,1,2,0]);
|
||||
my $p1 = Slic3r::Polyline->new;
|
||||
my $p2 = Slic3r::Polyline->new;
|
||||
$polyline->split_at($polyline->first_point, $p1, $p2);
|
||||
is scalar(@$p1), 1, 'split_at';
|
||||
is scalar(@$p2), 4, 'split_at';
|
||||
}
|
||||
|
||||
# disabled because we now use a more efficient but incomplete algorithm
|
||||
#if (0) {
|
||||
# my $polyline = Slic3r::Polyline->new(
|
||||
# map [$_,10], (0,10,20,30,40,50,60)
|
||||
# );
|
||||
# {
|
||||
# my $expolygon = Slic3r::ExPolygon->new(Slic3r::Polygon->new(
|
||||
# [25,0], [55,0], [55,30], [25,30],
|
||||
# ));
|
||||
# my $p = $polyline->clone;
|
||||
# $p->simplify_by_visibility($expolygon);
|
||||
# is_deeply $p->pp, [
|
||||
# map [$_,10], (0,10,20,30,50,60)
|
||||
# ], 'simplify_by_visibility()';
|
||||
# }
|
||||
# {
|
||||
# my $expolygon = Slic3r::ExPolygon->new(Slic3r::Polygon->new(
|
||||
# [-15,0], [75,0], [75,30], [-15,30],
|
||||
# ));
|
||||
# my $p = $polyline->clone;
|
||||
# $p->simplify_by_visibility($expolygon);
|
||||
# is_deeply $p->pp, [
|
||||
# map [$_,10], (0,60)
|
||||
# ], 'simplify_by_visibility()';
|
||||
# }
|
||||
# {
|
||||
# my $expolygon = Slic3r::ExPolygon->new(Slic3r::Polygon->new(
|
||||
# [-15,0], [25,0], [25,30], [-15,30],
|
||||
# ));
|
||||
# my $p = $polyline->clone;
|
||||
# $p->simplify_by_visibility($expolygon);
|
||||
# is_deeply $p->pp, [
|
||||
# map [$_,10], (0,20,30,40,50,60)
|
||||
# ], 'simplify_by_visibility()';
|
||||
# }
|
||||
#}
|
||||
|
||||
__END__
|
||||
81
xs/t/10_line.t
Normal file
81
xs/t/10_line.t
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 40;
|
||||
|
||||
use constant PI => 4 * atan2(1, 1);
|
||||
use constant EPSILON => 1E-4;
|
||||
|
||||
my $points = [
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
];
|
||||
|
||||
my $line = Slic3r::Line->new(@$points);
|
||||
is_deeply $line->pp, $points, 'line roundtrip';
|
||||
|
||||
is ref($line->arrayref), 'ARRAY', 'line arrayref is unblessed';
|
||||
isa_ok $line->[0], 'Slic3r::Point::Ref', 'line point is blessed';
|
||||
|
||||
{
|
||||
my $clone = $line->clone;
|
||||
$clone->reverse;
|
||||
is_deeply $clone->pp, [ reverse @$points ], 'reverse';
|
||||
}
|
||||
|
||||
{
|
||||
my $line2 = Slic3r::Line->new($line->a->clone, $line->b->clone);
|
||||
is_deeply $line2->pp, $points, 'line roundtrip with cloned points';
|
||||
}
|
||||
|
||||
{
|
||||
my $clone = $line->clone;
|
||||
$clone->translate(10, -5);
|
||||
is_deeply $clone->pp, [
|
||||
[110, 95],
|
||||
[210, 95],
|
||||
], 'translate';
|
||||
}
|
||||
|
||||
{
|
||||
ok +Slic3r::Line->new([0,0],[200,0])->parallel_to_line(Slic3r::Line->new([200,200],[0,200])), 'parallel_to';
|
||||
}
|
||||
|
||||
foreach my $base_angle (0, PI/4, PI/2, PI) {
|
||||
my $line = Slic3r::Line->new([0,0], [100,0]);
|
||||
$line->rotate($base_angle, [0,0]);
|
||||
my $clone = $line->clone;
|
||||
ok $line->parallel_to_line($clone), 'line is parallel to self';
|
||||
$clone->reverse;
|
||||
ok $line->parallel_to_line($clone), 'line is parallel to self + PI';
|
||||
ok $line->parallel_to($line->direction), 'line is parallel to its direction';
|
||||
ok $line->parallel_to($line->direction + PI), 'line is parallel to its direction + PI';
|
||||
ok $line->parallel_to($line->direction - PI), 'line is parallel to its direction - PI';
|
||||
{
|
||||
my $line2 = $line->clone;
|
||||
$line2->reverse;
|
||||
ok $line->parallel_to_line($line2), 'line is parallel to its opposite';
|
||||
}
|
||||
{
|
||||
my $line2 = $line->clone;
|
||||
$line2->rotate(+(EPSILON)/2, [0,0]);
|
||||
ok $line->parallel_to_line($line2), 'line is parallel within epsilon';
|
||||
}
|
||||
{
|
||||
my $line2 = $line->clone;
|
||||
$line2->rotate(-(EPSILON)/2, [0,0]);
|
||||
ok $line->parallel_to_line($line2), 'line is parallel within epsilon';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $a = Slic3r::Line->new([100, 0], [200, 0]);
|
||||
my $b = Slic3r::Line->new([300, 300], [300, 100]);
|
||||
my $r = $a->intersection_infinite($b);
|
||||
is_deeply $r->pp, [300, 0], 'intersection_infinite';
|
||||
}
|
||||
|
||||
__END__
|
||||
97
xs/t/12_extrusionpathcollection.t
Normal file
97
xs/t/12_extrusionpathcollection.t
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 18;
|
||||
|
||||
my $points = [
|
||||
[100, 100],
|
||||
[200, 100],
|
||||
[200, 200],
|
||||
];
|
||||
|
||||
my $path = Slic3r::ExtrusionPath->new(
|
||||
polyline => Slic3r::Polyline->new(@$points),
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
mm3_per_mm => 1,
|
||||
);
|
||||
|
||||
my $loop = Slic3r::ExtrusionLoop->new_from_paths(
|
||||
Slic3r::ExtrusionPath->new(
|
||||
polyline => Slic3r::Polygon->new(@$points)->split_at_first_point,
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_FILL,
|
||||
mm3_per_mm => 1,
|
||||
),
|
||||
);
|
||||
|
||||
my $collection = Slic3r::ExtrusionPath::Collection->new(
|
||||
$path,
|
||||
);
|
||||
isa_ok $collection, 'Slic3r::ExtrusionPath::Collection', 'collection object with items in constructor';
|
||||
ok !$collection->no_sort, 'no_sort is false by default';
|
||||
|
||||
$collection->append($collection);
|
||||
is scalar(@$collection), 2, 'append ExtrusionPath::Collection';
|
||||
|
||||
$collection->append($path);
|
||||
is scalar(@$collection), 3, 'append ExtrusionPath';
|
||||
|
||||
$collection->append($loop);
|
||||
is scalar(@$collection), 4, 'append ExtrusionLoop';
|
||||
|
||||
isa_ok $collection->[1], 'Slic3r::ExtrusionPath::Collection::Ref', 'correct object returned for collection';
|
||||
isa_ok $collection->[2], 'Slic3r::ExtrusionPath::Ref', 'correct object returned for path';
|
||||
isa_ok $collection->[3], 'Slic3r::ExtrusionLoop::Ref', 'correct object returned for loop';
|
||||
is ref($collection->[2]->clone), 'Slic3r::ExtrusionPath', 'correct object returned for cloned path';
|
||||
is ref($collection->[3]->clone), 'Slic3r::ExtrusionLoop', 'correct object returned for cloned loop';
|
||||
|
||||
is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated';
|
||||
|
||||
{
|
||||
my $collection_loop = $collection->[3];
|
||||
$collection_loop->polygon->scale(2);
|
||||
is_deeply $collection->[3]->polygon->pp, $collection_loop->polygon->pp, 'items are returned by reference';
|
||||
}
|
||||
|
||||
{
|
||||
my $collection = Slic3r::ExtrusionPath::Collection->new(
|
||||
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1),
|
||||
Slic3r::Polyline->new([0,15], [0,18], [0,20]),
|
||||
Slic3r::Polyline->new([0,10], [0,8], [0,5]),
|
||||
);
|
||||
is_deeply
|
||||
[ map $_->y, map @{$_->polyline}, @{$collection->chained_path_from(Slic3r::Point->new(0,30), 0)} ],
|
||||
[20, 18, 15, 10, 8, 5],
|
||||
'chained_path_from';
|
||||
is_deeply
|
||||
[ map $_->y, map @{$_->polyline}, @{$collection->chained_path(0)} ],
|
||||
[15, 18, 20, 10, 8, 5],
|
||||
'chained_path';
|
||||
}
|
||||
|
||||
{
|
||||
my $collection = Slic3r::ExtrusionPath::Collection->new(
|
||||
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1),
|
||||
Slic3r::Polyline->new([15,0], [10,0], [4,0]),
|
||||
Slic3r::Polyline->new([10,5], [15,5], [20,5]),
|
||||
);
|
||||
is_deeply
|
||||
[ map $_->x, map @{$_->polyline}, @{$collection->chained_path_from(Slic3r::Point->new(30,0), 0)} ],
|
||||
[reverse 4, 10, 15, 10, 15, 20],
|
||||
'chained_path_from';
|
||||
|
||||
$collection->no_sort(1);
|
||||
my @foo = @{$collection->chained_path(0)};
|
||||
pass 'chained_path with no_sort';
|
||||
}
|
||||
|
||||
{
|
||||
my $coll2 = $collection->clone;
|
||||
ok !$coll2->no_sort, 'expected no_sort value';
|
||||
$coll2->no_sort(1);
|
||||
ok $coll2->clone->no_sort, 'no_sort is kept after clone';
|
||||
}
|
||||
|
||||
__END__
|
||||
35
xs/t/13_polylinecollection.t
Normal file
35
xs/t/13_polylinecollection.t
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 3;
|
||||
|
||||
{
|
||||
my $collection = Slic3r::Polyline::Collection->new(
|
||||
Slic3r::Polyline->new([0,15], [0,18], [0,20]),
|
||||
Slic3r::Polyline->new([0,10], [0,8], [0,5]),
|
||||
);
|
||||
is_deeply
|
||||
[ map $_->y, map @$_, @{$collection->chained_path_from(Slic3r::Point->new(0,30), 0)} ],
|
||||
[20, 18, 15, 10, 8, 5],
|
||||
'chained_path_from';
|
||||
is_deeply
|
||||
[ map $_->y, map @$_, @{$collection->chained_path(0)} ],
|
||||
[15, 18, 20, 10, 8, 5],
|
||||
'chained_path';
|
||||
}
|
||||
|
||||
{
|
||||
my $collection = Slic3r::Polyline::Collection->new(
|
||||
Slic3r::Polyline->new([15,0], [10,0], [4,0]),
|
||||
Slic3r::Polyline->new([10,5], [15,5], [20,5]),
|
||||
);
|
||||
is_deeply
|
||||
[ map $_->x, map @$_, @{$collection->chained_path_from(Slic3r::Point->new(30,0), 0)} ],
|
||||
[reverse 4, 10, 15, 10, 15, 20],
|
||||
'chained_path_from';
|
||||
}
|
||||
|
||||
__END__
|
||||
252
xs/t/15_config.t
Normal file
252
xs/t/15_config.t
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 143;
|
||||
|
||||
foreach my $config (Slic3r::Config->new, Slic3r::Config::Static::new_FullPrintConfig) {
|
||||
$config->set('layer_height', 0.3);
|
||||
ok abs($config->get('layer_height') - 0.3) < 1e-4, 'set/get float';
|
||||
is $config->opt_serialize('layer_height'), '0.3', 'serialize float';
|
||||
|
||||
$config->set('perimeters', 2);
|
||||
is $config->get('perimeters'), 2, 'set/get int';
|
||||
is $config->opt_serialize('perimeters'), '2', 'serialize int';
|
||||
|
||||
$config->set('extrusion_axis', 'A');
|
||||
is $config->get('extrusion_axis'), 'A', 'set/get string';
|
||||
is $config->opt_serialize('extrusion_axis'), 'A', 'serialize string';
|
||||
|
||||
$config->set('notes', "foo\nbar");
|
||||
is $config->get('notes'), "foo\nbar", 'set/get string with newline';
|
||||
is $config->opt_serialize('notes'), 'foo\nbar', 'serialize string with newline';
|
||||
$config->set_deserialize('notes', 'bar\nbaz');
|
||||
is $config->get('notes'), "bar\nbaz", 'deserialize string with newline';
|
||||
|
||||
foreach my $test_data (
|
||||
{
|
||||
name => 'empty',
|
||||
values => [],
|
||||
serialized => ''
|
||||
},
|
||||
{
|
||||
name => 'single empty',
|
||||
values => [''],
|
||||
serialized => '""'
|
||||
},
|
||||
{
|
||||
name => 'single noempty, simple',
|
||||
values => ['RGB'],
|
||||
serialized => 'RGB'
|
||||
},
|
||||
{
|
||||
name => 'multiple noempty, simple',
|
||||
values => ['ABC', 'DEF', '09182745@!#$*(&'],
|
||||
serialized => 'ABC;DEF;09182745@!#$*(&'
|
||||
},
|
||||
{
|
||||
name => 'multiple, simple, some empty',
|
||||
values => ['ABC', 'DEF', '', '09182745@!#$*(&', ''],
|
||||
serialized => 'ABC;DEF;;09182745@!#$*(&;'
|
||||
},
|
||||
{
|
||||
name => 'complex',
|
||||
values => ['some "quoted" notes', "yet\n some notes", "whatever \n notes", ''],
|
||||
serialized => '"some \"quoted\" notes";"yet\n some notes";"whatever \n notes";'
|
||||
}
|
||||
)
|
||||
{
|
||||
$config->set('filament_notes', $test_data->{values});
|
||||
is $config->opt_serialize('filament_notes'), $test_data->{serialized}, 'serialize multi-string value ' . $test_data->{name};
|
||||
$config->set_deserialize('filament_notes', '');
|
||||
is_deeply $config->get('filament_notes'), [], 'deserialize multi-string value - empty ' . $test_data->{name};
|
||||
$config->set_deserialize('filament_notes', $test_data->{serialized});
|
||||
is_deeply $config->get('filament_notes'), $test_data->{values}, 'deserialize complex multi-string value ' . $test_data->{name};
|
||||
}
|
||||
|
||||
$config->set('first_layer_height', 0.3);
|
||||
ok abs($config->get('first_layer_height') - 0.3) < 1e-4, 'set/get absolute floatOrPercent';
|
||||
is $config->opt_serialize('first_layer_height'), '0.3', 'serialize absolute floatOrPercent';
|
||||
|
||||
# This is no more supported after first_layer_height was moved from PrintObjectConfig to PrintConfig.
|
||||
# $config->set('first_layer_height', $config->get('layer_height'));
|
||||
# $config->get_abs_value('first_layer_height');
|
||||
# ok abs($config->get_abs_value('first_layer_height') - 0.15) < 1e-4, 'set/get relative floatOrPercent';
|
||||
# is $config->opt_serialize('first_layer_height'), '50%', 'serialize relative floatOrPercent';
|
||||
|
||||
# Uh-oh, we have no point option to test at the moment
|
||||
#ok $config->set('print_center', [50,80]), 'valid point coordinates';
|
||||
#is_deeply $config->get('print_center'), [50,80], 'set/get point';
|
||||
#is $config->serialize('print_center'), '50,80', 'serialize point';
|
||||
#$config->set_deserialize('print_center', '20,10');
|
||||
#is_deeply $config->get('print_center'), [20,10], 'deserialize point';
|
||||
#ok !$config->set('print_center', ['t',80]), 'invalid point X';
|
||||
#ok !$config->set('print_center', [50,'t']), 'invalid point Y';
|
||||
|
||||
$config->set('use_relative_e_distances', 1);
|
||||
is $config->get('use_relative_e_distances'), 1, 'set/get bool';
|
||||
is $config->opt_serialize('use_relative_e_distances'), '1', 'serialize bool';
|
||||
$config->set('gcode_flavor', 'teacup');
|
||||
is $config->get('gcode_flavor'), 'teacup', 'set/get enum';
|
||||
is $config->opt_serialize('gcode_flavor'), 'teacup', 'serialize enum';
|
||||
$config->set_deserialize('gcode_flavor', 'mach3');
|
||||
is $config->get('gcode_flavor'), 'mach3', 'deserialize enum (gcode_flavor)';
|
||||
$config->set_deserialize('gcode_flavor', 'machinekit');
|
||||
is $config->get('gcode_flavor'), 'machinekit', 'deserialize enum (gcode_flavor)';
|
||||
|
||||
$config->set_deserialize('fill_pattern', 'line');
|
||||
is $config->get('fill_pattern'), 'line', 'deserialize enum (fill_pattern)';
|
||||
|
||||
$config->set_deserialize('support_material_pattern', 'rectilinear');
|
||||
is $config->get('support_material_pattern'), 'rectilinear', 'deserialize enum (support_material_pattern)';
|
||||
|
||||
$config->set('extruder_offset', [[10,20],[30,45]]);
|
||||
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[10,20],[30,45]], 'set/get points';
|
||||
$config->set('extruder_offset', [Slic3r::Pointf->new(10,20),Slic3r::Pointf->new(30,45)]);
|
||||
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[10,20],[30,45]], 'set/get points';
|
||||
is $config->opt_serialize('extruder_offset'), '10x20,30x45', 'serialize points';
|
||||
$config->set_deserialize('extruder_offset', '20x10');
|
||||
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[20,10]], 'deserialize points';
|
||||
$config->set_deserialize('extruder_offset', '0x0');
|
||||
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[0,0]], 'deserialize points';
|
||||
{
|
||||
my @values = ([10,20]);
|
||||
$values[2] = [10,20]; # implicitely extend array; this is not the same as explicitely assigning undef to second item
|
||||
ok !$config->set('extruder_offset', \@values), 'reject undef points';
|
||||
}
|
||||
|
||||
# truncate ->get() to first decimal digit
|
||||
$config->set('nozzle_diameter', [0.2,3]);
|
||||
is_deeply [ map int($_*10)/10, @{$config->get('nozzle_diameter')} ], [0.2,3], 'set/get floats';
|
||||
is $config->opt_serialize('nozzle_diameter'), '0.2,3', 'serialize floats';
|
||||
$config->set_deserialize('nozzle_diameter', '0.1,0.4');
|
||||
is_deeply [ map int($_*10)/10, @{$config->get('nozzle_diameter')} ], [0.1,0.4], 'deserialize floats';
|
||||
$config->set_deserialize('nozzle_diameter', '3');
|
||||
is_deeply [ map int($_*10)/10, @{$config->get('nozzle_diameter')} ], [3], 'deserialize a single float';
|
||||
{
|
||||
my @values = (0.4);
|
||||
$values[2] = 2; # implicitely extend array; this is not the same as explicitely assigning undef to second item
|
||||
ok !$config->set('nozzle_diameter', \@values), 'reject undef floats';
|
||||
}
|
||||
|
||||
$config->set('temperature', [180,210]);
|
||||
is_deeply $config->get('temperature'), [180,210], 'set/get ints';
|
||||
is $config->opt_serialize('temperature'), '180,210', 'serialize ints';
|
||||
$config->set_deserialize('temperature', '195,220');
|
||||
is_deeply $config->get('temperature'), [195,220], 'deserialize ints';
|
||||
{
|
||||
my @values = (180);
|
||||
$values[2] = 200; # implicitely extend array; this is not the same as explicitely assigning undef to second item
|
||||
ok !$config->set('temperature', \@values), 'reject undef ints';
|
||||
}
|
||||
|
||||
$config->set('wipe', [1,0]);
|
||||
is_deeply $config->get('wipe'), [1,0], 'set/get bools';
|
||||
is $config->get_at('wipe', 0), 1, 'get_at bools';
|
||||
is $config->get_at('wipe', 1), 0, 'get_at bools';
|
||||
is $config->get_at('wipe', 9), 1, 'get_at bools';
|
||||
is $config->opt_serialize('wipe'), '1,0', 'serialize bools';
|
||||
$config->set_deserialize('wipe', '0,1,1');
|
||||
is_deeply $config->get('wipe'), [0,1,1], 'deserialize bools';
|
||||
$config->set_deserialize('wipe', '');
|
||||
is_deeply $config->get('wipe'), [], 'deserialize bools from empty string';
|
||||
$config->set_deserialize('retract_layer_change', 0);
|
||||
is_deeply $config->get('retract_layer_change'), [0], 'deserialize bools from non-string value';
|
||||
{
|
||||
my @values = (1);
|
||||
$values[2] = 1; # implicitely extend array; this is not the same as explicitely assigning undef to second item
|
||||
ok !$config->set('wipe', \@values), 'reject undef bools';
|
||||
}
|
||||
|
||||
$config->set('post_process', ['foo','bar']);
|
||||
is_deeply $config->get('post_process'), ['foo','bar'], 'set/get strings';
|
||||
is $config->opt_serialize('post_process'), 'foo;bar', 'serialize strings';
|
||||
$config->set_deserialize('post_process', 'bar;baz');
|
||||
is_deeply $config->get('post_process'), ['bar','baz'], 'deserialize strings';
|
||||
{
|
||||
my @values = ('foo');
|
||||
$values[2] = 'bar'; # implicitely extend array; this is not the same as explicitely assigning undef to second item
|
||||
ok !$config->set('post_process', \@values), 'reject undef strings';
|
||||
}
|
||||
|
||||
is_deeply [ sort @{$config->get_keys} ], [ sort keys %{$config->as_hash} ], 'get_keys and as_hash';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('perimeters', 2);
|
||||
|
||||
# test that no crash happens when using set_deserialize() with a key that hasn't been set() yet
|
||||
$config->set_deserialize('filament_diameter', '3');
|
||||
|
||||
my $config2 = Slic3r::Config::Static::new_FullPrintConfig;
|
||||
$config2->apply_dynamic($config);
|
||||
is $config2->get('perimeters'), 2, 'apply_dynamic';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config::Static::new_FullPrintConfig;
|
||||
my $config2 = Slic3r::Config->new;
|
||||
$config2->apply_static($config);
|
||||
is $config2->get('perimeters'), Slic3r::Config::print_config_def()->{perimeters}{default}, 'apply_static and print_config_def';
|
||||
|
||||
$config->set('top_solid_infill_speed', 70);
|
||||
is $config->get_abs_value('top_solid_infill_speed'), 70, 'get_abs_value() works when ratio_over references a floatOrPercent option';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('fill_pattern', 'line');
|
||||
|
||||
my $config2 = Slic3r::Config->new;
|
||||
$config2->set('fill_pattern', 'hilbertcurve');
|
||||
|
||||
is $config->get('fill_pattern'), 'line', 'no interferences between DynamicConfig objects';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
# the pair [0,0] is part of the test, since it checks whether the 0x0 serialized value is correctly parsed
|
||||
$config->set('extruder_offset', [ [0,0], [20,0], [0,20] ]);
|
||||
my $config2 = Slic3r::Config->new;
|
||||
$config2->apply($config);
|
||||
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [ map $_->pp, @{$config2->get('extruder_offset')} ],
|
||||
'apply dynamic over dynamic';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('extruder', 2);
|
||||
$config->set('perimeter_extruder', 3);
|
||||
$config->normalize_fdm;
|
||||
ok !$config->has('extruder'), 'extruder option is removed after normalize()';
|
||||
is $config->get('infill_extruder'), 2, 'undefined extruder is populated with default extruder';
|
||||
is $config->get('perimeter_extruder'), 3, 'defined extruder is not overwritten by default extruder';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('infill_extruder', 2);
|
||||
$config->normalize_fdm;
|
||||
is $config->get('solid_infill_extruder'), 2, 'undefined solid infill extruder is populated with infill extruder';
|
||||
}
|
||||
|
||||
{
|
||||
my $config = Slic3r::Config->new;
|
||||
$config->set('spiral_vase', 1);
|
||||
$config->set('retract_layer_change', [1,0]);
|
||||
$config->normalize_fdm;
|
||||
is_deeply $config->get('retract_layer_change'), [0,0], 'retract_layer_change is disabled with spiral_vase';
|
||||
}
|
||||
|
||||
{
|
||||
use Cwd qw(abs_path);
|
||||
use File::Basename qw(dirname);
|
||||
my $path = abs_path($0);
|
||||
my $config = Slic3r::Config::load(dirname($path)."/inc/22_config_bad_config_options.ini");
|
||||
ok 1, 'did not crash on reading invalid items in config';
|
||||
}
|
||||
|
||||
__END__
|
||||
27
xs/t/17_boundingbox.t
Normal file
27
xs/t/17_boundingbox.t
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 5;
|
||||
|
||||
{
|
||||
my @points = (
|
||||
Slic3r::Point->new(100, 200),
|
||||
Slic3r::Point->new(500, -600),
|
||||
);
|
||||
my $bb = Slic3r::Geometry::BoundingBox->new_from_points(\@points);
|
||||
isa_ok $bb, 'Slic3r::Geometry::BoundingBox', 'new_from_points';
|
||||
is_deeply $bb->min_point->pp, [100,-600], 'min_point';
|
||||
is_deeply $bb->max_point->pp, [500,200], 'max_point';
|
||||
}
|
||||
|
||||
{
|
||||
my $bb = Slic3r::Geometry::BoundingBox->new;
|
||||
$bb->merge_point(Slic3r::Point->new(10, 10));
|
||||
is_deeply $bb->min_point->pp, [10,10], 'min_point equals to the only defined point';
|
||||
is_deeply $bb->max_point->pp, [10,10], 'max_point equals to the only defined point';
|
||||
}
|
||||
|
||||
__END__
|
||||
7
xs/t/inc/22_config_bad_config_options.ini
Normal file
7
xs/t/inc/22_config_bad_config_options.ini
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# generated by Slic3r 1.1.7 on Tue Aug 19 21:49:50 2014
|
||||
avoid_crossing_perimeters = 1
|
||||
bed_size = 200,180
|
||||
g0 = 0
|
||||
perimeter_acceleration = 0
|
||||
support_material_extruder = 1
|
||||
support_material_extrusion_width = 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue