Merge remote-tracking branch 'origin/master' into feature_slice_to_png

This commit is contained in:
tamasmeszaros 2018-07-18 10:14:15 +02:00
commit 9559ad77e5
121 changed files with 18093 additions and 3459 deletions

File diff suppressed because it is too large Load diff

View file

@ -32,6 +32,7 @@ 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') {
@ -74,6 +75,17 @@ sub new {
$appController->set_model($self->{plater}->{model});
$appController->set_print($self->{plater}->{print});
# Make the global status bar and its progress indicator available in C++
$appController->set_global_progress_indicator(
$self->{statusbar}->{prog}->GetId(),
$self->{statusbar}->GetId(),
);
$appController->set_model($self->{plater}->{model});
$appController->set_print($self->{plater}->{print});
$self->{plater}->{appController} = $appController;
$self->{loaded} = 1;
# initialize layout

View file

@ -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);
}
});

View file

@ -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;
@ -45,6 +46,7 @@ use constant FILAMENT_CHOOSERS_SPACING => 0;
use constant PROCESS_DELAY => 0.5 * 1000; # milliseconds
my $PreventListEvents = 0;
our $appController;
sub new {
my ($class, $parent) = @_;
@ -115,6 +117,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?
@ -126,7 +130,6 @@ sub new {
$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.)
@ -134,6 +137,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});
@ -151,7 +175,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);
@ -203,7 +229,7 @@ sub new {
if (($preview != $self->{preview3D}) && ($preview != $self->{canvas3D})) {
$preview->OnActivate if $preview->can('OnActivate');
} elsif ($preview == $self->{preview3D}) {
$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}) {
@ -509,7 +535,11 @@ sub new {
fil_mm3 => L("Used Filament (mm³)"),
fil_g => L("Used Filament (g)"),
cost => L("Cost"),
time => L("Estimated printing time"),
#==========================================================================================================================================
normal_time => L("Estimated printing time (normal mode)"),
# default_time => L("Estimated printing time (default mode)"),
#==========================================================================================================================================
silent_time => L("Estimated printing time (silent mode)"),
);
while (my $field = shift @info) {
my $label = shift @info;
@ -1054,7 +1084,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
@ -1188,13 +1228,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 {
@ -1577,7 +1621,11 @@ sub on_export_completed {
$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_normal_time"}->SetLabel($self->{print}->estimated_normal_print_time);
# $self->{"print_info_default_time"}->SetLabel($self->{print}->estimated_default_print_time);
#==========================================================================================================================================
$self->{"print_info_silent_time"}->SetLabel($self->{print}->estimated_silent_print_time);
$self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000));
$self->{"print_info_box_show"}->(1);
@ -1654,34 +1702,6 @@ sub export_object_stl {
$self->statusbar->SetStatusText(L("STL file exported to ").$output_file);
}
sub fix_through_netfabb {
my ($self) = @_;
my ($obj_idx, $object) = $self->selected_object;
return if !defined $obj_idx;
my $model_object = $self->{model}->objects->[$obj_idx];
my $model_fixed = Slic3r::Model->new;
Slic3r::GUI::fix_model_by_win10_sdk_gui($model_object, $self->{print}, $model_fixed);
my @new_obj_idx = $self->load_model_objects(@{$model_fixed->objects});
return if !@new_obj_idx;
foreach my $new_obj_idx (@new_obj_idx) {
my $o = $self->{model}->objects->[$new_obj_idx];
$o->clear_instances;
$o->add_instance($_) for @{$model_object->instances};
#$o->invalidate_bounding_box;
if ($o->volumes_count == $model_object->volumes_count) {
for my $i (0..($o->volumes_count-1)) {
$o->get_volume($i)->config->apply($model_object->get_volume($i)->config);
}
}
#FIXME restore volumes and their configs, layer_height_ranges, layer_height_profile, layer_height_profile_valid,
}
$self->remove($obj_idx);
}
sub export_amf {
my ($self) = @_;
return if !@{$self->{objects}};
@ -2260,11 +2280,6 @@ sub object_menu {
$frame->_append_menu_item($menu, L("Export object as STL…"), L('Export this single object as STL file'), sub {
$self->export_object_stl;
}, undef, 'brick_go.png');
if (Slic3r::GUI::is_windows10) {
$frame->_append_menu_item($menu, L("Fix STL through Netfabb"), L('Fix the model by sending it to a Netfabb cloud service through Windows 10 API'), sub {
$self->fix_through_netfabb;
}, undef, 'brick_go.png');
}
return $menu;
}

View file

@ -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;

View file

@ -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;
}