From a73a1a3f09bbaae9cacd9011c393bd0bb6dbc167 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 14 Jun 2017 12:05:23 +0200 Subject: [PATCH] Removed the DLP projector dialog as it is confusing to our customers and we doubt anybody is using it. --- lib/Slic3r.pm | 1 + lib/Slic3r/GUI.pm | 1 - lib/Slic3r/GUI/MainFrame.pm | 7 - lib/Slic3r/GUI/Projector.pm | 922 ------------------------------------ var/film.png | Bin 653 -> 0 bytes 5 files changed, 1 insertion(+), 930 deletions(-) delete mode 100644 lib/Slic3r/GUI/Projector.pm delete mode 100644 var/film.png diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index efb7e3752..8d0de99cd 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -72,6 +72,7 @@ use Slic3r::Polygon; use Slic3r::Polyline; use Slic3r::Print; use Slic3r::Print::Object; +use Slic3r::Print::Simple; use Slic3r::Surface; our $build = eval "use Slic3r::Build; 1"; use Thread::Semaphore; diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index b04a14901..011ed972f 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -28,7 +28,6 @@ use Slic3r::GUI::Plater::LambdaObjectDialog; use Slic3r::GUI::Plater::OverrideSettingsPanel; use Slic3r::GUI::Preferences; use Slic3r::GUI::ProgressStatusBar; -use Slic3r::GUI::Projector; use Slic3r::GUI::OptionsGroup; use Slic3r::GUI::OptionsGroup::Field; use Slic3r::GUI::SystemInfo; diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index ddfd4f227..f3fb2d00b 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -235,13 +235,6 @@ sub _init_menubar { $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->_append_menu_item($self->{plater_menu}, "Open DLP Projector…\tCtrl+L", 'Open projector window for DLP printing', sub { - my $projector = Slic3r::GUI::Projector->new($self); - - # this double invocation is needed for properly hiding the MainFrame - $projector->Show; - $projector->ShowModal; - }, undef, 'film.png'); $self->{object_menu} = $self->{plater}->object_menu; $self->on_plater_selection_changed(0); diff --git a/lib/Slic3r/GUI/Projector.pm b/lib/Slic3r/GUI/Projector.pm deleted file mode 100644 index a89181371..000000000 --- a/lib/Slic3r/GUI/Projector.pm +++ /dev/null @@ -1,922 +0,0 @@ -# DLP Projector screen for the SLA (stereolitography) print process - -package Slic3r::GUI::Projector; -use strict; -use warnings; -use Wx qw(:dialog :id :misc :sizer :systemsettings :bitmap :button :icon wxTheApp); -use Wx::Event qw(EVT_BUTTON 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)); - -sub new { - my ($class, $parent) = @_; - my $self = $class->SUPER::new($parent, -1, "Projector for DLP", wxDefaultPosition, wxDefaultSize); - $self->config2({ - display => 0, - show_bed => 1, - invert_y => 0, - zoom => 100, - exposure_time => 2, - bottom_exposure_time => 7, - settle_time => 1.5, - bottom_layers => 3, - z_lift => 5, - z_lift_speed => 8, - offset => [0,0], - }); - - my $ini = eval { Slic3r::Config->read_ini("$Slic3r::GUI::datadir/DLP.ini") }; - if ($ini) { - foreach my $opt_id (keys %{$ini->{_}}) { - my $value = $ini->{_}{$opt_id}; - if ($opt_id eq 'offset') { - $value = [ split /,/, $value ]; - } - $self->config2->{$opt_id} = $value; - } - } - - my $sizer = Wx::BoxSizer->new(wxVERTICAL); - - $self->config(Slic3r::Config->new_from_defaults( - qw(serial_port serial_speed bed_shape start_gcode end_gcode z_offset) - )); - $self->config->apply(wxTheApp->{mainframe}->config); - - my @optgroups = (); - { - push @optgroups, my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new( - parent => $self, - title => 'USB/Serial connection', - config => $self->config, - label_width => 200, - ); - $sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - - { - my $line = Slic3r::GUI::OptionsGroup::Line->new( - label => 'Serial port', - ); - my $serial_port = $optgroup->get_option('serial_port'); - $serial_port->side_widget(sub { - my ($parent) = @_; - - my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new($Slic3r::var->("arrow_rotate_clockwise.png"), wxBITMAP_TYPE_PNG), - wxDefaultPosition, wxDefaultSize, &Wx::wxBORDER_NONE); - $btn->SetToolTipString("Rescan serial ports") - if $btn->can('SetToolTipString'); - EVT_BUTTON($self, $btn, sub { - $optgroup->get_field('serial_port')->set_values([ wxTheApp->scan_serial_ports ]); - }); - - return $btn; - }); - my $serial_test = sub { - my ($parent) = @_; - - my $btn = $self->{serial_test_btn} = Wx::Button->new($parent, -1, - "Test", wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - $btn->SetFont($Slic3r::GUI::small_font); - if ($Slic3r::GUI::have_button_icons) { - $btn->SetBitmap(Wx::Bitmap->new($Slic3r::var->("wrench.png"), wxBITMAP_TYPE_PNG)); - } - - EVT_BUTTON($self, $btn, sub { - my $sender = Slic3r::GCode::Sender->new; - my $res = $sender->connect( - $self->{config}->serial_port, - $self->{config}->serial_speed, - ); - if ($res && $sender->wait_connected) { - Slic3r::GUI::show_info($self, "Connection to printer works correctly.", "Success!"); - } else { - Slic3r::GUI::show_error($self, "Connection failed."); - } - }); - return $btn; - }; - $line->append_option($serial_port); - $line->append_option($optgroup->get_option('serial_speed')); - $line->append_widget($serial_test); - $optgroup->append_line($line); - } - } - - { - push @optgroups, my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new( - parent => $self, - title => 'G-code', - config => $self->config, - label_width => 200, - ); - $sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - - { - my $option = $optgroup->get_option('start_gcode'); - $option->height(50); - $option->full_width(1); - $optgroup->append_single_option_line($option); - } - { - my $option = $optgroup->get_option('end_gcode'); - $option->height(50); - $option->full_width(1); - $optgroup->append_single_option_line($option); - } - } - - my $on_change = sub { - my ($opt_id, $value) = @_; - - $self->config2->{$opt_id} = $value; - $self->screen->reposition; - $self->show_print_time; - - my $serialized = {}; - foreach my $opt_id (keys %{$self->config2}) { - my $value = $self->config2->{$opt_id}; - if (ref($value) eq 'ARRAY') { - $value = join ',', @$value; - } - $serialized->{$opt_id} = $value; - } - Slic3r::Config->write_ini( - "$Slic3r::GUI::datadir/DLP.ini", - { _ => $serialized }); - }; - - { - push @optgroups, my $optgroup = Slic3r::GUI::OptionsGroup->new( - parent => $self, - title => 'Projection', - on_change => $on_change, - label_width => 200, - ); - $sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - - { - my $line = Slic3r::GUI::OptionsGroup::Line->new( - label => 'Display', - ); - - my @displays = 0 .. (Wx::Display::GetCount()-1); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'display', - type => 'select', - label => 'Display', - tooltip => '', - labels => [@displays], - values => [@displays], - default => $self->config2->{display}, - )); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'zoom', - type => 'percent', - label => 'Zoom %', - tooltip => '', - default => $self->config2->{zoom}, - min => 0.1, - max => 100, - )); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'offset', - type => 'point', - label => 'Offset', - tooltip => '', - default => $self->config2->{offset}, - )); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'invert_y', - type => 'bool', - label => 'Invert Y', - tooltip => '', - default => $self->config2->{invert_y}, - )); - $optgroup->append_line($line); - } - - $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'show_bed', - type => 'bool', - label => 'Show bed', - tooltip => '', - default => $self->config2->{show_bed}, - )); - } - - { - push @optgroups, my $optgroup = Slic3r::GUI::OptionsGroup->new( - parent => $self, - title => 'Print', - on_change => $on_change, - label_width => 200, - ); - $sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - - { - my $line = Slic3r::GUI::OptionsGroup::Line->new( - label => 'Time (seconds)', - ); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'bottom_exposure_time', - type => 'f', - label => 'Bottom exposure', - tooltip => '', - default => $self->config2->{bottom_exposure_time}, - )); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'exposure_time', - type => 'f', - label => 'Exposure', - tooltip => '', - default => $self->config2->{exposure_time}, - )); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'settle_time', - type => 'f', - label => 'Settle', - tooltip => '', - default => $self->config2->{settle_time}, - )); - $optgroup->append_line($line); - } - - $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'bottom_layers', - type => 'i', - label => 'Bottom layers', - tooltip => '', - default => $self->config2->{bottom_layers}, - )); - - { - my $line = Slic3r::GUI::OptionsGroup::Line->new( - label => 'Z Lift', - ); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'z_lift', - type => 'f', - label => 'Distance', - sidetext => 'mm', - tooltip => '', - default => $self->config2->{z_lift}, - )); - $line->append_option(Slic3r::GUI::OptionsGroup::Option->new( - opt_id => 'z_lift_speed', - type => 'f', - label => 'Speed', - sidetext => 'mm/s', - tooltip => '', - default => $self->config2->{z_lift_speed}, - )); - $optgroup->append_line($line); - } - } - - $self->_optgroups([@optgroups]); - - { - my $sizer1 = Wx::BoxSizer->new(wxHORIZONTAL); - $sizer->Add($sizer1, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - - { - my $btn = $self->{btn_manual_control} = Wx::Button->new($self, -1, 'Manual Control', wxDefaultPosition, wxDefaultSize); - if ($Slic3r::GUI::have_button_icons) { - $btn->SetBitmap(Wx::Bitmap->new($Slic3r::var->("cog.png"), wxBITMAP_TYPE_PNG)); - } - $sizer1->Add($btn, 0); - EVT_BUTTON($self, $btn, sub { - my $sender = Slic3r::GCode::Sender->new; - my $res = $sender->connect( - $self->config->serial_port, - $self->config->serial_speed, - ); - if (!$res || !$sender->wait_connected) { - Slic3r::GUI::show_error(undef, "Connection failed. Check serial port and speed."); - return; - } - my $dlg = Slic3r::GUI::Controller::ManualControlDialog->new - ($self, $self->config, $sender); - $dlg->ShowModal; - $sender->disconnect; - }); - - - } - { - my $btn = $self->{btn_print} = Wx::Button->new($self, -1, 'Print', wxDefaultPosition, wxDefaultSize); - if ($Slic3r::GUI::have_button_icons) { - $btn->SetBitmap(Wx::Bitmap->new($Slic3r::var->("control_play.png"), wxBITMAP_TYPE_PNG)); - } - $sizer1->Add($btn, 0); - EVT_BUTTON($self, $btn, sub { - $self->controller->start_print; - $self->_update_buttons; - $self->_set_status(''); - }); - } - { - my $btn = $self->{btn_stop} = Wx::Button->new($self, -1, 'Stop/Black', wxDefaultPosition, wxDefaultSize); - if ($Slic3r::GUI::have_button_icons) { - $btn->SetBitmap(Wx::Bitmap->new($Slic3r::var->("control_stop.png"), wxBITMAP_TYPE_PNG)); - } - $sizer1->Add($btn, 0); - EVT_BUTTON($self, $btn, sub { - $self->controller->stop_print; - $self->_update_buttons; - $self->_set_status(''); - }); - } - - { - { - my $text = Wx::StaticText->new($self, -1, "Layer:", wxDefaultPosition, wxDefaultSize); - $text->SetFont($Slic3r::GUI::small_font); - $sizer1->Add($text, 0, wxEXPAND | wxLEFT, 10); - } - { - my $spin = $self->{layers_spinctrl} = Wx::SpinCtrl->new($self, -1, 0, wxDefaultPosition, [60,-1], - 0, 0, 300, 0); - $sizer1->Add($spin, 0); - EVT_SPINCTRL($self, $spin, sub { - my $value = $spin->GetValue; - $self->{layers_slider}->SetValue($value); - $self->controller->project_layer($value); - $self->_update_buttons; - }); - } - { - my $slider = $self->{layers_slider} = Wx::Slider->new( - $self, -1, - 0, # default - 0, # min - 300, # max - wxDefaultPosition, - wxDefaultSize, - ); - $sizer1->Add($slider, 1); - EVT_SLIDER($self, $slider, sub { - my $value = $slider->GetValue; - $self->{layers_spinctrl}->SetValue($value); - $self->controller->project_layer($value); - $self->_update_buttons; - }); - } - } - - my $sizer2 = Wx::BoxSizer->new(wxHORIZONTAL); - $sizer->Add($sizer2, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - - { - $self->{status_text} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, wxDefaultSize); - $self->{status_text}->SetFont($Slic3r::GUI::small_font); - $sizer2->Add($self->{status_text}, 1 | wxEXPAND); - } - } - - { - my $buttons = $self->CreateStdDialogButtonSizer(wxOK); - EVT_BUTTON($self, wxID_CLOSE, sub { - $self->_close; - }); - $sizer->Add($buttons, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); - } - - $self->SetSizer($sizer); - $sizer->SetSizeHints($self); - - # reuse existing screen if any - if ($Slic3r::GUI::DLP_projection_screen) { - $self->screen($Slic3r::GUI::DLP_projection_screen); - $self->screen->config($self->config); - $self->screen->config2($self->config2); - } else { - $self->screen(Slic3r::GUI::Projector::Screen->new($parent, $self->config, $self->config2)); - $Slic3r::GUI::DLP_projection_screen = $self->screen; - } - $self->screen->reposition; - $self->screen->Show; - wxTheApp->{mainframe}->Hide; - - # initialize controller - $self->controller(Slic3r::GUI::Projector::Controller->new( - config => $self->config, - config2 => $self->config2, - screen => $self->screen, - on_project_layer => sub { - my ($layer_num) = @_; - - $self->{layers_spinctrl}->SetValue($layer_num); - $self->{layers_slider}->SetValue($layer_num); - - my $duration = $self->controller->remaining_print_time; - $self->_set_status(sprintf "Printing layer %d/%d (z = %.2f); %d minutes and %d seconds left", - $layer_num, $self->controller->layer_count, - $self->controller->current_layer_height, - int($duration/60), ($duration - int($duration/60)*60)); # % truncates to integer - }, - on_print_completed => sub { - $self->_update_buttons; - $self->_set_status(''); - Wx::Bell(); - }, - )); - { - my $max = $self->controller->layer_count-1; - $self->{layers_spinctrl}->SetRange(0, $max); - $self->{layers_slider}->SetRange(0, $max); - } - - $self->_update_buttons; - $self->show_print_time; - - return $self; -} - -sub _update_buttons { - my ($self) = @_; - - my $is_printing = $self->controller->is_printing; - my $is_projecting = $self->controller->is_projecting; - $self->{btn_manual_control}->Show(!$is_printing); - $self->{btn_print}->Show(!$is_printing && !$is_projecting); - $self->{btn_stop}->Show($is_printing || $is_projecting); - $self->{layers_spinctrl}->Enable(!$is_printing); - $self->{layers_slider}->Enable(!$is_printing); - if ($is_printing) { - $_->disable for @{$self->_optgroups}; - } else { - $_->enable for @{$self->_optgroups}; - } - $self->Layout; -} - -sub _set_status { - my ($self, $status) = @_; - $self->{status_text}->SetLabel($status // ''); - $self->{status_text}->Wrap($self->{status_text}->GetSize->GetWidth); - $self->{status_text}->Refresh; - $self->Layout; -} - -sub show_print_time { - my ($self) = @_; - - - my $duration = $self->controller->print_time; - $self->_set_status(sprintf "Estimated print time: %d minutes and %d seconds", - int($duration/60), ($duration - int($duration/60)*60)); # % truncates to integer -} - -sub _close { - my $self = shift; - - # if projection screen is not on the same display as our dialog, - # ask the user whether they want to keep it open - my $keep_screen = 0; - my $display_area = Wx::Display->new($self->config2->{display})->GetGeometry; - if (!$display_area->Contains($self->GetScreenPosition)) { - my $res = Wx::MessageDialog->new($self, "Do you want to keep the black screen open?", 'Black screen', wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION)->ShowModal; - $keep_screen = ($res == wxID_YES); - } - - if ($keep_screen) { - $self->screen->config(undef); - $self->screen->config2(undef); - $self->screen->Refresh; - } else { - $self->screen->Destroy; - $self->screen(undef); - $Slic3r::GUI::DLP_projection_screen = undef; - } - wxTheApp->{mainframe}->Show; - - my $printer_tab = wxTheApp->{mainframe}{options_tabs}{printer}; - $printer_tab->load_config($self->config); - - $self->EndModal(wxID_OK); -} - -package Slic3r::GUI::Projector::Controller; -use Moo; -use Wx qw(wxTheApp :id :timer); -use Wx::Event qw(EVT_TIMER); -use Slic3r::Print::State ':steps'; -use Time::HiRes qw(gettimeofday tv_interval); - -has 'config' => (is => 'ro', required => 1); -has 'config2' => (is => 'ro', required => 1); -has 'screen' => (is => 'ro', required => 1); -has 'on_project_layer' => (is => 'rw'); -has 'on_print_completed' => (is => 'rw'); -has 'sender' => (is => 'rw'); -has 'timer' => (is => 'rw'); -has 'is_printing' => (is => 'rw', default => sub { 0 }); -has '_print' => (is => 'rw'); -has '_layers' => (is => 'rw'); -has '_heights' => (is => 'rw'); -has '_layer_num' => (is => 'rw'); -has '_timer_cb' => (is => 'rw'); - -sub BUILD { - my ($self) = @_; - - Slic3r::GUI::disable_screensaver(); - - $self->set_print(wxTheApp->{mainframe}->{plater}->{print}); - - # projection timer - my $timer_id = &Wx::NewId(); - $self->timer(Wx::Timer->new($self->screen, $timer_id)); - EVT_TIMER($self->screen, $timer_id, sub { - my $cb = $self->_timer_cb; - $self->_timer_cb(undef); - $cb->(); - }); -} - -sub delay { - my ($self, $wait, $cb) = @_; - - $self->_timer_cb($cb); - $self->timer->Start($wait * 1000, wxTIMER_ONE_SHOT); -} - -sub set_print { - my ($self, $print) = @_; - - # make sure layers were sliced - { - my $progress_dialog; - foreach my $object (@{$print->objects}) { - next if $object->step_done(STEP_SLICE); - $progress_dialog //= Wx::ProgressDialog->new('Slicing…', "Processing layers…", 100, undef, 0); - $progress_dialog->Pulse; - $object->slice; - } - $progress_dialog->Destroy if $progress_dialog; - } - - $self->_print($print); - - # sort layers by Z - my %layers = (); - foreach my $layer (map { @{$_->layers}, @{$_->support_layers} } @{$print->objects}) { - my $height = $layer->print_z; - $layers{$height} //= []; - push @{$layers{$height}}, $layer; - } - $self->_layers({ %layers }); - $self->_heights([ sort { $a <=> $b } keys %layers ]); -} - -sub layer_count { - my ($self) = @_; - - return scalar @{$self->_heights}; -} - -sub current_layer_height { - my ($self) = @_; - - return $self->_heights->[$self->_layer_num]; -} - -sub start_print { - my ($self) = @_; - - { - $self->sender(Slic3r::GCode::Sender->new); - my $res = $self->sender->connect( - $self->config->serial_port, - $self->config->serial_speed, - ); - if (!$res || !$self->sender->wait_connected) { - Slic3r::GUI::show_error(undef, "Connection failed. Check serial port and speed."); - return; - } - Slic3r::debugf "connected to " . $self->config->serial_port . "\n"; - - # send custom start G-code - $self->sender->send($_, 1) for grep !/^;/, split /\n/, $self->config->start_gcode; - } - - $self->is_printing(1); - - # TODO: block until the G1 command has been performed - # we could do this with M400 + M115 but maybe it's not portable - $self->delay(5, sub { - # start with black - Slic3r::debugf "starting black projection\n"; - $self->_layer_num(-1); - $self->screen->project_layers(undef); - $self->delay($self->config2->{settle_time}, sub { - $self->project_next_layer; - }); - }); -} - -sub stop_print { - my ($self) = @_; - - if ($self->sender) { - $self->sender->disconnect; - } - - $self->is_printing(0); - $self->timer->Stop; - $self->_timer_cb(undef); - $self->screen->project_layers(undef); -} - -sub print_completed { - my ($self) = @_; - - # send custom end G-code - if ($self->sender) { - $self->sender->send($_, 1) for grep !/^;/, split /\n/, $self->config->end_gcode; - } - - # call this before the on_print_completed callback otherwise buttons - # won't be updated correctly - $self->stop_print; - - $self->on_print_completed->() - if $self->is_printing && $self->on_print_completed; -} - -sub is_projecting { - my ($self) = @_; - - return defined $self->screen->layers; -} - -sub project_layer { - my ($self, $layer_num) = @_; - - if (!defined $layer_num || $layer_num >= $self->layer_count) { - $self->screen->project_layers(undef); - return; - } - - my @layers = @{ $self->_layers->{ $self->_heights->[$layer_num] } }; - $self->screen->project_layers([ @layers ]); -} - -sub project_next_layer { - my ($self) = @_; - - $self->_layer_num($self->_layer_num + 1); - Slic3r::debugf "projecting layer %d\n", $self->_layer_num; - if ($self->_layer_num >= $self->layer_count) { - $self->print_completed; - return; - } - - $self->on_project_layer->($self->_layer_num) if $self->on_project_layer; - - if ($self->sender) { - my $z = $self->current_layer_height + $self->config->z_offset; - my $F = $self->config2->{z_lift_speed} * 60; - if ($self->config2->{z_lift} != 0) { - $self->sender->send(sprintf("G1 Z%.5f F%d", $z + $self->config2->{z_lift}, $F), 1); - } - $self->sender->send(sprintf("G1 Z%.5f F%d", $z, $F), 1); - } - - # TODO: we should block until G1 commands have been performed, see note below - $self->delay($self->config2->{settle_time}, sub { - $self->project_layer($self->_layer_num); - - # get exposure time - my $time = $self->config2->{exposure_time}; - if ($self->_layer_num < $self->config2->{bottom_layers}) { - $time = $self->config2->{bottom_exposure_time}; - } - - $self->delay($time, sub { - $self->screen->project_layers(undef); - $self->project_next_layer; - }); - }); -} - -sub remaining_print_time { - my ($self) = @_; - - my $remaining_layers = @{$self->_heights} - $self->_layer_num; - my $remaining_bottom_layers = $self->_layer_num >= $self->config2->{bottom_layers} - ? 0 - : $self->config2->{bottom_layers} - $self->_layer_num; - - return $remaining_bottom_layers * $self->config2->{bottom_exposure_time} - + ($remaining_layers - $remaining_bottom_layers) * $self->config2->{exposure_time} - + $remaining_layers * $self->config2->{settle_time}; -} - -sub print_time { - my ($self) = @_; - - return $self->config2->{bottom_layers} * $self->config2->{bottom_exposure_time} - + (@{$self->_heights} - $self->config2->{bottom_layers}) * $self->config2->{exposure_time} - + @{$self->_heights} * $self->config2->{settle_time}; -} - -sub DESTROY { - my ($self) = @_; - - $self->timer->Stop if $self->timer; - $self->sender->disconnect if $self->sender; - Slic3r::GUI::enable_screensaver(); -} - -package Slic3r::GUI::Projector::Screen; -use Wx qw(:dialog :id :misc :sizer :colour :pen :brush :font wxBG_STYLE_CUSTOM); -use Wx::Event qw(EVT_PAINT EVT_SIZE); -use base qw(Wx::Dialog Class::Accessor); - -use List::Util qw(min); -use Slic3r::Geometry qw(X Y unscale scale); -use Slic3r::Geometry::Clipper qw(intersection_pl); - -__PACKAGE__->mk_accessors(qw(config config2 scaling_factor bed_origin layers)); - -sub new { - my ($class, $parent, $config, $config2) = @_; - my $self = $class->SUPER::new($parent, -1, "Projector", wxDefaultPosition, wxDefaultSize, 0); - - $self->config($config); - $self->config2($config2); - $self->SetBackgroundStyle(wxBG_STYLE_CUSTOM); - EVT_SIZE($self, \&_resize); - EVT_PAINT($self, \&_repaint); - $self->_resize; - - return $self; -} - -sub reposition { - my ($self) = @_; - - my $display = Wx::Display->new($self->config2->{display}); - my $area = $display->GetGeometry; - $self->Move($area->GetPosition); - # ShowFullScreen doesn't use the right screen - #$self->ShowFullScreen($self->config2->{fullscreen}); - $self->SetSize($area->GetSize); - $self->_resize; - $self->Refresh; -} - -sub _resize { - my ($self) = @_; - - return if !$self->config; - my ($cw, $ch) = $self->GetSizeWH; - - # get bed shape polygon - my $bed_polygon = Slic3r::Polygon->new_scale(@{$self->config->bed_shape}); - my $bb = $bed_polygon->bounding_box; - my $size = $bb->size; - my $center = $bb->center; - - # calculate the scaling factor needed for constraining print bed area inside preview - # scaling_factor is expressed in pixel / mm - $self->scaling_factor(min($cw / unscale($size->x), $ch / unscale($size->y))); #) - - # apply zoom to scaling factor - if ($self->config2->{zoom} != 0) { - # TODO: make sure min and max in the option config are enforced - $self->scaling_factor($self->scaling_factor * ($self->config2->{zoom}/100)); - } - - # calculate the displacement needed for centering bed on screen - $self->bed_origin([ - $cw/2 - (unscale($center->x) - $self->config2->{offset}->[X]) * $self->scaling_factor, - $ch/2 - (unscale($center->y) - $self->config2->{offset}->[Y]) * $self->scaling_factor, #)) - ]); - - $self->Refresh; -} - -sub project_layers { - my ($self, $layers) = @_; - - $self->layers($layers); - $self->Refresh; -} - -sub _repaint { - my ($self) = @_; - - my $dc = Wx::AutoBufferedPaintDC->new($self); - my ($cw, $ch) = $self->GetSizeWH; - return if $cw == 0; # when canvas is not rendered yet, size is 0,0 - - $dc->SetPen(Wx::Pen->new(wxBLACK, 1, wxSOLID)); - $dc->SetBrush(Wx::Brush->new(wxBLACK, wxSOLID)); - $dc->DrawRectangle(0, 0, $cw, $ch); - - return if !$self->config; - - # turn size into max visible coordinates - # TODO: or should we use ClientArea? - $cw--; - $ch--; - - # draw bed - if ($self->config2->{show_bed}) { - $dc->SetPen(Wx::Pen->new(wxRED, 2, wxSOLID)); - $dc->SetBrush(Wx::Brush->new(wxWHITE, wxTRANSPARENT)); - - # draw contour - my $bed_polygon = Slic3r::Polygon->new_scale(@{$self->config->bed_shape}); - $dc->DrawPolygon($self->scaled_points_to_pixel($bed_polygon), 0, 0); - - # draw grid - $dc->SetPen(Wx::Pen->new(wxRED, 1, wxSOLID)); - { - my $bb = $bed_polygon->bounding_box; - my $step = scale 10; # 1cm grid - my @polylines = (); - for (my $x = $bb->x_min - ($bb->x_min % $step) + $step; $x < $bb->x_max; $x += $step) { - push @polylines, Slic3r::Polyline->new([$x, $bb->y_min], [$x, $bb->y_max]); - } - for (my $y = $bb->y_min - ($bb->y_min % $step) + $step; $y < $bb->y_max; $y += $step) { - push @polylines, Slic3r::Polyline->new([$bb->x_min, $y], [$bb->x_max, $y]); - } - $dc->DrawLine(map @$_, @$_) - for map $self->scaled_points_to_pixel([ @$_[0,-1] ]), - @{intersection_pl(\@polylines, [$bed_polygon])}; - } - - # draw axes orientation - $dc->SetPen(Wx::Pen->new(wxWHITE, 4, wxSOLID)); - { - foreach my $endpoint ([10, 0], [0, 10]) { - $dc->DrawLine( - map @{$self->unscaled_point_to_pixel($_)}, [0,0], $endpoint - ); - } - - $dc->SetTextForeground(wxWHITE); - $dc->SetFont(Wx::Font->new(20, wxDEFAULT, wxNORMAL, wxNORMAL)); - $dc->DrawText("X", @{$self->unscaled_point_to_pixel([10, -2])}); - $dc->DrawText("Y", @{$self->unscaled_point_to_pixel([-2, 10])}); - } - } - - return if !defined $self->layers; - - # get layers at this height - # draw layers - $dc->SetPen(Wx::Pen->new(wxWHITE, 1, wxSOLID)); - foreach my $layer (@{$self->layers}) { - my @polygons = sort { $a->contains_point($b->first_point) ? -1 : 1 } map @$_, @{ $layer->slices }; - foreach my $copy (@{$layer->object->_shifted_copies}) { - foreach my $polygon (@polygons) { - $polygon = $polygon->clone; - $polygon->translate(@$copy); - - if ($polygon->is_counter_clockwise) { - $dc->SetBrush(Wx::Brush->new(wxWHITE, wxSOLID)); - } else { - $dc->SetBrush(Wx::Brush->new(wxBLACK, wxSOLID)); - } - $dc->DrawPolygon($self->scaled_points_to_pixel($polygon->pp), 0, 0); - } - } - } -} - -# convert a model coordinate into a pixel coordinate -sub unscaled_point_to_pixel { - my ($self, $point) = @_; - - my $zero = $self->bed_origin; - my $p = [ - $point->[X] * $self->scaling_factor + $zero->[X], - $point->[Y] * $self->scaling_factor + $zero->[Y], - ]; - - if (!$self->config2->{invert_y}) { - my $ch = $self->GetSize->GetHeight; - $p->[Y] = $ch - $p->[Y]; - } - - return $p; -} - -sub scaled_points_to_pixel { - my ($self, $points) = @_; - - return [ - map $self->unscaled_point_to_pixel($_), - map Slic3r::Pointf->new_unscale(@$_), - @$points - ]; -} - -1; diff --git a/var/film.png b/var/film.png deleted file mode 100644 index b0ce7bb198a3b268bd634d2b26e9b710f3797d37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 653 zcmV;80&@L{P)WO3(`_cf+b25@DJ#zdQm}8GzWtq2-QnZ8W6mB^kfeK5f%S{ zUW%tGMCwrwic~ZrQcG=4f?5bkV+3dRk8hw6bk~y$KX#b!y*J4EJ~>;dRASqrSu;ZpM>?P}K~6AT zWv6Dmq?v&9LdXC(m%WCO6ma_di$R(v$@ad_>@R41N3N5lSJq9@6CGhX84-$%Xrd_6 z;){?{E|Ytt5$S-&Au>t4wDlIxdkfe-a22LMj``McG};r8@{GsRPm*+8fFey6C)@ifDBXVyTw(N@Xd41b45OFg6x_QA zpwLiigyy~cVoPxW^r~C7ZQpr%>1$*HKmv~AY-qJw4;gUecS--wnqslISSS=^KA&Ic n@BK|Onfz#3R%n{$a)0j^sqv5F(1NTL00000NkvXXu0mjf3S}fX