X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=reprap-play.git;a=blobdiff_plain;f=distort-stl;h=844344cdb0c1a1f09a80e3ea9fe61fa168507c36;hp=f8989923b6809d763ffbeeb4fb7172dcdb1210ba;hb=65a5654d9cdc3511df415d8fd92285b117dc2288;hpb=724e5ab69049a06164482b91a5312d243314388d diff --git a/distort-stl b/distort-stl index f898992..844344c 100755 --- a/distort-stl +++ b/distort-stl @@ -34,29 +34,78 @@ sub TAU () { M_PI * 2; } our $fa = 10; -our @triangles; +our $triangles; +our $output; sub shift_arg () { die unless @ARGV; scalar shift @ARGV; } -sub subdivide_triangle ($$) { - my ($t, $fn) = @_; - my @mids; +#no warnings qw(recursion); + +sub maybe_subdivide_triangle ($$$$) { + my ($t, $ok, $changed, $edge_need_subdivide_fn) = @_; + + printf STDERR + "%11.6f,%11.6f,%11.6f / ". + "%11.6f,%11.6f,%11.6f / ". + "%11.6f,%11.6f,%11.6f %-40s ", + $t->[0][0], $t->[0][1], $t->[0][2], + $t->[1][0], $t->[1][1], $t->[1][2], + $t->[2][0], $t->[2][1], $t->[2][2], + $t->[3]; + foreach my $ix (0..2) { my $jx = ($ix+1) % 3; - my @midp; - foreach my $ci (0..2) { - push @midp, 0.5 * ($t->[$ix][$ci] + $t->[$jx][$ci]); + my $kx = ($ix+2) % 3; + if ($edge_need_subdivide_fn->($t->[$ix], $t->[$jx])) { + printf STDERR + " S i=%d j=%d k=%d ", + $ix, $jx, $kx; + my @midp; + foreach my $ci (0..2) { + push @midp, 0.5 * ($t->[$ix][$ci] + $t->[$jx][$ci]); + } + # triangle i-j-k, splitting edge i-m + # gives i-m-k, k-m-j + my $n = [ @$t ]; $n->[$ix] = \@midp; $n->[3] = "$t->[3]a$ix$jx"; + unshift @$changed, $n; + + my $n = [ @$t ]; $n->[$jx] = \@midp; $n->[3] = "$t->[3]b$ix$jx"; + unshift @$changed, $n; + printf STDERR + " midp %11.6f,%11.6f,%11.6f\n", + @midp; + return; } - push @mids, @midp; } - foreach my $ix (0..2) { - my $kx = ($ix+2) % 3; - $fn->([ $t->[$ix], $mids[$ix], $t->[$kx] ]); + push @$ok, $t; + printf STDERR "OK nok=%d nchanged=%d\n", + (scalar @$ok), (scalar @$changed); +} + +sub maybe_subdivide ($) { + my ($edge_need_subdivide_fn) = @_; + + my @small_enough = (); + while (my $t = shift @$triangles) { + maybe_subdivide_triangle $t, \@small_enough, $triangles, + $edge_need_subdivide_fn; } - $fn->(\@mids); + + $triangles = \@small_enough; +} + +sub append_triangle ($) { + my ($t) = @_; + push @$output, $t; +} + +#---------- set-fa ---------- + +sub op__set_fa () { + $fa = shift_arg; } #---------- project-cylinder ---------- @@ -64,23 +113,20 @@ sub subdivide_triangle ($$) { our $project_cylinder_radius; our $project_cylinder_max_d_theta; +sub project_cylinder_edge_need_subdivide ($$) { + my @thetas = map { $_->[0] / $project_cylinder_radius } @_; + return abs($thetas[0] - $thetas[1]) > $project_cylinder_max_d_theta; +} + sub project_cylinder_tri { my ($t) = @_; - my $radius = $project_cylinder_radius; + #print STDERR 'PROJECT', Dumper($t); - my @thetas = map { $_->[0] / $radius } @$t; - - foreach my $ix (0..2) { - if (abs($thetas[$ix] - $thetas[($ix+1)%3]) - > $project_cylinder_max_d_theta) { - subdivide_triangle $t, \&project_cylinder_tri; - return; - } - } + my $radius = $project_cylinder_radius; my @ot; - foreach my $p ($t) { + foreach my $p (@$t) { my ($x,$y,$z) = @$p; my $r = $radius - $y; my $theta = $x / $radius; @@ -88,17 +134,20 @@ 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 = (); - - project_cylinder_tri $_ foreach @input; + maybe_subdivide \&project_cylinder_edge_need_subdivide; + + $output = []; + foreach my $t (@$triangles) { + project_cylinder_tri $t; + } + $triangles = $output; } #---------- main program ---------- @@ -147,7 +196,8 @@ while () { push @$triangle, \@xyz; } elsif (m/^endloop/) { die unless @$triangle == 3; - push @triangles, $triangle; + push @$triangle, $.; + push @$triangles, $triangle; undef $triangle; } elsif (m/^(?:solid|facet\s+normal|endfacet|endsolid)\s/) { } else { @@ -168,10 +218,12 @@ 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"; + die unless @$t==3; foreach my $p (@$t) { + die unless @$p==3; print " vertex"; printf " %.18g", $_ foreach @$p; print "\n";