diff --git a/lib/Slic3r/GUI/PreviewCanvas.pm b/lib/Slic3r/GUI/PreviewCanvas.pm
index 2cfa1c4e9..686d67f94 100644
--- a/lib/Slic3r/GUI/PreviewCanvas.pm
+++ b/lib/Slic3r/GUI/PreviewCanvas.pm
@@ -49,14 +49,14 @@ sub new {
             color => COLORS->[ $color_idx % scalar(@{&COLORS}) ],
         };
         
-        my ($vertices, $facets) = ($mesh->vertices, $mesh->facets);
         {
-            my @verts = map @{ $vertices->[$_] }, map @$_, @$facets;
+            my $vertices = $mesh->vertices;
+            my @verts = map @{ $vertices->[$_] }, map @$_, @{$mesh->facets};
             $v->{verts} = OpenGL::Array->new_list(GL_FLOAT, @verts);
         }
         
         {
-            my @norms = map { @$_, @$_, @$_ } map normalize(triangle_normal(map $vertices->[$_], @$_)), @$facets;
+            my @norms = map @$_, @{$mesh->normals};
             $v->{norms} = OpenGL::Array->new_list(GL_FLOAT, @norms);
         }
     }
diff --git a/xs/t/01_trianglemesh.t b/xs/t/01_trianglemesh.t
index 0585b461b..71ae47319 100644
--- a/xs/t/01_trianglemesh.t
+++ b/xs/t/01_trianglemesh.t
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 
 use Slic3r::XS;
-use Test::More tests => 50;
+use Test::More tests => 51;
 
 is Slic3r::TriangleMesh::hello_world(), 'Hello world!',
     'hello world';
@@ -22,6 +22,7 @@ my $cube = {
     
     is_deeply $vertices, $cube->{vertices}, 'vertices arrayref roundtrip';
     is_deeply $facets, $cube->{facets}, 'facets arrayref roundtrip';
+    is scalar(@{$m->normals}), scalar(@$facets), 'normals returns the right number of items';
     
     {
         my $m2 = $m->clone;
diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp
index b05c9b0f8..664c03713 100644
--- a/xs/xsp/TriangleMesh.xsp
+++ b/xs/xsp/TriangleMesh.xsp
@@ -92,6 +92,27 @@ TriangleMesh::facets()
     OUTPUT:
         RETVAL
 
+SV*
+TriangleMesh::normals()
+    CODE:
+        if (!THIS->repaired) CONFESS("normals() requires repair()");
+        
+        // normals
+        AV* normals = newAV();
+        av_extend(normals, THIS->stl.stats.number_of_facets);
+        for (int i = 0; i < THIS->stl.stats.number_of_facets; i++) {
+            AV* facet = newAV();
+            av_store(normals, i, newRV_noinc((SV*)facet));
+            av_extend(facet, 2);
+            av_store(facet, 0, newSVnv(THIS->stl.facet_start[i].normal.x));
+            av_store(facet, 1, newSVnv(THIS->stl.facet_start[i].normal.y));
+            av_store(facet, 2, newSVnv(THIS->stl.facet_start[i].normal.z));
+        }
+        
+        RETVAL = newRV_noinc((SV*)normals);
+    OUTPUT:
+        RETVAL
+
 SV*
 TriangleMesh::size()
     CODE: