2015-12-01 20:40:00 +01:00
use Test::More tests => 59 ;
2013-06-21 14:52:35 +02:00
use strict ;
use warnings ;
BEGIN {
use FindBin ;
use lib "$FindBin::Bin/../lib" ;
2017-08-18 09:58:50 +02:00
use local::lib "$FindBin::Bin/../local-lib" ;
2013-06-21 14:52:35 +02:00
}
2015-01-08 15:19:56 +01:00
use Slic3r::ExtrusionLoop ':roles' ;
use Slic3r::ExtrusionPath ':roles' ;
2014-04-18 17:30:35 +02:00
use List::Util qw(first) ;
2013-06-21 14:52:35 +02:00
use Slic3r ;
2014-04-15 00:57:43 +02:00
use Slic3r::Flow ':roles' ;
use Slic3r::Geometry qw(PI scale unscale) ;
2014-04-11 23:10:14 +02:00
use Slic3r::Geometry::Clipper qw(union_ex diff union offset) ;
use Slic3r::Surface ':types' ;
2013-06-21 14:52:35 +02:00
use Slic3r::Test ;
2015-07-23 15:53:02 +02:00
{
my $flow = Slic3r::Flow -> new (
width => 1 ,
height => 1 ,
nozzle_diameter => 1 ,
);
my $config = Slic3r::Config -> new ;
my $test = sub {
my ( $expolygons , %expected ) = @_ ;
my $slices = Slic3r::Surface::Collection -> new ;
$slices -> append ( Slic3r::Surface -> new (
surface_type => S_TYPE_INTERNAL ,
expolygon => $_ ,
)) for @$expolygons ;
2016-11-17 23:22:59 +01:00
my ( $region_config , $object_config , $print_config , $loops , $gap_fill , $fill_surfaces );
2015-07-23 15:53:02 +02:00
my $g = Slic3r::Layer::PerimeterGenerator -> new (
# input:
$slices ,
1 , # layer height
$flow ,
( $region_config = Slic3r::Config::PrintRegion -> new ),
( $object_config = Slic3r::Config::PrintObject -> new ),
( $print_config = Slic3r::Config::Print -> new ),
# output:
( $loops = Slic3r::ExtrusionPath::Collection -> new ),
( $gap_fill = Slic3r::ExtrusionPath::Collection -> new ),
( $fill_surfaces = Slic3r::Surface::Collection -> new ),
);
$g -> config -> apply_dynamic ( $config );
$g -> process ;
is scalar ( @$loops ),
scalar ( @$expolygons ), 'expected number of collections' ;
ok ! defined ( first { ! $_ -> isa ( 'Slic3r::ExtrusionPath::Collection' ) } @$loops ),
'everything is returned as collections' ;
my $flattened_loops = $loops -> flatten ;
my @loops = @$flattened_loops ;
is scalar ( @loops ),
$expected { total }, 'expected number of loops' ;
is scalar ( grep $_ -> role == EXTR_ROLE_EXTERNAL_PERIMETER , map @$_ , @loops ),
$expected { external }, 'expected number of external loops' ;
2015-12-01 20:40:00 +01:00
is_deeply [ map { ( $_ -> role == EXTR_ROLE_EXTERNAL_PERIMETER ) || 0 } map @$_ , @loops ],
$expected { ext_order }, 'expected external order' ;
2017-04-07 17:37:30 +02:00
is scalar ( grep $_ -> loop_role == EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER , @loops ),
2015-07-23 15:53:02 +02:00
$expected { cinternal }, 'expected number of internal contour loops' ;
is scalar ( grep $_ -> polygon -> is_counter_clockwise , @loops ),
$expected { ccw }, 'expected number of ccw loops' ;
2015-12-01 20:40:00 +01:00
is_deeply [ map $_ -> polygon -> is_counter_clockwise , @loops ],
$expected { ccw_order }, 'expected ccw/cw order' ;
if ( $expected { nesting }) {
foreach my $nesting ( @ { $expected { nesting } }) {
for my $i ( 1 .. $#$nesting ) {
ok $loops [ $nesting -> [ $i - 1 ]] -> polygon -> contains_point ( $loops [ $nesting -> [ $i ]] -> first_point ),
'expected nesting order' ;
}
}
}
2015-07-23 15:53:02 +02:00
};
$config -> set ( 'perimeters' , 3 );
$test -> (
[
Slic3r::ExPolygon -> new (
Slic3r::Polygon -> new_scale ([ 0 , 0 ], [ 100 , 0 ], [ 100 , 100 ], [ 0 , 100 ]),
),
],
total => 3 ,
external => 1 ,
2015-12-01 20:40:00 +01:00
ext_order => [ 0 , 0 , 1 ],
2015-07-23 15:53:02 +02:00
cinternal => 1 ,
ccw => 3 ,
2015-12-01 20:40:00 +01:00
ccw_order => [ 1 , 1 , 1 ],
nesting => [ [ 2 , 1 , 0 ] ],
2015-07-23 15:53:02 +02:00
);
$test -> (
[
Slic3r::ExPolygon -> new (
Slic3r::Polygon -> new_scale ([ 0 , 0 ], [ 100 , 0 ], [ 100 , 100 ], [ 0 , 100 ]),
Slic3r::Polygon -> new_scale ([ 40 , 40 ], [ 40 , 60 ], [ 60 , 60 ], [ 60 , 40 ]),
),
],
total => 6 ,
external => 2 ,
2015-12-01 20:40:00 +01:00
ext_order => [ 0 , 0 , 1 , 0 , 0 , 1 ],
2015-07-23 15:53:02 +02:00
cinternal => 1 ,
ccw => 3 ,
2015-12-01 20:40:00 +01:00
ccw_order => [ 0 , 0 , 0 , 1 , 1 , 1 ],
nesting => [ [ 5 , 4 , 3 , 0 , 1 , 2 ] ],
2015-07-23 15:53:02 +02:00
);
$test -> (
[
Slic3r::ExPolygon -> new (
Slic3r::Polygon -> new_scale ([ 0 , 0 ], [ 200 , 0 ], [ 200 , 200 ], [ 0 , 200 ]),
Slic3r::Polygon -> new_scale ([ 20 , 20 ], [ 20 , 180 ], [ 180 , 180 ], [ 180 , 20 ]),
),
# nested:
Slic3r::ExPolygon -> new (
Slic3r::Polygon -> new_scale ([ 50 , 50 ], [ 150 , 50 ], [ 150 , 150 ], [ 50 , 150 ]),
Slic3r::Polygon -> new_scale ([ 80 , 80 ], [ 80 , 120 ], [ 120 , 120 ], [ 120 , 80 ]),
),
],
total => 4 * 3 ,
external => 4 ,
2015-12-01 20:40:00 +01:00
ext_order => [ 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 ],
2015-07-23 15:53:02 +02:00
cinternal => 2 ,
ccw => 2 * 3 ,
2015-12-01 20:40:00 +01:00
ccw_order => [ 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 ],
);
$config -> set ( 'perimeters' , 2 );
$test -> (
[
Slic3r::ExPolygon -> new (
Slic3r::Polygon -> new_scale ([ 0 , 0 ], [ 50 , 0 ], [ 50 , 50 ], [ 0 , 50 ]),
Slic3r::Polygon -> new_scale ([ 7.5 , 7.5 ], [ 7.5 , 12.5 ], [ 12.5 , 12.5 ], [ 12.5 , 7.5 ]),
Slic3r::Polygon -> new_scale ([ 7.5 , 17.5 ], [ 7.5 , 22.5 ], [ 12.5 , 22.5 ], [ 12.5 , 17.5 ]),
Slic3r::Polygon -> new_scale ([ 7.5 , 27.5 ], [ 7.5 , 32.5 ], [ 12.5 , 32.5 ], [ 12.5 , 27.5 ]),
Slic3r::Polygon -> new_scale ([ 7.5 , 37.5 ], [ 7.5 , 42.5 ], [ 12.5 , 42.5 ], [ 12.5 , 37.5 ]),
Slic3r::Polygon -> new_scale ([ 17.5 , 7.5 ], [ 17.5 , 12.5 ], [ 22.5 , 12.5 ], [ 22.5 , 7.5 ]),
),
],
total => 12 ,
external => 6 ,
ext_order => [ 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 ],
cinternal => 1 ,
ccw => 2 ,
ccw_order => [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 ],
nesting => [ [ 0 , 1 ],[ 2 , 3 ],[ 4 , 5 ],[ 6 , 7 ],[ 8 , 9 ] ],
2015-07-23 15:53:02 +02:00
);
}
2013-06-21 14:52:35 +02:00
{
2017-10-27 18:52:35 +02:00
my $config = Slic3r::Config:: new_from_defaults ;
2013-06-21 14:52:35 +02:00
$config -> set ( 'skirts' , 0 );
$config -> set ( 'fill_density' , 0 );
$config -> set ( 'perimeters' , 3 );
$config -> set ( 'top_solid_layers' , 0 );
$config -> set ( 'bottom_solid_layers' , 0 );
2017-06-21 16:15:39 +02:00
$config -> set ( 'cooling' , [ 0 ]); # to prevent speeds from being altered
2013-06-21 15:38:58 +02:00
$config -> set ( 'first_layer_speed' , '100%' ); # to prevent speeds from being altered
2013-06-21 14:52:35 +02:00
{
my $print = Slic3r::Test:: init_print ( 'overhang' , config => $config );
my $has_cw_loops = 0 ;
my $cur_loop ;
2013-08-28 16:51:58 +02:00
Slic3r::GCode::Reader -> new -> parse ( Slic3r::Test:: gcode ( $print ), sub {
2013-06-21 14:52:35 +02:00
my ( $self , $cmd , $args , $info ) = @_ ;
2013-06-22 15:22:58 +02:00
if ( $info -> { extruding } && $info -> { dist_XY } > 0 ) {
2013-06-21 14:52:35 +02:00
$cur_loop ||= [ [ $self -> X , $self -> Y ] ];
push @$cur_loop , [ @$info { qw(new_X new_Y) } ];
2018-07-13 10:46:30 +02:00
} elsif ( $cmd ne 'M73' ) { # skips remaining time lines (M73)
2013-06-21 14:52:35 +02:00
if ( $cur_loop ) {
2013-08-27 01:26:44 +02:00
$has_cw_loops = 1 if Slic3r::Polygon -> new ( @$cur_loop ) -> is_clockwise ;
2013-06-21 14:52:35 +02:00
$cur_loop = undef ;
}
}
});
ok ! $has_cw_loops , 'all perimeters extruded ccw' ;
}
2015-06-01 17:55:51 +02:00
foreach my $model ( qw(cube_with_hole cube_with_concave_hole) ) {
2013-06-23 00:05:08 +02:00
$config -> set ( 'external_perimeter_speed' , 68 );
2014-03-24 20:01:14 +01:00
my $print = Slic3r::Test:: init_print (
2015-06-01 17:55:51 +02:00
$model ,
2014-03-24 20:01:14 +01:00
config => $config ,
duplicate => 2 , # we test two copies to make sure ExtrusionLoop objects are not modified in-place (the second object would not detect cw loops and thus would calculate wrong inwards moves)
);
2015-06-01 17:55:51 +02:00
my $has_cw_loops = my $has_outwards_move = my $starts_on_convex_point = 0 ;
2013-06-23 00:05:08 +02:00
my $cur_loop ;
my %external_loops = (); # print_z => count of external loops
2013-08-28 16:51:58 +02:00
Slic3r::GCode::Reader -> new -> parse ( Slic3r::Test:: gcode ( $print ), sub {
2013-06-23 00:05:08 +02:00
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) } ];
2018-07-13 10:46:30 +02:00
} elsif ( $cmd ne 'M73' ) { # skips remaining time lines (M73)
2013-06-23 00:05:08 +02:00
if ( $cur_loop ) {
2013-09-02 22:10:52 +02:00
$has_cw_loops = 1 if Slic3r::Polygon -> new_scale ( @$cur_loop ) -> is_clockwise ;
2013-06-23 00:05:08 +02:00
if ( $self -> F == $config -> external_perimeter_speed * 60 ) {
2013-07-16 17:13:01 +02:00
my $move_dest = Slic3r::Point -> new_scale ( @$info { qw(new_X new_Y) });
2014-03-24 20:01:14 +01:00
# reset counter for second object
$external_loops { $self -> Z } = 0
if defined ( $external_loops { $self -> Z }) && $external_loops { $self -> Z } == 2 ;
2013-06-23 00:05:08 +02:00
$external_loops { $self -> Z } ++ ;
2015-06-01 17:55:51 +02:00
my $is_contour = $external_loops { $self -> Z } == 2 ;
my $is_hole = $external_loops { $self -> Z } == 1 ;
my $loop = Slic3r::Polygon -> new_scale ( @$cur_loop );
my $loop_contains_point = $loop -> contains_point ( $move_dest );
2013-06-23 00:05:08 +02:00
$has_outwards_move = 1
2015-06-01 17:55:51 +02:00
if ( ! $loop_contains_point && $is_contour ) # contour should include destination
|| ( $loop_contains_point && $is_hole ); # hole should not
if ( $model eq 'cube_with_concave_hole' ) {
# check that loop starts at a concave vertex
my $ccw_angle = $loop -> first_point -> ccw_angle ( @$loop [ - 2 , 1 ]);
my $convex = ( $ccw_angle > PI ); # whether the angle on the *right* side is convex
$starts_on_convex_point = 1
if ( $convex && $is_contour ) || ( ! $convex && $is_hole );
}
2013-06-23 00:05:08 +02:00
}
$cur_loop = undef ;
}
}
});
ok ! $has_cw_loops , 'all perimeters extruded ccw' ;
ok ! $has_outwards_move , 'move inwards after completing external loop' ;
2015-06-01 17:55:51 +02:00
ok ! $starts_on_convex_point , 'loops start on concave point if any' ;
2013-06-23 00:05:08 +02:00
}
2013-06-21 14:52:35 +02:00
{
$config -> set ( 'perimeters' , 1 );
$config -> set ( 'perimeter_speed' , 77 );
$config -> set ( 'external_perimeter_speed' , 66 );
$config -> set ( 'bridge_speed' , 99 );
2017-06-21 16:15:39 +02:00
$config -> set ( 'cooling' , [ 1 ]);
$config -> set ( 'fan_below_layer_time' , [ 0 ]);
$config -> set ( 'slowdown_below_layer_time' , [ 0 ]);
$config -> set ( 'bridge_fan_speed' , [ 100 ]);
2013-09-17 10:36:06 +02:00
$config -> set ( 'bridge_flow_ratio' , 33 ); # arbitrary value
2013-07-06 11:35:40 +02:00
$config -> set ( 'overhangs' , 1 );
2013-06-21 14:52:35 +02:00
my $print = Slic3r::Test:: init_print ( 'overhang' , config => $config );
my %layer_speeds = (); # print Z => [ speeds ]
2013-06-21 15:38:58 +02:00
my $fan_speed = 0 ;
2013-09-17 10:36:06 +02:00
my $bridge_mm_per_mm = ( $config -> nozzle_diameter -> [ 0 ] ** 2 ) / ( $config -> filament_diameter -> [ 0 ] ** 2 ) * $config -> bridge_flow_ratio ;
2013-08-28 16:51:58 +02:00
Slic3r::GCode::Reader -> new -> parse ( Slic3r::Test:: gcode ( $print ), sub {
2013-06-21 14:52:35 +02:00
my ( $self , $cmd , $args , $info ) = @_ ;
2013-06-21 15:38:58 +02:00
$fan_speed = 0 if $cmd eq 'M107' ;
$fan_speed = $args -> { S } if $cmd eq 'M106' ;
2013-06-21 14:52:35 +02:00
if ( $info -> { extruding } && $info -> { dist_XY } > 0 ) {
$layer_speeds { $self -> Z } ||= {};
$layer_speeds { $self -> Z }{ my $feedrate = $args -> { F } // $self -> F } = 1 ;
2013-06-21 15:38:58 +02:00
2013-06-21 14:52:35 +02:00
fail 'wrong speed found'
if $feedrate != $config -> perimeter_speed * 60
&& $feedrate != $config -> external_perimeter_speed * 60
&& $feedrate != $config -> bridge_speed * 60 ;
2013-06-21 15:38:58 +02:00
if ( $feedrate == $config -> bridge_speed * 60 ) {
fail 'printing overhang but fan is not enabled or running at wrong speed'
if $fan_speed != 255 ;
2013-09-17 10:36:06 +02:00
my $mm_per_mm = $info -> { dist_E } / $info -> { dist_XY };
fail 'wrong bridge flow' if abs ( $mm_per_mm - $bridge_mm_per_mm ) > 0.01 ;
2013-06-21 15:38:58 +02:00
} else {
fail 'fan is running when not supposed to'
if $fan_speed > 0 ;
}
2013-06-21 14:52:35 +02:00
}
});
is scalar ( grep { keys %$_ > 1 } values %layer_speeds ), 1 ,
'only overhang layer has more than one speed' ;
}
}
2013-09-17 20:18:54 +02:00
{
2017-10-27 18:52:35 +02:00
my $config = Slic3r::Config:: new_from_defaults ;
2013-09-17 20:18:54 +02:00
$config -> set ( 'skirts' , 0 );
$config -> set ( 'perimeters' , 3 );
$config -> set ( 'layer_height' , 0.4 );
$config -> set ( 'first_layer_height' , 0.35 );
$config -> set ( 'extra_perimeters' , 1 );
2017-06-21 16:15:39 +02:00
$config -> set ( 'cooling' , [ 0 ]); # to prevent speeds from being altered
2013-09-17 20:18:54 +02:00
$config -> set ( 'first_layer_speed' , '100%' ); # to prevent speeds from being altered
$config -> set ( 'perimeter_speed' , 99 );
$config -> set ( 'external_perimeter_speed' , 99 );
$config -> set ( 'small_perimeter_speed' , 99 );
2014-03-02 22:26:52 +01:00
$config -> set ( 'thin_walls' , 0 );
2013-09-17 20:18:54 +02:00
my $print = Slic3r::Test:: init_print ( 'ipadstand' , config => $config );
my %perimeters = (); # z => number of loops
my $in_loop = 0 ;
Slic3r::GCode::Reader -> new -> parse ( Slic3r::Test:: gcode ( $print ), sub {
my ( $self , $cmd , $args , $info ) = @_ ;
if ( $info -> { extruding } && $info -> { dist_XY } > 0 && ( $args -> { F } // $self -> F ) == $config -> perimeter_speed * 60 ) {
$perimeters { $self -> Z } ++ if ! $in_loop ;
$in_loop = 1 ;
2018-07-13 10:46:30 +02:00
} elsif ( $cmd ne 'M73' ) { # skips remaining time lines (M73)
2013-09-17 20:18:54 +02:00
$in_loop = 0 ;
}
});
ok ! ( grep { $_ % $ config -> perimeters } values %perimeters ), 'no superfluous extra perimeters' ;
}
2014-04-18 17:30:35 +02:00
{
2017-10-27 18:52:35 +02:00
my $config = Slic3r::Config:: new_from_defaults ;
2014-04-18 17:30:35 +02:00
$config -> set ( 'nozzle_diameter' , [ 0.4 ]);
$config -> set ( 'perimeters' , 2 );
$config -> set ( 'perimeter_extrusion_width' , 0.4 );
2017-07-20 11:03:54 +02:00
$config -> set ( 'external_perimeter_extrusion_width' , 0.4 );
2014-04-18 17:30:35 +02:00
$config -> set ( 'infill_extrusion_width' , 0.53 );
$config -> set ( 'solid_infill_extrusion_width' , 0.53 );
# we just need a pre-filled Print object
my $print = Slic3r::Test:: init_print ( '20mm_cube' , config => $config );
# override a layer's slices
my $expolygon = Slic3r::ExPolygon -> new ([[ - 71974463 , - 139999376 ],[ - 71731792 , - 139987456 ],[ - 71706544 , - 139985616 ],[ - 71682119 , - 139982639 ],[ - 71441248 , - 139946912 ],[ - 71417487 , - 139942895 ],[ - 71379384 , - 139933984 ],[ - 71141800 , - 139874480 ],[ - 71105247 , - 139862895 ],[ - 70873544 , - 139779984 ],[ - 70838592 , - 139765856 ],[ - 70614943 , - 139660064 ],[ - 70581783 , - 139643567 ],[ - 70368368 , - 139515680 ],[ - 70323751 , - 139487872 ],[ - 70122160 , - 139338352 ],[ - 70082399 , - 139306639 ],[ - 69894800 , - 139136624 ],[ - 69878679 , - 139121327 ],[ - 69707992 , - 138933008 ],[ - 69668575 , - 138887343 ],[ - 69518775 , - 138685359 ],[ - 69484336 , - 138631632 ],[ - 69356423 , - 138418207 ],[ - 69250040 , - 138193296 ],[ - 69220920 , - 138128976 ],[ - 69137992 , - 137897168 ],[ - 69126095 , - 137860255 ],[ - 69066568 , - 137622608 ],[ - 69057104 , - 137582511 ],[ - 69053079 , - 137558751 ],[ - 69017352 , - 137317872 ],[ - 69014392 , - 137293456 ],[ - 69012543 , - 137268207 ],[ - 68999369 , - 137000000 ],[ - 63999999 , - 137000000 ],[ - 63705947 , - 136985551 ],[ - 63654984 , - 136977984 ],[ - 63414731 , - 136942351 ],[ - 63364756 , - 136929840 ],[ - 63129151 , - 136870815 ],[ - 62851950 , - 136771631 ],[ - 62585807 , - 136645743 ],[ - 62377483 , - 136520895 ],[ - 62333291 , - 136494415 ],[ - 62291908 , - 136463728 ],[ - 62096819 , - 136319023 ],[ - 62058644 , - 136284432 ],[ - 61878676 , - 136121328 ],[ - 61680968 , - 135903184 ],[ - 61650275 , - 135861807 ],[ - 61505591 , - 135666719 ],[ - 61354239 , - 135414191 ],[ - 61332211 , - 135367615 ],[ - 61228359 , - 135148063 ],[ - 61129179 , - 134870847 ],[ - 61057639 , - 134585262 ],[ - 61014451 , - 134294047 ],[ - 61000000 , - 134000000 ],[ - 61000000 , - 107999999 ],[ - 61014451 , - 107705944 ],[ - 61057639 , - 107414736 ],[ - 61129179 , - 107129152 ],[ - 61228359 , - 106851953 ],[ - 61354239 , - 106585808 ],[ - 61505591 , - 106333288 ],[ - 61680967 , - 106096816 ],[ - 61878675 , - 105878680 ],[ - 62096820 , - 105680967 ],[ - 62138204 , - 105650279 ],[ - 62333292 , - 105505591 ],[ - 62585808 , - 105354239 ],[ - 62632384 , - 105332207 ],[ - 62851951 , - 105228360 ],[ - 62900463 , - 105211008 ],[ - 63129152 , - 105129183 ],[ - 63414731 , - 105057640 ],[ - 63705947 , - 105014448 ],[ - 63999999 , - 105000000 ],[ - 68999369 , - 105000000 ],[ - 69012543 , - 104731792 ],[ - 69014392 , - 104706544 ],[ - 69017352 , - 104682119 ],[ - 69053079 , - 104441248 ],[ - 69057104 , - 104417487 ],[ - 69066008 , - 104379383 ],[ - 69125528 , - 104141799 ],[ - 69137111 , - 104105248 ],[ - 69220007 , - 103873544 ],[ - 69234136 , - 103838591 ],[ - 69339920 , - 103614943 ],[ - 69356415 , - 103581784 ],[ - 69484328 , - 103368367 ],[ - 69512143 , - 103323752 ],[ - 69661647 , - 103122160 ],[ - 69693352 , - 103082399 ],[ - 69863383 , - 102894800 ],[ - 69878680 , - 102878679 ],[ - 70066999 , - 102707992 ],[ - 70112656 , - 102668576 ],[ - 70314648 , - 102518775 ],[ - 70368367 , - 102484336 ],[ - 70581783 , - 102356424 ],[ - 70806711 , - 102250040 ],[ - 70871040 , - 102220919 ],[ - 71102823 , - 102137992 ],[ - 71139752 , - 102126095 ],[ - 71377383 , - 102066568 ],[ - 71417487 , - 102057104 ],[ - 71441248 , - 102053079 ],[ - 71682119 , - 102017352 ],[ - 71706535 , - 102014392 ],[ - 71731784 , - 102012543 ],[ - 71974456 , - 102000624 ],[ - 71999999 , - 102000000 ],[ - 104000000 , - 102000000 ],[ - 104025536 , - 102000624 ],[ - 104268207 , - 102012543 ],[ - 104293455 , - 102014392 ],[ - 104317880 , - 102017352 ],[ - 104558751 , - 102053079 ],[ - 104582512 , - 102057104 ],[ - 104620616 , - 102066008 ],[ - 104858200 , - 102125528 ],[ - 104894751 , - 102137111 ],[ - 105126455 , - 102220007 ],[ - 105161408 , - 102234136 ],[ - 105385056 , - 102339920 ],[ - 105418215 , - 102356415 ],[ - 105631632 , - 102484328 ],[ - 105676247 , - 102512143 ],[ - 105877839 , - 102661647 ],[ - 105917600 , - 102693352 ],[ - 106105199 , - 102863383 ],[ - 106121320 , - 102878680 ],[ - 106292007 , - 103066999 ],[ - 106331424 , - 103112656 ],[ - 106481224 , - 103314648 ],[ - 106515663 , - 103368367 ],[ - 106643575 , - 103581783 ],[ - 106749959 , - 103806711 ],[ - 106779080 , - 103871040 ],[ - 106862007 , - 104102823 ],[ - 106873904 , - 104139752 ],[ - 106933431 , - 104377383 ],[ - 106942896 , - 104417487 ],[ - 106946920 , - 104441248 ],[ - 106982648 , - 104682119 ],[ - 106985607 , - 104706535 ],[ - 106987456 , - 104731784 ],[ - 107000630 , - 105000000 ],[ - 112000000 , - 105000000 ],[ - 112294056 , - 105014448 ],[ - 112585264 , - 105057640 ],[ - 112870848 , - 105129184 ],[ - 112919359 , - 105146535 ],[ - 113148048 , - 105228360 ],[ - 113194624 , - 105250392 ],[ - 113414191 , - 105354239 ],[ - 113666711 , - 105505591 ],[ - 113708095 , - 105536279 ],[ - 113903183 , - 105680967 ],[ - 114121320 , - 105878679 ],[ - 114319032 , - 106096816 ],[ - 114349720 , - 106138200 ],[ - 114494408 , - 106333288 ],[ - 114645760 , - 106585808 ],[ - 114667792 , - 106632384 ],[ - 114771640 , - 106851952 ],[ - 114788991 , - 106900463 ],[ - 114870815 , - 107129151 ],[ - 114942359 , - 107414735 ],[ - 114985551 , - 107705943 ],[ - 115000000 , - 1
2014-05-09 14:24:35 +02:00
my $object = $print -> print -> objects -> [ 0 ];
2014-04-18 17:30:35 +02:00
$object -> slice ;
2014-06-14 00:05:24 +02:00
my $layer = $object -> get_layer ( 1 );
2014-04-18 17:30:35 +02:00
my $layerm = $layer -> regions -> [ 0 ];
$layerm -> slices -> clear ;
$layerm -> slices -> append ( Slic3r::Surface -> new ( surface_type => S_TYPE_INTERNAL , expolygon => $expolygon ));
# make perimeters
$layer -> make_perimeters ;
# compute the covered area
my $pflow = $layerm -> flow ( FLOW_ROLE_PERIMETER );
2014-07-26 15:29:24 +02:00
my $iflow = $layerm -> flow ( FLOW_ROLE_INFILL );
2014-04-18 17:30:35 +02:00
my $covered_by_perimeters = union_ex ([
2015-01-08 15:19:56 +01:00
( map @ { $_ -> polygon -> split_at_first_point -> grow ( $pflow -> scaled_width / 2 )}, map @$_ , @ { $layerm -> perimeters }),
2014-04-18 17:30:35 +02:00
]);
my $covered_by_infill = union_ex ([
( map $_ -> p , @ { $layerm -> fill_surfaces }),
2014-07-26 15:29:24 +02:00
( map @ { $_ -> polyline -> grow ( $iflow -> scaled_width / 2 )}, @ { $layerm -> thin_fills }),
2014-04-18 17:30:35 +02:00
]);
# compute the non covered area
my $non_covered = diff (
[ map @ { $_ -> expolygon }, @ { $layerm -> slices } ],
[ map @$_ , ( @$covered_by_perimeters , @$covered_by_infill ) ],
);
2015-07-23 16:27:21 +02:00
if ( 0 ) {
2014-04-18 17:30:35 +02:00
printf "max non covered = %f\n" , List::Util:: max ( map unscale unscale $_ -> area , @$non_covered );
require "Slic3r/SVG.pm" ;
Slic3r::SVG:: output (
"gaps.svg" ,
expolygons => [ map $_ -> expolygon , @ { $layerm -> slices } ],
red_expolygons => union_ex ([ map @$_ , ( @$covered_by_perimeters , @$covered_by_infill ) ]),
green_expolygons => union_ex ( $non_covered ),
2015-07-23 15:53:02 +02:00
no_arrows => 1 ,
polylines => [
map $_ -> polygon -> split_at_first_point , map @$_ , @ { $layerm -> perimeters },
],
2014-04-18 17:30:35 +02:00
);
}
2014-07-26 15:29:24 +02:00
ok ! ( defined first { $_ -> area > ( $iflow -> scaled_width ** 2 ) } @$non_covered ), 'no gap between perimeters and infill' ;
2014-04-18 17:30:35 +02:00
}
2014-04-29 19:58:58 +02:00
{
2017-10-27 18:52:35 +02:00
my $config = Slic3r::Config:: new_from_defaults ;
2014-04-29 19:58:58 +02:00
$config -> set ( 'skirts' , 0 );
$config -> set ( 'perimeters' , 3 );
$config -> set ( 'layer_height' , 0.4 );
$config -> set ( 'bridge_speed' , 99 );
$config -> set ( 'fill_density' , 0 ); # to prevent bridging over sparse infill
$config -> set ( 'overhangs' , 1 );
2017-06-21 16:15:39 +02:00
$config -> set ( 'cooling' , [ 0 ]); # to prevent speeds from being altered
2014-04-29 19:58:58 +02:00
$config -> set ( 'first_layer_speed' , '100%' ); # to prevent speeds from being altered
my $test = sub {
my ( $print ) = @_ ;
2015-03-06 21:35:00 +01:00
my %z_with_bridges = (); # z => 1
2014-04-29 19:58:58 +02:00
Slic3r::GCode::Reader -> new -> parse ( Slic3r::Test:: gcode ( $print ), sub {
my ( $self , $cmd , $args , $info ) = @_ ;
if ( $info -> { extruding } && $info -> { dist_XY } > 0 ) {
2015-03-06 21:35:00 +01:00
$z_with_bridges { $self -> Z } = 1 if ( $args -> { F } // $self -> F ) == $config -> bridge_speed * 60 ;
2014-04-29 19:58:58 +02:00
}
});
2015-03-06 21:35:00 +01:00
return scalar keys %z_with_bridges ;
2014-04-29 19:58:58 +02:00
};
2015-03-06 21:35:00 +01:00
ok $test -> ( Slic3r::Test:: init_print ( 'V' , config => $config )) == 1 ,
'no overhangs printed with bridge speed' ; # except for the first internal solid layers above void
ok $test -> ( Slic3r::Test:: init_print ( 'V' , config => $config , scale_xyz => [ 3 , 1 , 1 ])) > 1 ,
2014-04-29 19:58:58 +02:00
'overhangs printed with bridge speed' ;
}
2014-05-12 21:49:17 +02:00
{
2017-10-27 18:52:35 +02:00
my $config = Slic3r::Config:: new_from_defaults ;
2014-05-24 22:10:28 +02:00
$config -> set ( 'seam_position' , 'random' );
2014-05-12 21:49:17 +02:00
my $print = Slic3r::Test:: init_print ( '20mm_cube' , config => $config );
2014-05-24 22:10:28 +02:00
ok Slic3r::Test:: gcode ( $print ), 'successful generation of G-code with seam_position = random' ;
2014-05-12 21:49:17 +02:00
}
2014-06-11 21:57:32 +02:00
{
my $test = sub {
my ( $model_name ) = @_ ;
2017-10-27 18:52:35 +02:00
my $config = Slic3r::Config:: new_from_defaults ;
2014-06-11 21:57:32 +02:00
$config -> set ( 'seam_position' , 'aligned' );
$config -> set ( 'skirts' , 0 );
$config -> set ( 'perimeters' , 1 );
$config -> set ( 'fill_density' , 0 );
$config -> set ( 'top_solid_layers' , 0 );
$config -> set ( 'bottom_solid_layers' , 0 );
$config -> set ( 'retract_layer_change' , [ 0 ]);
my $was_extruding = 0 ;
my @seam_points = ();
my $print = Slic3r::Test:: init_print ( $model_name , config => $config );
2014-12-07 19:53:22 +01:00
Slic3r::GCode::Reader -> new -> parse ( my $gcode = Slic3r::Test:: gcode ( $print ), sub {
2014-06-11 21:57:32 +02:00
my ( $self , $cmd , $args , $info ) = @_ ;
if ( $info -> { extruding }) {
if ( ! $was_extruding ) {
push @seam_points , Slic3r::Point -> new_scale ( $self -> X , $self -> Y );
}
$was_extruding = 1 ;
2018-07-13 10:46:30 +02:00
} elsif ( $cmd ne 'M73' ) { # skips remaining time lines (M73)
2014-06-11 21:57:32 +02:00
$was_extruding = 0 ;
}
});
my @dist = map unscale ( $_ ), map $seam_points [ $_ ] -> distance_to ( $seam_points [ $_ + 1 ]), 0 .. ( $#seam_points - 1 );
ok ! ( defined first { $_ > 3 } @dist ), 'seam is aligned' ;
};
$test -> ( '20mm_cube' );
$test -> ( 'small_dorito' );
}
2013-06-21 14:52:35 +02:00
__END__