ExtrusionLoop.pm 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package Slic3r::ExtrusionLoop;
  2. use Moo;
  3. use Slic3r::Geometry qw(same_point);
  4. # the underlying Slic3r::Polygon objects holds the geometry
  5. has 'polygon' => (
  6. is => 'rw',
  7. required => 1,
  8. handles => [qw(is_printable nearest_point_index_to reverse)],
  9. );
  10. has 'flow_spacing' => (is => 'rw');
  11. # see EXTR_ROLE_* constants in ExtrusionPath.pm
  12. has 'role' => (is => 'rw', required => 1);
  13. use constant PACK_FMT => 'fca*';
  14. # class or object method
  15. sub pack {
  16. my $self = shift;
  17. my %args = @_;
  18. if (ref $self) {
  19. %args = map { $_ => $self->$_ } qw(flow_spacing role polygon);
  20. }
  21. my $o = \ pack PACK_FMT,
  22. $args{flow_spacing} || -1,
  23. $args{role} // (die "Missing mandatory attribute 'role'"), #/
  24. $args{polygon}->serialize;
  25. bless $o, 'Slic3r::ExtrusionLoop::Packed';
  26. return $o;
  27. }
  28. sub split_at_index {
  29. my $self = shift;
  30. my ($index) = @_;
  31. my @new_points = ();
  32. push @new_points, @{$self->polygon}[$index .. $#{$self->polygon}];
  33. push @new_points, @{$self->polygon}[0 .. $index];
  34. return Slic3r::ExtrusionPath->new(
  35. polyline => Slic3r::Polyline->new(\@new_points),
  36. role => $self->role,
  37. flow_spacing => $self->flow_spacing,
  38. );
  39. }
  40. sub split_at {
  41. my $self = shift;
  42. my ($point) = @_;
  43. $point = Slic3r::Point->new($point);
  44. # find index of point
  45. my $i = -1;
  46. for (my $n = 0; $n <= $#{$self->polygon}; $n++) {
  47. if (same_point($point, $self->polygon->[$n])) {
  48. $i = $n;
  49. last;
  50. }
  51. }
  52. die "Point not found" if $i == -1;
  53. return $self->split_at_index($i);
  54. }
  55. sub split_at_first_point {
  56. my $self = shift;
  57. return $self->split_at_index(0);
  58. }
  59. # although a loop doesn't have endpoints, this method is provided to allow
  60. # ExtrusionLoop objects to be added to an ExtrusionPath::Collection and
  61. # sorted by the ->shortest_path() method
  62. sub endpoints {
  63. my $self = shift;
  64. return ($self->polygon->[0], $self->polygon->[-1]);
  65. }
  66. # provided for ExtrusionPath::Collection->shortest_path()
  67. sub points {
  68. my $self = shift;
  69. return $self->polygon;
  70. }
  71. package Slic3r::ExtrusionLoop::Packed;
  72. sub unpack {
  73. my $self = shift;
  74. my ($flow_spacing, $role, $polygon_s)
  75. = unpack Slic3r::ExtrusionLoop::PACK_FMT, $$self;
  76. return Slic3r::ExtrusionLoop->new(
  77. flow_spacing => ($flow_spacing == -1) ? undef : $flow_spacing,
  78. role => $role,
  79. polygon => Slic3r::Polygon->deserialize($polygon_s),
  80. );
  81. }
  82. 1;