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