diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index bf1d24e8a..8e48a56d6 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -201,12 +201,13 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T // Let the m_writer know the current extruder_id, but ignore the generated G-code. if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id)) gcodegen.writer().toolchange(new_extruder_id); + gcodegen.placeholder_parser().set("current_extruder", new_extruder_id); + // Always append the filament start G-code even if the extruder did not switch, // because the wipe tower resets the linear advance and we want it to be re-enabled. const std::string &start_filament_gcode = gcodegen.config().start_filament_gcode.get_at(new_extruder_id); if (! start_filament_gcode.empty()) { // Process the start_filament_gcode for the active filament only. - gcodegen.placeholder_parser().set("current_extruder", new_extruder_id); DynamicConfig config; config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_extruder_id)); gcode += gcodegen.placeholder_parser_process("start_filament_gcode", start_filament_gcode, new_extruder_id, &config); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index f43c3bf7a..64b2160b0 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -176,6 +176,8 @@ private: { return level(r1) < level(r2); }); + + if(it == cont.end()) return it; T diff = std::abs(level(*it) - lvl); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 4eb6c5aa8..c8e411ee4 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -44,6 +44,10 @@ #include "SysInfoDialog.hpp" #include "KBShortcutsDialog.hpp" +#ifdef __WXMSW__ +#include +#endif // __WXMSW__ + namespace Slic3r { namespace GUI { @@ -182,6 +186,10 @@ bool GUI_App::on_init_inner() app_config->set("version", SLIC3R_VERSION); app_config->save(); +#ifdef __WXMSW__ + associate_3mf_files(); +#endif // __WXMSW__ + preset_updater = new PresetUpdater(); Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent &evt) { app_config->set("version_online", into_u8(evt.GetString())); @@ -951,5 +959,64 @@ void GUI_App::window_pos_sanitize(wxTopLevelWindow* window) // } +#ifdef __WXMSW__ +void GUI_App::associate_3mf_files() +{ + // see as reference: https://stackoverflow.com/questions/20245262/c-program-needs-an-file-association + + auto reg_set = [](HKEY hkeyHive, const wchar_t* pszVar, const wchar_t* pszValue) + { + wchar_t szValueCurrent[1000]; + DWORD dwType; + DWORD dwSize = sizeof(szValueCurrent); + + int iRC = ::RegGetValueW(hkeyHive, pszVar, nullptr, RRF_RT_ANY, &dwType, szValueCurrent, &dwSize); + + bool bDidntExist = iRC == ERROR_FILE_NOT_FOUND; + + if ((iRC != ERROR_SUCCESS) && !bDidntExist) + // an error occurred + return; + + if (!bDidntExist) + { + if (dwType != REG_SZ) + // invalid type + return; + + if (::wcscmp(szValueCurrent, pszValue) == 0) + // value already set + return; + } + + DWORD dwDisposition; + HKEY hkey; + iRC = ::RegCreateKeyExW(hkeyHive, pszVar, 0, 0, 0, KEY_ALL_ACCESS, nullptr, &hkey, &dwDisposition); + if (iRC == ERROR_SUCCESS) + iRC = ::RegSetValueExW(hkey, L"", 0, REG_SZ, (BYTE*)pszValue, (::wcslen(pszValue) + 1) * sizeof(wchar_t)); + + RegCloseKey(hkey); + }; + + wchar_t app_path[MAX_PATH]; + ::GetModuleFileNameW(nullptr, app_path, sizeof(app_path)); + + std::wstring prog_path = L"\"" + std::wstring(app_path) + L"\""; + std::wstring prog_id = L"Prusa.Slicer.1"; + std::wstring prog_desc = L"PrusaSlicer"; + std::wstring prog_command = prog_path + L" \"%1\""; + std::wstring reg_base = L"Software\\Classes"; + std::wstring reg_extension = reg_base + L"\\.3mf"; + std::wstring reg_prog_id = reg_base + L"\\" + prog_id; + std::wstring reg_prog_id_command = reg_prog_id + L"\\Shell\\Open\\Command"; + + reg_set(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str()); + reg_set(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str()); + reg_set(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str()); + + ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); +} +#endif // __WXMSW__ + } // GUI } //Slic3r diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 5c2ead49c..716bb8fd0 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -178,6 +178,9 @@ private: void window_pos_save(wxTopLevelWindow* window, const std::string &name); void window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false); void window_pos_sanitize(wxTopLevelWindow* window); +#ifdef __WXMSW__ + void associate_3mf_files(); +#endif // __WXMSW__ }; DECLARE_APP(GUI_App)