diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm
index 5b13e13ff..ea18e8ced 100644
--- a/lib/Slic3r/Polygon.pm
+++ b/lib/Slic3r/Polygon.pm
@@ -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) {
diff --git a/lib/Slic3r/Test.pm b/lib/Slic3r/Test.pm
index 5531ae4f0..403ca4947 100644
--- a/lib/Slic3r/Test.pm
+++ b/lib/Slic3r/Test.pm
@@ -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;
     }
diff --git a/t/perimeters.t b/t/perimeters.t
index d432f480d..0954a4c7c 100644
--- a/t/perimeters.t
+++ b/t/perimeters.t
@@ -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__
diff --git a/xs/src/Point.cpp b/xs/src/Point.cpp
index 6129f6ac3..a17d0cd39 100644
--- a/xs/src/Point.cpp
+++ b/xs/src/Point.cpp
@@ -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
 {
diff --git a/xs/src/Point.hpp b/xs/src/Point.hpp
index b87fa3a45..9ba665f55 100644
--- a/xs/src/Point.hpp
+++ b/xs/src/Point.hpp
@@ -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;
diff --git a/xs/xsp/Point.xsp b/xs/xsp/Point.xsp
index 4817ca650..1380c01f1 100644
--- a/xs/xsp/Point.xsp
+++ b/xs/xsp/Point.xsp
@@ -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); %};
 
 %{