WIP: Plater, tracking in Plater.pm

This commit is contained in:
Vojtech Kral 2018-10-08 19:14:55 +02:00
parent 1f926964ee
commit ceb295944a
3 changed files with 136 additions and 31 deletions

View File

@ -41,6 +41,7 @@ our $PROCESS_COMPLETED_EVENT = Wx::NewEventType;
my $PreventListEvents = 0;
our $appController;
# XXX: VK: done, except callback handling and timer
sub new {
my ($class, $parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
@ -813,12 +814,14 @@ sub new {
return $self;
}
# XXX: VK: WIP
# sets the callback
sub on_select_preset {
my ($self, $cb) = @_;
$self->{on_select_preset} = $cb;
}
# XXX: merged with on_select_preset
# Called from the platter combo boxes selecting the active print, filament or printer.
sub _on_select_preset {
my ($self, $group, $choice, $idx) = @_;
@ -855,6 +858,7 @@ sub _on_select_preset {
$self->on_config_change(wxTheApp->{preset_bundle}->full_config);
}
# XXX: VK: done
sub on_layer_editing_toggled {
my ($self, $new_state) = @_;
Slic3r::GUI::_3DScene::enable_layers_editing($self->{canvas3D}, $new_state);
@ -873,11 +877,13 @@ sub on_layer_editing_toggled {
$self->{canvas3D}->Update;
}
sub GetFrame { # XXX: main_frame in C++ Plater
# XXX: VK: done (Plater::priv::main_frame)
sub GetFrame {
my ($self) = @_;
return &Wx::GetTopLevelParent($self);
}
# XXX: not done
# Called after the Preferences dialog is closed and the program settings are saved.
# Update the UI based on the current preferences.
sub update_ui_from_settings
@ -889,6 +895,7 @@ sub update_ui_from_settings
}
}
# XXX: VK: done
# Update preset combo boxes (Print settings, Filament, Material, Printer) from their respective tabs.
# Called by
# Slic3r::GUI::Tab::Print::_on_presets_changed
@ -934,12 +941,14 @@ sub update_presets {
wxTheApp->{preset_bundle}->export_selections(wxTheApp->{app_config});
}
# XXX: VK: done, in on_action_add()
sub add {
my ($self) = @_;
my @input_files = wxTheApp->open_model($self);
$self->load_files(\@input_files);
}
# XXX: VK: done
sub load_files {
my ($self, $input_files) = @_;
@ -1030,6 +1039,7 @@ sub load_files {
return @obj_idx;
}
# XXX: VK: done, except a few todos
sub load_model_objects {
my ($self, @model_objects) = @_;
@ -1112,6 +1122,7 @@ sub load_model_objects {
return @obj_idx;
}
# XXX: Removed
sub bed_centerf {
my ($self) = @_;
@ -1120,6 +1131,7 @@ sub bed_centerf {
return Slic3r::Pointf->new(unscale($bed_center->x), unscale($bed_center->y)); #)
}
# XXX: VK: done
sub remove {
my ($self, $obj_idx) = @_;
@ -1146,6 +1158,7 @@ sub remove {
$self->update;
}
# XXX: VK: done
sub reset {
my ($self) = @_;
@ -1166,6 +1179,7 @@ sub reset {
$self->update;
}
# XXX: not done
sub increase {
my ($self, $copies) = @_;
$copies //= 1;
@ -1197,6 +1211,7 @@ sub increase {
$self->schedule_background_process;
}
# XXX: not done
sub decrease {
my ($self, $copies_asked) = @_;
my $copies = $copies_asked // 1;
@ -1224,6 +1239,7 @@ sub decrease {
$self->update;
}
# XXX: not done
sub set_number_of_copies {
my ($self) = @_;
# get current number of copies
@ -1242,6 +1258,7 @@ sub set_number_of_copies {
}
}
# XXX: not done (?)
sub _get_number_from_user { # XXX: Enrico
my ($self, $title, $prompt_message, $error_message, $default, $only_positive) = @_;
for (;;) {
@ -1264,6 +1281,7 @@ sub _get_number_from_user { # XXX: Enrico
}
}
# XXX: not done
sub rotate {
my ($self, $angle, $axis, $relative_key, $axis_x, $axis_y, $axis_z) = @_;
$relative_key //= 'absolute'; # relative or absolute coordinates
@ -1334,6 +1352,7 @@ sub rotate {
$self->update;
}
# XXX: not done
sub mirror {
my ($self, $axis) = @_;
@ -1363,6 +1382,7 @@ sub mirror {
$self->update;
}
# XXX: not done
sub changescale {
my ($self, $axis, $tosize) = @_;
@ -1437,6 +1457,7 @@ sub changescale {
$self->update;
}
# XXX: not done
sub arrange {
my ($self) = @_;
@ -1454,6 +1475,7 @@ sub arrange {
$self->update(0);
}
# XXX: not done
sub split_object {
my $self = shift;
@ -1485,6 +1507,7 @@ sub split_object {
}
}
# XXX: not done
# Trigger $self->async_apply_config() after 500ms.
# The call is delayed to avoid restarting the background processing during typing into an edit field.
sub schedule_background_process {
@ -1492,6 +1515,7 @@ sub schedule_background_process {
$self->{apply_config_timer}->Start(0.5 * 1000, 1); # 1 = one shot, every half a second.
}
# XXX: not done
# Executed asynchronously by a timer every PROCESS_DELAY (0.5 second).
# The timer is started by schedule_background_process(),
sub async_apply_config {
@ -1526,6 +1550,7 @@ sub async_apply_config {
}
}
# XXX: not done
# Background processing is started either by the "Slice now" button, by the "Export G-code button" or by async_apply_config().
sub start_background_process {
my ($self) = @_;
@ -1546,6 +1571,7 @@ sub start_background_process {
$self->{background_slicing_process}->start;
}
# XXX: not done
# Stop the background processing
sub stop_background_process {
my ($self) = @_;
@ -1554,6 +1580,7 @@ sub stop_background_process {
# $self->{preview3D}->reload_print if $self->{preview3D};
}
# XXX: not done
# Called by the "Slice now" button, which is visible only if the background processing is disabled.
sub reslice {
# explicitly cancel a previous thread and start a new one.
@ -1574,6 +1601,7 @@ sub reslice {
}
}
# XXX: VK: done
sub export_gcode {
my ($self, $output_file) = @_;
@ -1654,6 +1682,7 @@ sub export_gcode {
return $self->{export_gcode_output_file};
}
# XXX: not done
# This message should be called by the background process synchronously.
sub on_update_print_preview {
my ($self) = @_;
@ -1666,6 +1695,7 @@ sub on_update_print_preview {
Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1);
}
# XXX: not done
# This gets called also if we have no threads.
sub on_progress_event {
my ($self, $percent, $message) = @_;
@ -1676,6 +1706,7 @@ sub on_progress_event {
$self->statusbar->SetStatusText("$message...");
}
# XXX: not done
# Called when the G-code export finishes, either successfully or with an error.
# This gets called also if we don't have threads.
sub on_process_completed {
@ -1743,6 +1774,7 @@ sub on_process_completed {
# $self->{preview3D}->reload_print if $self->{preview3D};
}
# XXX: partially done in the Sidebar
# Fill in the "Sliced info" box with the result of the G-code generator.
sub print_info_box_show {
my ($self, $show) = @_;
@ -1819,6 +1851,7 @@ sub print_info_box_show {
$panel->Refresh;
}
# XXX: not done - to be removed
sub do_print {
my ($self) = @_;
@ -1832,6 +1865,7 @@ sub do_print {
$printer_panel->load_print_job($self->{print_file}, $filament_stats);
}
# XXX: VK: done
sub export_stl {
my ($self) = @_;
return if !@{$self->{objects}};
@ -1842,6 +1876,7 @@ sub export_stl {
$self->statusbar->SetStatusText(L("STL file exported to ").$output_file);
}
# XXX: not done
sub reload_from_disk {
my ($self) = @_;
@ -1873,6 +1908,7 @@ sub reload_from_disk {
$self->remove($obj_idx);
}
# XXX: VK: done
sub export_object_stl {
my ($self) = @_;
my ($obj_idx, $object) = $self->selected_object;
@ -1884,6 +1920,7 @@ sub export_object_stl {
$self->statusbar->SetStatusText(L("STL file exported to ").$output_file);
}
# XXX: not done
sub fix_through_netfabb {
my ($self) = @_;
my ($obj_idx, $object) = $self->selected_object;
@ -1912,6 +1949,7 @@ sub fix_through_netfabb {
$self->remove($obj_idx);
}
# XXX: VK: WIP
sub export_amf {
my ($self) = @_;
return if !@{$self->{objects}};
@ -1928,6 +1966,7 @@ sub export_amf {
}
}
# XXX: VK: WIP
sub export_3mf {
my ($self) = @_;
return if !@{$self->{objects}};
@ -1944,6 +1983,7 @@ sub export_3mf {
}
}
# XXX: VK: done
# Ask user to select an output file for a given file format (STl, AMF, 3MF).
# Propose a default file name based on the 'output_filename_format' configuration value.
sub _get_export_file {
@ -1993,6 +2033,7 @@ sub _get_export_file {
# $self->{objects}[$obj_idx]->thumbnail(undef);
#}
# XXX: VK: done
# this method gets called whenever print center is changed or the objects' bounding box changes
# (i.e. when an object is added/removed/moved/rotated/scaled)
sub update {
@ -2016,6 +2057,7 @@ sub update {
$self->Thaw;
}
# XXX: done in sidebar?
# When a printer technology is changed, the UI needs to be updated to show/hide needed preset combo boxes.
sub show_preset_comboboxes{
my ($self, $showSLA) = @_; #if showSLA is oposite value to "ptFFF"
@ -2034,6 +2076,7 @@ sub show_preset_comboboxes{
$self->Layout;
}
# XXX: not done
# When a number of extruders changes, the UI needs to be updated to show a single filament selection combo box per extruder.
# Also the wxTheApp->{preset_bundle}->filament_presets needs to be resized accordingly
# and some reasonable default has to be selected for the additional extruders.
@ -2078,6 +2121,7 @@ sub on_extruders_change {
$self->Layout;
}
# XXX: not done
sub on_config_change {
my ($self, $config) = @_;
@ -2144,6 +2188,7 @@ sub on_config_change {
$self->schedule_background_process;
}
# XXX: not done
sub item_changed_selection {
my ($self, $obj_idx) = @_;
@ -2159,6 +2204,7 @@ sub item_changed_selection {
}
}
# XXX: VK: done
sub collect_selections {
my ($self) = @_;
my $selections = [];
@ -2168,6 +2214,7 @@ sub collect_selections {
return $selections;
}
# XXX: not done
# Called when clicked on the filament preset combo box.
# When clicked on the icon, show the color picker.
sub filament_color_box_lmouse_down
@ -2221,6 +2268,7 @@ sub filament_color_box_lmouse_down
# }
#}
# XXX: not done
sub changed_object_settings {
my ($self, $obj_idx, $parts_changed, $part_settings_changed) = @_;
@ -2246,6 +2294,7 @@ sub changed_object_settings {
}
}
# XXX: VK: done
# Called to update various buttons depending on whether there are any objects or
# whether background processing (export of a G-code, sending to Octoprint, forced background re-slicing) is active.
sub object_list_changed {
@ -2276,6 +2325,7 @@ sub object_list_changed {
for grep $self->{"btn_$_"}, qw(reslice export_gcode print send_gcode);
}
# XXX: VK: WIP
# Selection of an active 3D object changed.
sub selection_changed {
my ($self) = @_;
@ -2393,6 +2443,7 @@ sub selection_changed {
$self->{right_panel}->Thaw;
}
# XXX: VK: done
sub select_object {
my ($self, $obj_idx, $child) = @_;
@ -2413,6 +2464,7 @@ sub select_object {
$self->selection_changed(1);
}
# XXX: not done
sub select_object_from_cpp {
my ($self, $obj_idx, $vol_idx) = @_;
@ -2457,16 +2509,19 @@ sub select_object_from_cpp {
$self->selection_changed(1);
}
# XXX: VK: done
sub selected_object {
my ($self) = @_;
my $obj_idx = first { $self->{objects}[$_]->selected } 0..$#{ $self->{objects} };
return defined $obj_idx ? ($obj_idx, $self->{objects}[$obj_idx]) : undef;
}
# XXX: VK: done
sub statusbar {
return $_[0]->GetFrame->{statusbar};
}
# XXX: not done, to be removed (?)
sub object_menu {
my ($self) = @_;
@ -2577,6 +2632,7 @@ sub object_menu {
return $menu;
}
# XXX: not done
# Set a camera direction, zoom to all objects.
sub select_view {
my ($self, $direction) = @_;
@ -2594,6 +2650,8 @@ sub select_view {
}
}
# XXX: VK: done, in PlaterDropTarget
package Slic3r::GUI::Plater::DropTarget;
use Wx::DND;
use base 'Wx::FileDropTarget';

View File

@ -566,6 +566,13 @@ void Sidebar::show_buttons(const bool show)
}
}
void Sidebar::enable_buttons(bool enable)
{
p->btn_reslice->Enable(enable);
p->btn_export_gcode->Enable(enable);
p->btn_send_gcode->Enable(enable);
}
// Plater::Object
struct PlaterObject
@ -587,13 +594,28 @@ public:
private:
Plater *plater;
static const std::regex pattern_drop;
};
const std::regex PlaterDropTarget::pattern_drop("[.](stl|obj|amf|3mf|prusa)$", std::regex::icase);
bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
{
// TODO
// return false;
throw 0;
std::vector<fs::path> paths;
for (const auto &filename : filenames) {
fs::path path(filename);
if (std::regex_match(path.string(), pattern_drop)) {
paths.push_back(std::move(path));
} else {
return false;
}
}
plater->load_files(paths);
return true;
}
// Plater / private
@ -643,7 +665,9 @@ struct Plater::priv
void select_object(optional<size_t> obj_idx);
optional<size_t> selected_object() const;
void selection_changed();
void object_list_changed();
void remove(size_t obj_idx);
void reset();
void on_notebook_changed(wxBookCtrlEvent &);
@ -1081,8 +1105,16 @@ void Plater::priv::select_object(optional<size_t> obj_idx)
objects[*obj_idx].selected = true;
}
// TODO:
// $self->selection_changed(1);
selection_changed();
}
optional<size_t> Plater::priv::selected_object() const
{
for (size_t i = 0; i < objects.size(); i++) {
if (objects[i].selected) { return i; }
}
return boost::none;
}
void Plater::priv::selection_changed()
@ -1107,12 +1139,9 @@ void Plater::priv::selection_changed()
bool can_select_by_parts = false;
if (have_sel) {
// my $model_object = $self->{model}->objects->[$obj_idx];
const auto *model_object = model.objects[*obj_idx];
// $can_select_by_parts = ($obj_idx >= 0) && ($obj_idx < 1000) && ($model_object->volumes_count > 1);
// XXX: ?
can_select_by_parts = *obj_idx < 1000 && model_object->volumes.size() > 1;
// Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "fewer", $model_object->instances_count > 1);
_3DScene::enable_toolbar_item(canvas3D, "fewer", model_object->instances.size() > 1);
}
@ -1170,20 +1199,43 @@ void Plater::priv::selection_changed()
q->Layout();
}
optional<size_t> Plater::priv::selected_object() const
void Plater::priv::object_list_changed()
{
for (size_t i = 0; i < objects.size(); i++) {
if (objects[i].selected) { return i; }
}
// Enable/disable buttons depending on whether there are any objects on the platter.
const bool have_objects = !objects.empty();
return boost::none;
_3DScene::enable_toolbar_item(canvas3D, "deleteall", have_objects);
_3DScene::enable_toolbar_item(canvas3D, "arrange", have_objects);
const bool export_in_progress = !(export_gcode_output_file.empty() && send_gcode_file.empty());
// XXX: is this right?
const bool model_fits = _3DScene::check_volumes_outside_state(canvas3D, config) == ModelInstance::PVS_Inside;
sidebar->enable_buttons(have_objects && !export_in_progress && model_fits);
}
void Plater::priv::remove(size_t obj_idx)
{
// $self->stop_background_process; // TODO
// Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false);
objects.erase(objects.begin() + obj_idx);
model.delete_object(obj_idx);
print.delete_object(obj_idx);
// Delete object from Sidebar list
sidebar->obj_list()->delete_object_from_list();
object_list_changed();
select_object(boost::none);
update();
}
void Plater::priv::reset()
{
// TODO
// $self->stop_background_process;
// $self->stop_background_process; // TODO
// Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false);
@ -1193,13 +1245,10 @@ void Plater::priv::reset()
print.clear_objects();
// Delete all objects from list on c++ side
// TODO
// Slic3r::GUI::delete_all_objects_from_list();
sidebar->obj_list()->delete_all_objects_from_list();
// $self->object_list_changed;
object_list_changed();
// TODO
// $self->select_object(undef);
select_object(boost::none);
update();
}
@ -1350,15 +1399,8 @@ Plater::~Plater()
Sidebar& Plater::sidebar() { return *p->sidebar; }
Model& Plater::model() { return p->model; }
void Plater::update(bool force_autocenter)
{
p->update(force_autocenter);
}
void Plater::remove(size_t obj_idx)
{
// TODO
}
void Plater::update(bool force_autocenter) { p->update(force_autocenter); }
void Plater::remove(size_t obj_idx) { p->remove(obj_idx); }
void Plater::remove_selected()
{
@ -1368,6 +1410,7 @@ void Plater::remove_selected()
}
}
void Plater::load_files(const std::vector<fs::path> &input_files) { p->load_files(input_files); }
fs::path Plater::export_gcode(const fs::path &output_path)
{

View File

@ -2,6 +2,7 @@
#define slic3r_Plater_hpp_
#include <memory>
#include <vector>
#include <boost/filesystem/path.hpp>
#include <wx/panel.h>
@ -47,6 +48,7 @@ public:
int get_ol_selection();
void show_info_sizers(const bool show);
void show_buttons(const bool show);
void enable_buttons(bool enable);
private:
struct priv;
@ -71,6 +73,8 @@ public:
void remove(size_t obj_idx);
void remove_selected();
void load_files(const std::vector<boost::filesystem::path> &input_files);
// Note: empty path means "use the default"
boost::filesystem::path export_gcode(const boost::filesystem::path &output_path = boost::filesystem::path());
void export_stl();