From 8d1b854acbbb1686d92cd38a696dab2a97dec00d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 3 Jan 2019 14:34:53 +0100 Subject: [PATCH 01/14] Replaced all wxString.ToStdString() with wxString.ToUTF8().data() to be sure that the strings are correctly converted to UTF8. --- src/libslic3r/Config.cpp | 4 ++-- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 2 +- src/slic3r/GUI/BedShapeDialog.cpp | 2 +- src/slic3r/GUI/ConfigWizard.cpp | 3 +-- src/slic3r/GUI/Field.cpp | 2 +- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/GUI_ObjectList.cpp | 12 ++++++------ src/slic3r/GUI/MainFrame.cpp | 10 +++++----- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 4 ++-- src/slic3r/GUI/wxExtensions.cpp | 4 ++-- 11 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 2f61cc008..c295d6def 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -404,7 +404,7 @@ void ConfigBase::load_from_gcode_file(const std::string &file) size_t key_value_pairs = load_from_gcode_string(data.data()); if (key_value_pairs < 80) - throw std::runtime_error((boost::format("Suspiciously low number of configuration values extracted from %1: %2") % file % key_value_pairs).str()); + throw std::runtime_error((boost::format("Suspiciously low number of configuration values extracted from %1%: %2%") % file % key_value_pairs).str()); } // Load the config keys from the given string. @@ -536,7 +536,7 @@ void DynamicConfig::read_cli(const std::vector &tokens, t_config_op args.emplace_back(const_cast("")); for (size_t i = 0; i < tokens.size(); ++ i) args.emplace_back(const_cast(tokens[i].c_str())); - this->read_cli(args.size(), &args[0], extra); + this->read_cli(int(args.size()), &args[0], extra); } bool DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 44ac1bc71..4ef020bf8 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -126,7 +126,7 @@ public: } inline std::string get_name() const { - return fpath.GetName().ToStdString(); + return fpath.GetName().ToUTF8().data(); } template inline LayerWriter& operator<<(const T& arg) { diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index dbc9e36d8..feb44a922 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -305,7 +305,7 @@ void BedShapePanel::load_stl() dialog->GetPaths(input_file); dialog->Destroy(); - std::string file_name = input_file[0].ToStdString(); + std::string file_name = input_file[0].ToUTF8().data(); Model model; try { diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index ba87cd46a..c0c582baf 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -72,8 +72,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, cons std::vector variants_panels; for (const auto &model : models) { - auto bitmap_file = wxString::Format("printers/%s_%s.png", vendor.id, model.id); - wxBitmap bitmap(GUI::from_u8(Slic3r::var(bitmap_file.ToStdString())), wxBITMAP_TYPE_PNG); + wxBitmap bitmap(GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())), wxBITMAP_TYPE_PNG); auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); title->SetFont(namefont); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 9855806be..81a90cfbd 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -188,7 +188,7 @@ void Field::get_value_by_opt_type(wxString& str) } } - m_value = str.ToStdString(); + m_value = str.ToUTF8().data(); break; } default: break; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b1ecef7df..1d11bbe00 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -509,7 +509,7 @@ void GUI_App::save_language() if (m_wxLocale) language = m_wxLocale->GetCanonicalName(); - app_config->set("translation_language", language.ToStdString()); + app_config->set("translation_language", language.ToUTF8().data()); app_config->save(); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index afeaca327..dffaf7afc 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -298,13 +298,13 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) if (obj_idx < 0) return; if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { - (*m_objects)[obj_idx]->name = m_objects_model->GetName(item).ToStdString(); + (*m_objects)[obj_idx]->name = m_objects_model->GetName(item).ToUTF8().data(); return; } const int volume_id = m_objects_model->GetVolumeIdByItem(item); if (volume_id < 0) return; - (*m_objects)[obj_idx]->volumes[volume_id]->name = m_objects_model->GetName(item).ToStdString(); + (*m_objects)[obj_idx]->volumes[volume_id]->name = m_objects_model->GetName(item).ToUTF8().data(); } void ObjectList::init_icons() @@ -657,7 +657,7 @@ void ObjectList::append_menu_item_add_generic(wxMenuItem* menu, const int type) std::vector menu_items = { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") }; for (auto& item : menu_items) { append_menu_item(sub_menu, wxID_ANY, _(item), "", - [this, type, item](wxCommandEvent&) { load_generic_subobject(_(item).ToStdString(), type); }, "", menu->GetMenu()); + [this, type, item](wxCommandEvent&) { load_generic_subobject(_(item).ToUTF8().data(), type); }, "", menu->GetMenu()); } menu->SetSubMenu(sub_menu); @@ -683,10 +683,10 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu) append_menu_item(menu, wxID_ANY, _(L("Add part")), "", [this](wxCommandEvent&) { load_subobject(ModelVolume::MODEL_PART); }, *m_bmp_vector[ModelVolume::MODEL_PART]); append_menu_item(menu, wxID_ANY, _(L("Add support enforcer")), "", - [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToStdString(), ModelVolume::SUPPORT_ENFORCER); }, + [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToUTF8().data(), ModelVolume::SUPPORT_ENFORCER); }, *m_bmp_vector[ModelVolume::SUPPORT_ENFORCER]); append_menu_item(menu, wxID_ANY, _(L("Add support blocker")), "", - [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToStdString(), ModelVolume::SUPPORT_BLOCKER); }, + [this](wxCommandEvent&) { load_generic_subobject(_(L("Box")).ToUTF8().data(), ModelVolume::SUPPORT_BLOCKER); }, *m_bmp_vector[ModelVolume::SUPPORT_BLOCKER]); return; @@ -823,7 +823,7 @@ void ObjectList::load_part( ModelObject* model_object, wxArrayString input_files; wxGetApp().import_model(parent, input_files); for (int i = 0; i < input_files.size(); ++i) { - std::string input_file = input_files.Item(i).ToStdString(); + std::string input_file = input_files.Item(i).ToUTF8().data(); Model model; try { diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 734285db7..7eff483cf 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -488,7 +488,7 @@ void MainFrame::quick_slice(const int qs) // }); // keep model around - auto model = Slic3r::Model::read_from_file(input_file.ToStdString()); + auto model = Slic3r::Model::read_from_file(input_file.ToUTF8().data()); // sprint->apply_config(config); // sprint->set_model(model); @@ -630,7 +630,7 @@ void MainFrame::export_config() if (!file.IsEmpty()) { wxGetApp().app_config->update_config_dir(get_dir_name(file)); m_last_config = file; - config.save(file.ToStdString()); + config.save(file.ToUTF8().data()); } } @@ -649,7 +649,7 @@ void MainFrame::load_config_file(wxString file/* = wxEmptyString*/) dlg->Destroy(); } try { - wxGetApp().preset_bundle->load_config_file(file.ToStdString()); + wxGetApp().preset_bundle->load_config_file(file.ToUTF8().data()); } catch (const std::exception &ex) { show_error(this, ex.what()); return; @@ -682,7 +682,7 @@ void MainFrame::export_configbundle() // Export the config bundle. wxGetApp().app_config->update_config_dir(get_dir_name(file)); try { - wxGetApp().preset_bundle->export_configbundle(file.ToStdString()); + wxGetApp().preset_bundle->export_configbundle(file.ToUTF8().data()); } catch (const std::exception &ex) { show_error(this, ex.what()); } @@ -710,7 +710,7 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re auto presets_imported = 0; try { - presets_imported = wxGetApp().preset_bundle->load_configbundle(file.ToStdString()); + presets_imported = wxGetApp().preset_bundle->load_configbundle(file.ToUTF8().data()); } catch (const std::exception &ex) { show_error(this, ex.what()); return; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c9440a9d0..a1ca93d62 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2083,7 +2083,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) //! So, to get selected string we do //! combo->GetString(combo->GetSelection()) //! instead of - //! combo->GetStringSelection().ToStdString()); + //! combo->GetStringSelection().ToUTF8().data()); std::string selected_string = combo->GetString(combo->GetSelection()).ToUTF8().data(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 41318a854..162e62155 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -209,7 +209,7 @@ void Tab::create_preset_tab() m_presets_choice->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { //! Because of The MSW and GTK version of wxBitmapComboBox derived from wxComboBox, //! but the OSX version derived from wxOwnerDrawnCombo, instead of: - //! select_preset(m_presets_choice->GetStringSelection().ToStdString()); + //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data()); //! we doing next: int selected_item = m_presets_choice->GetSelection(); if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty()) @@ -2804,7 +2804,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep selections.Clear(); selections = dlg.GetSelections(); for (auto idx : selections) - value.push_back(presets[idx].ToStdString()); + value.push_back(presets[idx].ToUTF8().data()); if (value.empty()) { deps.checkbox->SetValue(1); deps.btn->Disable(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 6ea47b45b..466580074 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -422,13 +422,13 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vectorfind(m_name.ToStdString()); + wxBitmap *bmp = m_bitmap_cache->find(m_name.ToUTF8().data()); if (bmp == nullptr) { std::vector bmps; for (auto& cat : m_opt_categories) bmps.emplace_back(categories_icon.find(cat) == categories_icon.end() ? wxNullBitmap : categories_icon.at(cat)); - bmp = m_bitmap_cache->insert(m_name.ToStdString(), bmps); + bmp = m_bitmap_cache->insert(m_name.ToUTF8().data(), bmps); } m_bmp = *bmp; From 474e06ac858bf53956030fe45f47aa5d9c731178 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 3 Jan 2019 15:04:29 +0100 Subject: [PATCH 02/14] Fixed missing mirror transform data when increasing instances count --- src/libslic3r/Model.cpp | 3 ++- src/libslic3r/Model.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 20c4a44b2..900397f70 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -719,12 +719,13 @@ ModelInstance* ModelObject::add_instance(const ModelInstance &other) return i; } -ModelInstance* ModelObject::add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation) +ModelInstance* ModelObject::add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation, const Vec3d &mirror) { auto *instance = add_instance(); instance->set_offset(offset); instance->set_scaling_factor(scaling_factor); instance->set_rotation(rotation); + instance->set_mirror(mirror); return instance; } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index e65228d80..947301437 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -200,7 +200,7 @@ public: ModelInstance* add_instance(); ModelInstance* add_instance(const ModelInstance &instance); - ModelInstance* add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation); + ModelInstance* add_instance(const Vec3d &offset, const Vec3d &scaling_factor, const Vec3d &rotation, const Vec3d &mirror); void delete_instance(size_t idx); void delete_last_instance(); void clear_instances(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a1ca93d62..941a181d3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2628,7 +2628,7 @@ void Plater::increase_instances(size_t num) float offset = 10.0; for (size_t i = 0; i < num; i++, offset += 10.0) { Vec3d offset_vec = model_instance->get_offset() + Vec3d(offset, offset, 0.0); - model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation()); + model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation(), model_instance->get_mirror()); // p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec)); } From 360dbca52e65633c3a15558ecfffaa248124ccf1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 3 Jan 2019 15:43:03 +0100 Subject: [PATCH 03/14] Attempt to fix camera movements after importing object --- src/slic3r/GUI/GLCanvas3D.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1695a532b..5fa09d334 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4896,6 +4896,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } m_mouse.set_start_position_2D_as_invalid(); + m_mouse.set_start_position_3D_as_invalid(); #endif } else if (evt.Leaving()) From 237eaa5f6f49bee0276c40ccc6fd85f1911831f2 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 3 Jan 2019 13:25:56 +0100 Subject: [PATCH 04/14] Fix #1526 --datadir not working --- src/libslic3r/PrintConfig.cpp | 7 +++++++ src/libslic3r/PrintConfig.hpp | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 215b17481..7da839dc3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3118,6 +3118,13 @@ CLIConfigDef::CLIConfigDef() const CLIConfigDef cli_config_def; DynamicPrintAndCLIConfig::PrintAndCLIConfigDef DynamicPrintAndCLIConfig::s_def; +void DynamicPrintAndCLIConfig::handle_legacy(t_config_option_key &opt_key, std::string &value) const +{ + if (cli_config_def.options.find(opt_key) == cli_config_def.options.end()) { + PrintConfigDef::handle_legacy(opt_key, value); + } +} + std::ostream& print_cli_options(std::ostream& out) { for (const auto& opt : cli_config_def.options) { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 08f42f39b..8713ed03f 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1171,6 +1171,12 @@ public: const ConfigDef* def() const override { return &s_def; } t_config_option_keys keys() const override { return s_def.keys(); } + // Verify whether the opt_key has not been obsoleted or renamed. + // Both opt_key and value may be modified by handle_legacy(). + // If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy(). + // handle_legacy() is called internally by set_deserialize(). + void handle_legacy(t_config_option_key &opt_key, std::string &value) const override; + private: class PrintAndCLIConfigDef : public ConfigDef { From b1a7ac07c93fce30fd90054e2f7cb2d2daa2f65e Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 3 Jan 2019 16:36:45 +0100 Subject: [PATCH 05/14] Fix of "System presets listed among user presets (and can't be deleted) [1.42.0-alpha1] #1511" When loading a user provided Config Bundle (not a vendor Config Bundle), profiles of the same name as the system profiles already loaded into Slic3r will be ignored, while emiting an error message into the log. Also when loading a user provided Config Bundle, imported vs. overwritten profiles are reported into the log as well. --- src/slic3r/GUI/PresetBundle.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index ee7ba279f..274f2a7ef 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1164,6 +1164,22 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla section.first << "\" has already been loaded from another Confing Bundle."; continue; } + } else if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) { + // This is a user config bundle. + const Preset *existing = presets->find_preset(preset_name, false); + if (existing != nullptr) { + if (existing->is_system) { + assert(existing->vendor != nullptr); + BOOST_LOG_TRIVIAL(error) << "Error in a user provided Config Bundle \"" << path << "\": The " << presets->name() << " preset \"" << + existing->name << "\" is a system preset of vendor " << existing->vendor->name << " and it will be ignored."; + continue; + } else { + assert(existing->vendor == nullptr); + BOOST_LOG_TRIVIAL(trace) << "A " << presets->name() << " preset \"" << existing->name << "\" was overwritten with a preset from user Config Bundle \"" << path << "\""; + } + } else { + BOOST_LOG_TRIVIAL(trace) << "A new " << presets->name() << " preset \"" << preset_name << "\" was imported from user Config Bundle \"" << path << "\""; + } } // Decide a full path to this .ini file. auto file_name = boost::algorithm::iends_with(preset_name, ".ini") ? preset_name : preset_name + ".ini"; From 30184cc0f6a1998368f66818617332cab29efc88 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 3 Jan 2019 17:26:03 +0100 Subject: [PATCH 06/14] Fix #1502 Upload to duet does not start the print Code was erroneously removed during refactoring --- src/slic3r/Utils/Duet.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/slic3r/Utils/Duet.cpp b/src/slic3r/Utils/Duet.cpp index 3449e610e..77137a7d2 100644 --- a/src/slic3r/Utils/Duet.cpp +++ b/src/slic3r/Utils/Duet.cpp @@ -75,6 +75,19 @@ bool Duet::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn e http.set_post_body(upload_data.source_path) .on_complete([&](std::string body, unsigned status) { BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: File uploaded: HTTP %1%: %2%") % status % body; + + int err_code = get_err_code_from_body(body); + if (err_code != 0) { + BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Request completed but error code was received: %1%") % err_code; + error_fn(format_error(body, L("Unknown error occured"), 0)); + res = false; + } else if (upload_data.start_print) { + wxString errormsg; + res = start_print(errormsg, upload_data.upload_path.string()); + if (! res) { + error_fn(std::move(errormsg)); + } + } }) .on_error([&](std::string body, std::string error, unsigned status) { BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body; From 41c27754688cc5fb7593cdf2c420cef173ccfe92 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 3 Jan 2019 18:54:45 +0100 Subject: [PATCH 07/14] Fix of #1501, #1522 This time the wWinMain did not provide a valid command line. Calling ::GetCommandLineW() helped. --- src/slic3r_app_msvc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r_app_msvc.cpp b/src/slic3r_app_msvc.cpp index 9823a325d..7cd97dfc3 100644 --- a/src/slic3r_app_msvc.cpp +++ b/src/slic3r_app_msvc.cpp @@ -181,10 +181,10 @@ extern "C" { } #ifdef SLIC3R_WRAPPER_NOCONSOLE -int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpCmdLine, int nCmdShow) +int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */) { int argc; - wchar_t **argv = CommandLineToArgvW(lpCmdLine, &argc); + wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); #else int wmain(int argc, wchar_t **argv) { From 8e001972a9efaf23e4ee5129d6a2c82a5e438cd2 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 4 Jan 2019 12:56:48 +0100 Subject: [PATCH 08/14] Added print bed models for mk2 and mk3 printers to 3D scene --- resources/models/mk2_bed.stl | Bin 0 -> 2484 bytes resources/models/mk3_bed.stl | Bin 0 -> 59984 bytes src/libslic3r/Technologies.hpp | 4 +- src/slic3r/GUI/3DScene.cpp | 82 +++++++++++++++++++++++++++++---- src/slic3r/GUI/3DScene.hpp | 27 +++++++++++ src/slic3r/GUI/GLCanvas3D.cpp | 63 ++++++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 11 +++++ 7 files changed, 176 insertions(+), 11 deletions(-) create mode 100644 resources/models/mk2_bed.stl create mode 100644 resources/models/mk3_bed.stl diff --git a/resources/models/mk2_bed.stl b/resources/models/mk2_bed.stl new file mode 100644 index 0000000000000000000000000000000000000000..07b7655ea6f601ec070d0c06f70265e35d2d1e5b GIT binary patch literal 2484 zcma)-ziJgx5XMh1Q3#}vyuc~7i-s*_F{TQsqCP+n!64i~tkNCC#uQ1b;7g=S6ZRIq zfrzcx3&I7lbiOk?XTG!9WOE>!Vej{we>*$7_vT=B`0Dl1;k&qXFxx*mj?Z80#s_g{ ze-`6re7x~!Gd^5fjkh~%s~e%56hi9uc0X?)KRJ08LY$vBVqd;5_TOJ0vz-Z1lG95WPR(4R$1X9F z)X{pcLIADRs;v`K^dbl0T@1mWpb(|gV}xc^t9%xELj2>TmVaTt98aZ?gBaFfxig)K z{xTpacYppS)&EjCsbE{LMv0W`C{q%GPe$E^>|NA2sr4r%-7S-G6XBCstC&{j`Px50 zdmbE*>r<^{)FCaND<|UIZPVXONQPxXLEK$w+Mml!j^Vy!mz2uc9uT>sHtkMmr>#CP zsl^4BtJJS;HQZMls%e5fLBCjTTKoZZU)mqryQt5mvLbR;mIuG@+JTP literal 0 HcmV?d00001 diff --git a/resources/models/mk3_bed.stl b/resources/models/mk3_bed.stl new file mode 100644 index 0000000000000000000000000000000000000000..cfa6d8c6d63e3f8e767556727c04277de82285c6 GIT binary patch literal 59984 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 literal 0 HcmV?d00001 diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c32fe3e8d..dc6a2041c 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -42,8 +42,10 @@ //==================== #define ENABLE_1_42_0_ALPHA2 1 +// Improves navigation between sidebar fields #define ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION (1 && ENABLE_1_42_0_ALPHA2) - +// Adds print bed models to 3D scene +#define ENABLE_PRINT_BED_MODELS (1 && ENABLE_1_42_0_ALPHA2) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 42b025093..d44789b7a 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -11,6 +11,9 @@ #include "libslic3r/Slicing.hpp" #include "libslic3r/GCode/Analyzer.hpp" #include "slic3r/GUI/PresetBundle.hpp" +#if ENABLE_PRINT_BED_MODELS +#include "libslic3r/Format/STL.hpp" +#endif // ENABLE_PRINT_BED_MODELS #include #include @@ -20,6 +23,11 @@ #include +#if ENABLE_PRINT_BED_MODELS +#include +#include +#endif // ENABLE_PRINT_BED_MODELS + #include #include @@ -249,11 +257,7 @@ void GLVolume::set_render_color(float r, float g, float b, float a) void GLVolume::set_render_color(const float* rgba, unsigned int size) { - size = std::min((unsigned int)4, size); - for (unsigned int i = 0; i < size; ++i) - { - render_color[i] = rgba[i]; - } + ::memcpy((void*)render_color, (const void*)rgba, (size_t)(std::min((unsigned int)4, size) * sizeof(float))); } void GLVolume::set_render_color() @@ -1790,17 +1794,27 @@ GUI::GLCanvas3DManager _3DScene::s_canvas_mgr; #if ENABLE_SIDEBAR_VISUAL_HINTS GLModel::GLModel() : m_useVBOs(false) +#if ENABLE_PRINT_BED_MODELS + , m_filename("") +#endif // ENABLE_PRINT_BED_MODELS { m_volume.shader_outside_printer_detection_enabled = false; } GLModel::~GLModel() { +#if ENABLE_PRINT_BED_MODELS + reset(); +#else m_volume.release_geometry(); +#endif // ENABLE_PRINT_BED_MODELS } void GLModel::set_color(const float* color, unsigned int size) { +#if ENABLE_PRINT_BED_MODELS + ::memcpy((void*)m_volume.color, (const void*)color, (size_t)(std::min((unsigned int)4, size) * sizeof(float))); +#endif // ENABLE_PRINT_BED_MODELS m_volume.set_render_color(color, size); } @@ -1834,6 +1848,14 @@ void GLModel::set_scale(const Vec3d& scale) m_volume.set_volume_scaling_factor(scale); } +#if ENABLE_PRINT_BED_MODELS +void GLModel::reset() +{ + m_volume.release_geometry(); + m_filename = ""; +} +#endif // ENABLE_PRINT_BED_MODELS + void GLModel::render() const { if (m_useVBOs) @@ -1854,9 +1876,7 @@ void GLModel::render_VBOs() const GLint current_program_id; ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id); GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; - GLint print_box_detection_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; - - m_volume.render_VBOs(color_id, print_box_detection_id, -1); + m_volume.render_VBOs(color_id, -1, -1); ::glBindBuffer(GL_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -2066,11 +2086,57 @@ bool GLCurvedArrow::on_init(bool useVBOs) else m_volume.indexed_vertex_array.load_mesh_flat_shading(TriangleMesh(vertices, triangles)); + m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); m_volume.finalize_geometry(m_useVBOs); return true; } #endif // ENABLE_SIDEBAR_VISUAL_HINTS +#if ENABLE_PRINT_BED_MODELS +bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) +{ + reset(); + + if (!boost::filesystem::exists(filename)) + return false; + + if (!boost::algorithm::iends_with(filename, ".stl")) + return false; + + Model model; + try + { + model = Model::read_from_file(filename); + } + catch (std::exception &e) + { + return false; + } + + m_filename = filename; + m_useVBOs = useVBOs; + + ModelObject* model_object = model.objects.front(); + model_object->center_around_origin(); + + TriangleMesh mesh = model.mesh(); + mesh.repair(); + + if (m_useVBOs) + m_volume.indexed_vertex_array.load_mesh_full_shading(mesh); + else + m_volume.indexed_vertex_array.load_mesh_flat_shading(mesh); + + float color[4] = { 0.235f, 0.235, 0.235f, 1.0f }; + set_color(color, 4); + + m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); + m_volume.finalize_geometry(m_useVBOs); + + return true; +} +#endif // ENABLE_PRINT_BED_MODELS + std::string _3DScene::get_gl_info(bool format_as_html, bool extensions) { return s_canvas_mgr.get_gl_info(format_as_html, extensions); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 38996dc04..b7b1af73d 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -569,13 +569,20 @@ class GLModel protected: GLVolume m_volume; bool m_useVBOs; +#if ENABLE_PRINT_BED_MODELS + std::string m_filename; +#endif // ENABLE_PRINT_BED_MODELS public: GLModel(); virtual ~GLModel(); bool init(bool useVBOs) { return on_init(useVBOs); } +#if ENABLE_PRINT_BED_MODELS + bool init_from_file(const std::string& filename, bool useVBOs) { return on_init_from_file(filename, useVBOs); } + void center_around(const Vec3d& center) { m_volume.set_volume_offset(center - m_volume.bounding_box.center()); } +#endif // ENABLE_PRINT_BED_MODELS void set_color(const float* color, unsigned int size); const Vec3d& get_offset() const; @@ -585,10 +592,22 @@ public: const Vec3d& get_scale() const; void set_scale(const Vec3d& scale); +#if ENABLE_PRINT_BED_MODELS + const std::string& get_filename() const { return m_filename; } + const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box; } + + void reset(); +#endif // ENABLE_PRINT_BED_MODELS + void render() const; protected: +#if ENABLE_PRINT_BED_MODELS + virtual bool on_init(bool useVBOs) { return false; } + virtual bool on_init_from_file(const std::string& filename, bool useVBOs) { return false; } +#else virtual bool on_init(bool useVBOs) = 0; +#endif // ENABLE_PRINT_BED_MODELS private: void render_VBOs() const; @@ -613,6 +632,14 @@ protected: }; #endif // ENABLE_SIDEBAR_VISUAL_HINTS +#if ENABLE_PRINT_BED_MODELS +class GLBed : public GLModel +{ +protected: + virtual bool on_init_from_file(const std::string& filename, bool useVBOs); +}; +#endif // ENABLE_PRINT_BED_MODELS + class _3DScene { static GUI::GLCanvas3DManager s_canvas_mgr; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5fa09d334..91b4a2855 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -386,6 +386,35 @@ Point GLCanvas3D::Bed::point_projection(const Point& point) const return m_polygon.point_projection(point); } +#if ENABLE_PRINT_BED_MODELS +void GLCanvas3D::Bed::render(float theta, bool useVBOs) const +{ + switch (m_type) + { + case MK2: + { + _render_prusa("mk2", theta, useVBOs); + break; + } + case MK3: + { + _render_prusa("mk3", theta, useVBOs); + break; + } + case SL1: + { + _render_prusa("sl1", theta, useVBOs); + break; + } + default: + case Custom: + { + _render_custom(); + break; + } + } +} +#else void GLCanvas3D::Bed::render(float theta) const { switch (m_type) @@ -413,6 +442,7 @@ void GLCanvas3D::Bed::render(float theta) const } } } +#endif // ENABLE_PRINT_BED_MODELS void GLCanvas3D::Bed::_calc_bounding_box() { @@ -504,9 +534,18 @@ GLCanvas3D::Bed::EType GLCanvas3D::Bed::_detect_type() const return type; } +#if ENABLE_PRINT_BED_MODELS +void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta, bool useVBOs) const +#else void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const +#endif // ENABLE_PRINT_BED_MODELS { - std::string filename = resources_dir() + "/icons/bed/" + key + "_top.png"; + std::string tex_path = resources_dir() + "/icons/bed/" + key; +#if ENABLE_PRINT_BED_MODELS + std::string model_path = resources_dir() + "/models/" + key; +#endif // ENABLE_PRINT_BED_MODELS + + std::string filename = tex_path + "_top.png"; if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename)) { if (!m_top_texture.load_from_file(filename, true)) @@ -516,7 +555,7 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const } } - filename = resources_dir() + "/icons/bed/" + key + "_bottom.png"; + filename = tex_path + "_bottom.png"; if ((m_bottom_texture.get_id() == 0) || (m_bottom_texture.get_source() != filename)) { if (!m_bottom_texture.load_from_file(filename, true)) @@ -526,6 +565,22 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const } } +#if ENABLE_PRINT_BED_MODELS + if (theta <= 90.0f) + { + filename = model_path + "_bed.stl"; + if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) + m_model.center_around(m_bounding_box.center() - Vec3d(0.0, 0.0, 1.0 + 0.5 * m_model.get_bounding_box().size()(2))); + + if (!m_model.get_filename().empty()) + { + ::glEnable(GL_LIGHTING); + m_model.render(); + ::glDisable(GL_LIGHTING); + } + } +#endif // ENABLE_PRINT_BED_MODELS + unsigned int triangles_vcount = m_triangles.get_vertices_count(); if (triangles_vcount > 0) { @@ -6087,7 +6142,11 @@ void GLCanvas3D::_render_background() const void GLCanvas3D::_render_bed(float theta) const { +#if ENABLE_PRINT_BED_MODELS + m_bed.render(theta, m_use_VBOs); +#else m_bed.render(theta); +#endif // ENABLE_PRINT_BED_MODELS } void GLCanvas3D::_render_axes() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 73aa4bd02..c2f2074c1 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -201,6 +201,9 @@ class GLCanvas3D GeometryBuffer m_gridlines; mutable GLTexture m_top_texture; mutable GLTexture m_bottom_texture; +#if ENABLE_PRINT_BED_MODELS + mutable GLBed m_model; +#endif // ENABLE_PRINT_BED_MODELS public: Bed(); @@ -216,14 +219,22 @@ class GLCanvas3D bool contains(const Point& point) const; Point point_projection(const Point& point) const; +#if ENABLE_PRINT_BED_MODELS + void render(float theta, bool useVBOs) const; +#else void render(float theta) const; +#endif // ENABLE_PRINT_BED_MODELS private: void _calc_bounding_box(); void _calc_triangles(const ExPolygon& poly); void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); EType _detect_type() const; +#if ENABLE_PRINT_BED_MODELS + void _render_prusa(const std::string &key, float theta, bool useVBOs) const; +#else void _render_prusa(const std::string &key, float theta) const; +#endif // ENABLE_PRINT_BED_MODELS void _render_custom() const; static bool _are_equal(const Pointfs& bed_1, const Pointfs& bed_2); }; From 2ce308693f885b168e92aa7b8973c0f71a60129e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 4 Jan 2019 13:59:41 +0100 Subject: [PATCH 09/14] Fixed object size changes using sidebar --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 34 +++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 32a38a77c..be421e5d3 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -438,7 +438,7 @@ void ObjectManipulation::change_scale_value(const Vec3d& scale) max_diff = abs_scale_diff(Z); max_diff_axis = Z; } - scaling_factor = Vec3d(scale(max_diff_axis), scale(max_diff_axis), scale(max_diff_axis)); + scaling_factor = scale(max_diff_axis) * Vec3d::Ones(); } scaling_factor *= 0.01; @@ -464,10 +464,38 @@ void ObjectManipulation::change_size_value(const Vec3d& size) ref_size = volume->bounding_box.size(); } - change_scale_value(100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2))); - #if ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION + Vec3d scale = 100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2)); + Vec3d scaling_factor = scale; + + if (selection.requires_uniform_scale()) + { + Vec3d abs_scale_diff = (scale - m_cache_scale).cwiseAbs(); + double max_diff = abs_scale_diff(X); + Axis max_diff_axis = X; + if (max_diff < abs_scale_diff(Y)) + { + max_diff = abs_scale_diff(Y); + max_diff_axis = Y; + } + if (max_diff < abs_scale_diff(Z)) + { + max_diff = abs_scale_diff(Z); + max_diff_axis = Z; + } + scaling_factor = scale(max_diff_axis) * Vec3d::Ones(); + } + + scaling_factor *= 0.01; + + auto canvas = wxGetApp().plater()->canvas3D(); + canvas->get_selection().start_dragging(); + canvas->get_selection().scale(scaling_factor, false); + canvas->do_scale(); + m_cache_size = size; +#else + change_scale_value(100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2))); #endif // ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION } From 94becf120bf0fe6b779fe952b68e73f1e62c90f1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 4 Jan 2019 14:53:01 +0100 Subject: [PATCH 10/14] Fixed euler angles calculation for the singular case --- src/libslic3r/Geometry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 317ca4f65..ba9c7b00e 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -1194,9 +1194,9 @@ Vec3d extract_euler_angles(const Eigen::Matrix& } else { - angles(0) = ::atan2(-rotation_matrix(1, 2), rotation_matrix(1, 1)); + angles(1) = 0.0; angles(1) = ::atan2(-rotation_matrix(2, 0), sy); - angles(2) = 0.0; + angles(2) = (angles(1) >-0.0) ? ::atan2(rotation_matrix(1, 2), rotation_matrix(1, 1)) : ::atan2(-rotation_matrix(1, 2), rotation_matrix(1, 1)); } return angles; From f7726b99a746d62698e18982ecac21daf412e94f Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 4 Jan 2019 15:34:07 +0100 Subject: [PATCH 11/14] Place on bed improvements - works with large meshes - area discrimination takes into account scaling of the object - planes are recalculated when some volume's type is changed (e.g. from a part to modifier mesh) --- src/slic3r/GUI/GLGizmo.cpp | 108 +++++++++++++++++++++---------------- src/slic3r/GUI/GLGizmo.hpp | 2 + 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 7de065065..9ab030490 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1519,13 +1519,14 @@ void GLGizmoFlatten::update_planes() } ch = ch.convex_hull_3d(); - - const Vec3d& bb_size = ch.bounding_box().size(); - double min_bb_face_area = std::min(bb_size(0) * bb_size(1), std::min(bb_size(0) * bb_size(2), bb_size(1) * bb_size(2))); - m_planes.clear(); - // Now we'll go through all the facets and append Points of facets sharing the same normal: + // Following constants are used for discarding too small polygons. + const float minimal_area = 20.f; // in square mm (world coordinates) + const float minimal_side = 1.f; // mm + + // Now we'll go through all the facets and append Points of facets sharing the same normal. + // This part is still performed in mesh coordinate system. const int num_of_facets = ch.stl.stats.number_of_facets; std::vector facet_queue(num_of_facets, 0); std::vector facet_visited(num_of_facets, false); @@ -1548,7 +1549,7 @@ void GLGizmoFlatten::update_planes() while (facet_queue_cnt > 0) { int facet_idx = facet_queue[-- facet_queue_cnt]; const stl_normal& this_normal = ch.stl.facet_start[facet_idx].normal; - if (std::abs(this_normal(0) - (*normal_ptr)(0)) < 0.001 && std::abs(this_normal(1) - (*normal_ptr)(1)) < 0.001 && std::abs(this_normal(2) - (*normal_ptr)(2)) < 0.001) { + if (this_normal.isApprox(*normal_ptr)) { stl_vertex* first_vertex = ch.stl.facet_start[facet_idx].vertex; for (int j=0; j<3; ++j) m_planes.back().vertices.emplace_back((double)first_vertex[j](0), (double)first_vertex[j](1), (double)first_vertex[j](2)); @@ -1563,16 +1564,18 @@ void GLGizmoFlatten::update_planes() } m_planes.back().normal = Vec3d((double)(*normal_ptr)(0), (double)(*normal_ptr)(1), (double)(*normal_ptr)(2)); - // if this is a just a very small triangle, remove it to speed up further calculations (it would be rejected anyway): + // Now we'll transform all the points into world coordinates, so that the areas, angles and distances + // make real sense. + m_planes.back().vertices = transform(m_planes.back().vertices, m_model_object->instances.front()->get_matrix()); + + // if this is a just a very small triangle, remove it to speed up further calculations (it would be rejected later anyway): if (m_planes.back().vertices.size() == 3 && - ((m_planes.back().vertices[0] - m_planes.back().vertices[1]).norm() < 1.0 - || (m_planes.back().vertices[0] - m_planes.back().vertices[2]).norm() < 1.0 - || (m_planes.back().vertices[1] - m_planes.back().vertices[2]).norm() < 1.0)) + ((m_planes.back().vertices[0] - m_planes.back().vertices[1]).norm() < minimal_side + || (m_planes.back().vertices[0] - m_planes.back().vertices[2]).norm() < minimal_side + || (m_planes.back().vertices[1] - m_planes.back().vertices[2]).norm() < minimal_side)) m_planes.pop_back(); } - const float minimal_area = 0.01f * (float)min_bb_face_area; - // Now we'll go through all the polygons, transform the points into xy plane to process them: for (unsigned int polygon_id=0; polygon_id < m_planes.size(); ++polygon_id) { Pointf3s& polygon = m_planes[polygon_id].vertices; @@ -1584,40 +1587,43 @@ void GLGizmoFlatten::update_planes() m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(normal, Vec3d::UnitZ()).toRotationMatrix(); polygon = transform(polygon, m); - polygon = Slic3r::Geometry::convex_hull(polygon); // To remove the inner points + // Now to remove the inner points. We'll misuse Geometry::convex_hull for that, but since + // it works in fixed point representation, we will rescale the polygon to avoid overflows. + // And yes, it is a nasty thing to do. Whoever has time is free to refactor. + Vec3d bb_size = BoundingBoxf3(polygon).size(); + float sf = std::min(1./bb_size(0), 1./bb_size(1)); + Transform3d tr = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d(sf, sf, 1.f)); + polygon = transform(polygon, tr); + polygon = Slic3r::Geometry::convex_hull(polygon); + polygon = transform(polygon, tr.inverse()); - // We will calculate area of the polygons and discard ones that are too small - // The limit is more forgiving in case the normal is in the direction of the coordinate axes - float area_threshold = (std::abs(normal(0)) > 0.999f || std::abs(normal(1)) > 0.999f || std::abs(normal(2)) > 0.999f) ? minimal_area : 10.0f * minimal_area; + // Calculate area of the polygons and discard ones that are too small float& area = m_planes[polygon_id].area; area = 0.f; for (unsigned int i = 0; i < polygon.size(); i++) // Shoelace formula area += polygon[i](0)*polygon[i + 1 < polygon.size() ? i + 1 : 0](1) - polygon[i + 1 < polygon.size() ? i + 1 : 0](0)*polygon[i](1); area = 0.5f * std::abs(area); - if (area < area_threshold) { - m_planes.erase(m_planes.begin()+(polygon_id--)); - continue; - } - // We check the inner angles and discard polygons with angles smaller than the following threshold - const double angle_threshold = ::cos(10.0 * (double)PI / 180.0); bool discard = false; + if (area < minimal_area) + discard = true; + else { + // We also check the inner angles and discard polygons with angles smaller than the following threshold + const double angle_threshold = ::cos(10.0 * (double)PI / 180.0); - for (unsigned int i = 0; i < polygon.size(); ++i) - { - const Vec3d& prec = polygon[(i == 0) ? polygon.size() - 1 : i - 1]; - const Vec3d& curr = polygon[i]; - const Vec3d& next = polygon[(i == polygon.size() - 1) ? 0 : i + 1]; + for (unsigned int i = 0; i < polygon.size(); ++i) { + const Vec3d& prec = polygon[(i == 0) ? polygon.size() - 1 : i - 1]; + const Vec3d& curr = polygon[i]; + const Vec3d& next = polygon[(i == polygon.size() - 1) ? 0 : i + 1]; - if ((prec - curr).normalized().dot((next - curr).normalized()) > angle_threshold) - { - discard = true; - break; + if ((prec - curr).normalized().dot((next - curr).normalized()) > angle_threshold) { + discard = true; + break; + } } } - if (discard) - { + if (discard) { m_planes.erase(m_planes.begin() + (polygon_id--)); continue; } @@ -1667,13 +1673,13 @@ void GLGizmoFlatten::update_planes() polygon = points_out; // replace the coarse polygon with the smooth one that we just created } - // Transform back to 3D; - for (auto& b : polygon) { - b(2) += 0.1f; // raise a bit above the object surface to avoid flickering - } - m = m.inverse(); - polygon = transform(polygon, m); + // Raise a bit above the object surface to avoid flickering: + for (auto& b : polygon) + b(2) += 0.1f; + + // Transform back to 3D (and also back to mesh coordinates) + polygon = transform(polygon, m_model_object->instances.front()->get_matrix().inverse() * m.inverse()); } // We'll sort the planes by area and only keep the 254 largest ones (because of the picking pass limitations): @@ -1682,12 +1688,15 @@ void GLGizmoFlatten::update_planes() // Planes are finished - let's save what we calculated it from: m_volumes_matrices.clear(); - for (const ModelVolume* vol : m_model_object->volumes) + m_volumes_types.clear(); + for (const ModelVolume* vol : m_model_object->volumes) { m_volumes_matrices.push_back(vol->get_matrix()); + m_volumes_types.push_back(vol->type()); + } + m_first_instance_scale = m_model_object->instances.front()->get_scaling_factor(); } -// Check if the bounding boxes of each volume's convex hull is the same as before -// and that scaling and rotation has not changed. In that case we don't have to recalculate it. + bool GLGizmoFlatten::is_plane_update_necessary() const { if (m_state != On || !m_model_object || m_model_object->instances.empty()) @@ -1696,8 +1705,13 @@ bool GLGizmoFlatten::is_plane_update_necessary() const if (m_model_object->volumes.size() != m_volumes_matrices.size()) return true; + // We want to recalculate when the scale changes - some planes could (dis)appear. + if (! m_model_object->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale)) + return true; + for (unsigned int i=0; i < m_model_object->volumes.size(); ++i) - if (! m_model_object->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i])) + if (! m_model_object->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i]) + || m_model_object->volumes[i]->type() != m_volumes_types[i]) return true; return false; @@ -1723,7 +1737,7 @@ GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent) if (m_quadric != nullptr) // using GLU_FILL does not work when the instance's transformation // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_SILHOUETTE); + ::gluQuadricDrawStyle(m_quadric, GLU_FILL); #endif // ENABLE_SLA_SUPPORT_GIZMO_MOD } @@ -1895,8 +1909,8 @@ void GLGizmoSlaSupports::render_grabbers(const GLCanvas3D::Selection& selection, ::glPushMatrix(); ::glLoadIdentity(); ::glTranslated(grabber_world_position(0), grabber_world_position(1), grabber_world_position(2) + z_shift); - ::gluQuadricDrawStyle(m_quadric, GLU_SILHOUETTE); - ::gluSphere(m_quadric, 0.75, 64, 36); + const float diameter = 0.8f; + ::gluSphere(m_quadric, diameter/2.f, 64, 36); ::glPopMatrix(); } @@ -1945,7 +1959,7 @@ void GLGizmoSlaSupports::render_grabbers(bool picking) const GLUquadricObj *quadric; quadric = ::gluNewQuadric(); ::gluQuadricDrawStyle(quadric, GLU_FILL ); - ::gluSphere( quadric , 0.75f, 64 , 32 ); + ::gluSphere( quadric , 0.4, 64 , 32 ); ::gluDeleteQuadric(quadric); ::glPopMatrix(); if (!picking) diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index 2588080b2..d10efa966 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -403,6 +403,8 @@ private: // This holds information to decide whether recalculation is necessary: std::vector m_volumes_matrices; + std::vector m_volumes_types; + Vec3d m_first_instance_scale; std::vector m_planes; mutable Vec3d m_starting_center; From d409abf4c6aa0fc25971ca7aef52d3bef71902e5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 4 Jan 2019 15:42:44 +0100 Subject: [PATCH 12/14] Reverted a change specific to Win32 to try to set Win32 locale for the decimal point. This only works for the current user's locale and it changes it system wide. --- src/slic3r/GUI/GUI_App.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 1d11bbe00..091071e16 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -461,10 +461,8 @@ bool GUI_App::select_language( wxArrayString & names, m_wxLocale->Init(identifiers[index]); m_wxLocale->AddCatalogLookupPathPrefix(wxString::FromUTF8(localization_dir())); m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE"); - wxSetlocale(LC_NUMERIC, "C"); -#ifdef WIN32 - ::SetLocaleInfoA(LOCALE_CUSTOM_DEFAULT, LOCALE_SDECIMAL, "."); -#endif /* WIN32 */ + //FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only. + wxSetlocale(LC_NUMERIC, "C"); Preset::update_suffix_modified(); return true; } @@ -491,10 +489,8 @@ bool GUI_App::load_language() m_wxLocale->Init(identifiers[i]); m_wxLocale->AddCatalogLookupPathPrefix(wxString::FromUTF8(localization_dir())); m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE"); + //FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only. wxSetlocale(LC_NUMERIC, "C"); -#ifdef WIN32 - ::SetLocaleInfoA(LOCALE_CUSTOM_DEFAULT, LOCALE_SDECIMAL, "."); -#endif /* WIN32 */ Preset::update_suffix_modified(); return true; } From 86e9cb604ac09318e503408947fbc5838448eddf Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 4 Jan 2019 16:18:25 +0100 Subject: [PATCH 13/14] Revert "Place on bed improvements" Some problem with disappearing planes, not worthy for a patch-release This reverts commit f7726b99a746d62698e18982ecac21daf412e94f. --- src/slic3r/GUI/GLGizmo.cpp | 108 ++++++++++++++++--------------------- src/slic3r/GUI/GLGizmo.hpp | 2 - 2 files changed, 47 insertions(+), 63 deletions(-) diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 9ab030490..7de065065 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1519,14 +1519,13 @@ void GLGizmoFlatten::update_planes() } ch = ch.convex_hull_3d(); + + const Vec3d& bb_size = ch.bounding_box().size(); + double min_bb_face_area = std::min(bb_size(0) * bb_size(1), std::min(bb_size(0) * bb_size(2), bb_size(1) * bb_size(2))); + m_planes.clear(); - // Following constants are used for discarding too small polygons. - const float minimal_area = 20.f; // in square mm (world coordinates) - const float minimal_side = 1.f; // mm - - // Now we'll go through all the facets and append Points of facets sharing the same normal. - // This part is still performed in mesh coordinate system. + // Now we'll go through all the facets and append Points of facets sharing the same normal: const int num_of_facets = ch.stl.stats.number_of_facets; std::vector facet_queue(num_of_facets, 0); std::vector facet_visited(num_of_facets, false); @@ -1549,7 +1548,7 @@ void GLGizmoFlatten::update_planes() while (facet_queue_cnt > 0) { int facet_idx = facet_queue[-- facet_queue_cnt]; const stl_normal& this_normal = ch.stl.facet_start[facet_idx].normal; - if (this_normal.isApprox(*normal_ptr)) { + if (std::abs(this_normal(0) - (*normal_ptr)(0)) < 0.001 && std::abs(this_normal(1) - (*normal_ptr)(1)) < 0.001 && std::abs(this_normal(2) - (*normal_ptr)(2)) < 0.001) { stl_vertex* first_vertex = ch.stl.facet_start[facet_idx].vertex; for (int j=0; j<3; ++j) m_planes.back().vertices.emplace_back((double)first_vertex[j](0), (double)first_vertex[j](1), (double)first_vertex[j](2)); @@ -1564,18 +1563,16 @@ void GLGizmoFlatten::update_planes() } m_planes.back().normal = Vec3d((double)(*normal_ptr)(0), (double)(*normal_ptr)(1), (double)(*normal_ptr)(2)); - // Now we'll transform all the points into world coordinates, so that the areas, angles and distances - // make real sense. - m_planes.back().vertices = transform(m_planes.back().vertices, m_model_object->instances.front()->get_matrix()); - - // if this is a just a very small triangle, remove it to speed up further calculations (it would be rejected later anyway): + // if this is a just a very small triangle, remove it to speed up further calculations (it would be rejected anyway): if (m_planes.back().vertices.size() == 3 && - ((m_planes.back().vertices[0] - m_planes.back().vertices[1]).norm() < minimal_side - || (m_planes.back().vertices[0] - m_planes.back().vertices[2]).norm() < minimal_side - || (m_planes.back().vertices[1] - m_planes.back().vertices[2]).norm() < minimal_side)) + ((m_planes.back().vertices[0] - m_planes.back().vertices[1]).norm() < 1.0 + || (m_planes.back().vertices[0] - m_planes.back().vertices[2]).norm() < 1.0 + || (m_planes.back().vertices[1] - m_planes.back().vertices[2]).norm() < 1.0)) m_planes.pop_back(); } + const float minimal_area = 0.01f * (float)min_bb_face_area; + // Now we'll go through all the polygons, transform the points into xy plane to process them: for (unsigned int polygon_id=0; polygon_id < m_planes.size(); ++polygon_id) { Pointf3s& polygon = m_planes[polygon_id].vertices; @@ -1587,43 +1584,40 @@ void GLGizmoFlatten::update_planes() m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(normal, Vec3d::UnitZ()).toRotationMatrix(); polygon = transform(polygon, m); - // Now to remove the inner points. We'll misuse Geometry::convex_hull for that, but since - // it works in fixed point representation, we will rescale the polygon to avoid overflows. - // And yes, it is a nasty thing to do. Whoever has time is free to refactor. - Vec3d bb_size = BoundingBoxf3(polygon).size(); - float sf = std::min(1./bb_size(0), 1./bb_size(1)); - Transform3d tr = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d(sf, sf, 1.f)); - polygon = transform(polygon, tr); - polygon = Slic3r::Geometry::convex_hull(polygon); - polygon = transform(polygon, tr.inverse()); + polygon = Slic3r::Geometry::convex_hull(polygon); // To remove the inner points - // Calculate area of the polygons and discard ones that are too small + // We will calculate area of the polygons and discard ones that are too small + // The limit is more forgiving in case the normal is in the direction of the coordinate axes + float area_threshold = (std::abs(normal(0)) > 0.999f || std::abs(normal(1)) > 0.999f || std::abs(normal(2)) > 0.999f) ? minimal_area : 10.0f * minimal_area; float& area = m_planes[polygon_id].area; area = 0.f; for (unsigned int i = 0; i < polygon.size(); i++) // Shoelace formula area += polygon[i](0)*polygon[i + 1 < polygon.size() ? i + 1 : 0](1) - polygon[i + 1 < polygon.size() ? i + 1 : 0](0)*polygon[i](1); area = 0.5f * std::abs(area); + if (area < area_threshold) { + m_planes.erase(m_planes.begin()+(polygon_id--)); + continue; + } + // We check the inner angles and discard polygons with angles smaller than the following threshold + const double angle_threshold = ::cos(10.0 * (double)PI / 180.0); bool discard = false; - if (area < minimal_area) - discard = true; - else { - // We also check the inner angles and discard polygons with angles smaller than the following threshold - const double angle_threshold = ::cos(10.0 * (double)PI / 180.0); - for (unsigned int i = 0; i < polygon.size(); ++i) { - const Vec3d& prec = polygon[(i == 0) ? polygon.size() - 1 : i - 1]; - const Vec3d& curr = polygon[i]; - const Vec3d& next = polygon[(i == polygon.size() - 1) ? 0 : i + 1]; + for (unsigned int i = 0; i < polygon.size(); ++i) + { + const Vec3d& prec = polygon[(i == 0) ? polygon.size() - 1 : i - 1]; + const Vec3d& curr = polygon[i]; + const Vec3d& next = polygon[(i == polygon.size() - 1) ? 0 : i + 1]; - if ((prec - curr).normalized().dot((next - curr).normalized()) > angle_threshold) { - discard = true; - break; - } + if ((prec - curr).normalized().dot((next - curr).normalized()) > angle_threshold) + { + discard = true; + break; } } - if (discard) { + if (discard) + { m_planes.erase(m_planes.begin() + (polygon_id--)); continue; } @@ -1673,13 +1667,13 @@ void GLGizmoFlatten::update_planes() polygon = points_out; // replace the coarse polygon with the smooth one that we just created } + // Transform back to 3D; + for (auto& b : polygon) { + b(2) += 0.1f; // raise a bit above the object surface to avoid flickering + } - // Raise a bit above the object surface to avoid flickering: - for (auto& b : polygon) - b(2) += 0.1f; - - // Transform back to 3D (and also back to mesh coordinates) - polygon = transform(polygon, m_model_object->instances.front()->get_matrix().inverse() * m.inverse()); + m = m.inverse(); + polygon = transform(polygon, m); } // We'll sort the planes by area and only keep the 254 largest ones (because of the picking pass limitations): @@ -1688,15 +1682,12 @@ void GLGizmoFlatten::update_planes() // Planes are finished - let's save what we calculated it from: m_volumes_matrices.clear(); - m_volumes_types.clear(); - for (const ModelVolume* vol : m_model_object->volumes) { + for (const ModelVolume* vol : m_model_object->volumes) m_volumes_matrices.push_back(vol->get_matrix()); - m_volumes_types.push_back(vol->type()); - } - m_first_instance_scale = m_model_object->instances.front()->get_scaling_factor(); } - +// Check if the bounding boxes of each volume's convex hull is the same as before +// and that scaling and rotation has not changed. In that case we don't have to recalculate it. bool GLGizmoFlatten::is_plane_update_necessary() const { if (m_state != On || !m_model_object || m_model_object->instances.empty()) @@ -1705,13 +1696,8 @@ bool GLGizmoFlatten::is_plane_update_necessary() const if (m_model_object->volumes.size() != m_volumes_matrices.size()) return true; - // We want to recalculate when the scale changes - some planes could (dis)appear. - if (! m_model_object->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale)) - return true; - for (unsigned int i=0; i < m_model_object->volumes.size(); ++i) - if (! m_model_object->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i]) - || m_model_object->volumes[i]->type() != m_volumes_types[i]) + if (! m_model_object->volumes[i]->get_matrix().isApprox(m_volumes_matrices[i])) return true; return false; @@ -1737,7 +1723,7 @@ GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent) if (m_quadric != nullptr) // using GLU_FILL does not work when the instance's transformation // contains mirroring (normals are reverted) - ::gluQuadricDrawStyle(m_quadric, GLU_FILL); + ::gluQuadricDrawStyle(m_quadric, GLU_SILHOUETTE); #endif // ENABLE_SLA_SUPPORT_GIZMO_MOD } @@ -1909,8 +1895,8 @@ void GLGizmoSlaSupports::render_grabbers(const GLCanvas3D::Selection& selection, ::glPushMatrix(); ::glLoadIdentity(); ::glTranslated(grabber_world_position(0), grabber_world_position(1), grabber_world_position(2) + z_shift); - const float diameter = 0.8f; - ::gluSphere(m_quadric, diameter/2.f, 64, 36); + ::gluQuadricDrawStyle(m_quadric, GLU_SILHOUETTE); + ::gluSphere(m_quadric, 0.75, 64, 36); ::glPopMatrix(); } @@ -1959,7 +1945,7 @@ void GLGizmoSlaSupports::render_grabbers(bool picking) const GLUquadricObj *quadric; quadric = ::gluNewQuadric(); ::gluQuadricDrawStyle(quadric, GLU_FILL ); - ::gluSphere( quadric , 0.4, 64 , 32 ); + ::gluSphere( quadric , 0.75f, 64 , 32 ); ::gluDeleteQuadric(quadric); ::glPopMatrix(); if (!picking) diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index d10efa966..2588080b2 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -403,8 +403,6 @@ private: // This holds information to decide whether recalculation is necessary: std::vector m_volumes_matrices; - std::vector m_volumes_types; - Vec3d m_first_instance_scale; std::vector m_planes; mutable Vec3d m_starting_center; From 567b3670613f0b695df8f783d973c53a4b6aae84 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 4 Jan 2019 16:48:41 +0100 Subject: [PATCH 14/14] Disabled the print bed mesh temporarily, bumped up the build version to alpha2, fixed one minor issue in G-code generator --- src/libslic3r/GCode.cpp | 2 +- src/libslic3r/Technologies.hpp | 2 +- version.inc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index b13c38742..1134b383f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -791,7 +791,7 @@ void GCode::_do_export(Print &print, FILE *file) } } else { for (const std::string &start_gcode : print.config().start_filament_gcode.values) - _writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config().start_filament_gcode.values.front()))); + _writeln(file, this->placeholder_parser_process("start_filament_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config().start_filament_gcode.values.front()))); } this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true); print.throw_if_canceled(); diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index dc6a2041c..bab7f3b73 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -45,7 +45,7 @@ // Improves navigation between sidebar fields #define ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION (1 && ENABLE_1_42_0_ALPHA2) // Adds print bed models to 3D scene -#define ENABLE_PRINT_BED_MODELS (1 && ENABLE_1_42_0_ALPHA2) +#define ENABLE_PRINT_BED_MODELS (0 && ENABLE_1_42_0_ALPHA2) #endif // _technologies_h_ diff --git a/version.inc b/version.inc index d648bc48b..3cdadcbb6 100644 --- a/version.inc +++ b/version.inc @@ -2,7 +2,7 @@ # (the version numbers are generated by the build script from the git current label) set(SLIC3R_FORK_NAME "Slic3r Prusa Edition") -set(SLIC3R_VERSION "1.42.0-alpha1") +set(SLIC3R_VERSION "1.42.0-alpha2") set(SLIC3R_BUILD "${SLIC3R_VERSION}+UNKNOWN") set(SLIC3R_BUILD_ID "${SLIC3R_BUILD_ID}") set(SLIC3R_RC_VERSION "1,42,0,0")