mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Merge remote-tracking branch 'origin/dev' into new_main_page_ui
This commit is contained in:
		
						commit
						73ee3f77c3
					
				
					 86 changed files with 4884 additions and 2922 deletions
				
			
		|  | @ -70,24 +70,11 @@ sub new { | |||
|     eval { Wx::ToolTip::SetAutoPop(32767) }; | ||||
|      | ||||
|     # initialize status bar | ||||
|     $self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new($self, Wx::NewId); | ||||
|     $self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new(); | ||||
|     $self->{statusbar}->Embed; | ||||
|     $self->{statusbar}->SetStatusText(L("Version ").$Slic3r::VERSION.L(" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases")); | ||||
|     $self->SetStatusBar($self->{statusbar}); | ||||
| 
 | ||||
|     # Make the global status bar and its progress indicator available in C++ | ||||
|     $appController->set_global_progress_indicator( | ||||
|         $self->{statusbar}->{prog}->GetId(), | ||||
|         $self->{statusbar}->GetId(), | ||||
|     ); | ||||
| 
 | ||||
|     $appController->set_model($self->{plater}->{model}); | ||||
|     $appController->set_print($self->{plater}->{print}); | ||||
|      | ||||
|     # Make the global status bar and its progress indicator available in C++ | ||||
|     $appController->set_global_progress_indicator( | ||||
|         $self->{statusbar}->{prog}->GetId(), | ||||
|         $self->{statusbar}->GetId(), | ||||
|     ); | ||||
|     $appController->set_global_progress_indicator($self->{statusbar}); | ||||
| 
 | ||||
|     $appController->set_model($self->{plater}->{model}); | ||||
|     $appController->set_print($self->{plater}->{print}); | ||||
|  |  | |||
|  | @ -85,9 +85,13 @@ sub new { | |||
|      | ||||
|     # Initialize handlers for canvases | ||||
|     my $on_select_object = sub { | ||||
|         my ($obj_idx) = @_; | ||||
|         # Ignore the special objects (the wipe tower proxy and such). | ||||
|         $self->select_object((defined($obj_idx) && $obj_idx >= 0 && $obj_idx < 1000) ? $obj_idx : undef); | ||||
|         my ($obj_idx, $vol_idx) = @_; | ||||
|                          | ||||
|         if (($obj_idx != -1) && ($vol_idx == -1)) { | ||||
|             # Ignore the special objects (the wipe tower proxy and such). | ||||
|             $self->select_object((defined($obj_idx) && $obj_idx >= 0 && $obj_idx < 1000) ? $obj_idx : undef); | ||||
|             $self->item_changed_selection($obj_idx) if (defined($obj_idx)); | ||||
|         } | ||||
|     }; | ||||
|     my $on_double_click = sub { | ||||
|         $self->object_settings_dialog if $self->selected_object; | ||||
|  | @ -150,16 +154,15 @@ sub new { | |||
|     }; | ||||
|      | ||||
|     # callback to react to gizmo rotate | ||||
|     # omitting last three parameters means rotation around Z | ||||
|     # otherwise they are the components of the rotation axis vector | ||||
|     my $on_gizmo_rotate = sub { | ||||
|         my ($angle) = @_; | ||||
|         $self->rotate(rad2deg($angle), Z, 'absolute'); | ||||
|     }; | ||||
|      | ||||
|     # callback to react to gizmo flatten | ||||
|     my $on_gizmo_flatten = sub { | ||||
|         my ($angle, $axis_x, $axis_y, $axis_z) = @_; | ||||
|         if (!defined $axis_x) { | ||||
|             $self->rotate(rad2deg($angle), Z, 'absolute'); | ||||
|         } | ||||
|         else { | ||||
|             $self->rotate(rad2deg($angle), undef, 'absolute', $axis_x, $axis_y, $axis_z) if $angle != 0; | ||||
|         } | ||||
|         $self->rotate(rad2deg($angle), undef, 'absolute', $axis_x, $axis_y, $axis_z) if $angle != 0; | ||||
|     }; | ||||
| 
 | ||||
|     # callback to update object's geometry info while using gizmos | ||||
|  | @ -218,6 +221,29 @@ sub new { | |||
|         my $state = Slic3r::GUI::_3DScene::is_toolbar_item_pressed($self->{canvas3D}, "layersediting"); | ||||
|         $self->on_layer_editing_toggled($state); | ||||
|     }; | ||||
| 
 | ||||
|     my $on_action_selectbyparts = sub { | ||||
|         my $curr = Slic3r::GUI::_3DScene::get_select_by($self->{canvas3D}); | ||||
|         if ($curr eq 'volume') { | ||||
|             Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'object'); | ||||
|             my $selections = $self->collect_selections; | ||||
|             Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); | ||||
|             Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1);         | ||||
|         } | ||||
|         elsif ($curr eq 'object') { | ||||
|             Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'volume'); | ||||
|             my $selections = []; | ||||
|             Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); | ||||
|             Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D}); | ||||
|             Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1);       | ||||
| 
 | ||||
|             my ($obj_idx, $object) = $self->selected_object; | ||||
|             if (defined $obj_idx) {             | ||||
|                 my $vol_idx = Slic3r::GUI::_3DScene::get_first_volume_id($self->{canvas3D}, $obj_idx);                  | ||||
|                 Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $vol_idx) if ($vol_idx != -1); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|          | ||||
|     # Initialize 3D plater | ||||
|     if ($Slic3r::GUI::have_OpenGL) { | ||||
|  | @ -237,6 +263,7 @@ sub new { | |||
|         Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons); | ||||
|         Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly); | ||||
|         Slic3r::GUI::_3DScene::register_on_gizmo_rotate_callback($self->{canvas3D}, $on_gizmo_rotate); | ||||
|         Slic3r::GUI::_3DScene::register_on_gizmo_flatten_callback($self->{canvas3D}, $on_gizmo_flatten); | ||||
|         Slic3r::GUI::_3DScene::register_on_update_geometry_info_callback($self->{canvas3D}, $on_update_geometry_info); | ||||
|         Slic3r::GUI::_3DScene::register_action_add_callback($self->{canvas3D}, $on_action_add); | ||||
|         Slic3r::GUI::_3DScene::register_action_delete_callback($self->{canvas3D}, $on_action_delete); | ||||
|  | @ -248,6 +275,7 @@ sub new { | |||
|         Slic3r::GUI::_3DScene::register_action_cut_callback($self->{canvas3D}, $on_action_cut); | ||||
|         Slic3r::GUI::_3DScene::register_action_settings_callback($self->{canvas3D}, $on_action_settings); | ||||
|         Slic3r::GUI::_3DScene::register_action_layersediting_callback($self->{canvas3D}, $on_action_layersediting); | ||||
|         Slic3r::GUI::_3DScene::register_action_selectbyparts_callback($self->{canvas3D}, $on_action_selectbyparts); | ||||
|         Slic3r::GUI::_3DScene::enable_gizmos($self->{canvas3D}, 1); | ||||
|         Slic3r::GUI::_3DScene::enable_toolbar($self->{canvas3D}, 1); | ||||
|         Slic3r::GUI::_3DScene::enable_shader($self->{canvas3D}, 1); | ||||
|  | @ -871,6 +899,15 @@ sub load_files { | |||
|             $model->convert_multipart_object(scalar(@$nozzle_dmrs)) if $dialog->ShowModal() == wxID_YES; | ||||
|         } | ||||
|          | ||||
|         # objects imported from 3mf require a call to center_around_origin to have gizmos working properly and this call | ||||
|         # need to be done after looks_like_multipart_object detection | ||||
|         if ($input_file =~ /.3[mM][fF]$/) | ||||
|         { | ||||
|             foreach my $model_object (@{$model->objects}) { | ||||
|                 $model_object->center_around_origin;  # also aligns object to Z = 0 | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         if ($one_by_one) { | ||||
|             push @obj_idx, $self->load_model_objects(@{$model->objects}); | ||||
|         } else { | ||||
|  | @ -1161,13 +1198,12 @@ sub rotate { | |||
|     } | ||||
| 
 | ||||
|     # Let's calculate vector of rotation axis (if we don't have it already) | ||||
|     # The minus is there so that the direction is the same as was established | ||||
|     if (defined $axis) { | ||||
|         if ($axis == X) { | ||||
|             $axis_x = -1; | ||||
|             $axis_x = 1; | ||||
|         } | ||||
|         if ($axis == Y) { | ||||
|             $axis_y = -1; | ||||
|             $axis_y = 1; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  | @ -1202,11 +1238,7 @@ sub rotate { | |||
| #        $model_object->center_around_origin; | ||||
| #        $self->reset_thumbnail($obj_idx); | ||||
|     } | ||||
|      | ||||
|     if (defined $axis) { | ||||
|         Slic3r::GUI::update_rotation_value(deg2rad($angle), $axis == X ? "x" : ($axis == Y ? "y" : "z")); | ||||
|     } | ||||
|      | ||||
|          | ||||
|     # update print and start background processing | ||||
|     $self->{print}->add_model_object($model_object, $obj_idx); | ||||
|      | ||||
|  | @ -1676,7 +1708,9 @@ sub on_progress_event { | |||
|     my ($self, $percent, $message) = @_; | ||||
|      | ||||
|     $self->statusbar->SetProgress($percent); | ||||
|     $self->statusbar->SetStatusText("$message…"); | ||||
|     # TODO: three dot character is not properly translated into C++ | ||||
|     # $self->statusbar->SetStatusText("$message…"); | ||||
|     $self->statusbar->SetStatusText("$message..."); | ||||
| } | ||||
| 
 | ||||
| # Called when the G-code export finishes, either successfully or with an error. | ||||
|  | @ -2129,17 +2163,18 @@ sub on_config_change { | |||
|     $self->schedule_background_process; | ||||
| } | ||||
| 
 | ||||
| sub item_changed_selection{ | ||||
| sub item_changed_selection { | ||||
|     my ($self, $obj_idx) = @_; | ||||
| 
 | ||||
| #    $self->{canvas}->Refresh; | ||||
|     if ($self->{canvas3D}) { | ||||
|         Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D}); | ||||
|         if ($obj_idx >= 0){ | ||||
|             my $selections = $self->collect_selections; | ||||
|             Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections); | ||||
|     if (($obj_idx >= 0) && ($obj_idx < 1000)) { # skip if wipe tower selected | ||||
|         if ($self->{canvas3D}) { | ||||
|             Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D}); | ||||
|             if ($obj_idx >= 0) { | ||||
|                 my $selections = $self->collect_selections; | ||||
|                 Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections); | ||||
|             } | ||||
| #            Slic3r::GUI::_3DScene::render($self->{canvas3D}); | ||||
|         } | ||||
|         Slic3r::GUI::_3DScene::render($self->{canvas3D}); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -2359,12 +2394,24 @@ sub selection_changed { | |||
|     } | ||||
|      | ||||
|     Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "layersediting", $layers_height_allowed); | ||||
| 
 | ||||
|     my $can_select_by_parts = 0; | ||||
|      | ||||
|     if ($have_sel) { | ||||
|         my $model_object = $self->{model}->objects->[$obj_idx]; | ||||
|         $can_select_by_parts = ($obj_idx >= 0) && ($obj_idx < 1000) && ($model_object->volumes_count > 1); | ||||
|         Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "fewer", $model_object->instances_count > 1); | ||||
|     } | ||||
|      | ||||
|     if ($can_select_by_parts) { | ||||
|         # first disable to let the item in the toolbar to switch to the unpressed state | ||||
|         Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "selectbyparts", 0); | ||||
|         Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "selectbyparts", 1); | ||||
|     } else { | ||||
|         Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "selectbyparts", 0); | ||||
|         Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'object'); | ||||
|     } | ||||
|          | ||||
|     if ($self->{object_info_size}) { # have we already loaded the info pane? | ||||
|         if ($have_sel) { | ||||
|             my $model_object = $self->{model}->objects->[$obj_idx]; | ||||
|  |  | |||
|  | @ -1,144 +1,18 @@ | |||
| # Status bar at the bottom of the main screen. | ||||
| # Now it just implements cancel cb on perl side, every other functionality is | ||||
| # in C++ | ||||
| 
 | ||||
| package Slic3r::GUI::ProgressStatusBar; | ||||
| package Slic3r::GUI::ProgressStatusBar;  | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| use Wx qw(:gauge :misc); | ||||
| use base 'Wx::StatusBar'; | ||||
| 
 | ||||
| sub new { | ||||
|     my $class = shift; | ||||
|     my $self = $class->SUPER::new(@_); | ||||
|      | ||||
|     $self->{busy} = 0; | ||||
|     $self->{timer} = Wx::Timer->new($self); | ||||
|     $self->{prog} = Wx::Gauge->new($self, wxGA_HORIZONTAL, 100, wxDefaultPosition, wxDefaultSize); | ||||
|     $self->{prog}->Hide; | ||||
|     $self->{cancelbutton} = Wx::Button->new($self, -1, "Cancel", wxDefaultPosition, wxDefaultSize); | ||||
|     $self->{cancelbutton}->Hide; | ||||
|      | ||||
|     $self->SetFieldsCount(3); | ||||
|     $self->SetStatusWidths(-1, 150, 155); | ||||
|      | ||||
|     Wx::Event::EVT_TIMER($self, \&OnTimer, $self->{timer}); | ||||
|     Wx::Event::EVT_SIZE($self, \&OnSize); | ||||
|     Wx::Event::EVT_BUTTON($self, $self->{cancelbutton}, sub { | ||||
|         $self->{cancel_cb}->(); | ||||
|         $self->{cancelbutton}->Hide; | ||||
|     }); | ||||
|      | ||||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| sub DESTROY { | ||||
|     my $self = shift;     | ||||
|     $self->{timer}->Stop if $self->{timer} && $self->{timer}->IsRunning; | ||||
| } | ||||
| 
 | ||||
| sub OnSize { | ||||
|     my ($self, $event) = @_; | ||||
|      | ||||
|     my %fields = ( | ||||
|         # 0 is reserved for status text | ||||
|         1 => $self->{cancelbutton}, | ||||
|         2 => $self->{prog}, | ||||
|     ); | ||||
| 
 | ||||
|     foreach (keys %fields) { | ||||
|         my $rect = $self->GetFieldRect($_); | ||||
|         my $offset = &Wx::wxGTK ? 1 : 0; # add a cosmetic 1 pixel offset on wxGTK | ||||
|         my $pos = [$rect->GetX + $offset, $rect->GetY + $offset]; | ||||
|         $fields{$_}->Move($pos); | ||||
|         $fields{$_}->SetSize($rect->GetWidth - $offset, $rect->GetHeight); | ||||
|     } | ||||
| 
 | ||||
|     $event->Skip; | ||||
| } | ||||
| 
 | ||||
| sub OnTimer { | ||||
|     my ($self, $event) = @_; | ||||
|      | ||||
|     if ($self->{prog}->IsShown) { | ||||
|         $self->{timer}->Stop; | ||||
|     } | ||||
|     $self->{prog}->Pulse if $self->{_busy}; | ||||
| } | ||||
| our $cancel_cb; | ||||
| 
 | ||||
| sub SetCancelCallback { | ||||
|     my $self = shift; | ||||
|     my ($cb) = @_; | ||||
|     $self->{cancel_cb} = $cb; | ||||
|     $cb ? $self->{cancelbutton}->Show : $self->{cancelbutton}->Hide; | ||||
| } | ||||
| 
 | ||||
| sub Run { | ||||
|     my $self = shift; | ||||
|     my $rate = shift || 100; | ||||
|     if (!$self->{timer}->IsRunning) { | ||||
|         $self->{timer}->Start($rate); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| sub GetProgress { | ||||
|     my $self = shift; | ||||
|     return $self->{prog}->GetValue; | ||||
| } | ||||
| 
 | ||||
| sub SetProgress { | ||||
|     my $self = shift; | ||||
|     my ($val) = @_; | ||||
|     if (!$self->{prog}->IsShown) { | ||||
|         $self->ShowProgress(1); | ||||
|     } | ||||
|     if ($val == $self->{prog}->GetRange) { | ||||
|         $self->{prog}->SetValue(0); | ||||
|         $self->ShowProgress(0); | ||||
|     } else { | ||||
|         $self->{prog}->SetValue($val); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| sub SetRange { | ||||
|     my $self = shift; | ||||
|     my ($val) = @_; | ||||
|      | ||||
|     if ($val != $self->{prog}->GetRange) { | ||||
|         $self->{prog}->SetRange($val); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| sub ShowProgress { | ||||
|     my $self = shift; | ||||
|     my ($show) = @_; | ||||
|      | ||||
|     $self->{prog}->Show($show); | ||||
|     $self->{prog}->Pulse; | ||||
| } | ||||
| 
 | ||||
| sub StartBusy { | ||||
|     my $self = shift; | ||||
|     my $rate = shift || 100; | ||||
|      | ||||
|     $self->{_busy} = 1; | ||||
|     $self->ShowProgress(1); | ||||
|     if (!$self->{timer}->IsRunning) { | ||||
|         $self->{timer}->Start($rate); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| sub StopBusy { | ||||
|     my $self = shift; | ||||
|      | ||||
|     $self->{timer}->Stop; | ||||
|     $self->ShowProgress(0); | ||||
|     $self->{prog}->SetValue(0); | ||||
|     $self->{_busy} = 0; | ||||
| } | ||||
| 
 | ||||
| sub IsBusy { | ||||
|     my $self = shift; | ||||
|     return $self->{_busy}; | ||||
|     $cancel_cb = $cb; | ||||
|     $cb ? $self->ShowCancelButton : $self->HideCancelButton; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka