From 45146328f74d660232d33b0867ae1f6cd700e034 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 22 Nov 2018 20:39:55 +0000 Subject: [PATCH] distort-stl: wip fixing edge mismatch bug 807ba5b3024fb82823d2f3fb9dafa1702470e56a "poster-tube-lid: Makefile: get set-fa argument right" was wrong, because it's not permitted to have a vertex of one triangle in the middle of the edge of an adjacent triangle. What we should be doing is splitting *edges*. If we do that based only on the properties of the *edge*, and get the same midpoint coordinate each time, then the result will be consistent when we process the "same" edge as part of different triangles. So we don't need to memoise everything. Right now this is just the initial cut and does not actually run. Signed-off-by: Ian Jackson --- distort-stl | 70 ++++++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 39 deletions(-) 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; -- 2.30.2