mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-04 23:50:41 +08:00
217 lines
8.3 KiB
C++
217 lines
8.3 KiB
C++
#include <memory>
|
|
#include <wx/progdlg.h>
|
|
#include <wx/window.h>
|
|
|
|
|
|
#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> _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<int> 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<int>()};
|
|
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<int>();
|
|
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<UndoOperation>();
|
|
return obj_idx;
|
|
}
|
|
|
|
|
|
|
|
std::vector<int> Plater::load_model_objects(ModelObject* model_object) {
|
|
ModelObjectPtrs tmp {model_object}; // wrap in a std::vector
|
|
return load_model_objects(tmp);
|
|
}
|
|
std::vector<int> Plater::load_model_objects(ModelObjectPtrs model_objects) {
|
|
return std::vector<int>();
|
|
}
|
|
|
|
MainFrame* Plater::GetFrame() { return dynamic_cast<MainFrame*>(wxGetTopLevelParent(this)); }
|
|
|
|
|
|
}} // Namespace Slic3r::GUI
|
|
|