Some compatibility bugs. Slic3r will still fail hard with non-manifold objects

This commit is contained in:
Alessandro Ranellucci 2011-10-11 15:51:08 +02:00
parent bca3abb755
commit f01ddae974
4 changed files with 32 additions and 23 deletions

View File

@ -201,7 +201,7 @@ sub polygon_lines {
sub nearest_point { sub nearest_point {
my ($point, $points) = @_; my ($point, $points) = @_;
my ($nearest_point, $distance); my ($nearest_point, $distance) = ();
foreach my $p (@$points) { foreach my $p (@$points) {
my $d = distance_between_points($point, $p); my $d = distance_between_points($point, $p);
if (!defined $distance || $d < $distance) { if (!defined $distance || $d < $distance) {

View File

@ -3,7 +3,8 @@ use Moo;
use Math::Clipper ':all'; use Math::Clipper ':all';
use Math::ConvexHull qw(convex_hull); use Math::ConvexHull qw(convex_hull);
use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines); use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines nearest_point
line_length);
use Slic3r::Geometry::Clipper qw(union_ex); use Slic3r::Geometry::Clipper qw(union_ex);
use XXX; use XXX;
@ -135,6 +136,7 @@ sub make_surfaces {
my @lines = (); my @lines = ();
push @lines, map $_->p, @{$self->lines}; push @lines, map $_->p, @{$self->lines};
#@lines = grep line_length($_) > xx, @lines;
#use Slic3r::SVG; #use Slic3r::SVG;
#Slic3r::SVG::output(undef, "lines.svg", #Slic3r::SVG::output(undef, "lines.svg",
@ -144,10 +146,13 @@ sub make_surfaces {
my $get_point_id = sub { sprintf "%.0f,%.0f", @{$_[0]} }; my $get_point_id = sub { sprintf "%.0f,%.0f", @{$_[0]} };
my (%pointmap) = (); my (%pointmap, @pointmap_keys) = ();
foreach my $line (@lines) { foreach my $line (@lines) {
my $point_id = $get_point_id->($line->[A]); my $point_id = $get_point_id->($line->[A]);
$pointmap{$point_id} ||= []; if (!exists $pointmap{$point_id}) {
$pointmap{$point_id} = [];
push @pointmap_keys, $line->[A];
}
push @{ $pointmap{$point_id} }, $line; push @{ $pointmap{$point_id} }, $line;
} }
@ -163,16 +168,25 @@ sub make_surfaces {
# shouldn't we find the point, let's try with a slower algorithm # shouldn't we find the point, let's try with a slower algorithm
# as approximation may make the coordinates differ # as approximation may make the coordinates differ
if (!$next_lines) { if (!$next_lines) {
local $Slic3r::Geometry::epsilon = 1; my $nearest_point = nearest_point($points[-1], \@pointmap_keys);
for (keys %pointmap) { #printf " we have a nearest point: %f,%f (%s)\n", @$nearest_point, $get_point_id->($nearest_point);
$next_lines = $pointmap{$_} if points_coincide($points[-1], [ split /,/, $_ ]);
last if $next_lines; if ($nearest_point) {
local $Slic3r::Geometry::epsilon = 1000000;
$next_lines = $pointmap{$get_point_id->($nearest_point)}
if points_coincide($points[-1], $nearest_point);
} }
} }
#Slic3r::SVG::output(undef, "lines.svg",
# lines => [ map $_->p, grep !$_->isa('Slic3r::Line::FacetEdge'), @{$self->lines} ],
# red_lines => [ map $_->p, grep $_->isa('Slic3r::Line::FacetEdge'), @{$self->lines} ],
# points => [ $points[-1] ],
# no_arrows => 1,
#) if !$next_lines;
$next_lines $next_lines
or die sprintf "No lines start at point %s. This shouldn't happen", or die sprintf("No lines start at point %s. This shouldn't happen", $get_point_id->($points[-1]));
$get_point_id->($points[-1]);
last CYCLE if !@$next_lines; last CYCLE if !@$next_lines;
my @ordered_next_lines = sort my @ordered_next_lines = sort
@ -210,17 +224,11 @@ sub make_surfaces {
push @polylines, [@points]; push @polylines, [@points];
} }
#use Slic3r::SVG;
#Slic3r::SVG::output(undef, "polylines.svg",
# polylines => [ @polylines ],
#);
#exit if $self->id == 30;
{ {
my $expolygons = union_ex([ @polylines ]); my $expolygons = union_ex([ @polylines ]);
Slic3r::debugf " %d surface(s) detected from %d polylines\n", Slic3r::debugf " %d surface(s) detected from %d polylines\n",
scalar(@$expolygons), scalar(@polylines); scalar(@$expolygons), scalar(@polylines);
push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'), @$expolygons; push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'), @$expolygons;
} }

View File

@ -157,7 +157,7 @@ sub intersect_facet {
[ [$a->[X], $a->[Y]], [$b->[X], $b->[Y]] ], [ [$a->[X], $a->[Y]], [$b->[X], $b->[Y]] ],
edge_type => $edge_type, edge_type => $edge_type,
); );
#print "Horizontal edge!\n"; #print "Horizontal edge at $z!\n";
} elsif (($a->[Z] < $z && $b->[Z] > $z) || ($b->[Z] < $z && $a->[Z] > $z)) { } elsif (($a->[Z] < $z && $b->[Z] > $z) || ($b->[Z] < $z && $a->[Z] > $z)) {
# edge intersects the current layer; calculate intersection # edge intersects the current layer; calculate intersection
@ -165,14 +165,14 @@ sub intersect_facet {
$b->[X] + ($a->[X] - $b->[X]) * ($z - $b->[Z]) / ($a->[Z] - $b->[Z]), $b->[X] + ($a->[X] - $b->[X]) * ($z - $b->[Z]) / ($a->[Z] - $b->[Z]),
$b->[Y] + ($a->[Y] - $b->[Y]) * ($z - $b->[Z]) / ($a->[Z] - $b->[Z]), $b->[Y] + ($a->[Y] - $b->[Y]) * ($z - $b->[Z]) / ($a->[Z] - $b->[Z]),
]; ];
#print "Intersects!\n"; #print "Intersects at $z!\n";
} elsif ($a->[Z] == $z) { } elsif ($a->[Z] == $z) {
#print "A point on plane!\n"; #print "A point on plane $z!\n";
push @intersection_points, [ $a->[X], $a->[Y] ]; push @intersection_points, [ $a->[X], $a->[Y] ];
} elsif ($b->[Z] == $z) { } elsif ($b->[Z] == $z) {
#print "B point on plane!\n"; #print "B point on plane $z!\n";
push @intersection_points, [ $b->[X], $b->[Y] ]; push @intersection_points, [ $b->[X], $b->[Y] ];
} }
} }
@ -194,6 +194,7 @@ sub intersect_facet {
# connect points: # connect points:
push @lines, Slic3r::Line->cast([ @intersection_points ]); push @lines, Slic3r::Line->cast([ @intersection_points ]);
#printf " intersection points = %f,%f - %f,%f\n", map @$_, @intersection_points;
} }
return @lines; return @lines;

View File

@ -58,7 +58,7 @@ sub output {
); );
$g->$method( $g->$method(
%$path, %$path,
'marker-end' => "url(#endArrow)", 'marker-end' => $things{no_arrows} ? "" : "url(#endArrow)",
); );
} }
} }
@ -101,7 +101,7 @@ sub output {
style => { style => {
'stroke' => $colour || 'black', 'stroke' => $colour || 'black',
}, },
'marker-end' => "url(#endArrow)", 'marker-end' => $things{no_arrows} ? "" : "url(#endArrow)",
); );
} }
} }