Merge branch 'master' into gui3-shortcuts

This commit is contained in:
Alessandro Ranellucci 2017-04-29 19:57:53 +02:00
commit 202a00c270
28 changed files with 504 additions and 214 deletions

2
.gitignore vendored
View File

@ -14,3 +14,5 @@ xs/assertlib*
local-lib
package/osx/Slic3r*.app
*.dmg
*.swp
*.swo

View File

@ -7,7 +7,6 @@ install:
- export SLIC3R_STATIC=1
- export CXX=g++-4.9
- export CC=g++-4.9
- export WXDIR=$HOME/wx302
- source $HOME/perl5/perlbrew/etc/bashrc
script:
- bash package/linux/travis-setup.sh
@ -32,6 +31,8 @@ addons:
packages:
- g++-4.9
- gcc-4.9
- libgtk2.0-0
- libgtk2.0-dev
ssh_known_hosts: dl.slic3r.org
notifications:
irc:

View File

@ -5,6 +5,7 @@ use utf8;
use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow
:filedialog :font);
use Wx::Event qw(EVT_MENU);
BEGIN {
# Wrap the Wx::_load_plugin() function which doesn't work with non-ASCII paths
@ -436,6 +437,30 @@ sub scan_serial_ports {
return grep !/Bluetooth|FireFly/, @ports;
}
sub append_menu_item {
my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_;
$id //= &Wx::NewId();
my $item = Wx::MenuItem->new($menu, $id, $string, $description // '', $kind // 0);
$self->set_menu_item_icon($item, $icon);
$menu->Append($item);
EVT_MENU($self, $id, $cb);
return $item;
}
sub append_submenu {
my ($self, $menu, $string, $description, $submenu, $id, $icon) = @_;
$id //= &Wx::NewId();
my $item = Wx::MenuItem->new($menu, $id, $string, $description // '');
$self->set_menu_item_icon($item, $icon);
$item->SetSubMenu($submenu);
$menu->Append($item);
return $item;
}
sub set_menu_item_icon {
my ($self, $menuItem, $icon) = @_;

View File

@ -10,7 +10,7 @@ use List::Util qw(min);
use Slic3r::Geometry qw(X Y Z);
use Wx qw(:frame :bitmap :id :misc :notebook :panel :sizer :menu :dialog :filedialog
:font :icon wxTheApp);
use Wx::Event qw(EVT_CLOSE EVT_MENU EVT_NOTEBOOK_PAGE_CHANGED);
use Wx::Event qw(EVT_CLOSE EVT_NOTEBOOK_PAGE_CHANGED);
use base 'Wx::Frame';
our $qs_last_input_file;
@ -109,60 +109,60 @@ sub _init_menubar {
# File menu
my $fileMenu = Wx::Menu->new;
{
$self->_append_menu_item($fileMenu, "Open STL/OBJ/AMF…\tCtrl+O", 'Open a model', sub {
wxTheApp->append_menu_item($fileMenu, "Open STL/OBJ/AMF…\tCtrl+O", 'Open a model', sub {
$self->{plater}->add if $self->{plater};
}, undef, 'brick_add.png');
$self->_append_menu_item($fileMenu, "Open 2.5D TIN mesh…", 'Import a 2.5D TIN mesh', sub {
wxTheApp->append_menu_item($fileMenu, "Open 2.5D TIN mesh…", 'Import a 2.5D TIN mesh', sub {
$self->{plater}->add_tin if $self->{plater};
}, undef, 'map_add.png');
$fileMenu->AppendSeparator();
$self->_append_menu_item($fileMenu, "&Load Config…\tCtrl+L", 'Load exported configuration file', sub {
wxTheApp->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 {
wxTheApp->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 {
wxTheApp->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 {
wxTheApp->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 {
wxTheApp->append_menu_item($fileMenu, "Q&uick Slice…\tCtrl+U", 'Slice file', sub {
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 {
wxTheApp->append_menu_item($fileMenu, "Quick Slice and Save &As…\tCtrl+Alt+U", 'Slice file and save as', sub {
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 {
$repeat = wxTheApp->append_menu_item($fileMenu, "&Repeat Last Quick Slice\tCtrl+Shift+U", 'Repeat last quick slice', sub {
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 {
wxTheApp->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 {
wxTheApp->append_menu_item($fileMenu, "Repair STL file…", 'Automatically repair an STL file', sub {
$self->repair_stl;
}, undef, 'wrench.png');
$fileMenu->AppendSeparator();
# Cmd+, is standard on OS X - what about other operating systems?
$self->_append_menu_item($fileMenu, "Preferences…\tCtrl+,", 'Application preferences', sub {
wxTheApp->append_menu_item($fileMenu, "Preferences…\tCtrl+,", 'Application preferences', sub {
Slic3r::GUI::Preferences->new($self)->ShowModal;
}, wxID_PREFERENCES);
$fileMenu->AppendSeparator();
$self->_append_menu_item($fileMenu, "&Quit", 'Quit Slic3r', sub {
wxTheApp->append_menu_item($fileMenu, "&Quit", 'Quit Slic3r', sub {
$self->Close(0);
}, wxID_EXIT);
}
@ -174,23 +174,22 @@ sub _init_menubar {
$self->{plater_menu} = Wx::Menu->new;
{
my $selectMenu = $self->{plater_select_menu} = Wx::Menu->new;
my $selectMenuItem = $self->{plater_menu}->AppendSubMenu($selectMenu, "Select", 'Select an object in the plater');
wxTheApp->set_menu_item_icon($selectMenuItem, 'brick.png');
wxTheApp->append_submenu($self->{plater_menu}, "Select", 'Select an object in the plater', $selectMenu, undef, 'brick.png');
}
$self->_append_menu_item($self->{plater_menu}, "Select Next Object\tCtrl+Right", 'Select Next Object in the plater', sub {
wxTheApp->append_menu_item($self->{plater_menu}, "Select Next Object\tCtrl+Right", 'Select Next Object in the plater', sub {
$plater->select_next;
}, undef, 'arrow_right.png');
$self->_append_menu_item($self->{plater_menu}, "Select Prev Object\tCtrl+Left", 'Select Previous Object in the plater', sub {
wxTheApp->append_menu_item($self->{plater_menu}, "Select Prev Object\tCtrl+Left", 'Select Previous Object in the plater', sub {
$plater->select_prev;
}, undef, 'arrow_left.png');
$self->{plater_menu}->AppendSeparator();
$self->_append_menu_item($self->{plater_menu}, "Export G-code...", 'Export current plate as G-code', sub {
wxTheApp->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 {
wxTheApp->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 with modifiers as AMF...", 'Export current plate as AMF, including all modifier meshes', sub {
wxTheApp->append_menu_item($self->{plater_menu}, "Export plate with modifiers as AMF...", 'Export current plate as AMF, including all modifier meshes', sub {
$plater->export_amf;
}, undef, 'brick_go.png');
@ -201,13 +200,13 @@ sub _init_menubar {
# Settings menu
my $settingsMenu = Wx::Menu->new;
{
$self->_append_menu_item($settingsMenu, "P&rint Settings…\tCtrl+1", 'Show the print settings editor', sub {
wxTheApp->append_menu_item($settingsMenu, "P&rint Settings…\tCtrl+1", 'Show the print settings editor', sub {
$self->{plater}->show_preset_editor('print');
}, undef, 'cog.png');
$self->_append_menu_item($settingsMenu, "&Filament Settings…\tCtrl+2", 'Show the filament settings editor', sub {
wxTheApp->append_menu_item($settingsMenu, "&Filament Settings…\tCtrl+2", 'Show the filament settings editor', sub {
$self->{plater}->show_preset_editor('filament');
}, undef, 'spool.png');
$self->_append_menu_item($settingsMenu, "Print&er Settings…\tCtrl+3", 'Show the printer settings editor', sub {
wxTheApp->append_menu_item($settingsMenu, "Print&er Settings…\tCtrl+3", 'Show the printer settings editor', sub {
$self->{plater}->show_preset_editor('printer');
}, undef, 'printer_empty.png');
}
@ -215,15 +214,15 @@ sub _init_menubar {
# View menu
{
$self->{viewMenu} = Wx::Menu->new;
$self->_append_menu_item($self->{viewMenu}, "Top\tCtrl+4" , 'Top View' , sub { $self->select_view('top' ); });
$self->_append_menu_item($self->{viewMenu}, "Bottom\tCtrl+5" , 'Bottom View' , sub { $self->select_view('bottom' ); });
$self->_append_menu_item($self->{viewMenu}, "Left\tCtrl+6" , 'Left View' , sub { $self->select_view('left' ); });
$self->_append_menu_item($self->{viewMenu}, "Right\tCtrl+7" , 'Right View' , sub { $self->select_view('right' ); });
$self->_append_menu_item($self->{viewMenu}, "Front\tCtrl+8" , 'Front View' , sub { $self->select_view('front' ); });
$self->_append_menu_item($self->{viewMenu}, "Back\tCtrl+9" , 'Back View' , sub { $self->select_view('back' ); });
$self->_append_menu_item($self->{viewMenu}, "Diagonal\tCtrl+0", 'Diagonal View', sub { $self->select_view('diagonal'); });
wxTheApp->append_menu_item($self->{viewMenu}, "Top\tCtrl+4" , 'Top View' , sub { $self->select_view('top' ); });
wxTheApp->append_menu_item($self->{viewMenu}, "Bottom\tCtrl+5" , 'Bottom View' , sub { $self->select_view('bottom' ); });
wxTheApp->append_menu_item($self->{viewMenu}, "Left\tCtrl+6" , 'Left View' , sub { $self->select_view('left' ); });
wxTheApp->append_menu_item($self->{viewMenu}, "Right\tCtrl+7" , 'Right View' , sub { $self->select_view('right' ); });
wxTheApp->append_menu_item($self->{viewMenu}, "Front\tCtrl+8" , 'Front View' , sub { $self->select_view('front' ); });
wxTheApp->append_menu_item($self->{viewMenu}, "Back\tCtrl+9" , 'Back View' , sub { $self->select_view('back' ); });
wxTheApp->append_menu_item($self->{viewMenu}, "Diagonal\tCtrl+0", 'Diagonal View', sub { $self->select_view('diagonal'); });
$self->{viewMenu}->AppendSeparator();
$self->{color_toolpaths_by_role} = $self->_append_menu_item($self->{viewMenu},
$self->{color_toolpaths_by_role} = wxTheApp->append_menu_item($self->{viewMenu},
"Color Toolpaths by Role",
'Color toolpaths according to perimeter/infill/support material',
sub {
@ -233,7 +232,7 @@ sub _init_menubar {
},
undef, undef, wxITEM_RADIO
);
$self->{color_toolpaths_by_extruder} = $self->_append_menu_item($self->{viewMenu},
$self->{color_toolpaths_by_extruder} = wxTheApp->append_menu_item($self->{viewMenu},
"Color Toolpaths by Filament",
'Color toolpaths using the configured extruder/filament color',
sub {
@ -253,13 +252,13 @@ sub _init_menubar {
# Window menu
my $windowMenu = Wx::Menu->new;
{
$self->_append_menu_item($windowMenu, "&Plater\tCtrl+T", 'Show the plater', sub {
wxTheApp->append_menu_item($windowMenu, "&Plater\tCtrl+T", 'Show the plater', sub {
$self->select_tab(0);
}, undef, 'application_view_tile.png');
$self->_append_menu_item($windowMenu, "&Controller\tCtrl+Y", 'Show the printer controller', sub {
wxTheApp->append_menu_item($windowMenu, "&Controller\tCtrl+Y", 'Show the printer controller', sub {
$self->select_tab(1);
}, undef, 'printer_empty.png') unless ($Slic3r::GUI::Settings->{_}{no_controller});
$self->_append_menu_item($windowMenu, "DLP Projector…\tCtrl+P", 'Open projector window for DLP printing', sub {
wxTheApp->append_menu_item($windowMenu, "DLP Projector…\tCtrl+P", 'Open projector window for DLP printing', sub {
$self->{plater}->pause_background_process;
Slic3r::GUI::SLAPrintOptions->new($self)->ShowModal;
$self->{plater}->resume_background_process;
@ -269,22 +268,22 @@ sub _init_menubar {
# Help menu
my $helpMenu = Wx::Menu->new;
{
$self->_append_menu_item($helpMenu, "&Configuration $Slic3r::GUI::ConfigWizard::wizard…", "Run Configuration $Slic3r::GUI::ConfigWizard::wizard", sub {
wxTheApp->append_menu_item($helpMenu, "&Configuration $Slic3r::GUI::ConfigWizard::wizard…", "Run Configuration $Slic3r::GUI::ConfigWizard::wizard", sub {
$self->config_wizard;
});
$helpMenu->AppendSeparator();
$self->_append_menu_item($helpMenu, "Slic3r &Website", 'Open the Slic3r website in your browser', sub {
wxTheApp->append_menu_item($helpMenu, "Slic3r &Website", 'Open the Slic3r website in your browser', sub {
Wx::LaunchDefaultBrowser('http://slic3r.org/');
});
my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", 'Check for new Slic3r versions', sub {
my $versioncheck = wxTheApp->append_menu_item($helpMenu, "Check for &Updates...", 'Check for new Slic3r versions', sub {
wxTheApp->check_version(1);
});
$versioncheck->Enable(wxTheApp->have_version_check);
$self->_append_menu_item($helpMenu, "Slic3r &Manual", 'Open the Slic3r manual in your browser', sub {
wxTheApp->append_menu_item($helpMenu, "Slic3r &Manual", 'Open the Slic3r manual in your browser', sub {
Wx::LaunchDefaultBrowser('http://manual.slic3r.org/');
});
$helpMenu->AppendSeparator();
$self->_append_menu_item($helpMenu, "&About Slic3r", 'Show about dialog', sub {
wxTheApp->append_menu_item($helpMenu, "&About Slic3r", 'Show about dialog', sub {
wxTheApp->about;
});
}
@ -631,15 +630,4 @@ sub select_view {
$self->{plater}->select_view($direction);
}
sub _append_menu_item {
my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_;
$id //= &Wx::NewId();
my $item = $menu->Append($id, $string, $description, $kind);
wxTheApp->set_menu_item_icon($item, $icon);
EVT_MENU($self, $id, $cb);
return $item;
}
1;

View File

@ -323,7 +323,6 @@ sub new {
if ($self->{preview3D}) {
$self->{preview3D}->set_bed_shape($self->{config}->bed_shape);
}
$self->on_model_change;
{
my $presets = $self->{presets_sizer} = Wx::FlexGridSizer->new(3, 3, 1, 2);
@ -894,6 +893,11 @@ sub load_file {
sub load_model_objects {
my ($self, @model_objects) = @_;
# Always restart background process when adding new objects.
# This prevents lack of processing in some circumstances when background process is
# running but adding a new object does not invalidate anything.
$self->stop_background_process;
my $bed_centerf = $self->bed_centerf;
my $bed_shape = Slic3r::Polygon->new_scale(@{$self->{config}->bed_shape});
my $bed_size = $bed_shape->bounding_box->size;
@ -1969,7 +1973,7 @@ sub on_model_change {
if ($count > 1) {
$name .= " (${count}x)";
}
my $item = $self->GetFrame->_append_menu_item($menu, $name, 'Select object', sub {
my $item = wxTheApp->append_menu_item($menu, $name, 'Select object', sub {
$self->select_object($i);
$self->refresh_canvases;
}, undef, undef, wxITEM_CHECK);
@ -2320,105 +2324,109 @@ sub object_menu {
my $frame = $self->GetFrame;
my $menu = Wx::Menu->new;
$frame->_append_menu_item($menu, "Delete\tCtrl+Del", 'Remove the selected object', sub {
wxTheApp->append_menu_item($menu, "Delete\tCtrl+Del", 'Remove the selected object', sub {
$self->remove;
}, undef, 'brick_delete.png');
$frame->_append_menu_item($menu, "Increase copies\tCtrl++", 'Place one more copy of the selected object', sub {
wxTheApp->append_menu_item($menu, "Increase copies\tCtrl++", 'Place one more copy of the selected object', sub {
$self->increase;
}, undef, 'add.png');
$frame->_append_menu_item($menu, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object', sub {
wxTheApp->append_menu_item($menu, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object', sub {
$self->decrease;
}, undef, 'delete.png');
$frame->_append_menu_item($menu, "Set number of copies…", 'Change the number of copies of the selected object', sub {
wxTheApp->append_menu_item($menu, "Set number of copies…", 'Change the number of copies of the selected object', sub {
$self->set_number_of_copies;
}, undef, 'textfield.png');
$menu->AppendSeparator();
$frame->_append_menu_item($menu, "Move to bed center", 'Center object around bed center', sub {
wxTheApp->append_menu_item($menu, "Move to bed center", 'Center object around bed center', sub {
$self->center_selected_object_on_bed;
}, undef, 'arrow_in.png');
$frame->_append_menu_item($menu, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise', sub {
wxTheApp->append_menu_item($menu, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise', sub {
$self->rotate(-45);
}, undef, 'arrow_rotate_clockwise.png');
$frame->_append_menu_item($menu, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise', sub {
wxTheApp->append_menu_item($menu, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise', sub {
$self->rotate(+45);
}, undef, 'arrow_rotate_anticlockwise.png');
my $rotateMenu = Wx::Menu->new;
my $rotateMenuItem = $menu->AppendSubMenu($rotateMenu, "Rotate", 'Rotate the selected object by an arbitrary angle');
wxTheApp->set_menu_item_icon($rotateMenuItem, 'textfield.png');
$frame->_append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub {
$self->rotate(undef, X);
}, undef, 'bullet_red.png');
$frame->_append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub {
$self->rotate(undef, Y);
}, undef, 'bullet_green.png');
$frame->_append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub {
$self->rotate(undef, Z);
}, undef, 'bullet_blue.png');
{
my $rotateMenu = Wx::Menu->new;
wxTheApp->append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis', sub {
$self->rotate(undef, X);
}, undef, 'bullet_red.png');
wxTheApp->append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis', sub {
$self->rotate(undef, Y);
}, undef, 'bullet_green.png');
wxTheApp->append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis', sub {
$self->rotate(undef, Z);
}, undef, 'bullet_blue.png');
wxTheApp->append_submenu($menu, "Rotate", 'Rotate the selected object by an arbitrary angle', $rotateMenu, undef, 'textfield.png');
}
my $mirrorMenu = Wx::Menu->new;
my $mirrorMenuItem = $menu->AppendSubMenu($mirrorMenu, "Mirror", 'Mirror the selected object');
wxTheApp->set_menu_item_icon($mirrorMenuItem, 'shape_flip_horizontal.png');
$frame->_append_menu_item($mirrorMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub {
$self->mirror(X);
}, undef, 'bullet_red.png');
$frame->_append_menu_item($mirrorMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub {
$self->mirror(Y);
}, undef, 'bullet_green.png');
$frame->_append_menu_item($mirrorMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub {
$self->mirror(Z);
}, undef, 'bullet_blue.png');
{
my $mirrorMenu = Wx::Menu->new;
wxTheApp->append_menu_item($mirrorMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub {
$self->mirror(X);
}, undef, 'bullet_red.png');
wxTheApp->append_menu_item($mirrorMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub {
$self->mirror(Y);
}, undef, 'bullet_green.png');
wxTheApp->append_menu_item($mirrorMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub {
$self->mirror(Z);
}, undef, 'bullet_blue.png');
wxTheApp->append_submenu($menu, "Mirror", 'Mirror the selected object', $mirrorMenu, undef, 'shape_flip_horizontal.png');
}
my $scaleMenu = Wx::Menu->new;
my $scaleMenuItem = $menu->AppendSubMenu($scaleMenu, "Scale", 'Scale the selected object along a single axis');
wxTheApp->set_menu_item_icon($scaleMenuItem, 'arrow_out.png');
$frame->_append_menu_item($scaleMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub {
$self->changescale(undef);
});
$frame->_append_menu_item($scaleMenu, "Along X axis…", 'Scale the selected object along the X axis', sub {
$self->changescale(X);
}, undef, 'bullet_red.png');
$frame->_append_menu_item($scaleMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub {
$self->changescale(Y);
}, undef, 'bullet_green.png');
$frame->_append_menu_item($scaleMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub {
$self->changescale(Z);
}, undef, 'bullet_blue.png');
{
my $scaleMenu = Wx::Menu->new;
wxTheApp->append_menu_item($scaleMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub {
$self->changescale(undef);
});
wxTheApp->append_menu_item($scaleMenu, "Along X axis…", 'Scale the selected object along the X axis', sub {
$self->changescale(X);
}, undef, 'bullet_red.png');
wxTheApp->append_menu_item($scaleMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub {
$self->changescale(Y);
}, undef, 'bullet_green.png');
wxTheApp->append_menu_item($scaleMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub {
$self->changescale(Z);
}, undef, 'bullet_blue.png');
wxTheApp->append_submenu($menu, "Scale", 'Scale the selected object by a given factor', $scaleMenu, undef, 'arrow_out.png');
}
my $scaleToSizeMenu = Wx::Menu->new;
my $scaleToSizeMenuItem = $menu->AppendSubMenu($scaleToSizeMenu, "Scale to size", 'Scale the selected object along a single axis');
wxTheApp->set_menu_item_icon($scaleToSizeMenuItem, 'arrow_out.png');
$frame->_append_menu_item($scaleToSizeMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub {
$self->changescale(undef, 1);
});
$frame->_append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis', sub {
$self->changescale(X, 1);
}, undef, 'bullet_red.png');
$frame->_append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub {
$self->changescale(Y, 1);
}, undef, 'bullet_green.png');
$frame->_append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub {
$self->changescale(Z, 1);
}, undef, 'bullet_blue.png');
{
my $scaleToSizeMenu = Wx::Menu->new;
wxTheApp->append_menu_item($scaleToSizeMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub {
$self->changescale(undef, 1);
});
wxTheApp->append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis', sub {
$self->changescale(X, 1);
}, undef, 'bullet_red.png');
wxTheApp->append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis', sub {
$self->changescale(Y, 1);
}, undef, 'bullet_green.png');
wxTheApp->append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis', sub {
$self->changescale(Z, 1);
}, undef, 'bullet_blue.png');
wxTheApp->append_submenu($menu, "Scale to size", 'Scale the selected object to match a given size', $scaleToSizeMenu, undef, 'arrow_out.png');
}
$frame->_append_menu_item($menu, "Split", 'Split the selected object into individual parts', sub {
wxTheApp->append_menu_item($menu, "Split", 'Split the selected object into individual parts', sub {
$self->split_object;
}, undef, 'shape_ungroup.png');
$frame->_append_menu_item($menu, "Cut…", 'Open the 3D cutting tool', sub {
wxTheApp->append_menu_item($menu, "Cut…", 'Open the 3D cutting tool', sub {
$self->object_cut_dialog;
}, undef, 'package.png');
$menu->AppendSeparator();
$frame->_append_menu_item($menu, "Settings…", 'Open the object editor dialog', sub {
wxTheApp->append_menu_item($menu, "Settings…", 'Open the object editor dialog', sub {
$self->object_settings_dialog;
}, undef, 'cog.png');
$menu->AppendSeparator();
$frame->_append_menu_item($menu, "Reload from Disk", 'Reload the selected file from Disk', sub {
wxTheApp->append_menu_item($menu, "Reload from Disk", 'Reload the selected file from Disk', sub {
$self->reload_from_disk;
}, undef, 'arrow_refresh.png');
$frame->_append_menu_item($menu, "Export object as STL…", 'Export this single object as STL file', sub {
wxTheApp->append_menu_item($menu, "Export object as STL…", 'Export this single object as STL file', sub {
$self->export_object_stl;
}, undef, 'brick_go.png');
$frame->_append_menu_item($menu, "Export object and modifiers as AMF…", 'Export this single object and all associated modifiers as AMF file', sub {
wxTheApp->append_menu_item($menu, "Export object and modifiers as AMF…", 'Export this single object and all associated modifiers as AMF file', sub {
$self->export_object_amf;
}, undef, 'brick_go.png');

View File

@ -9,7 +9,9 @@ use utf8;
use File::Basename qw(basename);
use Wx qw(:misc :sizer :treectrl :button wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL
wxTheApp);
use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED);
use List::Util qw(max);
use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED EVT_TREE_ITEM_RIGHT_CLICK);
use Slic3r::Geometry qw(X Y Z MIN MAX scale unscale deg2rad rad2deg);
use base 'Wx::Panel';
use constant ICON_OBJECT => 0;
@ -156,6 +158,51 @@ sub new {
return if $self->{disable_tree_sel_changed_event};
$self->selection_changed;
});
EVT_TREE_ITEM_RIGHT_CLICK($self, $tree, sub {
my ($self, $event) = @_;
my $item = $event->GetItem;
my $frame = $self->GetFrame;
my $menu = Wx::Menu->new;
{
my $scaleMenu = Wx::Menu->new;
wxTheApp->append_menu_item($scaleMenu, "Uniformly… ", 'Scale the selected object along the XYZ axes',
sub { $self->changescale(undef, 0) });
wxTheApp->append_menu_item($scaleMenu, "Along X axis…", 'Scale the selected object along the X axis',
sub { $self->changescale(X, 0) }, undef, 'bullet_red.png');
wxTheApp->append_menu_item($scaleMenu, "Along Y axis…", 'Scale the selected object along the Y axis',
sub { $self->changescale(Y, 0) }, undef, 'bullet_green.png');
wxTheApp->append_menu_item($scaleMenu, "Along Z axis…", 'Scale the selected object along the Z axis',
sub { $self->changescale(Z, 0) }, undef, 'bullet_blue.png');
wxTheApp->append_submenu($menu, "Scale", 'Scale the selected object by a given factor',
$scaleMenu, undef, 'arrow_out.png');
}
{
my $scaleToSizeMenu = Wx::Menu->new;
wxTheApp->append_menu_item($scaleToSizeMenu, "Uniformly… ", 'Scale the selected object along the XYZ axes',
sub { $self->changescale(undef, 1) });
wxTheApp->append_menu_item($scaleToSizeMenu, "Along X axis…", 'Scale the selected object along the X axis',
sub { $self->changescale(X, 1) }, undef, 'bullet_red.png');
wxTheApp->append_menu_item($scaleToSizeMenu, "Along Y axis…", 'Scale the selected object along the Y axis',
sub { $self->changescale(Y, 1) }, undef, 'bullet_green.png');
wxTheApp->append_menu_item($scaleToSizeMenu, "Along Z axis…", 'Scale the selected object along the Z axis',
sub { $self->changescale(Z, 1) }, undef, 'bullet_blue.png');
wxTheApp->append_submenu($menu, "Scale to size", 'Scale the selected object to match a given size',
$scaleToSizeMenu, undef, 'arrow_out.png');
}
{
my $rotateMenu = Wx::Menu->new;
wxTheApp->append_menu_item($rotateMenu, "Around X axis…", 'Rotate the selected object by an arbitrary angle around X axis',
sub { $self->rotate(undef, X) }, undef, 'bullet_red.png');
wxTheApp->append_menu_item($rotateMenu, "Around Y axis…", 'Rotate the selected object by an arbitrary angle around Y axis',
sub { $self->rotate(undef, Y) }, undef, 'bullet_green.png');
wxTheApp->append_menu_item($rotateMenu, "Around Z axis…", 'Rotate the selected object by an arbitrary angle around Z axis',
sub { $self->rotate(undef, Z) }, undef, 'bullet_blue.png');
wxTheApp->append_submenu($menu, "Rotate", 'Rotate the selected object by an arbitrary angle',
$rotateMenu, undef, 'arrow_rotate_anticlockwise.png');
}
$frame->PopupMenu($menu, $event->GetPoint);
});
EVT_BUTTON($self, $self->{btn_load_part}, sub { $self->on_btn_load(0) });
EVT_BUTTON($self, $self->{btn_load_modifier}, sub { $self->on_btn_load(1) });
EVT_BUTTON($self, $self->{btn_load_lambda_modifier}, sub { $self->on_btn_lambda(1) });
@ -371,7 +418,6 @@ sub on_btn_lambda {
# set a default extruder value, since user can't add it manually
$new_volume->config->set_ifndef('extruder', 0);
$self->{parts_changed} = 1;
$self->_parts_changed($self->{model_object}->volumes_count-1);
}
@ -398,6 +444,7 @@ sub on_btn_delete {
sub _parts_changed {
my ($self, $selected_volume_idx) = @_;
$self->{parts_changed} = 1;
$self->reload_tree($selected_volume_idx);
if ($self->{canvas}) {
$self->{canvas}->reset_objects;
@ -450,4 +497,82 @@ sub _update {
$self->{canvas}->Render;
}
sub changescale {
my ($self, $axis, $tosize) = @_;
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
my $object_size = $volume->bounding_box->size;
if (defined $axis) {
my $axis_name = $axis == X ? 'X' : $axis == Y ? 'Y' : 'Z';
my $scale;
if (defined $tosize) {
my $cursize = $object_size->[$axis];
# Wx::GetNumberFromUser() does not support decimal numbers
my $newsize = Wx::GetTextFromUser(
sprintf("Enter the new size for the selected mesh:"),
"Scale along $axis_name",
$cursize, $self);
return if !$newsize || $newsize !~ /^\d*(?:\.\d*)?$/ || $newsize < 0;
$scale = $newsize / $cursize * 100;
} else {
# Wx::GetNumberFromUser() does not support decimal numbers
$scale = Wx::GetTextFromUser("Enter the scale % for the selected object:",
"Scale along $axis_name", 100, $self);
$scale =~ s/%$//;
return if !$scale || $scale !~ /^\d*(?:\.\d*)?$/ || $scale < 0;
}
my $versor = [1,1,1];
$versor->[$axis] = $scale/100;
$volume->mesh->scale_xyz(Slic3r::Pointf3->new(@$versor));
} else {
my $scale;
if ($tosize) {
my $cursize = max(@$object_size);
# Wx::GetNumberFromUser() does not support decimal numbers
my $newsize = Wx::GetTextFromUser("Enter the new max size for the selected object:",
"Scale", $cursize, $self);
return if !$newsize || $newsize !~ /^\d*(?:\.\d*)?$/ || $newsize < 0;
$scale = $newsize / $cursize;
} else {
# max scale factor should be above 2540 to allow importing files exported in inches
# Wx::GetNumberFromUser() does not support decimal numbers
$scale = Wx::GetTextFromUser("Enter the scale % for the selected object:", 'Scale',
100, $self);
return if !$scale || $scale !~ /^\d*(?:\.\d*)?$/ || $scale < 0;
}
return if !$scale || $scale < 0;
$volume->mesh->scale($scale);
}
$self->_parts_changed;
}
}
sub rotate {
my $self = shift;
my ($angle, $axis) = @_;
# angle is in degrees
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
if (!defined $angle) {
my $axis_name = $axis == X ? 'X' : $axis == Y ? 'Y' : 'Z';
my $default = $axis == Z ? 0 : 0;
# Wx::GetNumberFromUser() does not support decimal numbers
$angle = Wx::GetTextFromUser("Enter the rotation angle:", "Rotate around $axis_name axis",
$default, $self);
return if !$angle || $angle !~ /^-?\d*(?:\.\d*)?$/ || $angle == -1;
}
if ($axis == X) { $volume->mesh->rotate_x(deg2rad($angle)); }
if ($axis == Y) { $volume->mesh->rotate_y(deg2rad($angle)); }
if ($axis == Z) { $volume->mesh->rotate_z(deg2rad($angle)); }
$self->_parts_changed;
}
}
sub GetFrame {
my ($self) = @_;
return &Wx::GetTopLevelParent($self);
}
1;

View File

@ -7,8 +7,8 @@ use strict;
use warnings;
use utf8;
use Wx qw(:dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_BUTTON);
use Wx qw(:dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL wxTheApp);
use Wx::Event qw(EVT_BUTTON EVT_MENU);
use base 'Wx::Dialog';
sub new {
@ -54,6 +54,7 @@ sub PartSettingsChanged {
return $self->{parts}->PartSettingsChanged || $self->{layers}->LayersChanged;
}
package Slic3r::GUI::Plater::ObjectDialog::BaseTab;
use base 'Wx::Panel';

View File

@ -53,8 +53,6 @@ sub new {
my $menu = Wx::Menu->new;
my $last_cat = '';
foreach my $opt_key (@{$self->{options}}) {
my $id = &Wx::NewId();
# add icon, if we have one for this category
my $icon;
if (my $cat = $Slic3r::Config::Options->{$opt_key}{category}) {
@ -65,14 +63,14 @@ sub new {
$icon = $icons{$cat};
}
my $menuItem = $menu->Append($id, $self->{option_labels}{$opt_key});
wxTheApp->set_menu_item_icon($menuItem, $icon) if $icon;
EVT_MENU($menu, $id, sub {
my $cb = sub {
$self->{config}->set($opt_key, $self->{default_config}->get($opt_key));
$self->update_optgroup;
$self->{on_change}->($opt_key) if $self->{on_change};
});
};
wxTheApp->append_menu_item($menu, $self->{option_labels}{$opt_key},
$Slic3r::Config::Options->{$opt_key}{tooltip}, $cb, undef, $icon);
}
$self->PopupMenu($menu, $btn->GetPosition);
$menu->Destroy;

View File

@ -9,7 +9,7 @@ use Wx::Event qw(EVT_BUTTON EVT_CLOSE EVT_TEXT_ENTER EVT_SPINCTRL EVT_SLIDER);
use base qw(Wx::Dialog Class::Accessor);
use utf8;
__PACKAGE__->mk_accessors(qw(config config2 screen controller _optgroups));
__PACKAGE__->mk_accessors(qw(config config2 manual_control_config screen controller _optgroups));
sub new {
my ($class, $parent) = @_;
@ -27,6 +27,12 @@ sub new {
z_lift_speed => 8,
offset => [0,0],
});
$self->manual_control_config({
xy_travel_speed => 130,
z_travel_speed => 10,
temperature => '',
bed_temperature => '',
});
my $ini = eval { Slic3r::Config->read_ini("$Slic3r::GUI::datadir/DLP.ini") };
if ($ini) {
@ -286,7 +292,7 @@ sub new {
return;
}
my $dlg = Slic3r::GUI::Controller::ManualControlDialog->new
($self, $self->config, $sender);
($self, $self->config, $sender, $self->manual_control_config);
$dlg->ShowModal;
$sender->disconnect;
});

View File

@ -12,6 +12,10 @@ sub new {
$self->config(Slic3r::Config::SLAPrint->new);
$self->config->apply_dynamic(wxTheApp->{mainframe}->{plater}->config);
# Set some defaults
$self->config->set('infill_extrusion_width', 0.5) if $self->config->infill_extrusion_width == 0;
$self->config->set('perimeter_extrusion_width', 1) if $self->config->perimeter_extrusion_width == 0;
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
my $new_optgroup = sub {
my ($title) = @_;

View File

@ -213,7 +213,11 @@ sub generate_support_material {
$self->clear_support_layers;
if ((!$self->config->support_material && $self->config->raft_layers == 0) || scalar(@{$self->layers}) < 2) {
if ((!$self->config->support_material
&& $self->config->raft_layers == 0
&& $self->config->support_material_enforce_layers == 0)
|| scalar(@{$self->layers}) < 2
) {
$self->set_step_done(STEP_SUPPORTMATERIAL);
return;
}

View File

@ -93,18 +93,21 @@ sub generate {
sub contact_area {
# $object is Slic3r::Print::Object
my ($self, $object) = @_;
my $conf = $self->object_config;
# if user specified a custom angle threshold, convert it to radians
my $threshold_rad;
if (!($self->object_config->support_material_threshold =~ /%$/)) {
$threshold_rad = deg2rad($self->object_config->support_material_threshold + 1); # +1 makes the threshold inclusive
if (!($conf->support_material_threshold =~ /%$/)) {
$threshold_rad = deg2rad($conf->support_material_threshold + 1); # +1 makes the threshold inclusive
Slic3r::debugf "Threshold angle = %d°\n", rad2deg($threshold_rad);
}
# Build support on a build plate only? If so, then collect top surfaces into $buildplate_only_top_surfaces
# and subtract $buildplate_only_top_surfaces from the contact surfaces, so
# there is no contact surface supported by a top surface.
my $buildplate_only = $self->object_config->support_material && $self->object_config->support_material_buildplate_only;
my $buildplate_only =
( $conf->support_material || $conf->support_material_enforce_layers)
&& $conf->support_material_buildplate_only;
my $buildplate_only_top_surfaces = [];
# determine contact areas
@ -115,12 +118,19 @@ sub contact_area {
# so $layer_id == 0 means first object layer
# and $layer->id == 0 means first print layer (including raft)
if ($self->object_config->raft_layers == 0) {
next if $layer_id == 0;
} elsif (!$self->object_config->support_material) {
# if no raft, and we're at layer 0, skip to layer 1
if ( $conf->raft_layers == 0 && $layer_id == 0 ) {
next;
}
# with or without raft, if we're above layer 1, we need to quit
# support generation if supports are disabled, or if we're at a high
# enough layer that enforce-supports no longer applies
if ( $layer_id > 0
&& !$conf->support_material
&& ($layer_id >= $conf->support_material_enforce_layers) ) {
# if we are only going to generate raft just check
# the 'overhangs' of the first object layer
last if $layer_id > 0;
last;
}
my $layer = $object->get_layer($layer_id);
@ -154,12 +164,19 @@ sub contact_area {
my $diff;
# If a threshold angle was specified, use a different logic for detecting overhangs.
if (defined $threshold_rad
|| $layer_id < $self->object_config->support_material_enforce_layers
|| ($self->object_config->raft_layers > 0 && $layer_id == 0)) {
my $d = defined $threshold_rad
? scale $lower_layer->height * ((cos $threshold_rad) / (sin $threshold_rad))
: 0;
if (($conf->support_material && defined $threshold_rad)
|| $layer_id <= $conf->support_material_enforce_layers
|| ($conf->raft_layers > 0 && $layer_id == 0)) {
my $d = 0;
my $layer_threshold_rad = $threshold_rad;
if ($layer_id <= $conf->support_material_enforce_layers) {
# Use ~45 deg number for enforced supports if we are in auto
$layer_threshold_rad = deg2rad(89);
}
if (defined $layer_threshold_rad) {
$d = scale $lower_layer->height
* ((cos $layer_threshold_rad) / (sin $layer_threshold_rad));
}
$diff = diff(
offset([ map $_->p, @{$layerm->slices} ], -$d),
@ -177,7 +194,7 @@ sub contact_area {
} else {
$diff = diff(
[ map $_->p, @{$layerm->slices} ],
offset([ map @$_, @{$lower_layer->slices} ], +$self->object_config->get_abs_value_over('support_material_threshold', $fw)),
offset([ map @$_, @{$lower_layer->slices} ], +$conf->get_abs_value_over('support_material_threshold', $fw)),
);
# collapse very tiny spots
@ -189,7 +206,7 @@ sub contact_area {
# outside the lower slice boundary, thus no overhang
}
if ($self->object_config->dont_support_bridges) {
if ($conf->dont_support_bridges) {
# compute the area of bridging perimeters
# Note: this is duplicate code from GCode.pm, we need to refactor
@ -264,7 +281,7 @@ sub contact_area {
1,
);
}
} # if ($self->object_config->dont_support_bridges)
} # if ($conf->dont_support_bridges)
if ($buildplate_only) {
# Don't support overhangs above the top surfaces.
@ -309,7 +326,7 @@ sub contact_area {
my $contact_z = $layer->print_z - $self->contact_distance($layer->height, $nozzle_diameter);
# ignore this contact area if it's too low
next if $contact_z < $self->object_config->get_value('first_layer_height') - epsilon;
next if $contact_z < $conf->get_value('first_layer_height') - epsilon;
$contact{$contact_z} = [ @contact ];
$overhang{$contact_z} = [ @overhang ];

View File

@ -1,7 +1,6 @@
#include <EXTERN.h> // from the Perl distribution
#include <perl.h> // from the Perl distribution
#ifdef WIN32
// Perl win32 specific includes, found in perl\\lib\\CORE\\win32.h
// Defines the windows specific convenience RunPerl() function,
@ -17,13 +16,8 @@
int main(int argc, char **argv, char **env)
{
// replaces following Windows batch file: @"%~dp0\perl5.24.0.exe"
// "%~dp0\slic3r.pl" --DataDir "C:\Users\Public\Documents\Prusa3D\Slic3r
// settings MK2"%*
// If the Slic3r is installed in a localized directory (containing non-iso
// characters), spaces or semicolons, use short file names.
char exe_path[MAX_PATH] = {0};
char script_path[MAX_PATH];
char gui_flag[6] = {"--gui"};

View File

@ -0,0 +1,28 @@
/home/travis/builds/alexrj/Slic3r/local-lib/lib/perl5/x86_64-linux-thread-multi/Alien/wxWidgets/gtk_3_0_2_uni/lib/libwx_baseu-3.0.so.0
/home/travis/builds/alexrj/Slic3r/local-lib/lib/perl5/x86_64-linux-thread-multi/Alien/wxWidgets/gtk_3_0_2_uni/lib/libwx_gtk2u_adv-3.0.so.0
/home/travis/builds/alexrj/Slic3r/local-lib/lib/perl5/x86_64-linux-thread-multi/Alien/wxWidgets/gtk_3_0_2_uni/lib/libwx_gtk2u_core-3.0.so.0
/lib/x86_64-linux-gnu/liblzma.so.5
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libpcre.so.3
/lib/x86_64-linux-gnu/libpng12.so.0
/lib/x86_64-linux-gnu/libresolv.so.2
/lib/x86_64-linux-gnu/libuuid.so.1
/usr/lib/x86_64-linux-gnu/libSM.so.6
/usr/lib/x86_64-linux-gnu/libatk-1.0.so.0
/usr/lib/x86_64-linux-gnu/libdatrie.so.1
/usr/lib/x86_64-linux-gnu/libfreetype.so.6
/usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
/usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0
/usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
/usr/lib/x86_64-linux-gnu/libgraphite2.so.3
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0
/usr/lib/x86_64-linux-gnu/libjbig.so.0
/usr/lib/x86_64-linux-gnu/libjpeg.so.8
/usr/lib/x86_64-linux-gnu/libpango-1.0.so.0
/usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0
/usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0
/usr/lib/x86_64-linux-gnu/libpixman-1.so.0
/usr/lib/x86_64-linux-gnu/libtiff.so.5

View File

@ -47,7 +47,7 @@ echo "Appfolder: $appfolder, archivefolder: $archivefolder"
# Our slic3r dir and location of perl
PERL_BIN=$(which perl)
PP_BIN=$(which wxpar)
PP_BIN=$(which pp)
SLIC3R_DIR="./"
if [[ -d "${appfolder}" ]]; then
@ -96,7 +96,7 @@ cp -f $PERL_BIN $archivefolder/perl-local
${PP_BIN} wxextension .0 \
-M attributes -M base -M bytes -M B -M POSIX \
-M FindBin -M Unicode::Normalize -M Tie::Handle \
-M Time::Local -M Math::Trig \
-M Time::Local -M Math::Trig -M IO::Socket -M Errno \
-M lib -M overload \
-M warnings -M local::lib \
-M strict -M utf8 -M parent \
@ -104,8 +104,10 @@ ${PP_BIN} wxextension .0 \
unzip -qq -o $WD/_tmp/test.par -d $WD/_tmp/
cp -rf $WD/_tmp/lib/* $archivefolder/local-lib/lib/perl5/
cp -rf $WD/_tmp/shlib $archivefolder/
rm -rf $WD/_tmp
for i in $(cat $WD/libpaths.txt); do
install -v $i $archivefolder/bin
done
echo "Cleaning local-lib"
rm -rf $archivefolder/local-lib/bin

View File

@ -101,7 +101,7 @@ echo "Copying perl from $PERL_BIN"
cp -f $PERL_BIN $macosfolder/perl-local
${PP_BIN} -M attributes -M base -M bytes -M B -M POSIX \
-M FindBin -M Unicode::Normalize -M Tie::Handle \
-M Time::Local -M Math::Trig \
-M Time::Local -M Math::Trig -M IO::Socket -M Errno \
-M lib -M overload \
-M warnings -M local::lib \
-M strict -M utf8 -M parent \

View File

@ -3,10 +3,6 @@ cd package/win
./compile_wrapper.ps1 524 | Write-Output
./package_win32.ps1 524| Write-Output
cd ../../
Add-AppveyorCompilationMessage -Message "Uploading to server."
& ./package/deploy/winscp.ps1 -DIR win -KEY $env:APPVEYOR_BUILD_FOLDER/package/deploy/slic3r-upload.ppk -FILE *.zip *>> ./sftplog.txt
if (!(Test-Path C:\project\slic3r\slic3r.par)) {
Add-AppveyorCompilationMessage -Message "Failed to package!" -Category Error
return 1
}

View File

@ -1 +0,0 @@
@perl5.24.0.exe slic3r.pl %*

View File

@ -4,16 +4,27 @@ if ($args[0])
$perlver = $args[0]
} else
{
$perlver = 518
$perlver = 524
}
$perllib = "-lperl$perlver"
$shell_loc = "..\common\shell.cpp"
# Build the resource file (used to load icon, etc)
windres slic3r.rc -O coff -o slic3r.res
# Compile an object file that does not have gui forced.
g++ -c -I'C:\strawberry\perl\lib\CORE\' $shell_loc -o slic3r.o
# Compile an object file with --gui automatically passed as an argument
g++ -c -I'C:\strawberry\perl\lib\CORE\' -DFORCE_GUI $shell_loc -o slic3r-gui.o
# Build the EXE for the unforced version as slic3r-console
g++ -static-libgcc -static-libstdc++ -L'C:\strawberry\c\lib' -L'C:\strawberry\perl\bin' -L'C:\strawberry\perl\lib\CORE\' $perllib slic3r.o slic3r.res -o slic3r-console.exe | Write-Host
# Build the EXE for the forced GUI
g++ -static-libgcc -static-libstdc++ -L'C:\strawberry\c\lib' -mwindows -L'C:\strawberry\perl\bin' -L'C:\strawberry\perl\lib\CORE\' $perllib slic3r-gui.o slic3r.res -o slic3r.exe | Write-Host
# Build an extra copy of the GUI version that creates a console window
g++ -static-libgcc -static-libstdc++ -L'C:\strawberry\c\lib' -L'C:\strawberry\perl\bin' -L'C:\strawberry\perl\lib\CORE\' $perllib slic3r-gui.o slic3r.res -o slic3r-debug-console.exe | Write-Host

View File

@ -1,7 +1,7 @@
# Written by Joseph Lenox
# Licensed under the same license as the rest of Slic3r.
# ------------------------
# You need to have Strawberry Perl 5.24.0.1 installed for this to work,
# You need to have Strawberry Perl 5.24.0.1 (or slic3r-perl) installed for this to work,
param (
[switch]$exe = $false
)
@ -93,6 +93,7 @@ pp `
-M IO `
-M IO::Handle `
-M IO::Select `
-M IO::Socket `
-M LWP `
-M LWP::MediaTypes `
-M LWP::MemberMixin `

View File

@ -316,6 +316,9 @@ Usage: slic3r.pl [ OPTIONS ] [ file.stl ] [ file2.stl ] ...
--save <file> Save configuration to the specified file
--load <file> Load configuration from the specified file. It can be used
more than once to load options from multiple files.
--datadir <path> Load and store settings at the given directory.
This is useful for maintaining different profiles or including
configurations from a network storage.
-o, --output <file> File to output gcode to (by default, the file will be saved
into the same directory as the input file using the
--output-filename-format to generate the filename.) If a

View File

@ -1,4 +1,4 @@
use Test::More tests => 26;
use Test::More tests => 27;
use strict;
use warnings;
@ -10,6 +10,7 @@ BEGIN {
use List::Util qw(any);
use Slic3r;
use Slic3r::Geometry qw(epsilon);
use Slic3r::Test qw(_eq);
{
@ -209,20 +210,55 @@ use Slic3r::Test qw(_eq);
my $config = Slic3r::Config->new_from_defaults;
$config->set('start_gcode', '');
$config->set('retract_lift', [3, 4]);
$config->set('only_retract_when_crossing_perimeters', 0);
my @lifted_at = ();
my $test = sub {
my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2);
@lifted_at = ();
my $retracted = 0;
my $lifted = 0;
my $tool = 0;
Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub {
my ($self, $cmd, $args, $info) = @_;
if ($cmd eq 'G1' && $info->{dist_Z} < 0) {
push @lifted_at, $info->{new_Z};
if ($cmd eq 'G1') {
if ($info->{dist_Z} < 0) {
# going downwards; this is a "restore lift" move
$lifted = 0;
push @lifted_at, $info->{new_Z};
} elsif (abs($info->{dist_Z} - $config->get_at('retract_lift', $tool)) < &epsilon) {
# going upwards by a large amount; this is a lift move
fail 'always lift after retraction' if !$retracted;
### It would be useful to prevent the double lift happening at layer change:
###fail 'no double lift' if $lifted;
$lifted = 1;
} elsif ($info->{retracting}) {
$retracted = 1;
} elsif ($info->{extruding} && $info->{dist_XY} == 0) {
# consider the lift as layer change if they are configured with the same distance
$lifted = 0 if $config->get_at('retract_lift', $tool) == $config->layer_height;
fail 'always unretract after unlifting' if $lifted;
$retracted = 0;
} elsif ($info->{travel} && $info->{dist_XY} >= $config->get_at('retract_before_travel', $tool)) {
#printf "dist_XY = %f, rbt = %f\n", $info->{dist_XY}, $config->get_at('retract_before_travel', 0);
my $below = $config->get_at('retract_lift_below', $tool);
fail 'no retraction for long travel move' if !$retracted;
fail 'no lift for long travel move'
if !$lifted
&& $self->Z >= $config->get_at('retract_lift_above', $tool)
&& ($below == 0 || $self->Z <= $below);
}
} elsif ($cmd =~ /^T(\d+)/) {
$tool = $1;
}
});
};
$config->set('retract_layer_change', [1,1]);
$test->();
ok !!@lifted_at, 'lift is compatible with retract_layer_change';
$config->set('retract_lift_above', [0, 0]);
$config->set('retract_lift_below', [0, 0]);
$test->();
@ -234,8 +270,12 @@ use Slic3r::Test qw(_eq);
ok !!@lifted_at, 'lift takes place when above/below != 0';
ok !(any { $_ < $config->get_at('retract_lift_above', 0) } @lifted_at),
'Z is not lifted below the configured value';
ok !(any { $_ > $config->get_at('retract_lift_below', 0) } @lifted_at),
'Z is not lifted above the configured value';
{
my $below = $config->get_at('retract_lift_below', 0);
$below += $config->layer_height if $config->get_at('retract_layer_change', 0);
ok !(any { $_ > $below } @lifted_at),
'Z is not lifted above the configured value';
}
# check lifting with different values for 2. extruder
$config->set('perimeter_extruder', 2);
@ -251,8 +291,20 @@ use Slic3r::Test qw(_eq);
ok !!@lifted_at, 'lift takes place when above/below != 0 for 2. extruder';
ok !(any { $_ < $config->get_at('retract_lift_above', 1) } @lifted_at),
'Z is not lifted below the configured value for 2. extruder';
ok !(any { $_ > $config->get_at('retract_lift_below', 1) } @lifted_at),
'Z is not lifted above the configured value for 2. extruder';
{
my $below = $config->get_at('retract_lift_below', 1);
$below += $config->layer_height if $config->get_at('retract_layer_change', 1);
ok !(any { $_ > $below } @lifted_at),
'Z is not lifted above the configured value for 2. extruder';
}
$config->set('retract_lift', [$config->layer_height]);
$config->set('perimeter_extruder', 1);
$config->set('infill_extruder', 1);
$config->set('retract_lift_above', [0, 0]);
$config->set('retract_lift_below', [0, 0]);
$test->();
}
__END__

View File

@ -1,4 +1,4 @@
use Test::More tests => 27;
use Test::More tests => 28;
use strict;
use warnings;
@ -258,5 +258,32 @@ use Slic3r::Test;
@{ $layer_heights_by_tool{$config->support_material_extruder-1} }),
'no support material layer is as thin as object layers';
}
{
my $config = Slic3r::Config->new_from_defaults;
$config->set('support_material_enforce_layers', 100);
$config->set('support_material', 0);
my @contact_z = my @top_z = ();
my $test = sub {
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
my $flow = $print->print->objects->[0]->support_material_flow;
my $support = Slic3r::Print::SupportMaterial->new(
object_config => $print->print->objects->[0]->config,
print_config => $print->print->config,
flow => $flow,
interface_flow => $flow,
first_layer_flow => $flow,
);
my $support_z = $support->support_layers_z(\@contact_z, \@top_z, $config->layer_height);
is scalar(grep { $support_z->[$_]-$support_z->[$_-1] <= 0 } 1..$#$support_z), 0,
'forced support is generated';
};
$config->set('layer_height', 0.2);
$config->set('first_layer_height', 0.3);
@contact_z = (1.9);
@top_z = (1.1);
$test->();
}
__END__

View File

@ -67,15 +67,13 @@ my @boost_include = ();
if (defined $ENV{BOOST_INCLUDEDIR}) {
push @boost_include, $ENV{BOOST_INCLUDEDIR}
} elsif (defined $ENV{BOOST_DIR}) {
my $subdir = $ENV{BOOST_DIR} . (($mswin == 1) ? '\include' : '/include');
if (-d $subdir) {
push @boost_include, $subdir;
} elsif (-d "../$subdir") {
# User might have provided a path relative to the Build.PL in the main directory
push @boost_include, "../$subdir";
} else {
push @boost_include, $ENV{BOOST_DIR};
# User might have provided a path relative to the Build.PL in the main directory
foreach my $subdir ($ENV{BOOST_DIR}, "../$ENV{BOOST_DIR}", "$ENV{BOOST_DIR}/include", "../$ENV{BOOST_DIR}/include") {
if (-d $subdir) {
push @boost_include, $subdir;
}
}
die "Invalid BOOST_DIR: no such directory\n" if !@boost_include;
} else {
# Boost library was not defined by the environment.
# Try to guess at some default paths.
@ -99,15 +97,13 @@ my @boost_libs = ();
if (defined $ENV{BOOST_LIBRARYPATH}) {
push @boost_libs, $ENV{BOOST_LIBRARYPATH}
} elsif (defined $ENV{BOOST_DIR}) {
my $subdir = $ENV{BOOST_DIR} . ($mswin ? '\stage\lib' : '/stage/lib');
if (-d $subdir) {
push @boost_libs, $subdir;
} elsif (-d "../$subdir") {
# User might have provided a path relative to the Build.PL in the main directory
push @boost_libs, "../$subdir";
} else {
push @boost_libs, $ENV{BOOST_DIR};
# User might have provided a path relative to the Build.PL in the main directory
foreach my $subdir ("$ENV{BOOST_DIR}/stage/lib", "../$ENV{BOOST_DIR}/stage/lib") {
if (-d $subdir) {
push @boost_libs, $subdir;
}
}
die "Invalid BOOST_DIR: no such directory\n" if !@boost_libs;
} else {
# Boost library was not defined by the environment.
# Try to guess at some default paths.

View File

@ -525,7 +525,7 @@ void FillCubic::_fill_surface_single(
direction_t direction2 = direction;
const coord_t range = scale_(this->min_spacing / this->density);
const coord_t x_shift = abs(( (coord_t)(scale_(this->z) + range) % (coord_t)(range * 2)) - range);
const coord_t x_shift = (coord_t)(scale_(this->z) + range) % (coord_t)(range*3);
fill2._fill_single_direction(expolygon, direction2, -x_shift, out);

View File

@ -330,7 +330,7 @@ GCodeWriter::travel_to_z(double z, const std::string &comment)
reducing the lift amount that will be used for unlift. */
if (!this->will_move_z(z)) {
double nominal_z = this->_pos.z - this->_lifted;
this->_lifted = this->_lifted - (z - nominal_z);
this->_lifted -= (z - nominal_z);
return "";
}
@ -500,10 +500,15 @@ GCodeWriter::lift()
if (this->_pos.z >= above && (below == 0 || this->_pos.z <= below))
target_lift = this->config.retract_lift.get_at(this->_extruder->id);
}
if (this->_lifted == 0 && target_lift > 0) {
// compare against epsilon because travel_to_z() does math on it
// and subtracting layer_height from retract_lift might not give
// exactly zero
if (std::abs(this->_lifted) < EPSILON && target_lift > 0) {
this->_lifted = target_lift;
return this->_travel_to_z(this->_pos.z + target_lift, "lift Z");
}
return "";
}

View File

@ -574,18 +574,6 @@ class SLAPrintConfig
ConfigOptionFloat support_material_spacing;
ConfigOptionInt threads;
SLAPrintConfig() : StaticPrintConfig() {
this->set_defaults();
// override some defaults
this->fill_density.value = 100;
this->fill_pattern.value = ipGrid;
this->infill_extrusion_width.value = 0.5;
this->infill_extrusion_width.percent = false;
this->perimeter_extrusion_width.value = 1;
this->perimeter_extrusion_width.percent = false;
};
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(fill_angle);
OPT_PTR(fill_density);

View File

@ -249,6 +249,15 @@ ModelMaterial::attributes()
%code%{ THIS->material_id(material_id); %};
Ref<ModelMaterial> material();
Clone<BoundingBoxf3> bounding_box()
%code%{
try {
RETVAL = THIS->mesh.bounding_box();
} catch (std::exception& e) {
croak("%s", e.what());
}
%};
Ref<DynamicPrintConfig> config()
%code%{ RETVAL = &THIS->config; %};
Ref<TriangleMesh> mesh()