arcs.t 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. use Test::More;
  2. use strict;
  3. use warnings;
  4. plan tests => 24;
  5. BEGIN {
  6. use FindBin;
  7. use lib "$FindBin::Bin/../lib";
  8. use local::lib "$FindBin::Bin/../local-lib";
  9. }
  10. use Slic3r;
  11. use Slic3r::ExtrusionPath ':roles';
  12. use Slic3r::Geometry qw(scaled_epsilon epsilon scale unscale X Y deg2rad);
  13. {
  14. my $angle = deg2rad(4);
  15. foreach my $ccw (1, 0) {
  16. my $polyline = Slic3r::Polyline->new_scale([0,0], [0,10]);
  17. {
  18. my $p3 = Slic3r::Point->new_scale(0, 20);
  19. $p3->rotate($angle * ($ccw ? 1 : -1), $polyline->[-1]);
  20. is $ccw, ($p3->[X] < $polyline->[-1][X]) ? 1 : 0, 'third point is rotated correctly';
  21. $polyline->append($p3);
  22. }
  23. ok abs($polyline->length - scale(20)) < scaled_epsilon, 'curved polyline length';
  24. is $ccw, ($polyline->[2]->ccw(@$polyline[0,1]) > 0) ? 1 : 0, 'curved polyline has wanted orientation';
  25. ok my $arc = Slic3r::GCode::ArcFitting::polyline_to_arc($polyline), 'arc is detected';
  26. is $ccw, $arc->is_ccw, 'arc orientation is correct';
  27. ok abs($arc->angle - $angle) < epsilon, 'arc relative angle is correct';
  28. ok $arc->start->coincides_with($polyline->[0]), 'arc start point is correct';
  29. ok $arc->end->coincides_with($polyline->[-1]), 'arc end point is correct';
  30. # since first polyline segment is vertical we expect arc center to have same Y as its first point
  31. is $arc->center->[Y], 0, 'arc center has correct Y';
  32. my $s1 = Slic3r::Line->new(@$polyline[0,1]);
  33. my $s2 = Slic3r::Line->new(@$polyline[1,2]);
  34. ok abs($arc->center->distance_to($s1->midpoint) - $arc->center->distance_to($s2->midpoint)) < scaled_epsilon,
  35. 'arc center is equidistant from both segments\' midpoints';
  36. }
  37. }
  38. #==========================================================
  39. {
  40. my $path = Slic3r::Polyline->new_scale(
  41. [13.532242,2.665496], [18.702911,9.954623], [22.251514,9.238193], [25.800116,9.954623],
  42. [28.697942,11.908391], [30.65171,14.806217], [31.36814,18.35482],
  43. [30.65171,21.903423], [28.697942,24.801249], [25.800116,26.755017], [22.251514,27.471447],
  44. [18.702911,26.755017], [15.805085,24.801249], [13.851317,21.903423], [13.134887,18.35482],
  45. [86948.77,175149.09], [119825.35,100585],
  46. );
  47. if (0) {
  48. require "Slic3r::SVG";
  49. Slic3r::SVG::output(
  50. "arc.svg",
  51. polylines => [$path],
  52. );
  53. }
  54. my $af = Slic3r::GCode::ArcFitting->new(max_relative_angle => deg2rad(30));
  55. my @chunks = $af->detect_arcs($path);
  56. is scalar(@chunks), 3, 'path collection now contains three paths';
  57. isa_ok $chunks[0], 'Slic3r::Polyline', 'first one is polyline';
  58. isa_ok $chunks[1], 'Slic3r::GCode::ArcFitting::Arc', 'second one is arc';
  59. isa_ok $chunks[2], 'Slic3r::Polyline', 'third one is polyline';
  60. }
  61. exit;
  62. #==========================================================
  63. {
  64. my @points = map [ scale $_->[0], scale $_->[1] ], (
  65. [10,20], [10.7845909572784,19.9691733373313], [11.5643446504023,19.8768834059514],
  66. [12.3344536385591,19.7236992039768], [13.0901699437495,19.5105651629515],
  67. [13.8268343236509,19.2387953251129], [14.5399049973955,18.9100652418837],
  68. [15.2249856471595,18.5264016435409], [15.8778525229247,18.0901699437495],
  69. [16.4944804833018,17.6040596560003]
  70. );
  71. my $path1 = Slic3r::ExtrusionPath->new(
  72. polyline => Slic3r::Polyline->new(@points),
  73. role => EXTR_ROLE_FILL,
  74. mm3_per_mm => 0.5,
  75. );
  76. my $path2 = Slic3r::ExtrusionPath->new(
  77. polyline => Slic3r::Polyline->new(reverse @points),
  78. role => EXTR_ROLE_FILL,
  79. mm3_per_mm => 0.5,
  80. );
  81. my @paths1 = $path1->detect_arcs(10, scale 1);
  82. my @paths2 = $path2->detect_arcs(10, scale 1);
  83. is scalar(@paths1), 1, 'path collection now contains one path';
  84. is scalar(@paths2), 1, 'path collection now contains one path';
  85. isa_ok $paths1[0], 'Slic3r::ExtrusionPath::Arc', 'path';
  86. isa_ok $paths2[0], 'Slic3r::ExtrusionPath::Arc', 'path';
  87. my $expected_length = scale 7.06858347057701;
  88. ok abs($paths1[0]->length - $expected_length) < scaled_epsilon, 'cw oriented arc has correct length';
  89. ok abs($paths2[0]->length - $expected_length) < scaled_epsilon, 'ccw oriented arc has correct length';
  90. is $paths1[0]->orientation, 'cw', 'cw orientation was correctly detected';
  91. is $paths2[0]->orientation, 'ccw', 'ccw orientation was correctly detected';
  92. is $paths1[0]->flow_spacing, $path1->flow_spacing, 'flow spacing was correctly preserved';
  93. my $center1 = [ map sprintf('%.0f', $_), @{ $paths1[0]->center } ];
  94. ok abs($center1->[X] - scale 10) < scaled_epsilon && abs($center1->[Y] - scale 10) < scaled_epsilon, 'center was correctly detected';
  95. my $center2 = [ map sprintf('%.0f', $_), @{ $paths2[0]->center } ];
  96. ok abs($center2->[X] - scale 10) < scaled_epsilon && abs($center1->[Y] - scale 10) < scaled_epsilon, 'center was correctly detected';
  97. }
  98. #==========================================================