adaptive_slicing.t 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. use Test::More tests => 9;
  2. use strict;
  3. use warnings;
  4. BEGIN {
  5. use FindBin;
  6. use lib "$FindBin::Bin/../lib";
  7. use local::lib "$FindBin::Bin/../local-lib";
  8. }
  9. use List::Util qw(first sum);
  10. use Slic3r;
  11. use Slic3r::Test qw(_eq);
  12. use Slic3r::Geometry qw(Z PI scale unscale);
  13. use Devel::Peek;
  14. my $config = Slic3r::Config->new_from_defaults;
  15. my $generate_gcode = sub {
  16. my ($conf) = @_;
  17. $conf ||= $config;
  18. my $print = Slic3r::Test::init_print('slopy_cube', config => $conf);
  19. my @z = ();
  20. my @increments = ();
  21. Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub {
  22. my ($self, $cmd, $args, $info) = @_;
  23. if ($info->{dist_Z}) {
  24. push @z, 1*$args->{Z};
  25. push @increments, $info->{dist_Z};
  26. }
  27. });
  28. return (@z);
  29. };
  30. my $horizontal_feature_test = sub {
  31. my (@z) = $generate_gcode->();
  32. ok (_eq($z[0], $config->get_value('first_layer_height') + $config->z_offset), 'first layer height.');
  33. ok (_eq($z[1], $config->get_value('first_layer_height') + $config->get('max_layer_height')->[0] + $config->z_offset), 'second layer height.');
  34. cmp_ok((first { _eq($_, 10.0) } @z[1..$#z]), '>', 0, 'horizontal facet matched');
  35. 1;
  36. };
  37. my $height_gradation_test = sub {
  38. my (@z) = $generate_gcode->();
  39. my $gradation = 1 / $config->get('z_steps_per_mm');
  40. # +1 is a "dirty fix" to avoid rounding issues with the modulo operator...
  41. my @results = map {unscale((scale($_)+1) % scale($gradation))} @z;
  42. ok (_eq(sum(@results), 0), 'layer z is multiple of gradation ' . $gradation );
  43. 1;
  44. };
  45. my $adaptive_slicing = Slic3r::SlicingAdaptive->new();
  46. my $mesh = Slic3r::Test::mesh('slopy_cube');
  47. $adaptive_slicing->add_mesh($mesh);
  48. $adaptive_slicing->prepare(20);
  49. subtest 'max layer_height limited by extruder capabilities' => sub {
  50. plan tests => 3;
  51. ok (_eq($adaptive_slicing->next_layer_height(1, 20, 0.1, 0.15), 0.15), 'low');
  52. ok (_eq($adaptive_slicing->next_layer_height(1, 20, 0.1, 0.4), 0.4), 'higher');
  53. ok (_eq($adaptive_slicing->next_layer_height(1, 20, 0.1, 0.65), 0.65), 'highest');
  54. };
  55. subtest 'min layer_height limited by extruder capabilities' => sub {
  56. plan tests => 3;
  57. ok (_eq($adaptive_slicing->next_layer_height(4, 99, 0.1, 0.15), 0.1), 'low');
  58. ok (_eq($adaptive_slicing->next_layer_height(4, 98, 0.2, 0.4), 0.2), 'higher');
  59. ok (_eq($adaptive_slicing->next_layer_height(4, 99, 0.3, 0.65), 0.3), 'highest');
  60. };
  61. subtest 'correct layer_height depending on the facet normals' => sub {
  62. plan tests => 3;
  63. ok (_eq($adaptive_slicing->next_layer_height(1, 10, 0.1, 0.5), 0.5), 'limit');
  64. ok (_eq($adaptive_slicing->next_layer_height(4, 80, 0.1, 0.5), 0.1546), '45deg facet, quality_value: 0.2');
  65. ok (_eq($adaptive_slicing->next_layer_height(4, 50, 0.1, 0.5), 0.3352), '45deg facet, quality_value: 0.5');
  66. };
  67. # 2.92893 ist lower slope edge
  68. # distance to slope must be higher than min extruder cap.
  69. # slopes layer height must be greater than the distance to the slope
  70. ok (_eq($adaptive_slicing->next_layer_height(2.798, 80, 0.1, 0.5), 0.1546), 'reducing layer_height due to higher slopy facet');
  71. # slopes layer height must be smaller than the distance to the slope
  72. ok (_eq($adaptive_slicing->next_layer_height(2.6289, 85, 0.1, 0.5), 0.3), 'reducing layer_height to z-diff');
  73. subtest 'horizontal planes' => sub {
  74. plan tests => 3;
  75. ok (_eq($adaptive_slicing->horizontal_facet_distance(1, 1.2), 1.2), 'max_height limit');
  76. ok (_eq($adaptive_slicing->horizontal_facet_distance(8.5, 4), 1.5), 'normal horizontal facet');
  77. ok (_eq($adaptive_slicing->horizontal_facet_distance(17, 5), 3.0), 'object maximum');
  78. };
  79. # shrink current layer to fit another layer under horizontal facet
  80. $config->set('start_gcode', ''); # to avoid dealing with the nozzle lift in start G-code
  81. $config->set('z_offset', 0);
  82. $config->set('adaptive_slicing', 1);
  83. $config->set('first_layer_height', 0.42893); # to catch lower slope edge
  84. $config->set('nozzle_diameter', [0.5]);
  85. $config->set('min_layer_height', [0.1]);
  86. $config->set('max_layer_height', [0.5]);
  87. $config->set('adaptive_slicing_quality', [81]);
  88. # slope height: 7,07107 (2.92893 to 10)
  89. subtest 'shrink to match horizontal facets' => sub {
  90. plan skip_all => 'spline smoothing currently prevents exact horizontal facet matching';
  91. plan tests => 3;
  92. $horizontal_feature_test->();
  93. };
  94. # widen current layer to match horizontal facet
  95. $config->set('adaptive_slicing_quality', [0.1]);
  96. subtest 'widen to match horizontal facets' => sub {
  97. plan skip_all => 'spline smoothing currently prevents exact horizontal facet matching';
  98. plan tests => 3;
  99. $horizontal_feature_test->();
  100. };
  101. subtest 'layer height gradation' => sub {
  102. plan tests => 5;
  103. foreach my $gradation (1/0.001, 1/0.01, 1/0.02, 1/0.05, 1/0.08) {
  104. $config->set('z_steps_per_mm', $gradation);
  105. $height_gradation_test->();
  106. }
  107. };
  108. __END__