chiark / gitweb /
distort-stl: wip fixing edge mismatch bug
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 22 Nov 2018 20:39:55 +0000 (20:39 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 22 Nov 2018 20:39:55 +0000 (20:39 +0000)
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 <ijackson@chiark.greenend.org.uk>
distort-stl

index 0eb71fd6179121f346c1d60e4c52e89ba82d1528..dd430c9e452663b9aafcabdd7dc0abc3dfaf5ae7 100755 (executable)
@@ -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;