Browse Source

Merge branch 'master' into sender

Conflicts:
	Build.PL
	lib/Slic3r/GUI/MainFrame.pm
Alessandro Ranellucci 9 years ago
parent
commit
13b7316807

+ 1 - 1
README.md

@@ -280,7 +280,7 @@ The author of the Silk icon set is Mark James.
                             Only retract before travel moves of this length in mm (default: 2)
         --retract-lift      Lift Z by the given distance in mm when retracting (default: 0)
         --retract-layer-change
-                            Enforce a retraction before each Z move (default: yes)
+                            Enforce a retraction before each Z move (default: no)
         --wipe              Wipe the nozzle while doing a retraction (default: no)
     
        Retraction options for multi-extruder setups:

+ 8 - 6
lib/Slic3r.pm

@@ -32,8 +32,6 @@ warn "Running Slic3r under Perl 5.16 is not supported nor recommended\n"
 use FindBin;
 our $var = "$FindBin::Bin/var";
 
-use Encode;
-use Encode::Locale;
 use Moo 1.003001;
 
 use Slic3r::XS;   # import all symbols (constants etc.) before they get parsed
@@ -262,13 +260,17 @@ sub resume_all_threads {
 }
 
 sub encode_path {
-    my ($filename) = @_;
-    return encode('locale_fs', $filename);
+    my ($path) = @_;
+    
+    utf8::downgrade($path) if $^O eq 'MSWin32';
+    return $path;
 }
 
 sub decode_path {
-    my ($filename) = @_;
-    return decode('locale_fs', $filename);
+    my ($path) = @_;
+    
+    utf8::upgrade($path) if $^O eq 'MSWin32';
+    return $path;
 }
 
 sub open {

+ 3 - 1
lib/Slic3r/Fill/Concentric.pm

@@ -6,6 +6,8 @@ extends 'Slic3r::Fill::Base';
 use Slic3r::Geometry qw(scale unscale X);
 use Slic3r::Geometry::Clipper qw(offset offset2 union_pt_chained);
 
+sub no_sort { 1 }
+
 sub fill_surface {
     my $self = shift;
     my ($surface, %params) = @_;
@@ -36,7 +38,7 @@ sub fill_surface {
     @loops = map Slic3r::Polygon->new(@$_),
         reverse @{union_pt_chained(\@loops)};
     
-    # order paths using a nearest neighbor search
+    # split paths using a nearest neighbor search
     my @paths = ();
     my $last_pos = Slic3r::Point->new(0,0);
     foreach my $loop (@loops) {

+ 4 - 4
lib/Slic3r/GCode.pm

@@ -21,7 +21,7 @@ has 'avoid_crossing_perimeters' => (is => 'rw', default => sub { Slic3r::GCode::
 has 'enable_loop_clipping' => (is => 'rw', default => sub {1});
 has 'enable_cooling_markers' => (is =>'rw', default => sub {0});
 has 'layer_count'        => (is => 'ro');
-has '_layer_index'       => (is => 'rw', default => sub {-1});  # just a counter
+has 'layer_index'        => (is => 'rw', default => sub {-1});  # just a counter
 has 'layer'              => (is => 'rw');
 has '_seam_position'     => (is => 'ro', default => sub { {} });  # $object => pos
 has 'first_layer'        => (is => 'rw', default => sub {0});   # this flag triggers first layer speeds
@@ -76,7 +76,7 @@ sub change_layer {
     my ($self, $layer) = @_;
     
     $self->layer($layer);
-    $self->_layer_index($self->_layer_index + 1);
+    $self->layer_index($self->layer_index + 1);
     $self->first_layer($layer->id == 0);
     
     # avoid computing islands and overhangs if they're not needed
@@ -88,14 +88,14 @@ sub change_layer {
     
     my $gcode = "";
     if (defined $self->layer_count) {
-        $gcode .= $self->writer->update_progress($self->_layer_index, $self->layer_count);
+        $gcode .= $self->writer->update_progress($self->layer_index, $self->layer_count);
     }
     
     my $z = $layer->print_z + $self->config->z_offset;  # in unscaled coordinates
     if ($self->config->get_at('retract_layer_change', $self->writer->extruder->id) && $self->writer->will_move_z($z)) {
         $gcode .= $self->retract;
     }
-    $gcode .= $self->writer->travel_to_z($z, 'move to next layer (' . $self->layer->id . ')');
+    $gcode .= $self->writer->travel_to_z($z, 'move to next layer (' . $self->layer_index . ')');
     
     # forget last wiping path as wiping after raising Z is pointless
     $self->wipe->path(undef);

+ 2 - 2
lib/Slic3r/GUI.pm

@@ -81,7 +81,7 @@ sub OnInit {
     $self->{notifier} = Slic3r::GUI::Notifier->new;
     
     # locate or create data directory
-    $datadir ||= Wx::StandardPaths::Get->GetUserDataDir;
+    $datadir ||= Slic3r::decode_path(Wx::StandardPaths::Get->GetUserDataDir);
     my $enc_datadir = Slic3r::encode_path($datadir);
     Slic3r::debugf "Data directory: %s\n", $datadir;
     
@@ -297,7 +297,7 @@ sub open_model {
         $dialog->Destroy;
         return;
     }
-    my @input_files = $dialog->GetPaths;
+    my @input_files = map Slic3r::decode_path($_), $dialog->GetPaths;
     $dialog->Destroy;
     
     return @input_files;

+ 55 - 2
lib/Slic3r/GUI/3DScene.pm

@@ -593,7 +593,7 @@ sub Resize {
         -$x/2, $x/2, -$y/2, $y/2,
         -$depth, 2*$depth,
     );
- 
+    
     glMatrixMode(GL_MODELVIEW);
 }
  
@@ -937,7 +937,7 @@ package Slic3r::GUI::3DScene;
 use base qw(Slic3r::GUI::3DScene::Base);
 
 use OpenGL qw(:glconstants :gluconstants :glufunctions);
-use List::Util qw(first);
+use List::Util qw(first min max);
 use Slic3r::Geometry qw(scale unscale epsilon);
 use Slic3r::Print::State ':steps';
 
@@ -1079,6 +1079,59 @@ sub load_print_object_slices {
     );
 }
 
+sub load_print_toolpaths {
+    my ($self, $print) = @_;
+    
+    return if !$print->step_done(STEP_SKIRT);
+    return if !$print->step_done(STEP_BRIM);
+    return if !$print->has_skirt && $print->config->brim_width == 0;
+    
+    my $qverts  = Slic3r::GUI::_3DScene::GLVertexArray->new;
+    my $tverts  = Slic3r::GUI::_3DScene::GLVertexArray->new;
+    my %offsets = ();  # print_z => [ qverts, tverts ]
+    
+    my $skirt_height = 0;  # number of layers
+    if ($print->has_infinite_skirt) {
+        $skirt_height = $print->total_layer_count;
+    } else {
+        $skirt_height = min($print->config->skirt_height, $print->total_layer_count);
+    }
+    $skirt_height ||= 1 if $print->config->brim_width > 0;
+    
+    # get first $skirt_height layers (maybe this should be moved to a PrintObject method?)
+    my $object0 = $print->get_object(0);
+    my @layers = ();
+    push @layers, map $object0->get_layer($_-1), 1..min($skirt_height, $object0->layer_count);
+    push @layers, map $object0->get_support_layer($_-1), 1..min($skirt_height, $object0->support_layer_count);
+    @layers = sort { $a->print_z <=> $b->print_z } @layers;
+    @layers = @layers[0..($skirt_height-1)];
+    
+    foreach my $i (0..($skirt_height-1)) {
+        my $top_z = $layers[$i]->print_z;
+        $offsets{$top_z} = [$qverts->size, $tverts->size];
+        
+        if ($i == 0) {
+            $self->_extrusionentity_to_verts($print->brim, $top_z, Slic3r::Point->new(0,0), $qverts, $tverts);
+        }
+        
+        $self->_extrusionentity_to_verts($print->skirt, $top_z, Slic3r::Point->new(0,0), $qverts, $tverts);
+    }
+    
+    my $bb = Slic3r::Geometry::BoundingBoxf3->new;
+    {
+        my $pbb = $print->bounding_box;
+        $bb->merge_point(Slic3r::Pointf3->new_unscale(@{$pbb->min_point}));
+        $bb->merge_point(Slic3r::Pointf3->new_unscale(@{$pbb->max_point}));
+    }
+    push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
+        bounding_box    => $bb,
+        color           => COLORS->[2],
+        qverts          => $qverts,
+        tverts          => $tverts,
+        offsets         => { %offsets },
+    );
+}
+
 sub load_print_object_toolpaths {
     my ($self, $object) = @_;
     

+ 2 - 2
lib/Slic3r/GUI/AboutDialog.pm

@@ -3,7 +3,7 @@ use strict;
 use warnings;
 use utf8;
 
-use Wx qw(:font :html :misc :sizer :systemsettings);
+use Wx qw(:font :html :misc :dialog :sizer :systemsettings);
 use Wx::Event qw(EVT_HTML_LINK_CLICKED);
 use Wx::Print;
 use Wx::Html;
@@ -12,7 +12,7 @@ use base 'Wx::Dialog';
 sub new {
     my $class = shift;
     my ($parent) = @_;
-    my $self = $class->SUPER::new($parent, -1, 'About Slic3r', wxDefaultPosition, [600, 300]);
+    my $self = $class->SUPER::new($parent, -1, 'About Slic3r', wxDefaultPosition, [600, 300], &Wx::wxCLOSE_BOX);
 
     $self->SetBackgroundColour(Wx::wxWHITE);
     my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);

+ 1 - 1
lib/Slic3r/GUI/BedShapeDialog.pm

@@ -386,7 +386,7 @@ sub _load_stl {
         $dialog->Destroy;
         return;
     }
-    my $input_file = $dialog->GetPaths;
+    my $input_file = Slic3r::decode_path($dialog->GetPaths);
     $dialog->Destroy;
     
     my $model = Slic3r::Model->read_from_file($input_file);

+ 63 - 37
lib/Slic3r/GUI/MainFrame.pm

@@ -141,8 +141,8 @@ sub _init_tabpanel {
     
     if ($self->{plater}) {
         $self->{plater}->on_select_preset(sub {
-            my ($group, $preset) = @_;
-	        $self->{options_tabs}{$group}->select_preset($preset);
+            my ($group, $i) = @_;
+	        $self->{options_tabs}{$group}->select_preset($i);
         });
         
         # load initial config
@@ -158,38 +158,44 @@ sub _init_menubar {
     {
         $self->_append_menu_item($fileMenu, "&Load Config…\tCtrl+L", 'Load exported configuration file', sub {
             $self->load_config_file;
-        });
+        }, undef, 'plugin_add.png');
         $self->_append_menu_item($fileMenu, "&Export Config…\tCtrl+E", 'Export current configuration to file', sub {
             $self->export_config;
-        });
+        }, undef, 'plugin_go.png');
         $self->_append_menu_item($fileMenu, "&Load Config Bundle…", 'Load presets from a bundle', sub {
             $self->load_configbundle;
-        });
+        }, undef, 'lorry_add.png');
         $self->_append_menu_item($fileMenu, "&Export Config Bundle…", 'Export all presets to file', sub {
             $self->export_configbundle;
-        });
+        }, undef, 'lorry_go.png');
         $fileMenu->AppendSeparator();
         my $repeat;
         $self->_append_menu_item($fileMenu, "Q&uick Slice…\tCtrl+U", 'Slice file', sub {
-            $self->quick_slice;
-            $repeat->Enable(defined $Slic3r::GUI::MainFrame::last_input_file);
-        });
+            wxTheApp->CallAfter(sub {
+                $self->quick_slice;
+                $repeat->Enable(defined $Slic3r::GUI::MainFrame::last_input_file);
+            });
+        }, undef, 'cog_go.png');
         $self->_append_menu_item($fileMenu, "Quick Slice and Save &As…\tCtrl+Alt+U", 'Slice file and save as', sub {
-            $self->quick_slice(save_as => 1);
-            $repeat->Enable(defined $Slic3r::GUI::MainFrame::last_input_file);
-        });
+            wxTheApp->CallAfter(sub {
+                $self->quick_slice(save_as => 1);
+                $repeat->Enable(defined $Slic3r::GUI::MainFrame::last_input_file);
+            });
+        }, undef, 'cog_go.png');
         $repeat = $self->_append_menu_item($fileMenu, "&Repeat Last Quick Slice\tCtrl+Shift+U", 'Repeat last quick slice', sub {
-            $self->quick_slice(reslice => 1);
-        });
+            wxTheApp->CallAfter(sub {
+                $self->quick_slice(reslice => 1);
+            });
+        }, undef, 'cog_go.png');
         $repeat->Enable(0);
         $fileMenu->AppendSeparator();
         $self->_append_menu_item($fileMenu, "Slice to SV&G…\tCtrl+G", 'Slice file to SVG', sub {
             $self->quick_slice(save_as => 1, export_svg => 1);
-        });
+        }, undef, 'shape_handles.png');
         $fileMenu->AppendSeparator();
         $self->_append_menu_item($fileMenu, "Repair STL file…", 'Automatically repair an STL file', sub {
             $self->repair_stl;
-        });
+        }, undef, 'wrench.png');
         $fileMenu->AppendSeparator();
         $self->_append_menu_item($fileMenu, "Preferences…", 'Application preferences', sub {
             Slic3r::GUI::Preferences->new($self)->ShowModal;
@@ -207,13 +213,13 @@ sub _init_menubar {
         $self->{plater_menu} = Wx::Menu->new;
         $self->_append_menu_item($self->{plater_menu}, "Export G-code...", 'Export current plate as G-code', sub {
             $plater->export_gcode;
-        });
+        }, undef, 'cog_go.png');
         $self->_append_menu_item($self->{plater_menu}, "Export plate as STL...", 'Export current plate as STL', sub {
             $plater->export_stl;
-        });
+        }, undef, 'brick_go.png');
         $self->_append_menu_item($self->{plater_menu}, "Export plate as AMF...", 'Export current plate as AMF', sub {
             $plater->export_amf;
-        });
+        }, undef, 'brick_go.png');
         
         $self->{object_menu} = $self->{plater}->object_menu;
         $self->on_plater_selection_changed(0);
@@ -226,22 +232,22 @@ sub _init_menubar {
         if (!$self->{no_plater}) {
             $self->_append_menu_item($windowMenu, "Select &Plater Tab\tCtrl+1", 'Show the plater', sub {
                 $self->select_tab(0);
-            });
+            }, undef, 'application_view_tile.png');
             $self->_append_menu_item($windowMenu, "Select &Controller Tab\tCtrl+T", 'Show the printer controller', sub {
                 $self->select_tab(1);
-            });
+            }, undef, 'printer_empty.png');
             $windowMenu->AppendSeparator();
             $tab_offset += 2;
         }
         $self->_append_menu_item($windowMenu, "Select P&rint Settings Tab\tCtrl+2", 'Show the print settings', sub {
             $self->select_tab($tab_offset+0);
-        });
+        }, undef, 'cog.png');
         $self->_append_menu_item($windowMenu, "Select &Filament Settings Tab\tCtrl+3", 'Show the filament settings', sub {
             $self->select_tab($tab_offset+1);
-        });
+        }, undef, 'spool.png');
         $self->_append_menu_item($windowMenu, "Select Print&er Settings Tab\tCtrl+4", 'Show the printer settings', sub {
             $self->select_tab($tab_offset+2);
-        });
+        }, undef, 'printer_empty.png');
     }
     
     # Help menu
@@ -313,7 +319,7 @@ sub quick_slice {
                 $dialog->Destroy;
                 return;
             }
-            $input_file = $dialog->GetPaths;
+            $input_file = Slic3r::decode_path($dialog->GetPaths);
             $dialog->Destroy;
             $last_input_file = $input_file unless $params{export_svg};
         } else {
@@ -373,7 +379,7 @@ sub quick_slice {
                 $dlg->Destroy;
                 return;
             }
-            $output_file = $dlg->GetPath;
+            $output_file = Slic3r::decode_path($dlg->GetPath);
             $last_output_file = $output_file unless $params{export_svg};
             $Slic3r::GUI::Settings->{_}{last_output_path} = dirname($output_file);
             wxTheApp->save_settings;
@@ -420,7 +426,7 @@ sub repair_stl {
             $dialog->Destroy;
             return;
         }
-        $input_file = $dialog->GetPaths;
+        $input_file = Slic3r::decode_path($dialog->GetPaths);
         $dialog->Destroy;
     }
     
@@ -433,7 +439,7 @@ sub repair_stl {
             $dlg->Destroy;
             return undef;
         }
-        $output_file = $dlg->GetPath;
+        $output_file = Slic3r::decode_path($dlg->GetPath);
         $dlg->Destroy;
     }
     
@@ -470,7 +476,7 @@ sub export_config {
     my $dlg = Wx::FileDialog->new($self, 'Save configuration as:', $dir, $filename, 
         &Slic3r::GUI::FILE_WILDCARDS->{ini}, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
     if ($dlg->ShowModal == wxID_OK) {
-        my $file = $dlg->GetPath;
+        my $file = Slic3r::decode_path($dlg->GetPath);
         $Slic3r::GUI::Settings->{recent}{config_directory} = dirname($file);
         wxTheApp->save_settings;
         $last_config = $file;
@@ -489,7 +495,7 @@ sub load_config_file {
         my $dlg = Wx::FileDialog->new($self, 'Select configuration to load:', $dir, "config.ini", 
                 &Slic3r::GUI::FILE_WILDCARDS->{ini}, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
         return unless $dlg->ShowModal == wxID_OK;
-        ($file) = $dlg->GetPaths;
+        $file = Slic3r::decode_path($dlg->GetPaths);
         $dlg->Destroy;
     }
     $Slic3r::GUI::Settings->{recent}{config_directory} = dirname($file);
@@ -514,7 +520,7 @@ sub export_configbundle {
     my $dlg = Wx::FileDialog->new($self, 'Save presets bundle as:', $dir, $filename, 
         &Slic3r::GUI::FILE_WILDCARDS->{ini}, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
     if ($dlg->ShowModal == wxID_OK) {
-        my $file = $dlg->GetPath;
+        my $file = Slic3r::decode_path($dlg->GetPath);
         $Slic3r::GUI::Settings->{recent}{config_directory} = dirname($file);
         wxTheApp->save_settings;
         
@@ -547,7 +553,7 @@ sub load_configbundle {
     my $dlg = Wx::FileDialog->new($self, 'Select configuration to load:', $dir, "config.ini", 
             &Slic3r::GUI::FILE_WILDCARDS->{ini}, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
     return unless $dlg->ShowModal == wxID_OK;
-    my ($file) = $dlg->GetPaths;
+    my $file = Slic3r::decode_path($dlg->GetPaths);
     $dlg->Destroy;
     
     $Slic3r::GUI::Settings->{recent}{config_directory} = dirname($file);
@@ -601,6 +607,9 @@ sub load_config {
     foreach my $tab (values %{$self->{options_tabs}}) {
         $tab->load_config($config);
     }
+    if ($self->{plater}) {
+        $self->{plater}->on_config_change($config);
+    }
 }
 
 sub config_wizard {
@@ -643,13 +652,19 @@ sub config {
     if (!$self->{plater} || $self->{plater}->filament_presets == 1 || $self->{mode} eq 'simple') {
         $filament_config = $self->{options_tabs}{filament}->config;
     } else {
-        # TODO: handle dirty presets.
-        # perhaps plater shouldn't expose dirty presets at all in multi-extruder environments.
         my $i = -1;
         foreach my $preset_idx ($self->{plater}->filament_presets) {
             $i++;
-            my $preset = $self->{options_tabs}{filament}->get_preset($preset_idx);
-            my $config = $self->{options_tabs}{filament}->get_preset_config($preset);
+            my $config;
+            if ($preset_idx == $self->{options_tabs}{filament}->current_preset) {
+                # the selected preset for this extruder is the one in the tab
+                # use the tab's config instead of the preset in case it is dirty
+                # perhaps plater shouldn't expose dirty presets at all in multi-extruder environments.
+                $config = $self->{options_tabs}{filament}->config;
+            } else {
+                my $preset = $self->{options_tabs}{filament}->get_preset($preset_idx);
+                $config = $self->{options_tabs}{filament}->get_preset_config($preset);
+            }
             if (!$filament_config) {
                 $filament_config = $config->clone;
                 next;
@@ -719,12 +734,23 @@ sub select_tab {
 }
 
 sub _append_menu_item {
-    my ($self, $menu, $string, $description, $cb, $id) = @_;
+    my ($self, $menu, $string, $description, $cb, $id, $icon) = @_;
     
     $id //= &Wx::NewId();
     my $item = $menu->Append($id, $string, $description);
+    $self->_set_menu_item_icon($item, $icon);
+    
     EVT_MENU($self, $id, $cb);
     return $item;
 }
 
+sub _set_menu_item_icon {
+    my ($self, $menuItem, $icon) = @_;
+    
+    # SetBitmap was not available on OS X before Wx 0.9927
+    if ($icon && $menuItem->can('SetBitmap')) {
+        $menuItem->SetBitmap(Wx::Bitmap->new("$Slic3r::var/$icon", wxBITMAP_TYPE_PNG));
+    }
+}
+
 1;

+ 5 - 0
lib/Slic3r/GUI/OptionsGroup.pm

@@ -178,6 +178,11 @@ sub _build_field {
             parent => $self->parent,
             option => $opt,
         );
+    } elsif ($type eq 'color') {
+        $field = Slic3r::GUI::OptionsGroup::Field::ColourPicker->new(
+            parent => $self->parent,
+            option => $opt,
+        );
     } elsif ($type =~ /^(f|s|s@|percent)$/) {
         $field = Slic3r::GUI::OptionsGroup::Field::TextCtrl->new(
             parent => $self->parent,

Some files were not shown because too many files changed in this diff