From b14290b9f67b3dfe12a5547eafcd434ae9fd0c75 Mon Sep 17 00:00:00 2001
From: Alessandro Ranellucci <aar@cpan.org>
Date: Thu, 2 Jul 2015 14:29:20 +0200
Subject: [PATCH] Make tests happy

---
 lib/Slic3r/ExtrusionPath.pm            |  3 ++-
 lib/Slic3r/GCode.pm                    |  4 ++--
 lib/Slic3r/Layer/PerimeterGenerator.pm |  2 +-
 t/perimeters.t                         | 11 +++++++----
 xs/src/libslic3r/ExtrusionEntity.hpp   |  1 +
 xs/src/libslic3r/GCode.cpp             |  4 ++--
 xs/src/libslic3r/GCode.hpp             |  2 +-
 xs/xsp/ExtrusionLoop.xsp               |  3 +--
 xs/xsp/ExtrusionPath.xsp               |  1 +
 xs/xsp/GCode.xsp                       |  2 +-
 10 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/lib/Slic3r/ExtrusionPath.pm b/lib/Slic3r/ExtrusionPath.pm
index 0c324ab09..3e9e6b8c7 100644
--- a/lib/Slic3r/ExtrusionPath.pm
+++ b/lib/Slic3r/ExtrusionPath.pm
@@ -6,7 +6,8 @@ use parent qw(Exporter);
 
 our @EXPORT_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_EXTERNAL_PERIMETER EXTR_ROLE_OVERHANG_PERIMETER
     EXTR_ROLE_FILL EXTR_ROLE_SOLIDFILL EXTR_ROLE_TOPSOLIDFILL EXTR_ROLE_GAPFILL EXTR_ROLE_BRIDGE 
-    EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_SUPPORTMATERIAL_INTERFACE);
+    EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_SUPPORTMATERIAL_INTERFACE
+    EXTR_ROLE_NONE);
 our %EXPORT_TAGS = (roles => \@EXPORT_OK);
 
 1;
diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm
index ae1ea0453..96a3170fd 100644
--- a/lib/Slic3r/GCode.pm
+++ b/lib/Slic3r/GCode.pm
@@ -306,7 +306,7 @@ sub travel_to {
     my $travel = Slic3r::Polyline->new($self->last_pos, $point);
     
     # check whether a straight travel move would need retraction
-    my $needs_retraction = $self->needs_retraction($travel, $role);
+    my $needs_retraction = $self->needs_retraction($travel, $role // EXTR_ROLE_NONE);
     
     # if a retraction would be needed, try to use avoid_crossing_perimeters to plan a
     # multi-hop travel path inside the configuration space
@@ -316,7 +316,7 @@ sub travel_to {
         $travel = $self->avoid_crossing_perimeters->travel_to($self, $point);
         
         # check again whether the new travel path still needs a retraction
-        $needs_retraction = $self->needs_retraction($travel, $role);
+        $needs_retraction = $self->needs_retraction($travel, $role // EXTR_ROLE_NONE);
     }
     
     # Re-allow avoid_crossing_perimeters for the next travel moves
diff --git a/lib/Slic3r/Layer/PerimeterGenerator.pm b/lib/Slic3r/Layer/PerimeterGenerator.pm
index 07da50f50..daf2ba8f8 100644
--- a/lib/Slic3r/Layer/PerimeterGenerator.pm
+++ b/lib/Slic3r/Layer/PerimeterGenerator.pm
@@ -355,7 +355,7 @@ sub _traverse_loops {
             # there's only one contour loop).
             $loop_role = EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER;
         } else {
-            $loop_role = EXTR_ROLE_PERIMETER;
+            $loop_role = EXTRL_ROLE_DEFAULT;
         }
         
         # detect overhanging/bridging perimeters
diff --git a/t/perimeters.t b/t/perimeters.t
index dc2644e9d..d103eb3f2 100644
--- a/t/perimeters.t
+++ b/t/perimeters.t
@@ -329,13 +329,16 @@ use Slic3r::Test;
             scalar(@$expolygons), 'expected number of collections';
         ok !defined(first { !$_->isa('Slic3r::ExtrusionPath::Collection') } @{$g->loops}),
             'everything is returned as collections';
-        is scalar(map @$_, @{$g->loops}),
+        
+        my $flattened_loops = $g->loops->flatten;
+        my @loops = @$flattened_loops;
+        is scalar(@loops),
             $expected{total}, 'expected number of loops';
-        is scalar(grep $_->role == EXTR_ROLE_EXTERNAL_PERIMETER, map @$_, map @$_, @{$g->loops}),
+        is scalar(grep $_->role == EXTR_ROLE_EXTERNAL_PERIMETER, map @$_, @loops),
             $expected{external}, 'expected number of external loops';
-        is scalar(grep $_->role == EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER, map @$_, @{$g->loops}),
+        is scalar(grep $_->role == EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER, @loops),
             $expected{cinternal}, 'expected number of internal contour loops';
-        is scalar(grep $_->polygon->is_counter_clockwise, map @$_, @{$g->loops}),
+        is scalar(grep $_->polygon->is_counter_clockwise, @loops),
             $expected{ccw}, 'expected number of ccw loops';
         
         return $g;
diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp
index 74541832f..9be5b4125 100644
--- a/xs/src/libslic3r/ExtrusionEntity.hpp
+++ b/xs/src/libslic3r/ExtrusionEntity.hpp
@@ -13,6 +13,7 @@ class Extruder;
 
 /* Each ExtrusionRole value identifies a distinct set of { extruder, speed } */
 enum ExtrusionRole {
+    erNone,
     erPerimeter,
     erExternalPerimeter,
     erOverhangPerimeter,
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index d7b2fcbfd..a7241b7d6 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -156,7 +156,7 @@ REGISTER_CLASS(Wipe, "GCode::Wipe");
 GCode::GCode()
     : enable_loop_clipping(true), enable_cooling_markers(false), layer_count(0),
         layer_index(-1), first_layer(false), elapsed_time(0), volumetric_speed(0),
-        _last_pos_defined(false)
+        _last_pos_defined(false), layer(NULL), placeholder_parser(NULL)
 {
 }
 
@@ -224,7 +224,7 @@ GCode::needs_retraction(const Polyline &travel, ExtrusionRole role)
     
     if (role == erSupportMaterial) {
         SupportLayer* support_layer = dynamic_cast<SupportLayer*>(this->layer);
-        if (support_layer->support_islands.contains(travel)) {
+        if (support_layer != NULL && support_layer->support_islands.contains(travel)) {
             // skip retraction if this is a travel move inside a support material island
             return false;
         }
diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp
index 2dbbebddb..846b82299 100644
--- a/xs/src/libslic3r/GCode.hpp
+++ b/xs/src/libslic3r/GCode.hpp
@@ -87,7 +87,7 @@ class GCode {
     void apply_print_config(const PrintConfig &print_config);
     void set_origin(const Pointf &pointf);
     std::string preamble();
-    bool needs_retraction(const Polyline &travel, ExtrusionRole role);
+    bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
     std::string retract(bool toolchange = false);
     std::string unretract();
     Pointf point_to_gcode(const Point &point);
diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp
index 0da0fe0d4..3b7adcd6a 100644
--- a/xs/xsp/ExtrusionLoop.xsp
+++ b/xs/xsp/ExtrusionLoop.xsp
@@ -38,9 +38,8 @@ ExtrusionLoop::arrayref()
     CODE:
         AV* av = newAV();
         av_fill(av, THIS->paths.size()-1);
-        int i = 0;
         for (ExtrusionPaths::iterator it = THIS->paths.begin(); it != THIS->paths.end(); ++it) {
-            av_store(av, i++, perl_to_SV_ref(*it));
+            av_store(av, it - THIS->paths.begin(), perl_to_SV_ref(*it));
         }
         RETVAL = newRV_noinc((SV*)av);
     OUTPUT:
diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp
index 57fee2b61..491862840 100644
--- a/xs/xsp/ExtrusionPath.xsp
+++ b/xs/xsp/ExtrusionPath.xsp
@@ -133,6 +133,7 @@ ExtrusionPath::subtract_expolygons(ExPolygonCollection* collection)
 IV
 _constant()
   ALIAS:
+    EXTR_ROLE_NONE                         = erNone
     EXTR_ROLE_PERIMETER                    = erPerimeter
     EXTR_ROLE_EXTERNAL_PERIMETER           = erExternalPerimeter
     EXTR_ROLE_OVERHANG_PERIMETER           = erOverhangPerimeter
diff --git a/xs/xsp/GCode.xsp b/xs/xsp/GCode.xsp
index fdfc3d894..5095fcfab 100644
--- a/xs/xsp/GCode.xsp
+++ b/xs/xsp/GCode.xsp
@@ -152,7 +152,7 @@
     void set_origin(Pointf* pointf)
         %code{% THIS->set_origin(*pointf); %};
     std::string preamble();
-    bool needs_retraction(Polyline* travel, ExtrusionRole role)
+    bool needs_retraction(Polyline* travel, ExtrusionRole role = erNone)
         %code{% RETVAL = THIS->needs_retraction(*travel, role); %};
     std::string retract(bool toolchange = false);
     std::string unretract();