mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11:15 -06:00 
			
		
		
		
	Merge remote-tracking branch 'remotes/origin/opengl_to_cpp'
This commit is contained in:
		
						commit
						5a56f08aad
					
				
					 49 changed files with 10551 additions and 3604 deletions
				
			
		
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -28,9 +28,9 @@ our $PRESETS_CHANGED_EVENT = Wx::NewEventType; | |||
| 
 | ||||
| sub new { | ||||
|     my ($class, %params) = @_; | ||||
|      | ||||
|          | ||||
|     my $self = $class->SUPER::new(undef, -1, $Slic3r::FORK_NAME . ' - ' . $Slic3r::VERSION, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE); | ||||
|     Slic3r::GUI::set_main_frame($self); | ||||
|         Slic3r::GUI::set_main_frame($self); | ||||
|     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'; | ||||
|  | @ -39,7 +39,7 @@ sub new { | |||
|     } else { | ||||
|         $self->SetIcon(Wx::Icon->new(Slic3r::var("Slic3r_128px.png"), wxBITMAP_TYPE_PNG));         | ||||
|     } | ||||
|      | ||||
|          | ||||
|     # store input params | ||||
|     # If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden. | ||||
|     $self->{no_controller} = $params{no_controller}; | ||||
|  | @ -47,7 +47,7 @@ sub new { | |||
|     $self->{loaded} = 0; | ||||
|     $self->{lang_ch_event} = $params{lang_ch_event}; | ||||
|     $self->{preferences_event} = $params{preferences_event}; | ||||
| 
 | ||||
|      | ||||
|     # initialize tabpanel and menubar | ||||
|     $self->_init_tabpanel; | ||||
|     $self->_init_menubar; | ||||
|  | @ -63,7 +63,7 @@ sub new { | |||
|     $self->SetStatusBar($self->{statusbar}); | ||||
|      | ||||
|     $self->{loaded} = 1; | ||||
|      | ||||
|          | ||||
|     # initialize layout | ||||
|     { | ||||
|         my $sizer = Wx::BoxSizer->new(wxVERTICAL); | ||||
|  | @ -90,6 +90,8 @@ sub new { | |||
|         # Save the slic3r.ini. Usually the ini file is saved from "on idle" callback, | ||||
|         # but in rare cases it may not have been called yet. | ||||
|         wxTheApp->{app_config}->save; | ||||
|         $self->{plater}->{print} = undef if($self->{plater}); | ||||
|         Slic3r::GUI::_3DScene::remove_all_canvases(); | ||||
|         # propagate event | ||||
|         $event->Skip; | ||||
|     }); | ||||
|  |  | |||
|  | @ -78,19 +78,19 @@ sub new { | |||
|     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 < 1000) ? $obj_idx : undef); | ||||
|         $self->select_object((defined($obj_idx) && $obj_idx >= 0 && $obj_idx < 1000) ? $obj_idx : undef); | ||||
|     }; | ||||
|     my $on_double_click = sub { | ||||
|         $self->object_settings_dialog if $self->selected_object; | ||||
|     }; | ||||
|     my $on_right_click = sub { | ||||
|         my ($canvas, $click_pos) = @_; | ||||
|          | ||||
|         my ($canvas, $click_pos_x, $click_pos_y) = @_; | ||||
| 
 | ||||
|         my ($obj_idx, $object) = $self->selected_object; | ||||
|         return if !defined $obj_idx; | ||||
|          | ||||
|         my $menu = $self->object_menu; | ||||
|         $canvas->PopupMenu($menu, $click_pos); | ||||
|         $canvas->PopupMenu($menu, $click_pos_x, $click_pos_y); | ||||
|         $menu->Destroy; | ||||
|     }; | ||||
|     my $on_instances_moved = sub { | ||||
|  | @ -105,32 +105,65 @@ sub new { | |||
|         $self->{btn_print}->Enable($enable); | ||||
|         $self->{btn_send_gcode}->Enable($enable); | ||||
|     }; | ||||
| 
 | ||||
|     # callback to react to gizmo scale | ||||
|     my $on_gizmo_scale_uniformly = sub { | ||||
|         my ($scale) = @_; | ||||
| 
 | ||||
|         my ($obj_idx, $object) = $self->selected_object; | ||||
|         return if !defined $obj_idx; | ||||
| 
 | ||||
|         my $model_object = $self->{model}->objects->[$obj_idx]; | ||||
|         my $model_instance = $model_object->instances->[0]; | ||||
|          | ||||
|         my $variation = $scale / $model_instance->scaling_factor; | ||||
|         #FIXME Scale the layer height profile? | ||||
|         foreach my $range (@{ $model_object->layer_height_ranges }) { | ||||
|             $range->[0] *= $variation; | ||||
|             $range->[1] *= $variation; | ||||
|         } | ||||
|         $_->set_scaling_factor($scale) for @{ $model_object->instances }; | ||||
|         $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.) | ||||
|         $self->update; | ||||
|         $self->schedule_background_process; | ||||
|     }; | ||||
|      | ||||
|     # 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}); | ||||
|         $self->{preview_notebook}->AddPage($self->{canvas3D}, L('3D')); | ||||
|         $self->{canvas3D}->set_on_select_object($on_select_object); | ||||
|         $self->{canvas3D}->set_on_double_click($on_double_click); | ||||
|         $self->{canvas3D}->set_on_right_click(sub { $on_right_click->($self->{canvas3D}, @_); }); | ||||
|         $self->{canvas3D}->set_on_arrange(sub { $self->arrange }); | ||||
|         $self->{canvas3D}->set_on_rotate_object_left(sub { $self->rotate(-45, Z, 'relative') }); | ||||
|         $self->{canvas3D}->set_on_rotate_object_right(sub { $self->rotate( 45, Z, 'relative') }); | ||||
|         $self->{canvas3D}->set_on_scale_object_uniformly(sub { $self->changescale(undef) }); | ||||
|         $self->{canvas3D}->set_on_increase_objects(sub { $self->increase() }); | ||||
|         $self->{canvas3D}->set_on_decrease_objects(sub { $self->decrease() }); | ||||
|         $self->{canvas3D}->set_on_remove_object(sub { $self->remove() }); | ||||
|         $self->{canvas3D}->set_on_instances_moved($on_instances_moved); | ||||
|         $self->{canvas3D}->set_on_enable_action_buttons($enable_action_buttons); | ||||
|         $self->{canvas3D}->use_plain_shader(1); | ||||
|         $self->{canvas3D}->set_on_wipe_tower_moved(sub { | ||||
|             my ($new_pos_3f) = @_; | ||||
|         Slic3r::GUI::_3DScene::register_on_select_object_callback($self->{canvas3D}, $on_select_object); | ||||
|         Slic3r::GUI::_3DScene::register_on_double_click_callback($self->{canvas3D}, $on_double_click); | ||||
|         Slic3r::GUI::_3DScene::register_on_right_click_callback($self->{canvas3D}, sub { $on_right_click->($self->{canvas3D}, @_); }); | ||||
|         Slic3r::GUI::_3DScene::register_on_arrange_callback($self->{canvas3D}, sub { $self->arrange }); | ||||
|         Slic3r::GUI::_3DScene::register_on_rotate_object_left_callback($self->{canvas3D}, sub { $self->rotate(-45, Z, 'relative') }); | ||||
|         Slic3r::GUI::_3DScene::register_on_rotate_object_right_callback($self->{canvas3D}, sub { $self->rotate( 45, Z, 'relative') }); | ||||
|         Slic3r::GUI::_3DScene::register_on_scale_object_uniformly_callback($self->{canvas3D}, sub { $self->changescale(undef) }); | ||||
|         Slic3r::GUI::_3DScene::register_on_increase_objects_callback($self->{canvas3D}, sub { $self->increase() }); | ||||
|         Slic3r::GUI::_3DScene::register_on_decrease_objects_callback($self->{canvas3D}, sub { $self->decrease() }); | ||||
|         Slic3r::GUI::_3DScene::register_on_remove_object_callback($self->{canvas3D}, sub { $self->remove() }); | ||||
|         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::enable_shader($self->{canvas3D}, 1); | ||||
|         Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($self->{canvas3D}, 1); | ||||
| 
 | ||||
|         Slic3r::GUI::_3DScene::register_on_wipe_tower_moved_callback($self->{canvas3D}, sub { | ||||
|             my ($x, $y) = @_; | ||||
|             my $cfg = Slic3r::Config->new; | ||||
|             $cfg->set('wipe_tower_x', $new_pos_3f->x); | ||||
|             $cfg->set('wipe_tower_y', $new_pos_3f->y); | ||||
|             $cfg->set('wipe_tower_x', $x); | ||||
|             $cfg->set('wipe_tower_y', $y); | ||||
|             $self->GetFrame->{options_tabs}{print}->load_config($cfg); | ||||
|         }); | ||||
|         $self->{canvas3D}->set_on_model_update(sub { | ||||
| 
 | ||||
|         Slic3r::GUI::_3DScene::register_on_model_update_callback($self->{canvas3D}, sub { | ||||
|             if (wxTheApp->{app_config}->get("background_processing")) { | ||||
|                 $self->schedule_background_process; | ||||
|             } else { | ||||
|  | @ -138,9 +171,8 @@ sub new { | |||
|                 $self->{"print_info_box_show"}->(0); | ||||
|             } | ||||
|         }); | ||||
|         $self->{canvas3D}->on_viewport_changed(sub { | ||||
|             $self->{preview3D}->canvas->set_viewport_from_scene($self->{canvas3D}); | ||||
|         }); | ||||
| 
 | ||||
|         Slic3r::GUI::_3DScene::register_on_viewport_changed_callback($self->{canvas3D}, sub { Slic3r::GUI::_3DScene::set_viewport_from_scene($self->{preview3D}->canvas, $self->{canvas3D}); }); | ||||
|     } | ||||
|      | ||||
|     # Initialize 2D preview canvas | ||||
|  | @ -154,9 +186,8 @@ 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}); | ||||
|         $self->{preview3D}->canvas->on_viewport_changed(sub { | ||||
|             $self->{canvas3D}->set_viewport_from_scene($self->{preview3D}->canvas); | ||||
|         }); | ||||
|         Slic3r::GUI::_3DScene::set_active($self->{preview3D}->canvas, 0); | ||||
|         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')); | ||||
|         $self->{preview3D_page_idx} = $self->{preview_notebook}->GetPageCount-1; | ||||
|     } | ||||
|  | @ -171,13 +202,25 @@ sub new { | |||
|         my $preview = $self->{preview_notebook}->GetCurrentPage; | ||||
|         if ($preview == $self->{preview3D}) | ||||
|         { | ||||
|             $self->{preview3D}->canvas->set_legend_enabled(1); | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{preview3D}->canvas, 1); | ||||
|             Slic3r::GUI::_3DScene::set_active($self->{canvas3D}, 0); | ||||
|             Slic3r::GUI::_3DScene::enable_legend_texture($self->{preview3D}->canvas, 1); | ||||
|             $self->{preview3D}->load_print(1); | ||||
|         } else { | ||||
|             $self->{preview3D}->canvas->set_legend_enabled(0); | ||||
|             Slic3r::GUI::_3DScene::enable_legend_texture($self->{preview3D}->canvas, 0); | ||||
|         } | ||||
| 
 | ||||
|         $preview->OnActivate if $preview->can('OnActivate');         | ||||
|         if ($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); | ||||
|                 Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1); | ||||
|             }             | ||||
|         } else { | ||||
|             $preview->OnActivate if $preview->can('OnActivate');         | ||||
|         } | ||||
|     }); | ||||
|      | ||||
|     # toolbar for object manipulation | ||||
|  | @ -314,7 +357,7 @@ sub new { | |||
|         EVT_TOOL($self, TB_CUT, sub { $_[0]->object_cut_dialog }); | ||||
|         EVT_TOOL($self, TB_SETTINGS, sub { $_[0]->object_settings_dialog }); | ||||
|         EVT_TOOL($self, TB_LAYER_EDITING, sub { | ||||
|             my $state = $self->{canvas3D}->layer_editing_enabled; | ||||
|             my $state = Slic3r::GUI::_3DScene::is_layers_editing_enabled($self->{canvas3D}); | ||||
|             $self->{htoolbar}->ToggleTool(TB_LAYER_EDITING, ! $state); | ||||
|             $self->on_layer_editing_toggled(! $state); | ||||
|         }); | ||||
|  | @ -369,11 +412,11 @@ sub new { | |||
|      | ||||
|     $self->{canvas}->update_bed_size; | ||||
|     if ($self->{canvas3D}) { | ||||
|         $self->{canvas3D}->update_bed_size; | ||||
|         $self->{canvas3D}->zoom_to_bed; | ||||
|         Slic3r::GUI::_3DScene::set_bed_shape($self->{canvas3D}, $self->{config}->bed_shape); | ||||
|         Slic3r::GUI::_3DScene::zoom_to_bed($self->{canvas3D}); | ||||
|     } | ||||
|     if ($self->{preview3D}) { | ||||
|         $self->{preview3D}->set_bed_shape($self->{config}->bed_shape); | ||||
|         Slic3r::GUI::_3DScene::set_bed_shape($self->{preview3D}->canvas, $self->{config}->bed_shape); | ||||
|     } | ||||
|     $self->update; | ||||
|      | ||||
|  | @ -590,8 +633,8 @@ sub _on_select_preset { | |||
| 
 | ||||
| sub on_layer_editing_toggled { | ||||
|     my ($self, $new_state) = @_; | ||||
|     $self->{canvas3D}->layer_editing_enabled($new_state); | ||||
|     if ($new_state && ! $self->{canvas3D}->layer_editing_enabled) { | ||||
|     Slic3r::GUI::_3DScene::enable_layers_editing($self->{canvas3D}, $new_state); | ||||
|     if ($new_state && ! Slic3r::GUI::_3DScene::is_layers_editing_enabled($self->{canvas3D})) { | ||||
|         # Initialization of the OpenGL shaders failed. Disable the tool. | ||||
|         if ($self->{htoolbar}) { | ||||
|             $self->{htoolbar}->EnableTool(TB_LAYER_EDITING, 0); | ||||
|  | @ -825,8 +868,7 @@ sub load_model_objects { | |||
|     $self->update; | ||||
|      | ||||
|     # zoom to objects | ||||
|     $self->{canvas3D}->zoom_to_volumes | ||||
|         if $self->{canvas3D}; | ||||
|     Slic3r::GUI::_3DScene::zoom_to_volumes($self->{canvas3D}) if $self->{canvas3D}; | ||||
|      | ||||
|     $self->{list}->Update; | ||||
|     $self->{list}->Select($obj_idx[-1], 1); | ||||
|  | @ -1217,8 +1259,7 @@ sub async_apply_config { | |||
|     my $invalidated = $self->{print}->apply_config(wxTheApp->{preset_bundle}->full_config); | ||||
| 
 | ||||
|     # Just redraw the 3D canvas without reloading the scene. | ||||
| #    $self->{canvas3D}->Refresh if ($invalidated && $self->{canvas3D}->layer_editing_enabled); | ||||
|     $self->{canvas3D}->Refresh if ($self->{canvas3D}->layer_editing_enabled); | ||||
|     $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; | ||||
|  | @ -1751,7 +1792,9 @@ sub update { | |||
|     } | ||||
| 
 | ||||
|     $self->{canvas}->reload_scene if $self->{canvas}; | ||||
|     $self->{canvas3D}->reload_scene if $self->{canvas3D}; | ||||
|     my $selections = $self->collect_selections; | ||||
|     Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); | ||||
|     Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 0); | ||||
|     $self->{preview3D}->reset_gcode_preview_data if $self->{preview3D}; | ||||
|     $self->{preview3D}->reload_print if $self->{preview3D}; | ||||
| } | ||||
|  | @ -1806,9 +1849,8 @@ sub on_config_change { | |||
|         $self->{config}->set($opt_key, $config->get($opt_key)); | ||||
|         if ($opt_key eq 'bed_shape') { | ||||
|             $self->{canvas}->update_bed_size; | ||||
|             $self->{canvas3D}->update_bed_size if $self->{canvas3D}; | ||||
|             $self->{preview3D}->set_bed_shape($self->{config}->bed_shape) | ||||
|                 if $self->{preview3D}; | ||||
|             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; | ||||
|         } elsif ($opt_key =~ '^wipe_tower' || $opt_key eq 'single_extruder_multi_material') { | ||||
|             $update_scheduled = 1; | ||||
|  | @ -1827,10 +1869,10 @@ sub on_config_change { | |||
|                     $self->{"btn_layer_editing"}->Disable; | ||||
|                     $self->{"btn_layer_editing"}->SetValue(0); | ||||
|                 } | ||||
|                 $self->{canvas3D}->layer_editing_enabled(0); | ||||
|                 Slic3r::GUI::_3DScene::enable_layers_editing($self->{canvas3D}, 0); | ||||
|                 $self->{canvas3D}->Refresh; | ||||
|                 $self->{canvas3D}->Update; | ||||
|             } elsif ($self->{canvas3D}->layer_editing_allowed) { | ||||
|             } elsif (Slic3r::GUI::_3DScene::is_layers_editing_allowed($self->{canvas3D})) { | ||||
|                 # Want to allow the layer editing, but do it only if the OpenGL supports it. | ||||
|                 if ($self->{htoolbar}) { | ||||
|                     $self->{htoolbar}->EnableTool(TB_LAYER_EDITING, 1); | ||||
|  | @ -1862,8 +1904,8 @@ sub list_item_deselected { | |||
|     if ($self->{list}->GetFirstSelected == -1) { | ||||
|         $self->select_object(undef); | ||||
|         $self->{canvas}->Refresh; | ||||
|         $self->{canvas3D}->deselect_volumes if $self->{canvas3D}; | ||||
|         $self->{canvas3D}->Render if $self->{canvas3D}; | ||||
|         Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D}) if $self->{canvas3D}; | ||||
|         Slic3r::GUI::_3DScene::render($self->{canvas3D}) if $self->{canvas3D}; | ||||
|     } | ||||
|     undef $self->{_lecursor}; | ||||
| } | ||||
|  | @ -1875,11 +1917,23 @@ sub list_item_selected { | |||
|     my $obj_idx = $event->GetIndex; | ||||
|     $self->select_object($obj_idx); | ||||
|     $self->{canvas}->Refresh; | ||||
|     $self->{canvas3D}->update_volumes_selection if $self->{canvas3D}; | ||||
|     $self->{canvas3D}->Render if $self->{canvas3D}; | ||||
|     if ($self->{canvas3D}) { | ||||
|         my $selections = $self->collect_selections; | ||||
|         Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections); | ||||
|         Slic3r::GUI::_3DScene::render($self->{canvas3D}); | ||||
|     } | ||||
|     undef $self->{_lecursor}; | ||||
| } | ||||
| 
 | ||||
| sub collect_selections { | ||||
|     my ($self) = @_; | ||||
|     my $selections = []; | ||||
|     foreach my $o (@{$self->{objects}}) { | ||||
|         push(@$selections, $o->selected); | ||||
|     }             | ||||
|     return $selections; | ||||
| } | ||||
| 
 | ||||
| sub list_item_activated { | ||||
|     my ($self, $event, $obj_idx) = @_; | ||||
|      | ||||
|  | @ -1936,7 +1990,7 @@ sub object_cut_dialog { | |||
| 	    $self->remove($obj_idx); | ||||
| 	    $self->load_model_objects(grep defined($_), @new_objects); | ||||
| 	    $self->arrange; | ||||
|         $self->{canvas3D}->zoom_to_volumes if $self->{canvas3D}; | ||||
|         Slic3r::GUI::_3DScene::zoom_to_volumes($self->{canvas3D}) if $self->{canvas3D}; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -1972,7 +2026,9 @@ sub object_settings_dialog { | |||
|         $self->{print}->reload_object($obj_idx); | ||||
|         $self->schedule_background_process; | ||||
|         $self->{canvas}->reload_scene if $self->{canvas}; | ||||
|         $self->{canvas3D}->reload_scene if $self->{canvas3D}; | ||||
|         my $selections = $self->collect_selections; | ||||
|         Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); | ||||
|         Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 0); | ||||
|     } else { | ||||
|         $self->resume_background_process; | ||||
|     } | ||||
|  | @ -1985,7 +2041,7 @@ sub object_list_changed { | |||
|          | ||||
|     # Enable/disable buttons depending on whether there are any objects on the platter. | ||||
|     my $have_objects = @{$self->{objects}} ? 1 : 0; | ||||
|     my $variable_layer_height_allowed = $self->{config}->variable_layer_height && $self->{canvas3D}->layer_editing_allowed; | ||||
|     my $variable_layer_height_allowed = $self->{config}->variable_layer_height && Slic3r::GUI::_3DScene::is_layers_editing_allowed($self->{canvas3D}); | ||||
|     if ($self->{htoolbar}) { | ||||
|         # On OSX or Linux | ||||
|         $self->{htoolbar}->EnableTool($_, $have_objects) | ||||
|  | @ -2000,7 +2056,7 @@ sub object_list_changed { | |||
|     } | ||||
| 
 | ||||
|     my $export_in_progress = $self->{export_gcode_output_file} || $self->{send_gcode_file}; | ||||
|     my $model_fits = $self->{canvas3D} ? $self->{canvas3D}->volumes->check_outside_state($self->{config}) : 1; | ||||
|     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'; | ||||
|     $self->{"btn_$_"}->$method | ||||
|         for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode); | ||||
|  | @ -2220,11 +2276,11 @@ sub select_view { | |||
|     my $idx_page = $self->{preview_notebook}->GetSelection; | ||||
|     my $page = ($idx_page == &Wx::wxNOT_FOUND) ? L('3D') : $self->{preview_notebook}->GetPageText($idx_page); | ||||
|     if ($page eq L('Preview')) { | ||||
|         $self->{preview3D}->canvas->select_view($direction); | ||||
|         $self->{canvas3D}->set_viewport_from_scene($self->{preview3D}->canvas); | ||||
|         Slic3r::GUI::_3DScene::select_view($self->{preview3D}->canvas, $direction); | ||||
|         Slic3r::GUI::_3DScene::set_viewport_from_scene($self->{canvas3D}, $self->{preview3D}->canvas); | ||||
|     } else { | ||||
|         $self->{canvas3D}->select_view($direction); | ||||
|         $self->{preview3D}->canvas->set_viewport_from_scene($self->{canvas3D}); | ||||
|         Slic3r::GUI::_3DScene::select_view($self->{canvas3D}, $direction); | ||||
|         Slic3r::GUI::_3DScene::set_viewport_from_scene($self->{preview3D}->canvas, $self->{canvas3D}); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -222,7 +222,7 @@ sub mouse_event { | |||
|                         ]; | ||||
|                         $self->{drag_object} = [ $obj_idx, $instance_idx ]; | ||||
|                     } elsif ($event->RightDown) { | ||||
|                         $self->{on_right_click}->($pos); | ||||
|                         $self->{on_right_click}->($pos->x, $pos->y); | ||||
|                     } | ||||
|                      | ||||
|                     last OBJECTS; | ||||
|  |  | |||
|  | @ -5,264 +5,279 @@ 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 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)); | ||||
| #============================================================================================================================== | ||||
| #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); | ||||
|     $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; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| #============================================================================================================================== | ||||
|     Slic3r::GUI::_3DScene::enable_picking($self, 1); | ||||
|     Slic3r::GUI::_3DScene::enable_moving($self, 1); | ||||
|     Slic3r::GUI::_3DScene::set_select_by($self, 'object'); | ||||
|     Slic3r::GUI::_3DScene::set_drag_by($self, 'instance'); | ||||
|     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}); | ||||
| } | ||||
| #============================================================================================================================== | ||||
| #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; | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ sub new { | |||
| 
 | ||||
|     # init GUI elements | ||||
|     my $canvas = Slic3r::GUI::3DScene->new($self); | ||||
|     $canvas->use_plain_shader(1); | ||||
|     Slic3r::GUI::_3DScene::enable_shader($canvas, 1); | ||||
|     $self->canvas($canvas); | ||||
|     my $slider_low = Wx::Slider->new( | ||||
|         $self, -1, | ||||
|  | @ -277,8 +277,8 @@ sub new { | |||
| 
 | ||||
| sub reload_print { | ||||
|     my ($self, $force) = @_; | ||||
|      | ||||
|     $self->canvas->reset_objects; | ||||
| 
 | ||||
|     Slic3r::GUI::_3DScene::reset_volumes($self->canvas); | ||||
|     $self->_loaded(0); | ||||
| 
 | ||||
|     if (! $self->IsShown && ! $force) { | ||||
|  | @ -304,7 +304,7 @@ sub refresh_print { | |||
| sub reset_gcode_preview_data { | ||||
|     my ($self) = @_; | ||||
|     $self->gcode_preview_data->reset; | ||||
|     $self->canvas->reset_legend_texture(); | ||||
|     Slic3r::GUI::_3DScene::reset_legend_texture(); | ||||
| } | ||||
| 
 | ||||
| sub load_print { | ||||
|  | @ -329,7 +329,7 @@ sub load_print { | |||
| 
 | ||||
|     if ($n_layers == 0) { | ||||
|         $self->reset_sliders; | ||||
|         $self->canvas->reset_legend_texture(); | ||||
|         Slic3r::GUI::_3DScene::reset_legend_texture(); | ||||
|         $self->canvas->Refresh;  # clears canvas | ||||
|         return; | ||||
|     } | ||||
|  | @ -364,23 +364,25 @@ sub load_print { | |||
| 
 | ||||
|         if ($self->gcode_preview_data->empty) { | ||||
|             # load skirt and brim | ||||
|             $self->canvas->load_print_toolpaths($self->print, \@colors); | ||||
|             $self->canvas->load_wipe_tower_toolpaths($self->print, \@colors);         | ||||
|             Slic3r::GUI::_3DScene::set_print($self->canvas, $self->print); | ||||
|             Slic3r::GUI::_3DScene::load_print_toolpaths($self->canvas); | ||||
|             Slic3r::GUI::_3DScene::load_wipe_tower_toolpaths($self->canvas, \@colors); | ||||
|             foreach my $object (@{$self->print->objects}) { | ||||
|                 $self->canvas->load_print_object_toolpaths($object, \@colors);             | ||||
|                 Slic3r::GUI::_3DScene::load_print_object_toolpaths($self->canvas, $object, \@colors); | ||||
|                 # Show the objects in very transparent color. | ||||
|                 #my @volume_ids = $self->canvas->load_object($object->model_object); | ||||
|                 #$self->canvas->volumes->[$_]->color->[3] = 0.2 for @volume_ids; | ||||
|             } | ||||
|             $self->show_hide_ui_elements('simple'); | ||||
|             $self->canvas->reset_legend_texture(); | ||||
|             Slic3r::GUI::_3DScene::reset_legend_texture(); | ||||
|         } else { | ||||
|             $self->{force_sliders_full_range} = (scalar(@{$self->canvas->volumes}) == 0); | ||||
|             $self->canvas->load_gcode_preview($self->print, $self->gcode_preview_data, \@colors); | ||||
|             $self->{force_sliders_full_range} = (Slic3r::GUI::_3DScene::get_volumes_count($self->canvas) == 0); | ||||
|             Slic3r::GUI::_3DScene::set_print($self->canvas, $self->print); | ||||
|             Slic3r::GUI::_3DScene::load_gcode_preview($self->canvas, $self->gcode_preview_data, \@colors); | ||||
|             $self->show_hide_ui_elements('full'); | ||||
| 
 | ||||
|             # recalculates zs and update sliders accordingly | ||||
|             $self->{layers_z} = $self->canvas->get_current_print_zs(1); | ||||
|             $self->{layers_z} = Slic3r::GUI::_3DScene::get_current_print_zs($self->canvas, 1); | ||||
|             $n_layers = scalar(@{$self->{layers_z}});             | ||||
|             if ($n_layers == 0) { | ||||
|                 # all layers filtered out | ||||
|  | @ -466,7 +468,7 @@ sub set_z_range | |||
|     $self->{z_label_low}->SetLabel(sprintf '%.2f', $z_low); | ||||
|     $self->{z_label_high}->SetLabel(sprintf '%.2f', $z_high); | ||||
|      | ||||
|     my $layers_z = $self->canvas->get_current_print_zs(0); | ||||
|     my $layers_z = Slic3r::GUI::_3DScene::get_current_print_zs($self->canvas, 0); | ||||
|     for (my $i = 0; $i < scalar(@{$layers_z}); $i += 1) { | ||||
|         if (($z_low - 1e-6 < @{$layers_z}[$i]) && (@{$layers_z}[$i] < $z_low + 1e-6)) { | ||||
|             $self->{z_label_low_idx}->SetLabel(sprintf '%d', $i + 1); | ||||
|  | @ -480,7 +482,7 @@ sub set_z_range | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     $self->canvas->set_toolpaths_range($z_low - 1e-6, $z_high + 1e-6); | ||||
|     Slic3r::GUI::_3DScene::set_toolpaths_range($self->canvas, $z_low - 1e-6, $z_high + 1e-6); | ||||
|     $self->canvas->Refresh if $self->IsShown; | ||||
| } | ||||
| 
 | ||||
|  | @ -510,11 +512,6 @@ sub set_z_idx_high | |||
|     } | ||||
| } | ||||
| 
 | ||||
| sub set_bed_shape { | ||||
|     my ($self, $bed_shape) = @_; | ||||
|     $self->canvas->set_bed_shape($bed_shape); | ||||
| } | ||||
| 
 | ||||
| sub set_number_extruders { | ||||
|     my ($self, $number_extruders) = @_; | ||||
|     if ($self->{number_extruders} != $number_extruders) { | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ use utf8; | |||
| use Slic3r::Geometry qw(PI X); | ||||
| use Wx qw(wxTheApp :dialog :id :misc :sizer wxTAB_TRAVERSAL); | ||||
| use Wx::Event qw(EVT_CLOSE EVT_BUTTON); | ||||
| use List::Util qw(max); | ||||
| use base 'Wx::Dialog'; | ||||
| 
 | ||||
| sub new { | ||||
|  | @ -112,10 +113,13 @@ sub new { | |||
|     my $canvas; | ||||
|     if ($Slic3r::GUI::have_OpenGL) { | ||||
|         $canvas = $self->{canvas} = Slic3r::GUI::3DScene->new($self); | ||||
|         $canvas->load_object($self->{model_object}, undef, undef, [0]); | ||||
|         $canvas->set_auto_bed_shape; | ||||
|         Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $self->{model_object}, 0, [0]); | ||||
|         Slic3r::GUI::_3DScene::set_auto_bed_shape($canvas); | ||||
|         Slic3r::GUI::_3DScene::set_axes_length($canvas, 2.0 * max(@{ Slic3r::GUI::_3DScene::get_volumes_bounding_box($canvas)->size })); | ||||
|         $canvas->SetSize([500,500]); | ||||
|         $canvas->SetMinSize($canvas->GetSize); | ||||
|         Slic3r::GUI::_3DScene::set_config($canvas, $self->GetParent->{config}); | ||||
|         Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($canvas, 1); | ||||
|     } | ||||
|      | ||||
|     $self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL); | ||||
|  | @ -144,6 +148,7 @@ sub new { | |||
|         # Note that the window was already closed, so a pending update will not be executed. | ||||
|         $self->{already_closed} = 1; | ||||
|         $self->EndModal(wxID_OK); | ||||
|         $self->{canvas}->Destroy; | ||||
|         $self->Destroy(); | ||||
|     }); | ||||
| 
 | ||||
|  | @ -151,6 +156,7 @@ sub new { | |||
|         # Note that the window was already closed, so a pending update will not be executed. | ||||
|         $self->{already_closed} = 1; | ||||
|         $self->EndModal(wxID_CANCEL); | ||||
|         $self->{canvas}->Destroy; | ||||
|         $self->Destroy(); | ||||
|     }); | ||||
| 
 | ||||
|  | @ -241,15 +247,12 @@ sub _update { | |||
|                     for @$expolygon; | ||||
|                 $expolygon->translate(map Slic3r::Geometry::scale($_), @{ $self->{model_object}->instances->[0]->offset }); | ||||
|             } | ||||
|              | ||||
|             $self->{canvas}->reset_objects; | ||||
|             $self->{canvas}->load_object($_, undef, undef, [0]) for @objects; | ||||
|             $self->{canvas}->SetCuttingPlane( | ||||
|                 $self->{cut_options}{z}, | ||||
|                 [@expolygons], | ||||
|             ); | ||||
|             $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->{config}); | ||||
|             $self->{canvas}->Render; | ||||
| 
 | ||||
|             Slic3r::GUI::_3DScene::reset_volumes($self->{canvas}); | ||||
|             Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $_, 0, [0]) for @objects; | ||||
|             Slic3r::GUI::_3DScene::set_cutting_plane($self->{canvas}, $self->{cut_options}{z}, [@expolygons]); | ||||
|             Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas}); | ||||
|             Slic3r::GUI::_3DScene::render($self->{canvas}); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ use File::Basename qw(basename); | |||
| use Wx qw(:misc :sizer :treectrl :button :keycode wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL wxMOD_CONTROL | ||||
|     wxTheApp); | ||||
| use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED EVT_TREE_KEY_DOWN EVT_KEY_DOWN); | ||||
| use List::Util qw(max); | ||||
| use base 'Wx::Panel'; | ||||
| 
 | ||||
| use constant ICON_OBJECT        => 0; | ||||
|  | @ -150,19 +151,19 @@ sub new { | |||
|     my $canvas; | ||||
|     if ($Slic3r::GUI::have_OpenGL) { | ||||
|         $canvas = $self->{canvas} = Slic3r::GUI::3DScene->new($self); | ||||
|         $canvas->enable_picking(1); | ||||
|         $canvas->select_by('volume'); | ||||
|          | ||||
|         $canvas->on_select(sub { | ||||
|         Slic3r::GUI::_3DScene::enable_picking($canvas, 1); | ||||
|         Slic3r::GUI::_3DScene::set_select_by($canvas, 'volume'); | ||||
|         Slic3r::GUI::_3DScene::register_on_select_object_callback($canvas, sub { | ||||
|             my ($volume_idx) = @_; | ||||
|             # convert scene volume to model object volume | ||||
|             $self->reload_tree(($volume_idx == -1) ? undef : $canvas->volumes->[$volume_idx]->volume_idx); | ||||
|             $self->reload_tree($volume_idx); | ||||
|         }); | ||||
|          | ||||
|         $canvas->load_object($self->{model_object}, undef, undef, [0]); | ||||
|         $canvas->set_auto_bed_shape; | ||||
|         Slic3r::GUI::_3DScene::load_model_object($canvas, $self->{model_object}, 0, [0]); | ||||
|         Slic3r::GUI::_3DScene::set_auto_bed_shape($canvas); | ||||
|         Slic3r::GUI::_3DScene::set_axes_length($canvas, 2.0 * max(@{ Slic3r::GUI::_3DScene::get_volumes_bounding_box($canvas)->size })); | ||||
|         $canvas->SetSize([500,700]); | ||||
|         $canvas->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); | ||||
|         Slic3r::GUI::_3DScene::set_config($canvas, $self->GetParent->GetParent->GetParent->{config}); | ||||
|         Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($canvas); | ||||
|         Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($canvas, 1); | ||||
|     } | ||||
|      | ||||
|     $self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL); | ||||
|  | @ -262,7 +263,7 @@ sub selection_changed { | |||
|      | ||||
|     # deselect all meshes | ||||
|     if ($self->{canvas}) { | ||||
|         $_->set_selected(0) for @{$self->{canvas}->volumes}; | ||||
|         Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas}); | ||||
|     } | ||||
|      | ||||
|     # disable things as if nothing is selected | ||||
|  | @ -290,7 +291,7 @@ sub selection_changed { | |||
|         if ($itemData->{type} eq 'volume') { | ||||
|             # select volume in 3D preview | ||||
|             if ($self->{canvas}) { | ||||
|                 $self->{canvas}->volumes->[ $itemData->{volume_id} ]->set_selected(1); | ||||
|                 Slic3r::GUI::_3DScene::select_volume($self->{canvas}, $itemData->{volume_id}); | ||||
|             } | ||||
|             $self->{btn_delete}->Enable; | ||||
|             $self->{btn_split}->Enable; | ||||
|  | @ -333,7 +334,7 @@ sub selection_changed { | |||
|         $self->{settings_panel}->enable; | ||||
|     } | ||||
|      | ||||
|     $self->{canvas}->Render if $self->{canvas}; | ||||
|     Slic3r::GUI::_3DScene::render($self->{canvas}) if $self->{canvas}; | ||||
| } | ||||
| 
 | ||||
| sub on_btn_load { | ||||
|  | @ -429,7 +430,7 @@ sub on_btn_move_up { | |||
|     if ($itemData && $itemData->{type} eq 'volume') { | ||||
|         my $volume_id = $itemData->{volume_id}; | ||||
|         if ($self->{model_object}->move_volume_up($volume_id)) { | ||||
|             $self->{canvas}->volumes->move_volume_up($volume_id); | ||||
|             Slic3r::GUI::_3DScene::move_volume_up($self->{canvas}, $volume_id); | ||||
|             $self->{parts_changed} = 1; | ||||
|             $self->reload_tree($volume_id - 1); | ||||
|         } | ||||
|  | @ -442,7 +443,7 @@ sub on_btn_move_down { | |||
|     if ($itemData && $itemData->{type} eq 'volume') { | ||||
|         my $volume_id = $itemData->{volume_id}; | ||||
|         if ($self->{model_object}->move_volume_down($volume_id)) { | ||||
|             $self->{canvas}->volumes->move_volume_down($volume_id); | ||||
|             Slic3r::GUI::_3DScene::move_volume_down($self->{canvas}, $volume_id); | ||||
|             $self->{parts_changed} = 1; | ||||
|             $self->reload_tree($volume_id + 1); | ||||
|         } | ||||
|  | @ -487,11 +488,11 @@ sub _parts_changed { | |||
|      | ||||
|     $self->reload_tree; | ||||
|     if ($self->{canvas}) { | ||||
|         $self->{canvas}->reset_objects; | ||||
|         $self->{canvas}->load_object($self->{model_object}); | ||||
|         $self->{canvas}->zoom_to_volumes; | ||||
|         $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); | ||||
|         $self->{canvas}->Render; | ||||
|         Slic3r::GUI::_3DScene::reset_volumes($self->{canvas}); | ||||
|         Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $self->{model_object}, 0, [0]); | ||||
|         Slic3r::GUI::_3DScene::zoom_to_volumes($self->{canvas}); | ||||
|         Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas}); | ||||
|         Slic3r::GUI::_3DScene::render($self->{canvas});         | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -511,6 +512,11 @@ sub CanClose { | |||
|     return ! Slic3r::GUI::catch_error($self); | ||||
| } | ||||
| 
 | ||||
| sub Destroy { | ||||
|     my ($self) = @_; | ||||
|     $self->{canvas}->Destroy if ($self->{canvas}); | ||||
| } | ||||
| 
 | ||||
| sub PartsChanged { | ||||
|     my ($self) = @_; | ||||
|     return $self->{parts_changed}; | ||||
|  | @ -525,18 +531,18 @@ sub _update_canvas { | |||
|     my ($self) = @_; | ||||
|      | ||||
|     if ($self->{canvas}) { | ||||
|         $self->{canvas}->reset_objects; | ||||
|         $self->{canvas}->load_object($self->{model_object}); | ||||
|         Slic3r::GUI::_3DScene::reset_volumes($self->{canvas}); | ||||
|         Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $self->{model_object}, 0, [0]); | ||||
| 
 | ||||
|         # restore selection, if any | ||||
|         if (my $itemData = $self->get_selection) { | ||||
|             if ($itemData->{type} eq 'volume') { | ||||
|                 $self->{canvas}->volumes->[ $itemData->{volume_id} ]->set_selected(1); | ||||
|                 Slic3r::GUI::_3DScene::select_volume($self->{canvas}, $itemData->{volume_id}); | ||||
|             } | ||||
|         } | ||||
|                  | ||||
|         $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); | ||||
|         $self->{canvas}->Render; | ||||
| 
 | ||||
|         Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas}); | ||||
|         Slic3r::GUI::_3DScene::render($self->{canvas}); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -558,10 +564,10 @@ sub _update { | |||
|     $self->{parts_changed} = 1; | ||||
|     my @objects = (); | ||||
|     push @objects, $self->{model_object}; | ||||
|     $self->{canvas}->reset_objects; | ||||
|     $self->{canvas}->load_object($_, undef, [0]) for @objects; | ||||
|     $self->{canvas}->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config}); | ||||
|     $self->{canvas}->Render; | ||||
|     Slic3r::GUI::_3DScene::reset_volumes($self->{canvas}); | ||||
|     Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $_, 0, [0]) for @objects; | ||||
|     Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas}); | ||||
|     Slic3r::GUI::_3DScene::render($self->{canvas}); | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ sub new { | |||
|         wxTheApp->save_window_pos($self, "object_settings"); | ||||
|          | ||||
|         $self->EndModal(wxID_OK); | ||||
|         $self->{parts}->Destroy; | ||||
|         $self->Destroy; | ||||
|     }); | ||||
|      | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv