From 9504780ef4155d2fe15c5b56945e171c13227911 Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Thu, 14 Jun 2018 15:33:42 +0200 Subject: [PATCH] Buttons "Add Part" and "Add Modifier" (in the Object Settings) works now --- lib/Slic3r/GUI/MainFrame.pm | 7 +- lib/Slic3r/GUI/Plater.pm | 2 +- xs/src/slic3r/GUI/GUI.cpp | 50 +++++++------ xs/src/slic3r/GUI/GUI.hpp | 14 +++- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 104 +++++++++++++++++++------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 5 ++ xs/xsp/GUI.xsp | 6 +- 7 files changed, 133 insertions(+), 55 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 626bdef81..fd2844783 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -188,12 +188,11 @@ sub _init_tabpanel { # The following event is emited by the C++ Tab implementation on object settings change. EVT_COMMAND($self, -1, $OBJECT_SETTINGS_CHANGED_EVENT, sub { my ($self, $event) = @_; - my $obj_idx = $event->GetInt; - #my $line = $event->GetString; - #my ($parts_changed, $part_settings_changed) = split('',$line); + my $line = $event->GetString; + my ($obj_idx, $parts_changed, $part_settings_changed) = split('',$line); - #$self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); + $self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); }); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index bc149a828..1d2168fe8 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -837,7 +837,7 @@ sub load_model_objects { my $model_object = $self->{model}->objects->[$obj_idx]; # Add object to list on c++ side - Slic3r::GUI::add_object_to_list($object->name, $model_object->instances_count, ($model_object->instances->[0]->scaling_factor * 100)); + Slic3r::GUI::add_object_to_list($object->name, $model_object); $self->reset_thumbnail($obj_idx); } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index dec2c7d7c..46e1a96d6 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -59,6 +59,7 @@ #include "../Utils/PresetUpdater.hpp" #include "../Config/Snapshot.hpp" +#include "Model.hpp" namespace Slic3r { namespace GUI { @@ -149,6 +150,7 @@ int m_event_object_settings_changed = 0; bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again +ModelObjectPtrs m_objects; wxFont g_small_font; wxFont g_bold_font; @@ -496,7 +498,7 @@ void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_languag add_config_menu(menu, event_preferences_changed, event_language_change); } -wxArrayString* open_model(wxWindow *parent){ +void open_model(wxWindow *parent, wxArrayString& input_files){ t_file_wild_card vec_FILE_WILDCARDS = get_file_wild_card(); std::vector<std::string> file_types = { "known", "stl", "obj", "amf", "3mf", "prusa" }; wxString MODEL_WILDCARD; @@ -509,12 +511,11 @@ wxArrayString* open_model(wxWindow *parent){ MODEL_WILDCARD, wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); if (dialog->ShowModal() != wxID_OK) { dialog->Destroy(); - return nullptr; + return ; } - wxArrayString input_files; + dialog->GetPaths(input_files); dialog->Destroy(); - return &input_files; } // This is called when closing the application, when loading a config file or when starting the config wizard @@ -810,6 +811,24 @@ unsigned get_colour_approx_luma(const wxColour &colour) b * b * .068 )); } +wxDataViewCtrl* get_objects_ctrl() { + return m_objects_ctrl; +} +MyObjectTreeModel* get_objects_model() { + return m_objects_model; +} + +ModelObjectPtrs& get_objects() { + return m_objects; +} + +const int& get_event_object_settings_changed() { + return m_event_object_settings_changed; +} + +wxFrame* get_main_frame() { + return g_wxMainFrame; +} void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value) { @@ -996,27 +1015,14 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); //*** button's functions - btn_load_part->Bind(wxEVT_BUTTON, [](wxEvent&) + btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) { - auto item = m_objects_ctrl->GetSelection(); - if (!item) return; - if (m_objects_model->GetParent(item) != wxDataViewItem(0)) - item = m_objects_model->GetParent(item); - if (!item) return; - wxString name = "Part"; - m_objects_ctrl->Select(m_objects_model->AddChild(item, name)); + on_btn_load(win); }); btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { on_btn_load(win, true); -// auto item = m_objects_ctrl->GetSelection(); -// if (!item) return; -// if (m_objects_model->GetParent(item) != wxDataViewItem(0)) -// item = m_objects_model->GetParent(item); -// if (!item) return; -// wxString name = "Part"; -// m_objects_ctrl->Select(m_objects_model->AddChild(item, name)); }); btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) @@ -1171,10 +1177,12 @@ wxBoxSizer* content_settings(wxWindow *win) return sizer; } -void add_object_to_list(const std::string &name, int instances_count, int scale) +void add_object_to_list(const std::string &name, ModelObject* model_object) { wxString item = name; - m_objects_ctrl->Select(m_objects_model->Add(item, instances_count, scale)); + int scale = model_object->instances[0]->scaling_factor * 100; + m_objects_ctrl->Select(m_objects_model->Add(item, model_object->instances.size(), scale)); + m_objects.push_back(model_object); } void delete_object_from_list() diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 22b41fb20..5c5a1a6a9 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -25,6 +25,8 @@ class wxButton; class wxFileDialog; class wxStaticBitmap; class wxFont; +class wxDataViewCtrl; +class MyObjectTreeModel; namespace Slic3r { @@ -34,6 +36,7 @@ class AppConfig; class PresetUpdater; class DynamicPrintConfig; class TabIface; +class ModelObject; #define _(s) Slic3r::translate((s)) inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); } @@ -67,6 +70,7 @@ enum ogGroup{ class Tab; class ConfigOptionsGroup; +typedef std::vector<ModelObject*> ModelObjectPtrs; // Map from an file_type name to full file wildcard name. typedef std::map<std::string, std::string> t_file_wild_card; inline t_file_wild_card& get_file_wild_card() { @@ -124,7 +128,13 @@ void set_label_clr_sys(const wxColour& clr); const wxFont& small_font(); const wxFont& bold_font(); -wxArrayString* open_model(wxWindow *parent); +void open_model(wxWindow *parent, wxArrayString& input_files); + +wxDataViewCtrl* get_objects_ctrl (); +MyObjectTreeModel* get_objects_model(); +ModelObjectPtrs& get_objects(); +const int& get_event_object_settings_changed(); +wxFrame* get_main_frame(); extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); @@ -191,7 +201,7 @@ wxString from_u8(const std::string &str); // Add object to the list //void add_object(const std::string &name); -void add_object_to_list(const std::string &name, int instances_count=1, int scale=100); +void add_object_to_list(const std::string &name, ModelObject* model_object); // Delete object from the list void delete_object_from_list(); // Delete all objects from the list diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index a5abf2af6..57d46c977 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1,42 +1,96 @@ #include "GUI.hpp" #include "GUI_ObjectParts.hpp" +#include "Model.hpp" +#include "wxExtensions.hpp" #include <wx/msgdlg.h> +#include <wx/frame.h> +#include <boost/filesystem.hpp> namespace Slic3r { namespace GUI { -void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) -{ - auto input_files = open_model(parent); -// for(auto input_file : input_files) { -// my $model = eval{ Slic3r::Model->read_from_file($input_file) }; -// if ($@) { -// Slic3r::GUI::show_error($self, $@); -// next; -// } +bool m_parts_changed = false; +bool m_part_settings_changed = false; -// foreach my $object(@{$model->objects}) { -// foreach my $volume(@{$object->volumes}) { -// my $new_volume = $self->{model_object}->add_volume($volume); -// $new_volume->set_modifier($is_modifier); -// $new_volume->set_name(basename($input_file)); -// -// # apply the same translation we applied to the object -// $new_volume->mesh->translate(@{$self->{model_object}->origin_translation}); -// -// # set a default extruder value, since user can't add it manually -// $new_volume->config->set_ifndef('extruder', 0); -// -// $self->{parts_changed} = 1; -// } -// } -// } +bool is_parts_changed(){return m_parts_changed;} +bool is_part_settings_changed(){ return m_part_settings_changed; } + +void load_part(wxWindow* parent, ModelObject* model_object, wxArrayString& part_names, bool is_modifier) +{ + wxArrayString input_files; + open_model(parent, input_files); + for (int i = 0; i < input_files.size(); ++i) { + std::string input_file = input_files.Item(i).ToStdString(); + + Model model; + try { + model = Model::read_from_file(input_file); + } + catch (std::exception &e) { + auto msg = _(L("Error! ")) + input_file + " : " + e.what() + "."; + show_error(parent, msg); + exit(1); + } + + for ( auto object : model.objects) { + for (auto volume : object->volumes) { + auto new_volume = model_object->add_volume(*volume); + new_volume->modifier = is_modifier; + boost::filesystem::path(input_file).filename().string(); + new_volume->name = boost::filesystem::path(input_file).filename().string(); + + part_names.Add(new_volume->name); + + // apply the same translation we applied to the object + new_volume->mesh.translate( model_object->origin_translation.x, + model_object->origin_translation.y, + model_object->origin_translation.y ); + + // set a default extruder value, since user can't add it manually + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); + + m_parts_changed = true; + } + } + } parts_changed(); } +void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) +{ + auto objects_ctrl = get_objects_ctrl(); + auto item = objects_ctrl->GetSelection(); + if (!item) + return; + int obj_idx = -1; + auto objects_model = get_objects_model(); + if (objects_model->GetParent(item) == wxDataViewItem(0)) + obj_idx = objects_model->GetIdByItem(item); + else + return; + + if (obj_idx < 0) return; + wxArrayString part_names; + ModelObjectPtrs& objects = get_objects(); + load_part(parent, objects[obj_idx], part_names, is_modifier); + + auto event = get_event_object_settings_changed(); + if (event > 0) { + wxCommandEvent e(event); + auto event_str = wxString::Format("%d %d %d", obj_idx, + is_parts_changed() ? 1 : 0, + is_part_settings_changed() ? 1 : 0); + e.SetString(event_str); + get_main_frame()->ProcessWindowEvent(e); + } + + for (int i = 0; i < part_names.size(); ++i) + objects_ctrl->Select(objects_model->AddChild(item, part_names.Item(i))); +} + void parts_changed(){ ; } } //namespace GUI diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index ffbda35bf..9ee982b96 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -5,6 +5,11 @@ namespace Slic3r { namespace GUI { +bool is_parts_changed(); +bool is_part_settings_changed(); + +void load_part( wxWindow* parent, ModelObject* model_object, + wxArrayString& part_names, bool is_modifier); void on_btn_load(wxWindow* parent, bool is_modifier = false); void parts_changed(); } //namespace GUI diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index ba800f38a..2c5e7fccd 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -122,8 +122,10 @@ void set_show_manifold_warning_icon(bool show) void update_mode() %code%{ Slic3r::GUI::update_mode(); %}; -void add_object_to_list(const char *name, int instances_count, int scale) - %code%{ Slic3r::GUI::add_object_to_list(name, instances_count, scale); %}; +void add_object_to_list(const char *name, SV *object_model) + %code%{ Slic3r::GUI::add_object_to_list( + name, + (ModelObject *)wxPli_sv_2_object(aTHX_ object_model, "Slic3r::Model::Object") ); %}; void delete_object_from_list() %code%{ Slic3r::GUI::delete_object_from_list(); %};