X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=reprap-play.git;a=blobdiff_plain;f=distort-stl;h=39e5a150512c339c38a7a635194194a95b886bce;hp=eb3a7a15deb92a6c393b45fd3db21f63426cab00;hb=1d7ee4585cc01e847229d7ebd5868a95ae33652f;hpb=0b7257ca44cddaf016c96b1998fe34b99d1701b6 diff --git a/distort-stl b/distort-stl index eb3a7a1..39e5a15 100755 --- a/distort-stl +++ b/distort-stl @@ -25,58 +25,81 @@ use strict; use autodie; -use File::Temp; use List::Util; +use POSIX; +use File::Temp (); +use Data::Dumper; + +sub TAU () { M_PI * 2; } our $fa = 10; -our @triangles; +our $triangles; +our $output; sub shift_arg () { die unless @ARGV; scalar shift @ARGV; } +#no warnings qw(recursion); + sub subdivide_triangle ($$) { - my ($it, $fn) = @_; + my ($t, $fn) = @_; + + #print STDERR 'SUBDIV', Dumper($t, $fn); + my @mids; foreach my $ix (0..2) { my $jx = ($ix+1) % 3; my @midp; foreach my $ci (0..2) { - push @midp, 0.5 * ($it->[$ix][$ci] + $it->[$jx][$ci]); + push @midp, 0.5 * ($t->[$ix][$ci] + $t->[$jx][$ci]); } - push @mids, @midp; + push @mids, \@midp; } foreach my $ix (0..2) { + #print STDERR 'SUBDIV IX ', $ix, "\n"; my $kx = ($ix+2) % 3; - $fn->([ $it->[$ix], $mids[$ix], $it->[$kx] ]); + $fn->([ $t->[$ix], $mids[$ix], $mids[$kx] ]); } + #print STDERR 'SUBDIV MID\n'; $fn->(\@mids); } +sub append_triangle ($) { + my ($t) = @_; + push @$output, $t; +} + #---------- project-cylinder ---------- our $project_cylinder_radius; our $project_cylinder_max_d_theta; -sub project_cylinder_tri { - my ($it) = @_; - - my $radius = project_cylinder_radius; - - my @thetas = map { $_->[0] / $radius } @$it; +sub project_cylinder_need_subdivide () { + foreach my $t (@$triangles) { + my @thetas = map { $_->[0] / $project_cylinder_radius } @$t; - foreach my $ix (0..2) { - if (abs($thetas[$ix] - $thetas[($ix+1)%3]) - > $project_cylinder_max_d_theta) { - subdivide_triangle $it, \&project_cylinder_tri; - return; + foreach my $ix (0..2) { + if (abs($thetas[$ix] - $thetas[($ix+1)%3]) + > $project_cylinder_max_d_theta) { + return 1; + } } } + return 0; +} + +sub project_cylinder_tri { + my ($t) = @_; + + #print STDERR 'PROJECT', Dumper($t); + + my $radius = $project_cylinder_radius; my @ot; - foreach my $p (@it) { + foreach my $p (@$t) { my ($x,$y,$z) = @$p; my $r = $radius - $y; my $theta = $x / $radius; @@ -84,50 +107,77 @@ sub project_cylinder_tri { -$r * cos($theta), $z ]; } - push @triangles, \@ot; + append_triangle \@ot; } sub op__project_cylinder () { $project_cylinder_radius = shift_arg; $project_cylinder_max_d_theta = $fa * TAU/360; - my @input = (@triangles); - @triangles = (); + while (project_cylinder_need_subdivide()) { + $output = []; + foreach my $t (@$triangles) { + subdivide_triangle $t, \&append_triangle; + } + $triangles = $output; + } - project_cylinder_tri $_ foreach @input; + $output = []; + foreach my $t (@$triangles) { + project_cylinder_tri $t; + } + $triangles = $output; } #---------- main program ---------- -if (@ARGV && $ARGV[0] =~ m/^-/) { - die "no options supported\n"; -} +our $raw; -my $itmp = new File::Temp; -my $otmp = new File::Temp; +while (@ARGV && $ARGV[0] =~ m/^-/) { + $_ = shift @ARGV; + last if m/^--$/; + if (s/^--raw$//) { + $raw = 1; + } else { + die "$_ ?"; + } +} -system "cat >$itmp"; +my $itmp; +my $otmp; my $admesh_stdout = '--write-ascii-stl /dev/fd/3 3>&1 >/dev/null'; -open I, "admesh $admesh_stdout $itmp |"; +if ($raw) { + open I, "<& STDIN"; + $otmp = *STDOUT; +} else { + $itmp = new File::Temp; + $otmp = new File::Temp; + + system "cat >$itmp"; + + open I, "admesh $admesh_stdout $itmp |"; +} my $triangle; while () { - if (m/^\s+outer\s+loop/) { + s/^\s*//; + if (m/^outer\s+loop/) { die if $triangle; $triangle = []; - } elsif (s/^\s+vertex\s+//) { + } elsif (s/^vertex\s+//) { my $lhs = $&; s/\s+$//; my @xyz = split /\s+/, $_; die unless $triangle; - push @$triangle, \@xya; - } elsif (m/^\s+endloop/) { + push @$triangle, \@xyz; + } elsif (m/^endloop/) { die unless @$triangle == 3; - push @triangles, $triangle; - } elsif (m/^\s+(?:solid|facet\s+normal|endfacet|endsolid)\s/) { + push @$triangles, $triangle; + undef $triangle; + } elsif (m/^(?:solid|facet\s+normal|endfacet|endsolid)\s/) { } else { die "$_ ?"; } @@ -146,12 +196,16 @@ select $otmp; print "solid distort-stl\n"; -foreach my $t (@triangles) { +foreach my $t (@$triangles) { print " facet normal 0 0 0\n"; print " outer loop\n"; - print " vertex"; - printf " %.18g", $_ foreach @$t; - print "\n"; + die unless @$t==3; + foreach my $p (@$t) { + die unless @$p==3; + print " vertex"; + printf " %.18g", $_ foreach @$p; + print "\n"; + } print " endloop\n"; print " endfacet\n"; } @@ -160,4 +214,6 @@ print "endsolid distort-stl\n"; flush $otmp; -system "admesh --normal-values $admesh_stdout $otmp"; +if (!$raw) { + system "admesh --normal-values $admesh_stdout $otmp"; +}