Bugfix: seam_position = aligned failed in certaim circumstances because of faulty concave points detection. Includes regression test

master
Alessandro Ranellucci 2014-06-11 21:57:32 +02:00
parent 1674108bac
commit 5dcc1eab79
6 changed files with 54 additions and 3 deletions

View File

@ -59,11 +59,12 @@ sub concave_points {
my @concave = ();
for my $i (-1 .. ($#points-1)) {
next if $points[$i-1]->coincides_with($points[$i]);
next if $points[$i-1]->coincides_with_epsilon($points[$i]) || $points[$i+1]->coincides_with_epsilon($points[$i]);
# angle is measured in ccw orientation
my $vertex_angle = Slic3r::Geometry::angle3points(@points_pp[$i, $i-1, $i+1]);
if ($vertex_angle <= $ccw_angle) {
push @concave, $points[$i];
use XXX; YYY ($points[$i]->pp);
}
}
return [@concave];
@ -83,7 +84,7 @@ sub convex_points {
my @convex = ();
for my $i (-1 .. ($#points-1)) {
next if $points[$i-1]->coincides_with($points[$i]);
next if $points[$i-1]->coincides_with_epsilon($points[$i]) || $points[$i+1]->coincides_with_epsilon($points[$i]);
# angle is measured in ccw orientation
my $vertex_angle = Slic3r::Geometry::angle3points(@points_pp[$i, $i-1, $i+1]);
if ($vertex_angle >= $ccw_angle) {

View File

@ -104,6 +104,13 @@ sub mesh {
$facets = [
[0,1,2],[3,4,5],[6,4,0],[6,0,2],[2,1,5],[7,4,3],[1,3,5],[0,4,7],[4,6,8],[6,9,8],[4,8,10],[6,2,9],[2,11,9],[2,12,11],[2,5,12],[5,13,12],[5,14,13],[4,10,15],[5,4,14],[4,15,14],[7,16,17],[0,7,18],[7,17,18],[1,19,20],[1,0,19],[0,18,19],[7,3,21],[3,22,21],[7,21,16],[3,23,22],[3,1,23],[1,20,23],[24,25,26],[25,27,26],[25,28,27],[29,24,30],[24,31,30],[24,26,31],[32,29,33],[29,30,33],[32,33,34],[32,34,35],[25,32,28],[32,35,28],[36,37,24],[38,32,25],[29,32,36],[29,36,24],[24,37,25],[39,32,38],[37,38,25],[36,32,39],[39,40,41],[36,39,42],[39,41,42],[37,43,44],[37,36,43],[36,42,43],[39,38,45],[38,46,45],[39,45,40],[38,47,46],[38,37,47],[37,44,47],[16,8,9],[16,10,8],[10,16,15],[15,16,21],[22,15,21],[15,22,14],[22,23,14],[23,20,14],[17,16,9],[18,17,9],[19,18,9],[19,9,11],[19,11,20],[13,14,20],[20,11,12],[13,20,12],[41,40,30],[42,41,30],[43,42,30],[43,30,31],[43,31,44],[27,28,44],[44,31,26],[27,44,26],[40,33,30],[40,34,33],[34,40,35],[35,40,45],[46,35,45],[35,46,28],[46,47,28],[47,44,28],
];
} elsif ($name eq 'small_dorito') {
$vertices = [
[6.00058937072754,-22.9982089996338,0],[22.0010242462158,-49.9998741149902,0],[-9.99957847595215,-49.999870300293,0],[6.00071382522583,-32.2371635437012,28.0019245147705],[11.1670551300049,-37.9727020263672,18.9601669311523],[6.00060224533081,-26.5392456054688,10.7321853637695]
];
$facets = [
[0,1,2],[3,4,5],[2,1,4],[2,4,3],[2,3,5],[2,5,0],[5,4,1],[5,1,0]
];
} else {
return undef;
}

View File

@ -1,4 +1,4 @@
use Test::More tests => 9;
use Test::More tests => 11;
use strict;
use warnings;
@ -250,4 +250,38 @@ use Slic3r::Test;
ok Slic3r::Test::gcode($print), 'successful generation of G-code with seam_position = random';
}
{
my $test = sub {
my ($model_name) = @_;
my $config = Slic3r::Config->new_from_defaults;
$config->set('seam_position', 'aligned');
$config->set('skirts', 0);
$config->set('perimeters', 1);
$config->set('fill_density', 0);
$config->set('top_solid_layers', 0);
$config->set('bottom_solid_layers', 0);
$config->set('retract_layer_change', [0]);
my $was_extruding = 0;
my @seam_points = ();
my $print = Slic3r::Test::init_print($model_name, config => $config);
Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub {
my ($self, $cmd, $args, $info) = @_;
if ($info->{extruding}) {
if (!$was_extruding) {
push @seam_points, Slic3r::Point->new_scale($self->X, $self->Y);
}
$was_extruding = 1;
} else {
$was_extruding = 0;
}
});
my @dist = map unscale($_), map $seam_points[$_]->distance_to($seam_points[$_+1]), 0..($#seam_points-1);
ok !(defined first { $_ > 3 } @dist), 'seam is aligned';
};
$test->('20mm_cube');
$test->('small_dorito');
}
__END__

View File

@ -55,6 +55,12 @@ Point::coincides_with(const Point &point) const
return this->x == point.x && this->y == point.y;
}
bool
Point::coincides_with_epsilon(const Point &point) const
{
return std::abs(this->x - point.x) < SCALED_EPSILON && std::abs(this->y - point.y) < SCALED_EPSILON;
}
int
Point::nearest_point_index(const Points &points) const
{

View File

@ -33,6 +33,7 @@ class Point
void translate(double x, double y);
void rotate(double angle, const Point &center);
bool coincides_with(const Point &point) const;
bool coincides_with_epsilon(const Point &point) const;
int nearest_point_index(const Points &points) const;
int nearest_point_index(const PointConstPtrs &points) const;
int nearest_point_index(const PointPtrs &points) const;

View File

@ -37,6 +37,8 @@
%code{% RETVAL = new Point(THIS->projection_onto(*line)); %};
Clone<Point> negative()
%code{% RETVAL = new Point(THIS->negative()); %};
bool coincides_with_epsilon(Point* point)
%code{% RETVAL = THIS->coincides_with_epsilon(*point); %};
%{