mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into new_main_page_ui
This commit is contained in:
		
						commit
						e0bb6bafd5
					
				
					 153 changed files with 20775 additions and 4724 deletions
				
			
		|  | @ -141,12 +141,12 @@ sub OnInit { | |||
|     $self->CallAfter(sub { | ||||
|         eval { | ||||
|             if (! $self->{preset_updater}->config_update()) { | ||||
|                 exit 0; | ||||
|                 $self->{mainframe}->Close; | ||||
|             } | ||||
|         }; | ||||
|         if ($@) { | ||||
|             warn $@ . "\n"; | ||||
|             fatal_error(undef, $@); | ||||
|             show_error(undef, $@); | ||||
|             $self->{mainframe}->Close; | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|  | @ -169,7 +169,8 @@ sub OnInit { | |||
|         $self->update_ui_from_settings; | ||||
|     }); | ||||
|      | ||||
|     # The following event is emited by PresetUpdater (C++) | ||||
|     # The following event is emited by PresetUpdater (C++) to inform about | ||||
|     # the newer Slic3r application version avaiable online. | ||||
|     EVT_COMMAND($self, -1, $VERSION_ONLINE_EVENT, sub { | ||||
|         my ($self, $event) = @_; | ||||
|         my $version = $event->GetString; | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -19,6 +19,7 @@ use Wx::Locale gettext => 'L'; | |||
| our $qs_last_input_file; | ||||
| our $qs_last_output_file; | ||||
| our $last_config; | ||||
| our $appController; | ||||
| 
 | ||||
| # Events to be sent from a C++ Tab implementation: | ||||
| # 1) To inform about a change of a configuration value. | ||||
|  | @ -39,6 +40,9 @@ sub new { | |||
|          | ||||
|     my $self = $class->SUPER::new(undef, -1, $Slic3r::FORK_NAME . ' - ' . $Slic3r::VERSION, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE); | ||||
|         Slic3r::GUI::set_main_frame($self); | ||||
|      | ||||
|     $appController = Slic3r::AppController->new(); | ||||
| 
 | ||||
|     if ($^O eq 'MSWin32') { | ||||
|         # Load the icon either from the exe, or from the ico file. | ||||
|         my $iconfile = Slic3r::decode_path($FindBin::Bin) . '\slic3r.exe'; | ||||
|  | @ -66,10 +70,21 @@ sub new { | |||
|     eval { Wx::ToolTip::SetAutoPop(32767) }; | ||||
|      | ||||
|     # initialize status bar | ||||
|     $self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new($self, -1); | ||||
|     $self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new($self, Wx::NewId); | ||||
|     $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}); | ||||
| 
 | ||||
|     $self->{plater}->{appController} = $appController; | ||||
| 
 | ||||
|     $self->{loaded} = 1; | ||||
|          | ||||
|     # initialize layout | ||||
|  | @ -120,6 +135,10 @@ sub _init_tabpanel { | |||
|     EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{tabpanel}, sub { | ||||
|         my $panel = $self->{tabpanel}->GetCurrentPage; | ||||
|         $panel->OnActivate if $panel->can('OnActivate'); | ||||
| 
 | ||||
|         for my $tab_name (qw(print filament printer)) { | ||||
|             Slic3r::GUI::get_preset_tab("$tab_name")->OnActivate if ("$tab_name" eq $panel->GetName); | ||||
|         } | ||||
|     }); | ||||
|      | ||||
|     if (!$self->{no_plater}) { | ||||
|  |  | |||
|  | @ -552,8 +552,9 @@ sub BUILD { | |||
|     $sizer->Add($textctrl, 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
|      | ||||
|     EVT_SLIDER($self->parent, $slider, sub { | ||||
|         if (! $self->disable_change_event) { | ||||
|             $self->textctrl->SetLabel($self->get_value); | ||||
|         if (! $self->disable_change_event) {     | ||||
|             # wxTextCtrl::SetLabel() does not work on Linux, use wxTextCtrl::SetValue() instead | ||||
|             $self->textctrl->SetValue($self->get_value); | ||||
|             $self->_on_change($self->option->opt_id); | ||||
|         } | ||||
|     }); | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ use Wx qw(:button :colour :cursor :dialog :filedialog :keycode :icon :font :id : | |||
| use Wx::Event qw(EVT_BUTTON EVT_TOGGLEBUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED  | ||||
|     EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_LEFT_DOWN EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL  | ||||
|     EVT_CHOICE EVT_COMBOBOX EVT_TIMER EVT_NOTEBOOK_PAGE_CHANGED); | ||||
| use Slic3r::Geometry qw(PI); | ||||
| use base 'Wx::Panel'; | ||||
| 
 | ||||
| use constant TB_ADD             => &Wx::NewId; | ||||
|  | @ -44,6 +45,9 @@ our $PROCESS_COMPLETED_EVENT : shared = Wx::NewEventType; | |||
| use constant FILAMENT_CHOOSERS_SPACING => 0; | ||||
| use constant PROCESS_DELAY => 0.5 * 1000; # milliseconds | ||||
| 
 | ||||
| my $PreventListEvents = 0; | ||||
| our $appController; | ||||
| 
 | ||||
| sub new { | ||||
|     my ($class, $parent, %params) = @_; | ||||
|     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||||
|  | @ -120,6 +124,8 @@ sub new { | |||
| 
 | ||||
|         my $model_object = $self->{model}->objects->[$obj_idx]; | ||||
|         my $model_instance = $model_object->instances->[0]; | ||||
| 
 | ||||
|         $self->stop_background_process; | ||||
|          | ||||
|         my $variation = $scale / $model_instance->scaling_factor; | ||||
|         #FIXME Scale the layer height profile? | ||||
|  | @ -128,10 +134,11 @@ sub new { | |||
|             $range->[1] *= $variation; | ||||
|         } | ||||
|         $_->set_scaling_factor($scale) for @{ $model_object->instances }; | ||||
|          | ||||
|         $self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%");         | ||||
|         $object->transform_thumbnail($self->{model}, $obj_idx); | ||||
|      | ||||
|         #update print and start background processing | ||||
|         $self->stop_background_process; | ||||
|         $self->{print}->add_model_object($model_object, $obj_idx); | ||||
|      | ||||
|         $self->selection_changed(1);  # refresh info (size, volume etc.) | ||||
|  | @ -139,6 +146,27 @@ sub new { | |||
|         $self->schedule_background_process; | ||||
|     }; | ||||
|      | ||||
|     # callback to react to gizmo rotate | ||||
|     my $on_gizmo_rotate = sub { | ||||
|         my ($angle_z) = @_; | ||||
|         $self->rotate(rad2deg($angle_z), Z, 'absolute'); | ||||
|     }; | ||||
|      | ||||
|     # callback to update object's geometry info while using gizmos | ||||
|     my $on_update_geometry_info = sub { | ||||
|         my ($size_x, $size_y, $size_z, $scale_factor) = @_; | ||||
|      | ||||
|         my ($obj_idx, $object) = $self->selected_object; | ||||
|      | ||||
|         if ((defined $obj_idx) && ($self->{object_info_size})) { # have we already loaded the info pane? | ||||
|             $self->{object_info_size}->SetLabel(sprintf("%.2f x %.2f x %.2f", $size_x, $size_y, $size_z)); | ||||
|             my $model_object = $self->{model}->objects->[$obj_idx]; | ||||
|             if (my $stats = $model_object->mesh_stats) { | ||||
|                 $self->{object_info_volume}->SetLabel(sprintf('%.2f', $stats->{volume} * $scale_factor**3)); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|      | ||||
|     # Initialize 3D plater | ||||
|     if ($Slic3r::GUI::have_OpenGL) { | ||||
|         $self->{canvas3D} = Slic3r::GUI::Plater::3D->new($self->{preview_notebook}, $self->{objects}, $self->{model}, $self->{print}, $self->{config}); | ||||
|  | @ -157,7 +185,9 @@ sub new { | |||
|         Slic3r::GUI::_3DScene::register_on_instance_moved_callback($self->{canvas3D}, $on_instances_moved); | ||||
|         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::enable_gizmos($self->{canvas3D}, 1); | ||||
|         Slic3r::GUI::_3DScene::register_on_gizmo_rotate_callback($self->{canvas3D}, $on_gizmo_rotate); | ||||
|         Slic3r::GUI::_3DScene::register_on_update_geometry_info_callback($self->{canvas3D}, $on_update_geometry_info); | ||||
|         Slic3r::GUI::_3DScene::enable_gizmos($self->{canvas3D}, 1); | ||||
|         Slic3r::GUI::_3DScene::enable_shader($self->{canvas3D}, 1); | ||||
|         Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($self->{canvas3D}, 1); | ||||
| 
 | ||||
|  | @ -174,7 +204,7 @@ sub new { | |||
|                 $self->schedule_background_process; | ||||
|             } else { | ||||
|                 # Hide the print info box, it is no more valid. | ||||
|                 $self->{"print_info_box_show"}->(0); | ||||
|                 $self->print_info_box_show(0); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|  | @ -192,7 +222,6 @@ sub new { | |||
|     # Initialize 3D toolpaths preview | ||||
|     if ($Slic3r::GUI::have_OpenGL) { | ||||
|         $self->{preview3D} = Slic3r::GUI::Plater::3DPreview->new($self->{preview_notebook}, $self->{print}, $self->{gcode_preview_data}, $self->{config}); | ||||
|         Slic3r::GUI::_3DScene::set_active($self->{preview3D}->canvas, 0); | ||||
|         Slic3r::GUI::_3DScene::enable_legend_texture($self->{preview3D}->canvas, 1); | ||||
|         Slic3r::GUI::_3DScene::register_on_viewport_changed_callback($self->{preview3D}->canvas, sub { Slic3r::GUI::_3DScene::set_viewport_from_scene($self->{canvas3D}, $self->{preview3D}->canvas); }); | ||||
|         $self->{preview_notebook}->AddPage($self->{preview3D}, L('Preview')); | ||||
|  | @ -208,19 +237,12 @@ sub new { | |||
|     EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{preview_notebook}, sub { | ||||
|         my $preview = $self->{preview_notebook}->GetCurrentPage; | ||||
|         if (($preview != $self->{preview3D}) && ($preview != $self->{canvas3D})) { | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{preview3D}->canvas, 0); | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{canvas3D}, 0); | ||||
|             Slic3r::GUI::_3DScene::reset_current_canvas(); | ||||
|             $preview->OnActivate if $preview->can('OnActivate');         | ||||
|         } elsif ($preview == $self->{preview3D}) { | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{preview3D}->canvas, 1); | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{canvas3D}, 0); | ||||
|             $self->{preview3D}->load_print; | ||||
|             $self->{preview3D}->reload_print; | ||||
|             # sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably) | ||||
|             Slic3r::GUI::_3DScene::set_as_dirty($self->{preview3D}->canvas); | ||||
|         } elsif ($preview == $self->{canvas3D}) { | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{canvas3D}, 1); | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{preview3D}->canvas, 0); | ||||
|             if (Slic3r::GUI::_3DScene::is_reload_delayed($self->{canvas3D})) { | ||||
|                 my $selections = $self->collect_selections; | ||||
|                 Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); | ||||
|  | @ -1094,7 +1116,17 @@ sub rotate { | |||
|      | ||||
|     if ($axis == Z) { | ||||
|         my $new_angle = deg2rad($angle); | ||||
|         $_->set_rotation(($relative ? $_->rotation : 0.) + $new_angle) for @{ $model_object->instances }; | ||||
|         foreach my $inst (@{ $model_object->instances }) { | ||||
|             my $rotation = ($relative ? $inst->rotation : 0.) + $new_angle; | ||||
|             while ($rotation > 2.0 * PI) { | ||||
|                 $rotation -= 2.0 * PI; | ||||
|             } | ||||
|             while ($rotation < 0.0) { | ||||
|                 $rotation += 2.0 * PI; | ||||
|             } | ||||
|             $inst->set_rotation($rotation); | ||||
|             Slic3r::GUI::_3DScene::update_gizmos_data($self->{canvas3D}) if ($self->{canvas3D});             | ||||
|         } | ||||
|         $object->transform_thumbnail($self->{model}, $obj_idx); | ||||
|     } else { | ||||
|         # rotation around X and Y needs to be performed on mesh | ||||
|  | @ -1229,13 +1261,17 @@ sub arrange { | |||
|      | ||||
|     $self->pause_background_process; | ||||
|      | ||||
|     my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($self->{config}->bed_shape); | ||||
|     my $success = $self->{model}->arrange_objects(wxTheApp->{preset_bundle}->full_config->min_object_distance, $bb); | ||||
|     # my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($self->{config}->bed_shape); | ||||
|     # my $success = $self->{model}->arrange_objects(wxTheApp->{preset_bundle}->full_config->min_object_distance, $bb); | ||||
|      | ||||
|     # Update is not implemented in C++ so we cannot call this for now | ||||
|     $self->{appController}->arrange_model; | ||||
| 
 | ||||
|     # ignore arrange failures on purpose: user has visual feedback and we don't need to warn him | ||||
|     # when parts don't fit in print bed | ||||
|      | ||||
|     # Force auto center of the aligned grid of of objects on the print bed. | ||||
|     $self->update(1); | ||||
|     $self->update(0); | ||||
| } | ||||
| 
 | ||||
| sub split_object { | ||||
|  | @ -1297,7 +1333,7 @@ sub async_apply_config { | |||
|     $self->{canvas3D}->Refresh if Slic3r::GUI::_3DScene::is_layers_editing_enabled($self->{canvas3D}); | ||||
| 
 | ||||
|     # Hide the slicing results if the current slicing status is no more valid.     | ||||
|     $self->{"print_info_box_show"}->(0) if $invalidated; | ||||
|     $self->print_info_box_show(0) if $invalidated; | ||||
| 
 | ||||
|     if (wxTheApp->{app_config}->get("background_processing")) {     | ||||
|         if ($invalidated) { | ||||
|  | @ -1615,12 +1651,7 @@ sub on_export_completed { | |||
| 
 | ||||
|     $self->{print_file} = undef; | ||||
|     $self->{send_gcode_file} = undef; | ||||
|     $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); | ||||
|     $self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight)); | ||||
|     $self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume)); | ||||
|     $self->{"print_info_time"}->SetLabel($self->{print}->estimated_print_time); | ||||
|     $self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000)); | ||||
|     $self->{"print_info_box_show"}->(1); | ||||
|     $self->print_info_box_show(1); | ||||
| 
 | ||||
|     # this updates buttons status | ||||
|     $self->object_list_changed; | ||||
|  | @ -1630,6 +1661,51 @@ sub on_export_completed { | |||
|     $self->{preview3D}->reload_print if $self->{preview3D}; | ||||
| } | ||||
| 
 | ||||
| # Fill in the "Sliced info" box with the result of the G-code generator. | ||||
| sub print_info_box_show { | ||||
|     my ($self, $show) = @_; | ||||
|     my $scrolled_window_panel = $self->{scrolled_window_panel};  | ||||
|     my $scrolled_window_sizer = $self->{scrolled_window_sizer}; | ||||
|     return if $scrolled_window_sizer->IsShown(2) == $show; | ||||
| 
 | ||||
|     if ($show) { | ||||
|         my $print_info_sizer = $self->{print_info_sizer}; | ||||
|         $print_info_sizer->Clear(1); | ||||
|         my $grid_sizer = Wx::FlexGridSizer->new(2, 2, 5, 5); | ||||
|         $grid_sizer->SetFlexibleDirection(wxHORIZONTAL); | ||||
|         $grid_sizer->AddGrowableCol(1, 1); | ||||
|         $grid_sizer->AddGrowableCol(3, 1); | ||||
|         $print_info_sizer->Add($grid_sizer, 0, wxEXPAND); | ||||
|         my @info = ( | ||||
|             L("Used Filament (m)") | ||||
|                 => sprintf("%.2f" , $self->{print}->total_used_filament / 1000), | ||||
|             L("Used Filament (mm³)") | ||||
|                 => sprintf("%.2f" , $self->{print}->total_extruded_volume), | ||||
|             L("Used Filament (g)"), | ||||
|                 => sprintf("%.2f" , $self->{print}->total_weight), | ||||
|             L("Cost"), | ||||
|                 => sprintf("%.2f" , $self->{print}->total_cost), | ||||
|             L("Estimated printing time (normal mode)") | ||||
|                 => $self->{print}->estimated_normal_print_time, | ||||
|             L("Estimated printing time (silent mode)") | ||||
|                 => $self->{print}->estimated_silent_print_time | ||||
|         ); | ||||
|         while ( my $label = shift @info) { | ||||
|             my $value = shift @info; | ||||
|             next if $value eq "N/A"; | ||||
|             my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); | ||||
|             $text->SetFont($Slic3r::GUI::small_font); | ||||
|             $grid_sizer->Add($text, 0);             | ||||
|             my $field = Wx::StaticText->new($scrolled_window_panel, -1, $value, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); | ||||
|             $field->SetFont($Slic3r::GUI::small_font); | ||||
|             $grid_sizer->Add($field, 0); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     $scrolled_window_sizer->Show(2, $show); | ||||
|     $scrolled_window_panel->Layout; | ||||
| } | ||||
| 
 | ||||
| sub do_print { | ||||
|     my ($self) = @_; | ||||
|      | ||||
|  | @ -1662,7 +1738,7 @@ sub reload_from_disk { | |||
|     my $model_object = $self->{model}->objects->[$obj_idx]; | ||||
|     #FIXME convert to local file encoding | ||||
|     return if !$model_object->input_file | ||||
|         || !-e $model_object->input_file; | ||||
|         || !-e Slic3r::encode_path($model_object->input_file); | ||||
|      | ||||
|     my @new_obj_idx = $self->load_files([$model_object->input_file]); | ||||
|     return if !@new_obj_idx; | ||||
|  | @ -1923,6 +1999,8 @@ sub on_config_change { | |||
|             $update_scheduled = 1; | ||||
|         } elsif ($opt_key eq 'printer_model') { | ||||
|             # update to force bed selection (for texturing) | ||||
|             Slic3r::GUI::_3DScene::set_bed_shape($self->{canvas3D}, $self->{config}->bed_shape) if $self->{canvas3D}; | ||||
|             Slic3r::GUI::_3DScene::set_bed_shape($self->{preview3D}->canvas, $self->{config}->bed_shape) if $self->{preview3D}; | ||||
|             $update_scheduled = 1; | ||||
|         } | ||||
|     } | ||||
|  | @ -2107,7 +2185,8 @@ sub object_list_changed { | |||
| 
 | ||||
|     my $export_in_progress = $self->{export_gcode_output_file} || $self->{send_gcode_file}; | ||||
|     my $model_fits = $self->{canvas3D} ? Slic3r::GUI::_3DScene::check_volumes_outside_state($self->{canvas3D}, $self->{config}) : 1; | ||||
|     my $method = ($have_objects && ! $export_in_progress && $model_fits) ? 'Enable' : 'Disable'; | ||||
|     # $model_fits == 1 -> ModelInstance::PVS_Partly_Outside | ||||
|     my $method = ($have_objects && ! $export_in_progress && ($model_fits != 1)) ? 'Enable' : 'Disable'; | ||||
|     $self->{"btn_$_"}->$method | ||||
|         for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode); | ||||
| } | ||||
|  |  | |||
|  | @ -233,7 +233,6 @@ sub mouse_event { | |||
|     } elsif ($event->LeftUp) { | ||||
|         if ($self->{drag_object}) { | ||||
|             $self->{on_instances_moved}->(); | ||||
|             Slic3r::GUI::_3DScene::reset_current_canvas();             | ||||
|         } | ||||
|         $self->{drag_start_pos} = undef; | ||||
|         $self->{drag_object} = undef; | ||||
|  |  | |||
|  | @ -199,11 +199,11 @@ sub new { | |||
|         my $old_zoom = $self->_zoom; | ||||
|          | ||||
|         # Calculate the zoom delta and apply it to the current zoom factor | ||||
|         my $zoom = $e->GetWheelRotation() / $e->GetWheelDelta(); | ||||
|         my $zoom = -$e->GetWheelRotation() / $e->GetWheelDelta(); | ||||
|         $zoom = max(min($zoom, 4), -4); | ||||
|         $zoom /= 10; | ||||
|         $self->_zoom($self->_zoom / (1-$zoom)); | ||||
|         $self->_zoom(1) if $self->_zoom > 1;  # prevent from zooming out too much | ||||
|         $self->_zoom(1.25) if $self->_zoom > 1.25;  # prevent from zooming out too much | ||||
|          | ||||
|         { | ||||
|             # In order to zoom around the mouse point we need to translate | ||||
|  | @ -227,7 +227,6 @@ sub new { | |||
|         } | ||||
|          | ||||
|         $self->_dirty(1); | ||||
|         $self->Refresh; | ||||
|     }); | ||||
|     EVT_MOUSE_EVENTS($self, \&mouse_event); | ||||
|      | ||||
|  | @ -255,8 +254,8 @@ sub mouse_event { | |||
|     return if !$self->GetParent->enabled; | ||||
|      | ||||
|     my $pos = Slic3r::Pointf->new($e->GetPositionXY); | ||||
|     if ($e->Entering && &Wx::wxMSW) { | ||||
|         # wxMSW needs focus in order to catch mouse wheel events | ||||
|     if ($e->Entering && (&Wx::wxMSW || $^O eq 'linux')) { | ||||
|         # wxMSW and Linux needs focus in order to catch key events | ||||
|         $self->SetFocus; | ||||
|     } elsif ($e->Dragging) { | ||||
|         if ($e->LeftIsDown || $e->MiddleIsDown || $e->RightIsDown) { | ||||
|  | @ -276,7 +275,6 @@ sub mouse_event { | |||
|                 ); | ||||
|                  | ||||
|                 $self->_dirty(1); | ||||
|                 $self->Refresh; | ||||
|             } | ||||
|             $self->_drag_start_xy($pos); | ||||
|         } | ||||
|  | @ -631,6 +629,27 @@ sub Resize { | |||
|     glLoadIdentity(); | ||||
|      | ||||
|     my $bb = $self->bb->clone; | ||||
| 
 | ||||
|     # rescale in dependence of window aspect ratio | ||||
|     my $bb_size = $bb->size;     | ||||
|     my $ratio_x = ($x != 0.0) ? $bb_size->x / $x : 1.0; | ||||
|     my $ratio_y = ($y != 0.0) ? $bb_size->y / $y : 1.0; | ||||
|          | ||||
|     if ($ratio_y < $ratio_x) { | ||||
|         if ($ratio_y != 0.0) { | ||||
|             my $new_size_y = $bb_size->y * $ratio_x / $ratio_y; | ||||
|             my $half_delta_size_y = 0.5 * ($new_size_y - $bb_size->y);         | ||||
|             $bb->set_y_min($bb->y_min - $half_delta_size_y); | ||||
|             $bb->set_y_max($bb->y_max + $half_delta_size_y); | ||||
|         } | ||||
|     } elsif ($ratio_x < $ratio_y) { | ||||
|         if ($ratio_x != 0.0) { | ||||
|             my $new_size_x = $bb_size->x * $ratio_y / $ratio_x; | ||||
|             my $half_delta_size_x = 0.5 * ($new_size_x - $bb_size->x);         | ||||
|             $bb->set_x_min($bb->x_min - $half_delta_size_x); | ||||
|             $bb->set_x_max($bb->x_max + $half_delta_size_x); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     # center bounding box around origin before scaling it | ||||
|     my $bb_center = $bb->center; | ||||
|  | @ -645,25 +664,25 @@ sub Resize { | |||
|     # translate camera | ||||
|     $bb->translate(@{$self->_camera_target}); | ||||
|      | ||||
|     # keep camera_bb within total bb | ||||
|     # (i.e. prevent user from panning outside the bounding box) | ||||
|     { | ||||
|         my @translate = (0,0); | ||||
|         if ($bb->x_min < $self->bb->x_min) { | ||||
|             $translate[X] += $self->bb->x_min - $bb->x_min; | ||||
|         } | ||||
|         if ($bb->y_min < $self->bb->y_min) { | ||||
|             $translate[Y] += $self->bb->y_min - $bb->y_min; | ||||
|         } | ||||
|         if ($bb->x_max > $self->bb->x_max) { | ||||
|             $translate[X] -= $bb->x_max - $self->bb->x_max; | ||||
|         } | ||||
|         if ($bb->y_max > $self->bb->y_max) { | ||||
|             $translate[Y] -= $bb->y_max - $self->bb->y_max; | ||||
|         } | ||||
|         $self->_camera_target->translate(@translate); | ||||
|         $bb->translate(@translate); | ||||
|     } | ||||
| #    # keep camera_bb within total bb | ||||
| #    # (i.e. prevent user from panning outside the bounding box) | ||||
| #    { | ||||
| #        my @translate = (0,0); | ||||
| #        if ($bb->x_min < $self->bb->x_min) { | ||||
| #            $translate[X] += $self->bb->x_min - $bb->x_min; | ||||
| #        } | ||||
| #        if ($bb->y_min < $self->bb->y_min) { | ||||
| #            $translate[Y] += $self->bb->y_min - $bb->y_min; | ||||
| #        } | ||||
| #        if ($bb->x_max > $self->bb->x_max) { | ||||
| #            $translate[X] -= $bb->x_max - $self->bb->x_max; | ||||
| #        } | ||||
| #        if ($bb->y_max > $self->bb->y_max) { | ||||
| #            $translate[Y] -= $bb->y_max - $self->bb->y_max; | ||||
| #        } | ||||
| #        $self->_camera_target->translate(@translate); | ||||
| #        $bb->translate(@translate); | ||||
| #    } | ||||
|      | ||||
|     # save camera | ||||
|     $self->_camera_bb($bb); | ||||
|  |  | |||
|  | @ -5,25 +5,13 @@ use utf8; | |||
| 
 | ||||
| use List::Util qw(); | ||||
| use Wx qw(:misc :pen :brush :sizer :font :cursor :keycode wxTAB_TRAVERSAL); | ||||
| #============================================================================================================================== | ||||
| #use Wx::Event qw(EVT_KEY_DOWN EVT_CHAR); | ||||
| #============================================================================================================================== | ||||
| use base qw(Slic3r::GUI::3DScene Class::Accessor); | ||||
| 
 | ||||
| #============================================================================================================================== | ||||
| #use Wx::Locale gettext => 'L'; | ||||
| # | ||||
| #__PACKAGE__->mk_accessors(qw( | ||||
| #    on_arrange on_rotate_object_left on_rotate_object_right on_scale_object_uniformly | ||||
| #    on_remove_object on_increase_objects on_decrease_objects on_enable_action_buttons)); | ||||
| #============================================================================================================================== | ||||
| 
 | ||||
| sub new { | ||||
|     my $class = shift; | ||||
|     my ($parent, $objects, $model, $print, $config) = @_; | ||||
|      | ||||
|     my $self = $class->SUPER::new($parent); | ||||
| #============================================================================================================================== | ||||
|     Slic3r::GUI::_3DScene::enable_picking($self, 1); | ||||
|     Slic3r::GUI::_3DScene::enable_moving($self, 1); | ||||
|     Slic3r::GUI::_3DScene::set_select_by($self, 'object'); | ||||
|  | @ -31,253 +19,8 @@ sub new { | |||
|     Slic3r::GUI::_3DScene::set_model($self, $model); | ||||
|     Slic3r::GUI::_3DScene::set_print($self, $print); | ||||
|     Slic3r::GUI::_3DScene::set_config($self, $config); | ||||
| #    $self->enable_picking(1); | ||||
| #    $self->enable_moving(1); | ||||
| #    $self->select_by('object'); | ||||
| #    $self->drag_by('instance'); | ||||
| #     | ||||
| #    $self->{objects}            = $objects; | ||||
| #    $self->{model}              = $model; | ||||
| #    $self->{print}              = $print; | ||||
| #    $self->{config}             = $config; | ||||
| #    $self->{on_select_object}   = sub {}; | ||||
| #    $self->{on_instances_moved} = sub {}; | ||||
| #    $self->{on_wipe_tower_moved} = sub {}; | ||||
| # | ||||
| #    $self->{objects_volumes_idxs} = []; | ||||
| # | ||||
| #    $self->on_select(sub { | ||||
| #        my ($volume_idx) = @_; | ||||
| #        $self->{on_select_object}->(($volume_idx == -1) ? undef : $self->volumes->[$volume_idx]->object_idx) | ||||
| #            if ($self->{on_select_object}); | ||||
| #    }); | ||||
| # | ||||
| #    $self->on_move(sub { | ||||
| #        my @volume_idxs = @_; | ||||
| #        my %done = ();  # prevent moving instances twice | ||||
| #        my $object_moved; | ||||
| #        my $wipe_tower_moved; | ||||
| #        foreach my $volume_idx (@volume_idxs) { | ||||
| #            my $volume = $self->volumes->[$volume_idx]; | ||||
| #            my $obj_idx = $volume->object_idx; | ||||
| #            my $instance_idx = $volume->instance_idx; | ||||
| #            next if $done{"${obj_idx}_${instance_idx}"}; | ||||
| #            $done{"${obj_idx}_${instance_idx}"} = 1; | ||||
| #            if ($obj_idx < 1000) { | ||||
| #                # Move a regular object. | ||||
| #                my $model_object = $self->{model}->get_object($obj_idx); | ||||
| #                $model_object | ||||
| #                    ->instances->[$instance_idx] | ||||
| #                    ->offset | ||||
| #                    ->translate($volume->origin->x, $volume->origin->y); #)) | ||||
| #                $model_object->invalidate_bounding_box; | ||||
| #                $object_moved = 1; | ||||
| #            } elsif ($obj_idx == 1000) { | ||||
| #                # Move a wipe tower proxy. | ||||
| #                $wipe_tower_moved = $volume->origin; | ||||
| #            } | ||||
| #        } | ||||
| #         | ||||
| #        $self->{on_instances_moved}->() | ||||
| #            if $object_moved && $self->{on_instances_moved}; | ||||
| #        $self->{on_wipe_tower_moved}->($wipe_tower_moved) | ||||
| #            if $wipe_tower_moved && $self->{on_wipe_tower_moved}; | ||||
| #    }); | ||||
| # | ||||
| #    EVT_KEY_DOWN($self, sub { | ||||
| #        my ($s, $event) = @_; | ||||
| #        if ($event->HasModifiers) { | ||||
| #            $event->Skip; | ||||
| #        } else { | ||||
| #            my $key = $event->GetKeyCode; | ||||
| #            if ($key == WXK_DELETE) { | ||||
| #                $self->on_remove_object->() if $self->on_remove_object; | ||||
| #            } else { | ||||
| #                $event->Skip; | ||||
| #            } | ||||
| #        } | ||||
| #    }); | ||||
| # | ||||
| #    EVT_CHAR($self, sub { | ||||
| #        my ($s, $event) = @_; | ||||
| #        if ($event->HasModifiers) { | ||||
| #            $event->Skip; | ||||
| #        } else { | ||||
| #            my $key = $event->GetKeyCode; | ||||
| #            if ($key == ord('a')) { | ||||
| #                $self->on_arrange->() if $self->on_arrange; | ||||
| #            } elsif ($key == ord('l')) { | ||||
| #                $self->on_rotate_object_left->() if $self->on_rotate_object_left; | ||||
| #            } elsif ($key == ord('r')) { | ||||
| #                $self->on_rotate_object_right->() if $self->on_rotate_object_right; | ||||
| #            } elsif ($key == ord('s')) { | ||||
| #                $self->on_scale_object_uniformly->() if $self->on_scale_object_uniformly; | ||||
| #            } elsif ($key == ord('+')) { | ||||
| #                $self->on_increase_objects->() if $self->on_increase_objects; | ||||
| #            } elsif ($key == ord('-')) { | ||||
| #                $self->on_decrease_objects->() if $self->on_decrease_objects; | ||||
| #            } else { | ||||
| #                $event->Skip; | ||||
| #            } | ||||
| #        } | ||||
| #    }); | ||||
| #============================================================================================================================== | ||||
|      | ||||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| #============================================================================================================================== | ||||
| #sub set_on_select_object { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->{on_select_object} = $cb; | ||||
| #} | ||||
| # | ||||
| #sub set_on_double_click { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_double_click($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_right_click { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_right_click($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_arrange { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_arrange($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_rotate_object_left { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_rotate_object_left($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_rotate_object_right { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_rotate_object_right($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_scale_object_uniformly { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_scale_object_uniformly($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_increase_objects { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_increase_objects($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_decrease_objects { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_decrease_objects($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_remove_object { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_remove_object($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_instances_moved { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->{on_instances_moved} = $cb; | ||||
| #} | ||||
| # | ||||
| #sub set_on_wipe_tower_moved { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->{on_wipe_tower_moved} = $cb; | ||||
| #} | ||||
| # | ||||
| #sub set_on_model_update { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_model_update($cb); | ||||
| #} | ||||
| # | ||||
| #sub set_on_enable_action_buttons { | ||||
| #    my ($self, $cb) = @_; | ||||
| #    $self->on_enable_action_buttons($cb); | ||||
| #} | ||||
| # | ||||
| #sub update_volumes_selection { | ||||
| #    my ($self) = @_; | ||||
| # | ||||
| #    foreach my $obj_idx (0..$#{$self->{model}->objects}) { | ||||
| #        if ($self->{objects}[$obj_idx]->selected) { | ||||
| #            my $volume_idxs = $self->{objects_volumes_idxs}->[$obj_idx]; | ||||
| #            $self->select_volume($_) for @{$volume_idxs}; | ||||
| #        } | ||||
| #    } | ||||
| #} | ||||
| # | ||||
| #sub reload_scene { | ||||
| #    my ($self, $force) = @_; | ||||
| # | ||||
| #    $self->reset_objects; | ||||
| #    $self->update_bed_size; | ||||
| # | ||||
| #    if (! $self->IsShown && ! $force) { | ||||
| #        $self->{reload_delayed} = 1; | ||||
| #        return; | ||||
| #    } | ||||
| # | ||||
| #    $self->{reload_delayed} = 0; | ||||
| # | ||||
| #    $self->{objects_volumes_idxs} = [];     | ||||
| #    foreach my $obj_idx (0..$#{$self->{model}->objects}) { | ||||
| #        my @volume_idxs = $self->load_object($self->{model}, $self->{print}, $obj_idx); | ||||
| #        push(@{$self->{objects_volumes_idxs}}, \@volume_idxs); | ||||
| #    } | ||||
| #     | ||||
| #    $self->update_volumes_selection; | ||||
| #         | ||||
| #    if (defined $self->{config}->nozzle_diameter) { | ||||
| #        # Should the wipe tower be visualized? | ||||
| #        my $extruders_count = scalar @{ $self->{config}->nozzle_diameter }; | ||||
| #        # Height of a print. | ||||
| #        my $height = $self->{model}->bounding_box->z_max; | ||||
| #        # Show at least a slab. | ||||
| #        $height = 10 if $height < 10; | ||||
| #        if ($extruders_count > 1 && $self->{config}->single_extruder_multi_material && $self->{config}->wipe_tower && | ||||
| #            ! $self->{config}->complete_objects) { | ||||
| #            $self->volumes->load_wipe_tower_preview(1000,  | ||||
| #                $self->{config}->wipe_tower_x, $self->{config}->wipe_tower_y, $self->{config}->wipe_tower_width, | ||||
| #		#$self->{config}->wipe_tower_per_color_wipe# 15 * ($extruders_count - 1), # this is just a hack when the config parameter became obsolete | ||||
| #		15 * ($extruders_count - 1), | ||||
| #                $self->{model}->bounding_box->z_max, $self->{config}->wipe_tower_rotation_angle, $self->UseVBOs); | ||||
| #        } | ||||
| #    } | ||||
| # | ||||
| #    $self->update_volumes_colors_by_extruder($self->{config}); | ||||
| #     | ||||
| #    # checks for geometry outside the print volume to render it accordingly | ||||
| #    if (scalar @{$self->volumes} > 0) | ||||
| #    { | ||||
| #        my $contained = $self->volumes->check_outside_state($self->{config}); | ||||
| #        if (!$contained) { | ||||
| #            $self->set_warning_enabled(1); | ||||
| #            Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume")); | ||||
| #            $self->on_enable_action_buttons->(0) if ($self->on_enable_action_buttons); | ||||
| #        } else { | ||||
| #            $self->set_warning_enabled(0); | ||||
| #            $self->volumes->reset_outside_state(); | ||||
| #            Slic3r::GUI::_3DScene::reset_warning_texture(); | ||||
| #            $self->on_enable_action_buttons->(scalar @{$self->{model}->objects} > 0) if ($self->on_enable_action_buttons); | ||||
| #        } | ||||
| #    } else { | ||||
| #        $self->set_warning_enabled(0); | ||||
| #        Slic3r::GUI::_3DScene::reset_warning_texture(); | ||||
| #    } | ||||
| #} | ||||
| # | ||||
| #sub update_bed_size { | ||||
| #    my ($self) = @_; | ||||
| #    $self->set_bed_shape($self->{config}->bed_shape); | ||||
| #} | ||||
| # | ||||
| ## Called by the Platter wxNotebook when this page is activated. | ||||
| #sub OnActivate { | ||||
| #    my ($self) = @_; | ||||
| #    $self->reload_scene(1) if ($self->{reload_delayed}); | ||||
| #} | ||||
| #============================================================================================================================== | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
|  | @ -322,7 +322,13 @@ sub selection_changed { | |||
|         } | ||||
|         # get default values | ||||
|         my $default_config = Slic3r::Config::new_from_defaults_keys(\@opt_keys); | ||||
|          | ||||
| 
 | ||||
|        # decide which settings will be shown by default | ||||
|         if ($itemData->{type} eq 'object') { | ||||
|             $config->set_ifndef('wipe_into_objects', 0); | ||||
|             $config->set_ifndef('wipe_into_infill', 0); | ||||
|         } | ||||
| 
 | ||||
|         # append default extruder | ||||
|         push @opt_keys, 'extruder'; | ||||
|         $default_config->set('extruder', 0); | ||||
|  | @ -330,7 +336,14 @@ sub selection_changed { | |||
|         $self->{settings_panel}->set_default_config($default_config); | ||||
|         $self->{settings_panel}->set_config($config); | ||||
|         $self->{settings_panel}->set_opt_keys(\@opt_keys); | ||||
|         $self->{settings_panel}->set_fixed_options([qw(extruder)]); | ||||
| 
 | ||||
|         # disable minus icon to remove the settings | ||||
|         if ($itemData->{type} eq 'object') { | ||||
|             $self->{settings_panel}->set_fixed_options([qw(extruder), qw(wipe_into_infill), qw(wipe_into_objects)]); | ||||
| 	} else { | ||||
|             $self->{settings_panel}->set_fixed_options([qw(extruder)]); | ||||
|         } | ||||
| 
 | ||||
|         $self->{settings_panel}->enable; | ||||
|     } | ||||
|      | ||||
|  |  | |||
|  | @ -101,7 +101,12 @@ sub export_gcode { | |||
|                 die "The configured post-processing script is not executable: check permissions. ($script)\n"; | ||||
|             } | ||||
|             if ($^O eq 'MSWin32' && $script =~ /\.[pP][lL]/) { | ||||
|                 system($^X, $script, $output_file); | ||||
|                 # The current process (^X) may be slic3r.exe or slic3r-console.exe. | ||||
|                 # Replace it with the current perl interpreter. | ||||
|                 my($filename, $directories, $suffix) = fileparse($^X); | ||||
|                 $filename =~ s/^slic3r.*$/perl5\.24\.0\.exe/; | ||||
|                 my $interpreter = $directories . $filename; | ||||
|                 system($interpreter, $script, $output_file); | ||||
|             } else { | ||||
|                 system($script, $output_file); | ||||
|             } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka