#include #include #include #include "Plater.hpp" #include "ProgressStatusBar.hpp" #include "Log.hpp" #include "MainFrame.hpp" namespace Slic3r { namespace GUI { const auto PROGRESS_BAR_EVENT = wxNewEventType(); Plater::Plater(wxWindow* parent, const wxString& title, std::shared_ptr _settings) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, title), settings(_settings) { // Set callback for status event for worker threads /* this->print->set_status_cb([=](std::string percent percent, std::wstring message) { wxPostEvent(this, new wxPlThreadEvent(-1, PROGRESS_BAR_EVENT, }); */ auto on_select_object { [=](size_t& obj_idx) { this->select_object(obj_idx); } }; /* # Initialize handlers for canvases my $on_select_object = sub { my ($obj_idx) = @_; $self->select_object($obj_idx); }; my $on_double_click = sub { $self->object_settings_dialog if $self->selected_object; }; my $on_right_click = sub { my ($canvas, $click_pos) = @_; my ($obj_idx, $object) = $self->selected_object; return if !defined $obj_idx; my $menu = $self->object_menu; $canvas->PopupMenu($menu, $click_pos); $menu->Destroy; }; my $on_instances_moved = sub { $self->on_model_change; }; # Initialize 3D plater if ($Slic3r::GUI::have_OpenGL) { $self->{canvas3D} = Slic3r::GUI::Plater::3D->new($self->{preview_notebook}, $self->{objects}, $self->{model}, $self->{config}); $self->{preview_notebook}->AddPage($self->{canvas3D}, '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_instances_moved($on_instances_moved); $self->{canvas3D}->on_viewport_changed(sub { $self->{preview3D}->canvas->set_viewport_from_scene($self->{canvas3D}); }); } */ canvas2D = new Plate2D(preview_notebook, wxDefaultSize, objects, model, config, settings); preview_notebook->AddPage(canvas2D, _("2D")); /* # Initialize 2D preview canvas $self->{canvas} = Slic3r::GUI::Plater::2D->new($self->{preview_notebook}, wxDefaultSize, $self->{objects}, $self->{model}, $self->{config}); $self->{preview_notebook}->AddPage($self->{canvas}, '2D'); $self->{canvas}->on_select_object($on_select_object); $self->{canvas}->on_double_click($on_double_click); $self->{canvas}->on_right_click(sub { $on_right_click->($self->{canvas}, @_); }); $self->{canvas}->on_instances_moved($on_instances_moved); # Initialize 3D toolpaths preview $self->{preview3D_page_idx} = -1; if ($Slic3r::GUI::have_OpenGL) { $self->{preview3D} = Slic3r::GUI::Plater::3DPreview->new($self->{preview_notebook}, $self->{print}); $self->{preview3D}->canvas->on_viewport_changed(sub { $self->{canvas3D}->set_viewport_from_scene($self->{preview3D}->canvas); }); $self->{preview_notebook}->AddPage($self->{preview3D}, 'Preview'); $self->{preview3D_page_idx} = $self->{preview_notebook}->GetPageCount-1; } # Initialize toolpaths preview $self->{toolpaths2D_page_idx} = -1; if ($Slic3r::GUI::have_OpenGL) { $self->{toolpaths2D} = Slic3r::GUI::Plater::2DToolpaths->new($self->{preview_notebook}, $self->{print}); $self->{preview_notebook}->AddPage($self->{toolpaths2D}, 'Layers'); $self->{toolpaths2D_page_idx} = $self->{preview_notebook}->GetPageCount-1; } EVT_NOTEBOOK_PAGE_CHANGED($self, $self->{preview_notebook}, sub { wxTheApp->CallAfter(sub { my $sel = $self->{preview_notebook}->GetSelection; if ($sel == $self->{preview3D_page_idx} || $sel == $self->{toolpaths2D_page_idx}) { if (!$Slic3r::GUI::Settings->{_}{background_processing} && !$self->{processed}) { $self->statusbar->SetCancelCallback(sub { $self->stop_background_process; $self->statusbar->SetStatusText("Slicing cancelled"); $self->{preview_notebook}->SetSelection(0); }); $self->start_background_process; } else { $self->{preview3D}->load_print if $sel == $self->{preview3D_page_idx}; } } }); }); */ } void Plater::add() { Log::info(LogChannel, L"Called Add function"); auto& start_object_id = this->object_identifier; const auto& input_files{open_model(this, *(this->settings), wxTheApp->GetTopWindow())}; for (const auto& f : input_files) { Log::info(LogChannel, (wxString(L"Calling Load File for ") + f).ToStdWstring()); this->load_file(f); } // abort if no objects actually added. if (start_object_id == this->object_identifier) return; // save the added objects // get newly added objects count } std::vector Plater::load_file(const wxString& file, const int obj_idx_to_load) { auto input_file {wxFileName(file)}; settings->skein_directory = input_file.GetPath(); settings->save_settings(); Slic3r::Model model; bool valid_load {true}; auto obj_idx {std::vector()}; auto progress_dialog {new wxProgressDialog(_(L"Loading…"), _(L"Processing input file…"), 100, this, 0)}; progress_dialog->Pulse(); //TODO: Add a std::wstring so we can handle non-roman characters as file names. try { auto model {Slic3r::Model::read_from_file(file.ToStdString())}; } catch (std::runtime_error& e) { show_error(this, e.what()); valid_load = false; } if (valid_load) { if (model.looks_like_multipart_object()) { auto dialog {new wxMessageDialog(this, _("This file contains several objects positioned at multiple heights. Instead of considering them as multiple objects, should I consider\n them this file as a single object having multiple parts?\n"), _("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO)}; if (dialog->ShowModal() == wxID_YES) { model.convert_multipart_object(); } } for (auto i = 0U; i < model.objects.size(); i++) { auto object {model.objects[i]}; object->input_file = file.ToStdString(); for (auto j = 0U; j < object->volumes.size(); j++) { auto volume {object->volumes.at(j)}; volume->input_file = file.ToStdString(); volume->input_file_obj_idx = i; volume->input_file_vol_idx = j; } } auto i {0U}; if (obj_idx_to_load > 0) { const size_t idx_load = obj_idx_to_load; if (idx_load >= model.objects.size()) return std::vector(); obj_idx = this->load_model_objects(model.objects.at(idx_load)); i = idx_load; } else { obj_idx = this->load_model_objects(model.objects); } for (const auto &j : obj_idx) { this->objects[j].input_file = file; this->objects[j].input_file_obj_idx = i++; } GetFrame()->statusbar->SetStatusText(_("Loaded ") + input_file.GetName()); if (this->scaled_down) { GetFrame()->statusbar->SetStatusText(_("Your object appears to be too large, so it was automatically scaled down to fit your print bed.")); } if (this->outside_bounds) { GetFrame()->statusbar->SetStatusText(_("Some of your object(s) appear to be outside the print bed. Use the arrange button to correct this.")); } } progress_dialog->Destroy(); this->redo = std::stack(); return obj_idx; } std::vector Plater::load_model_objects(ModelObject* model_object) { ModelObjectPtrs tmp {model_object}; // wrap in a std::vector return load_model_objects(tmp); } std::vector Plater::load_model_objects(ModelObjectPtrs model_objects) { return std::vector(); } MainFrame* Plater::GetFrame() { return dynamic_cast(wxGetTopLevelParent(this)); } }} // Namespace Slic3r::GUI