sl2/slicer.pl: complete basic processing structure (WIP)

This commit is contained in:
Werner Almesberger 2015-09-29 12:09:34 -03:00
parent 6800f025c1
commit 73c3a776a3
1 changed files with 90 additions and 36 deletions

View File

@ -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;
}
}