diff --git a/sl2/slicer.pl b/sl2/slicer.pl index 15e7a3b..58ecfe8 100755 --- a/sl2/slicer.pl +++ b/sl2/slicer.pl @@ -12,10 +12,19 @@ # -$epsilon = 0.0001; +$epsilon = 0.0001; # cutting offset +$height = 10; # height of workpiece +$margin = 5; # margin of workpiece box +$end = 0; # offset to add at the last layer +$flip = 1; # flip piece +$z0 = -35; # reference tool position +$z_step = 1; -$flip = 1; +#----- Read the STL mesh ------------------------------------------------------ + + +$xmin = $xmax = $ymin = $ymax = $zmin = $zmax = undef; $v_n = 0; $e_n = 0; @@ -35,21 +44,39 @@ while (<>) { if (/vertex\s+/) { my @tmp = split(/\s+/, $'); - if ($flip) { - push(@f, -$tmp[0], $tmp[1], -$tmp[2]); - } else { - push(@f, @tmp); - } + ($tmp[0], $tmp[2]) = (-$tmp[0], -$tmp[2]) if $flip; + + $xmin = $tmp[0] unless defined $xmin && $xmin < $tmp[0]; + $xmax = $tmp[0] unless defined $xmax && $xmax > $tmp[0]; + $ymin = $tmp[1] unless defined $ymin && $ymin < $tmp[1]; + $ymax = $tmp[1] unless defined $ymax && $ymax > $tmp[1]; + $zmin = $tmp[2] unless defined $zmin && $zmin < $tmp[2]; + $zmax = $tmp[2] unless defined $zmax && $zmax > $tmp[2]; + + push(@f, @tmp); next; } } +print STDERR "bbox\t($xmin, $ymin, $zmin)\n\t($xmax, $ymax, $zmax)\n"; + + +#----- Calculate Z offset ----------------------------------------------------- + +# align with bottom (zmin == 0), z_pos = height - zoff + +$z_off = $z0 - $zmin - $height; +$z_pos = $height + $zmin; + + +#----- Perform the slicing ---------------------------------------------------- + sub cut { local ($z, $a, $b, @f) = @_; - if ($f[$a + 2] < $z &&$f[$b + 2] > $z) { + if ($f[$a + 2] < $z && $f[$b + 2] > $z) { my $dx = $f[$b] - $f[$a]; my $dy = $f[$b + 1] - $f[$a + 1]; my $dz = $f[$b + 2] - $f[$a + 2]; @@ -57,7 +84,7 @@ sub cut my $f = ($z - $f[$a + 2]) / $dz; return [ $dx * $f + $f[$a], $dy * $f + $f[$a + 1] ]; } - if ($f[$a + 2] > $z &&$f[$b + 2] < $z) { + if ($f[$a + 2] > $z && $f[$b + 2] < $z) { return &cut($z, $b, $a, @f); } return (); @@ -78,46 +105,73 @@ sub remove } -for $level (sort keys %z_level) { - my $z = $level + $epsilon; +@z_levels = sort { $b <=> $a } keys %z_level; +for $level (@z_levels) { + my $z_cut = $level + $epsilon; -# print STDERR "level = $level\n"; - undef %next; + print STDERR "level $level (cut at $z_cut)\n"; + + undef %path; for (@m) { my @f = @{ $_ }; - my @p = &cut($z, 0, 3, @f); - push(@p, &cut($z, 0, 6, @f)); - push(@p, &cut($z, 3, 6, @f)); + my @p = &cut($z_cut, 0, 3, @f); + push(@p, &cut($z_cut, 0, 6, @f)); + push(@p, &cut($z_cut, 3, 6, @f)); next if $#p < 1; die "BAD $#p" if $#p > 1; my $a = "$p[0][0] $p[0][1]"; my $b = "$p[1][0] $p[1][1]"; - push(@{ $next{$a} }, $b); - push(@{ $next{$b} }, $a); + push(@{ $path{$a} }, $b); + push(@{ $path{$b} }, $a); # print STDERR "$z: ($a) to ($b)\n"; } while (1) { - my @k = keys %next; - - last if $#k == -1; - my $p0 = $k[0]; - $p = $p0; - while (1) { - my $next = $next{$p}[0]; - - print "$p $z\n"; -# print STDERR "at $p\n"; -# print STDERR "\tnext $next\n"; - die "open path" unless defined $next; - &remove($p, $next); - &remove($next, $p); - last if $p0 eq $next; - $p = $next; + if (defined $z_step) { + $z_pos = $z_pos - $z_step > $level ? + $z_pos - $z_step : $level; + } else { + $z_pos = $level; } - print "$p0 $z\n"; - print "\n"; + + my $z = $z_pos + $z_off; + $z += $end if $z_pos == $z_levels[$#z_levels]; + + print STDERR "\t$z_pos @ $z\n"; + if (defined $margin) { + print $xmin - $margin, " ", $ymin - $margin, " $z\n"; + print $xmax + $margin, " ", $ymin - $margin, " $z\n"; + print $xmax + $margin, " ", $ymax + $margin, " $z\n"; + print $xmin - $margin, " ", $ymax + $margin, " $z\n"; + print $xmin - $margin, " ", $ymin - $margin, " $z\n\n"; + } + + %next = %path; + while (1) { + my @k = keys %next; + + last if $#k == -1; + + my $p0 = $k[0]; + $p = $p0; + while (1) { + my $next = $next{$p}[0]; + + print "$p $z\n"; +# print STDERR "at $p\n"; +# print STDERR "\tnext $next\n"; + die "open path" unless defined $next; + &remove($p, $next); + &remove($next, $p); + last if $p0 eq $next; + $p = $next; + } + print "$p0 $z\n"; + print "\n"; + } + + last if $z_pos == $level; } }