X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=distort-stl;fp=distort-stl;h=dd430c9e452663b9aafcabdd7dc0abc3dfaf5ae7;hb=45146328f74d660232d33b0867ae1f6cd700e034;hp=0eb71fd6179121f346c1d60e4c52e89ba82d1528;hpb=f79993b675194a1e13713da23cf27642d2a381e4;p=reprap-play.git diff --git a/distort-stl b/distort-stl index 0eb71fd..dd430c9 100755 --- a/distort-stl +++ b/distort-stl @@ -44,27 +44,37 @@ sub shift_arg () { #no warnings qw(recursion); -sub subdivide_triangle ($$) { - my ($t, $fn) = @_; - - #print STDERR 'SUBDIV', Dumper($t, $fn); - - my @mids; +sub maybe_subdivide_triangle ($$$$) { + my ($t, $ok, $changed, $edge_need_subdivide_fn) = @_; + 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])) { + 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 + push @$changed, + [ $t[$ix], \@midp, $t[kx] ], + [ $t[$kx], \@midp, $t[jx] ]; + return; } - push @mids, \@midp; } - foreach my $ix (0..2) { - #print STDERR 'SUBDIV IX ', $ix, "\n"; - my $kx = ($ix+2) % 3; - $fn->([ $t->[$ix], $mids[$ix], $mids[$kx] ]); + push @$ok, $t; +} + +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; } - #print STDERR 'SUBDIV MID\n'; - $fn->(\@mids); + + $triangles = \@small_enough; } sub append_triangle ($) { @@ -83,17 +93,9 @@ sub op__set_fa () { our $project_cylinder_radius; our $project_cylinder_max_d_theta; -sub project_cylinder_triangle_need_subdivide ($) { - my ($t) = @_; - 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) { - return 1; - } - } - return 0; +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 { @@ -119,18 +121,8 @@ sub op__project_cylinder () { $project_cylinder_radius = shift_arg; $project_cylinder_max_d_theta = $fa * TAU/360; - my @small_enough = (); - while (my $t = shift @$triangles) { - if (!project_cylinder_triangle_need_subdivide $t) { - push @small_enough, $t; - } else { - local $output = $triangles; - subdivide_triangle $t, \&append_triangle; - } - } - - $triangles = \@small_enough; - + maybe_subdivide \&project_cylinder_triangle_need_subdivide; + $output = []; foreach my $t (@$triangles) { project_cylinder_tri $t;