08_extrusionloop.t 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use List::Util qw(sum);
  5. use Slic3r::XS;
  6. use Test::More tests => 48;
  7. {
  8. my $square = [
  9. [100, 100],
  10. [200, 100],
  11. [200, 200],
  12. [100, 200],
  13. ];
  14. my $square_p = Slic3r::Polygon->new(@$square);
  15. my $loop = Slic3r::ExtrusionLoop->new;
  16. $loop->append(Slic3r::ExtrusionPath->new(
  17. polyline => $square_p->split_at_first_point,
  18. role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
  19. mm3_per_mm => 1,
  20. ));
  21. isa_ok $loop, 'Slic3r::ExtrusionLoop';
  22. isa_ok $loop->polygon, 'Slic3r::Polygon', 'loop polygon';
  23. is $loop->polygon->area, $square_p->area, 'polygon area';
  24. is $loop->length, $square_p->length(), 'loop length';
  25. $loop = $loop->clone;
  26. is scalar(@$loop), 1, 'loop contains one path';
  27. {
  28. my $path = $loop->[0];
  29. isa_ok $path, 'Slic3r::ExtrusionPath::Ref';
  30. is $path->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'role';
  31. $path->role(Slic3r::ExtrusionPath::EXTR_ROLE_FILL);
  32. is $path->role, Slic3r::ExtrusionPath::EXTR_ROLE_FILL, 'modify role';
  33. }
  34. $loop->split_at_vertex($square_p->[2]);
  35. is scalar(@$loop), 1, 'splitting a single-path loop results in a single path';
  36. is scalar(@{$loop->[0]->polyline}), 5, 'path has correct number of points';
  37. ok $loop->[0]->polyline->[0]->coincides_with($square_p->[2]), 'expected point order';
  38. ok $loop->[0]->polyline->[1]->coincides_with($square_p->[3]), 'expected point order';
  39. ok $loop->[0]->polyline->[2]->coincides_with($square_p->[0]), 'expected point order';
  40. ok $loop->[0]->polyline->[3]->coincides_with($square_p->[1]), 'expected point order';
  41. ok $loop->[0]->polyline->[4]->coincides_with($square_p->[2]), 'expected point order';
  42. }
  43. {
  44. my $polyline1 = Slic3r::Polyline->new([100,100], [200,100], [200,200]);
  45. my $polyline2 = Slic3r::Polyline->new([200,200], [100,200], [100,100]);
  46. my $loop = Slic3r::ExtrusionLoop->new_from_paths(
  47. Slic3r::ExtrusionPath->new(
  48. polyline => $polyline1,
  49. role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
  50. mm3_per_mm => 1,
  51. ),
  52. Slic3r::ExtrusionPath->new(
  53. polyline => $polyline2,
  54. role => Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER,
  55. mm3_per_mm => 1,
  56. ),
  57. );
  58. my $tot_len = sum($polyline1->length, $polyline2->length);
  59. is $loop->length, $tot_len, 'length';
  60. is scalar(@$loop), 2, 'loop contains two paths';
  61. {
  62. # check splitting at intermediate point
  63. my $loop2 = $loop->clone;
  64. isa_ok $loop2, 'Slic3r::ExtrusionLoop';
  65. $loop2->split_at_vertex($polyline1->[1]);
  66. is $loop2->length, $tot_len, 'length after splitting is unchanged';
  67. is scalar(@$loop2), 3, 'loop contains three paths after splitting';
  68. ok $loop2->[0]->polyline->[0]->coincides_with($polyline1->[1]), 'expected starting point';
  69. ok $loop2->[-1]->polyline->[-1]->coincides_with($polyline1->[1]), 'expected ending point';
  70. ok $loop2->[0]->polyline->[-1]->coincides_with($loop2->[1]->polyline->[0]), 'paths have common point';
  71. ok $loop2->[1]->polyline->[-1]->coincides_with($loop2->[2]->polyline->[0]), 'paths have common point';
  72. is $loop2->[0]->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'expected order after splitting';
  73. is $loop2->[1]->role, Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, 'expected order after splitting';
  74. is $loop2->[2]->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'expected order after splitting';
  75. is scalar(@{$loop2->[0]->polyline}), 2, 'path has correct number of points';
  76. is scalar(@{$loop2->[1]->polyline}), 3, 'path has correct number of points';
  77. is scalar(@{$loop2->[2]->polyline}), 2, 'path has correct number of points';
  78. my @paths = @{$loop2->clip_end(3)};
  79. is sum(map $_->length, @paths), $loop2->length - 3, 'returned paths have expected length';
  80. }
  81. {
  82. # check splitting at endpoint
  83. my $loop2 = $loop->clone;
  84. $loop2->split_at_vertex($polyline2->[0]);
  85. is $loop2->length, $tot_len, 'length after splitting is unchanged';
  86. is scalar(@$loop2), 2, 'loop contains two paths after splitting';
  87. ok $loop2->[0]->polyline->[0]->coincides_with($polyline2->[0]), 'expected starting point';
  88. ok $loop2->[-1]->polyline->[-1]->coincides_with($polyline2->[0]), 'expected ending point';
  89. ok $loop2->[0]->polyline->[-1]->coincides_with($loop2->[1]->polyline->[0]), 'paths have common point';
  90. ok $loop2->[1]->polyline->[-1]->coincides_with($loop2->[0]->polyline->[0]), 'paths have common point';
  91. is $loop2->[0]->role, Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, 'expected order after splitting';
  92. is $loop2->[1]->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'expected order after splitting';
  93. is scalar(@{$loop2->[0]->polyline}), 3, 'path has correct number of points';
  94. is scalar(@{$loop2->[1]->polyline}), 3, 'path has correct number of points';
  95. }
  96. {
  97. my $loop2 = $loop->clone;
  98. my $point = Slic3r::Point->new(250,150);
  99. $loop2->split_at($point);
  100. is $loop2->length, $tot_len, 'length after splitting is unchanged';
  101. is scalar(@$loop2), 3, 'loop contains three paths after splitting';
  102. my $expected_start_point = Slic3r::Point->new(200,150);
  103. ok $loop2->[0]->polyline->[0]->coincides_with($expected_start_point), 'expected starting point';
  104. ok $loop2->[-1]->polyline->[-1]->coincides_with($expected_start_point), 'expected ending point';
  105. }
  106. }
  107. {
  108. my @polylines = (
  109. Slic3r::Polyline->new([59312736,4821067],[64321068,4821067],[64321068,4821067],[64321068,9321068],[59312736,9321068]),
  110. Slic3r::Polyline->new([59312736,9321068],[9829401,9321068]),
  111. Slic3r::Polyline->new([9829401,9321068],[4821067,9321068],[4821067,4821067],[9829401,4821067]),
  112. Slic3r::Polyline->new([9829401,4821067],[59312736,4821067]),
  113. );
  114. my $loop = Slic3r::ExtrusionLoop->new;
  115. $loop->append($_) for (
  116. Slic3r::ExtrusionPath->new(polyline => $polylines[0], role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1),
  117. Slic3r::ExtrusionPath->new(polyline => $polylines[1], role => Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, mm3_per_mm => 1),
  118. Slic3r::ExtrusionPath->new(polyline => $polylines[2], role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1),
  119. Slic3r::ExtrusionPath->new(polyline => $polylines[3], role => Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER, mm3_per_mm => 1),
  120. );
  121. my $len = $loop->length;
  122. my $point = Slic3r::Point->new(4821067,9321068);
  123. $loop->split_at_vertex($point) or $loop->split_at($point);
  124. is $loop->length, $len, 'total length is preserved after splitting';
  125. is_deeply [ map $_->role, @$loop ], [
  126. Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
  127. Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER,
  128. Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
  129. Slic3r::ExtrusionPath::EXTR_ROLE_OVERHANG_PERIMETER,
  130. Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
  131. ], 'order is correctly preserved after splitting';
  132. }
  133. {
  134. my $loop = Slic3r::ExtrusionLoop->new;
  135. $loop->append(Slic3r::ExtrusionPath->new(
  136. polyline => Slic3r::Polyline->new([15896783,15868739],[24842049,12117558],[33853238,15801279],[37591780,24780128],[37591780,24844970],[33853231,33825297],[24842049,37509013],[15896798,33757841],[12211841,24812544],[15896783,15868739]),
  137. role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, mm3_per_mm => 1
  138. ));
  139. my $len = $loop->length;
  140. $loop->split_at(Slic3r::Point->new(15896783,15868739));
  141. is $loop->length, $len, 'split_at() preserves total length';
  142. }
  143. __END__