From 5ebf6a71cd04e1e93efc9de8a01df72c55974088 Mon Sep 17 00:00:00 2001 From: Mark Hindess Date: Wed, 9 May 2012 19:57:00 +0100 Subject: [PATCH 1/3] Add FE_NONE with value 0 and increment FE_TOP and FE_BOTTOM to simplify and correct logic. --- lib/Slic3r/TriangleMesh.pm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/Slic3r/TriangleMesh.pm b/lib/Slic3r/TriangleMesh.pm index 216e28c1a..9e3f07223 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -23,8 +23,9 @@ use constant I_PREV_FACET_INDEX => 4; use constant I_NEXT_FACET_INDEX => 5; use constant I_FACET_EDGE => 6; -use constant FE_TOP => 0; -use constant FE_BOTTOM => 1; +use constant FE_NONE => 0; +use constant FE_TOP => 1; +use constant FE_BOTTOM => 2; # always make sure BUILD is idempotent sub BUILD { @@ -144,11 +145,11 @@ sub make_loops { # remove tangent edges { for (my $i = 0; $i <= $#lines; $i++) { - next unless defined $lines[$i] && defined $lines[$i][I_FACET_EDGE]; + next unless defined $lines[$i] && $lines[$i][I_FACET_EDGE]; # if the line is a facet edge, find another facet edge # having the same endpoints but in reverse order for (my $j = $i+1; $j <= $#lines; $j++) { - next unless defined $lines[$j] && defined $lines[$j][I_FACET_EDGE]; + next unless defined $lines[$j] && $lines[$j][I_FACET_EDGE]; # are these facets adjacent? (sharing a common edge on this layer) if ($lines[$i][I_A_ID] == $lines[$j][I_B_ID] && $lines[$i][I_B_ID] == $lines[$j][I_A_ID]) { @@ -156,7 +157,8 @@ sub make_loops { # if they are both oriented upwards or downwards (like a 'V') # then we can remove both edges from this layer since it won't # affect the sliced shape - if ($lines[$j][I_FACET_EDGE] == $lines[$i][I_FACET_EDGE]) { + if ($lines[$j][I_FACET_EDGE] && + $lines[$j][I_FACET_EDGE] == $lines[$i][I_FACET_EDGE]) { $lines[$i] = undef; $lines[$j] = undef; last; @@ -208,8 +210,8 @@ sub make_loops { if (0) { require "Slic3r/SVG.pm"; Slic3r::SVG::output(undef, "same_point.svg", - lines => [ map $_->line, grep !defined $_->[I_FACET_EDGE], @lines ], - red_lines => [ map $_->line, grep defined $_->[I_FACET_EDGE], @lines ], + lines => [ map $_->line, grep !$_->[I_FACET_EDGE], @lines ], + red_lines => [ map $_->line, grep $_->[I_FACET_EDGE], @lines ], points => [ $self->vertices->[$point_id] ], no_arrows => 0, ); @@ -482,7 +484,7 @@ sub intersect_facet { $facet_id, # I_FACET_INDEX $prev_facet_index, # I_PREV_FACET_INDEX $next_facet_index, # I_NEXT_FACET_INDEX - undef, # I_FACET_EDGE + FE_NONE, # I_FACET_EDGE # Unused data: # a => [$points[B][X], $points[B][Y]], From 9d85a19b9d4026c9d1a304802bcf34e83c62cca8 Mon Sep 17 00:00:00 2001 From: Mark Hindess Date: Thu, 10 May 2012 19:07:20 +0100 Subject: [PATCH 2/3] Rework fix to use undef correctly. --- lib/Slic3r/TriangleMesh.pm | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/Slic3r/TriangleMesh.pm b/lib/Slic3r/TriangleMesh.pm index 9e3f07223..47c1ab430 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -23,9 +23,8 @@ use constant I_PREV_FACET_INDEX => 4; use constant I_NEXT_FACET_INDEX => 5; use constant I_FACET_EDGE => 6; -use constant FE_NONE => 0; -use constant FE_TOP => 1; -use constant FE_BOTTOM => 2; +use constant FE_TOP => 0; +use constant FE_BOTTOM => 1; # always make sure BUILD is idempotent sub BUILD { @@ -145,11 +144,11 @@ sub make_loops { # remove tangent edges { for (my $i = 0; $i <= $#lines; $i++) { - next unless defined $lines[$i] && $lines[$i][I_FACET_EDGE]; + next unless defined $lines[$i] && defined $lines[$i][I_FACET_EDGE]; # if the line is a facet edge, find another facet edge # having the same endpoints but in reverse order for (my $j = $i+1; $j <= $#lines; $j++) { - next unless defined $lines[$j] && $lines[$j][I_FACET_EDGE]; + next unless defined $lines[$j] && defined $lines[$j][I_FACET_EDGE]; # are these facets adjacent? (sharing a common edge on this layer) if ($lines[$i][I_A_ID] == $lines[$j][I_B_ID] && $lines[$i][I_B_ID] == $lines[$j][I_A_ID]) { @@ -157,8 +156,7 @@ sub make_loops { # if they are both oriented upwards or downwards (like a 'V') # then we can remove both edges from this layer since it won't # affect the sliced shape - if ($lines[$j][I_FACET_EDGE] && - $lines[$j][I_FACET_EDGE] == $lines[$i][I_FACET_EDGE]) { + if ($lines[$j][I_FACET_EDGE] == $lines[$i][I_FACET_EDGE]) { $lines[$i] = undef; $lines[$j] = undef; last; @@ -192,7 +190,7 @@ sub make_loops { } foreach my $point_id (grep $a_count{$_} > 1, keys %a_count) { - my @lines_starting_here = grep defined $_->[I_A_ID] && $_->[I_A_ID] == $point_id, @lines; + my @lines_starting_here = grep defined $_->[I_A_ID] && defined $_[I_FACET_EDGE] && $_->[I_A_ID] == $point_id, @lines; Slic3r::debugf "%d lines start at point %d\n", scalar(@lines_starting_here), $point_id; # if two lines start at this point, one being a 'top' facet edge and the other being a 'bottom' one, @@ -210,8 +208,8 @@ sub make_loops { if (0) { require "Slic3r/SVG.pm"; Slic3r::SVG::output(undef, "same_point.svg", - lines => [ map $_->line, grep !$_->[I_FACET_EDGE], @lines ], - red_lines => [ map $_->line, grep $_->[I_FACET_EDGE], @lines ], + lines => [ map $_->line, grep !defined $_->[I_FACET_EDGE], @lines ], + red_lines => [ map $_->line, grep defined $_->[I_FACET_EDGE], @lines ], points => [ $self->vertices->[$point_id] ], no_arrows => 0, ); @@ -484,7 +482,7 @@ sub intersect_facet { $facet_id, # I_FACET_INDEX $prev_facet_index, # I_PREV_FACET_INDEX $next_facet_index, # I_NEXT_FACET_INDEX - FE_NONE, # I_FACET_EDGE + undef, # I_FACET_EDGE # Unused data: # a => [$points[B][X], $points[B][Y]], From 5a16756aacd25615fe1f259e169317c515bf9ade Mon Sep 17 00:00:00 2001 From: Mark Hindess Date: Thu, 10 May 2012 22:23:24 +0100 Subject: [PATCH 3/3] Avoid undef errors while keeping the debug so root cause can be found. --- lib/Slic3r/TriangleMesh.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/TriangleMesh.pm b/lib/Slic3r/TriangleMesh.pm index 47c1ab430..b95521274 100644 --- a/lib/Slic3r/TriangleMesh.pm +++ b/lib/Slic3r/TriangleMesh.pm @@ -190,13 +190,15 @@ sub make_loops { } foreach my $point_id (grep $a_count{$_} > 1, keys %a_count) { - my @lines_starting_here = grep defined $_->[I_A_ID] && defined $_[I_FACET_EDGE] && $_->[I_A_ID] == $point_id, @lines; + my @lines_starting_here = grep defined $_->[I_A_ID] && $_->[I_A_ID] == $point_id, @lines; Slic3r::debugf "%d lines start at point %d\n", scalar(@lines_starting_here), $point_id; # if two lines start at this point, one being a 'top' facet edge and the other being a 'bottom' one, # then remove the top one and those following it (removing the top or the bottom one is an arbitrary # choice) - if (@lines_starting_here == 2 && join('', sort map $_->[I_FACET_EDGE], @lines_starting_here) eq FE_TOP.FE_BOTTOM) { + # The "// ''" on the next line avoids uninitialized value errors mentioned in issue #357 but these + # errors occur on fixed models so the root cause still needs to be found + if (@lines_starting_here == 2 && join('', sort map $_->[I_FACET_EDGE] // '', @lines_starting_here) eq FE_TOP.FE_BOTTOM) { my @to_remove = grep $_->[I_FACET_EDGE] == FE_TOP, @lines_starting_here; while (!grep defined $_->[I_B_ID] && $_->[I_B_ID] == $to_remove[-1]->[I_B_ID] && $_ ne $to_remove[-1], @lines) { push @to_remove, grep defined $_->[I_A_ID] && $_->[I_A_ID] == $to_remove[-1]->[I_B_ID], @lines;