From 5b1c1d592261e96f626b1172601a5bd0e4348575 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 9 Jan 2019 10:43:17 +0100 Subject: [PATCH] Fixed a bug in the Win32 start wrapper (wrong number of parameters was passed for the GUI slic3r.exe). Reworked command line processing for the GUI slic3r. Now the config is loaded first, then the model files (also the configs from AMF/3MF are applied), and lastly the free standing parameters are applied. Fixed unescaping for command line parameters. The string parameters are now not unescaped, string vector parameters are unescaped only if enquoted. Tab::load_current_preset() - disabled CallAfter for predictability. With CallAfter, it was difficult to call the method in sequence with other methods. Fixed some missing ->Destroy() calls on dialogs created from MainFrame Fixed some compiler warnings. --- src/libslic3r/Config.cpp | 40 +++++++++------ src/libslic3r/Point.hpp | 2 +- src/libslic3r/PrintConfig.hpp | 5 +- src/slic3r.cpp | 54 +++++++++++++++------ src/slic3r/GUI/MainFrame.cpp | 91 ++++++++++++++++++++++++----------- src/slic3r/GUI/MainFrame.hpp | 9 ++-- src/slic3r/GUI/Plater.cpp | 10 ++++ src/slic3r/GUI/Plater.hpp | 2 + src/slic3r/GUI/Tab.cpp | 13 +++-- src/slic3r/GUI/Tab.hpp | 2 - src/slic3r_app_msvc.cpp | 58 ++++++++++++++-------- 11 files changed, 194 insertions(+), 92 deletions(-) diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index c295d6def..c9fbe90ac 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -604,23 +604,31 @@ bool DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra) value = argv[++ i]; } // Store the option value. - const bool existing = this->has(opt_key); - if (ConfigOptionBool* opt = this->opt(opt_key, true)) { - opt->value = !no; - } else if (ConfigOptionBools* opt = this->opt(opt_key, true)) { - if (!existing) opt->values.clear(); // remove the default values - opt->values.push_back(!no); - } else if (ConfigOptionStrings* opt = this->opt(opt_key, true)) { - if (!existing) opt->values.clear(); // remove the default values - opt->deserialize(value, true); - } else if (ConfigOptionFloats* opt = this->opt(opt_key, true)) { - if (!existing) opt->values.clear(); // remove the default values - opt->deserialize(value, true); - } else if (ConfigOptionPoints* opt = this->opt(opt_key, true)) { - if (!existing) opt->values.clear(); // remove the default values - opt->deserialize(value, true); + const bool existing = this->has(opt_key); + ConfigOption *opt_base = this->option(opt_key, true); + ConfigOptionVectorBase *opt_vector = opt_base->is_vector() ? static_cast(opt_base) : nullptr; + if (opt_vector) { + // Vector values will be chained. Repeated use of a parameter will append the parameter or parameters + // to the end of the value. + if (!existing) + // remove the default values + opt_vector->deserialize("", true); + if (opt_base->type() == coBools) + static_cast(opt_base)->values.push_back(!no); + else + // Deserialize any other vector value (ConfigOptionInts, Floats, Percents, Points) the same way + // they get deserialized from an .ini file. For ConfigOptionStrings, that means that the C-style unescape + // will be applied for values enclosed in quotes, while values non-enclosed in quotes are left to be + // unescaped by the calling shell. + opt_vector->deserialize(value, true); + } else if (opt_base->type() == coBool) { + static_cast(opt_base)->value = !no; + } else if (opt_base->type() == coString) { + // Do not unescape single string values, the unescaping is left to the calling shell. + static_cast(opt_base)->value = value; } else { - this->set_deserialize(opt_key, value, true); + // Any scalar value of a type different from Bool and String. + this->set_deserialize(opt_key, value, false); } } return true; diff --git a/src/libslic3r/Point.hpp b/src/libslic3r/Point.hpp index d92667362..d456fb9c6 100644 --- a/src/libslic3r/Point.hpp +++ b/src/libslic3r/Point.hpp @@ -103,7 +103,7 @@ public: Point& operator+=(const Point& rhs) { (*this)(0) += rhs(0); (*this)(1) += rhs(1); return *this; } Point& operator-=(const Point& rhs) { (*this)(0) -= rhs(0); (*this)(1) -= rhs(1); return *this; } - Point& operator*=(const double &rhs) { (*this)(0) *= rhs; (*this)(1) *= rhs; return *this; } + Point& operator*=(const double &rhs) { (*this)(0) = coord_t((*this)(0) * rhs); (*this)(1) = coord_t((*this)(1) * rhs); return *this; } void rotate(double angle); void rotate(double angle, const Point ¢er); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 8713ed03f..4e12114df 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1164,12 +1164,11 @@ public: class DynamicPrintAndCLIConfig : public DynamicPrintConfig { public: - DynamicPrintAndCLIConfig() { this->apply(FullPrintConfig::defaults()); this->apply(CLIConfig()); } - DynamicPrintAndCLIConfig(const DynamicPrintAndCLIConfig &other) : DynamicPrintConfig(other) {} + DynamicPrintAndCLIConfig() {} + DynamicPrintAndCLIConfig(const DynamicPrintAndCLIConfig &other) : DynamicPrintConfig(other) {} // Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here. 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(). diff --git a/src/slic3r.cpp b/src/slic3r.cpp index 6cd16889b..d242df168 100644 --- a/src/slic3r.cpp +++ b/src/slic3r.cpp @@ -59,10 +59,10 @@ int main(int argc, char **argv) } // parse all command line options into a DynamicConfig - DynamicPrintAndCLIConfig config; + DynamicPrintAndCLIConfig all_config; t_config_option_keys input_files; // if any option is unsupported, print usage and abort immediately - if (! config.read_cli(argc, argv, &input_files)) { + if (! all_config.read_cli(argc, argv, &input_files)) { printUsage(); return 0; } @@ -96,21 +96,15 @@ int main(int argc, char **argv) // apply command line options to a more handy CLIConfig CLIConfig cli_config; - cli_config.apply(config, true); + cli_config.apply(all_config, true); set_data_dir(cli_config.datadir.value); - DynamicPrintConfig print_config; + // Load the extra config values. + DynamicPrintConfig extra_config; + extra_config.apply(all_config, true); - if ((argc == 1 || cli_config.gui.value) && ! cli_config.no_gui.value && ! cli_config.help.value && cli_config.save.value.empty()) { -#if 1 - GUI::GUI_App *gui = new GUI::GUI_App(); - GUI::GUI_App::SetInstance(gui); - wxEntry(argc, argv); -#else - std::cout << "GUI support has not been built." << "\n"; -#endif - } // load config files supplied via --load + DynamicPrintConfig print_config; for (const std::string &file : cli_config.load.values) { if (! boost::filesystem::exists(file)) { boost::nowide::cout << "No such file: " << file << std::endl; @@ -126,10 +120,40 @@ int main(int argc, char **argv) c.normalize(); print_config.apply(c); } - + + if ((argc == 1 || cli_config.gui.value) && ! cli_config.no_gui.value && ! cli_config.help.value && cli_config.save.value.empty()) { +#if 1 + GUI::GUI_App *gui = new GUI::GUI_App(); + GUI::GUI_App::SetInstance(gui); + gui->CallAfter([gui, &input_files, &cli_config, &extra_config, &print_config] { +#if 0 + // Load the cummulative config over the currently active profiles. + //FIXME if multiple configs are loaded, only the last one will have an effect. + // We need to decide what to do about loading of separate presets (just print preset, just filament preset etc). + // As of now only the full configs are supported here. + if (! print_config.empty()) + gui->mainframe->load_config(print_config); +#endif + if (! cli_config.load.values.empty()) + // Load the last config to give it a name at the UI. The name of the preset may be later + // changed by loading an AMF or 3MF. + //FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config. + gui->mainframe->load_config_file(cli_config.load.values.back()); + // If loading a 3MF file, the config is loaded from the last one. + gui->plater()->load_files(input_files, true, true); + if (! extra_config.empty()) + gui->mainframe->load_config(extra_config); + }); + return wxEntry(argc, argv); +#else + std::cout << "GUI support has not been built." << "\n"; + return -1; +#endif + } + // apply command line options to a more specific DynamicPrintConfig which provides normalize() // (command line options override --load files) - print_config.apply(config, true); + print_config.apply(extra_config, true); // write config if requested if (! cli_config.save.value.empty()) { diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 7eff483cf..a721d1e18 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include "libslic3r/Print.hpp" #include "libslic3r/Polygon.hpp" @@ -635,28 +637,34 @@ void MainFrame::export_config() } // Load a config file containing a Print, Filament & Printer preset. -void MainFrame::load_config_file(wxString file/* = wxEmptyString*/) +void MainFrame::load_config_file() { - if (file.IsEmpty()) { - if (!wxGetApp().check_unsaved_changes()) - return; - auto dlg = new wxFileDialog(this, _(L("Select configuration to load:")), - !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(), - "config.ini", "INI files (*.ini, *.gcode)|*.ini;*.INI;*.gcode;*.g", wxFD_OPEN | wxFD_FILE_MUST_EXIST); - if (dlg->ShowModal() != wxID_OK) - return; - file = dlg->GetPath(); - dlg->Destroy(); + if (!wxGetApp().check_unsaved_changes()) + return; + auto dlg = new wxFileDialog(this, _(L("Select configuration to load:")), + !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(), + "config.ini", "INI files (*.ini, *.gcode)|*.ini;*.INI;*.gcode;*.g", wxFD_OPEN | wxFD_FILE_MUST_EXIST); + wxString file; + if (dlg->ShowModal() == wxID_OK) + file = dlg->GetPath(); + dlg->Destroy(); + if (! file.IsEmpty() && this->load_config_file(file.ToUTF8().data())) { + wxGetApp().app_config->update_config_dir(get_dir_name(file)); + m_last_config = file; } +} + +// Load a config file containing a Print, Filament & Printer preset from command line. +bool MainFrame::load_config_file(const std::string &path) +{ try { - wxGetApp().preset_bundle->load_config_file(file.ToUTF8().data()); + wxGetApp().preset_bundle->load_config_file(path); } catch (const std::exception &ex) { show_error(this, ex.what()); - return; + return false; } - wxGetApp().load_current_presets(); - wxGetApp().app_config->update_config_dir(get_dir_name(file)); - m_last_config = file; + wxGetApp().load_current_presets(); + return true; } void MainFrame::export_configbundle() @@ -700,11 +708,13 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re auto dlg = new wxFileDialog(this, _(L("Select configuration to load:")), !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(), "config.ini", file_wildcards(FT_INI), wxFD_OPEN | wxFD_FILE_MUST_EXIST); - if (dlg->ShowModal() != wxID_OK) - return; + if (dlg->ShowModal() != wxID_OK) { + dlg->Destroy(); + return; + } file = dlg->GetPath(); - dlg->Destroy(); - } + dlg->Destroy(); + } wxGetApp().app_config->update_config_dir(get_dir_name(file)); @@ -727,10 +737,37 @@ void MainFrame::load_configbundle(wxString file/* = wxEmptyString, const bool re // Also update the platter with the new presets. void MainFrame::load_config(const DynamicPrintConfig& config) { - for (auto tab : wxGetApp().tabs_list) - tab->load_config(config); - if (m_plater) + PrinterTechnology printer_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology(); + const auto *opt_printer_technology = config.option>("printer_technology"); + if (opt_printer_technology != nullptr && opt_printer_technology->value != printer_technology) { + printer_technology = opt_printer_technology->value; + this->plater()->set_printer_technology(printer_technology); + } +#if 0 + for (auto tab : wxGetApp().tabs_list) + if (tab->supports_printer_technology(printer_technology)) { + if (tab->name() == "printer") + static_cast(tab)->update_pages(); + tab->load_config(config); + } + if (m_plater) m_plater->on_config_change(config); +#else + // Load the currently selected preset into the GUI, update the preset selection box. + //FIXME this is not quite safe for multi-extruder printers, + // as the number of extruders is not adjusted for the vector values. + // (see PresetBundle::update_multi_material_filament_presets()) + // Better to call PresetBundle::load_config() instead? + for (auto tab : wxGetApp().tabs_list) + if (tab->supports_printer_technology(printer_technology)) { + // Only apply keys, which are present in the tab's config. Ignore the other keys. + for (const std::string &opt_key : tab->get_config()->diff(config)) + // Ignore print_settings_id, printer_settings_id, filament_settings_id etc. + if (! boost::algorithm::ends_with(opt_key, "_settings_id")) + tab->get_config()->option(opt_key)->set(config.option(opt_key)); + } + wxGetApp().load_current_presets(); +#endif } void MainFrame::select_tab(size_t tab) const @@ -806,14 +843,14 @@ void MainFrame::update_ui_from_settings() tab->update_ui_from_settings(); } -std::string MainFrame::get_base_name(const wxString full_name) const +std::string MainFrame::get_base_name(const wxString &full_name) const { - return boost::filesystem::path(full_name).filename().string(); + return boost::filesystem::path(full_name.wx_str()).filename().string(); } -std::string MainFrame::get_dir_name(const wxString full_name) const +std::string MainFrame::get_dir_name(const wxString &full_name) const { - return boost::filesystem::path(full_name).parent_path().string(); + return boost::filesystem::path(full_name.wx_str()).parent_path().string(); } diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index e0411b6da..954906903 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -53,8 +53,8 @@ class MainFrame : public wxFrame PrintHostQueueDialog *m_printhost_queue_dlg; - std::string get_base_name(const wxString full_name) const ; - std::string get_dir_name(const wxString full_name) const ; + std::string get_base_name(const wxString &full_name) const; + std::string get_dir_name(const wxString &full_name) const; void on_presets_changed(SimpleEvent&); void on_value_changed(wxCommandEvent&); @@ -86,7 +86,10 @@ public: void reslice_now(); void repair_stl(); void export_config(); - void load_config_file(wxString file = wxEmptyString); + // Query user for the config file and open it. + void load_config_file(); + // Open a config file. Return true if loaded. + bool load_config_file(const std::string &path); void export_configbundle(); void load_configbundle(wxString file = wxEmptyString); void load_config(const DynamicPrintConfig& config); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 941a181d3..9fb87a197 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2594,6 +2594,16 @@ void Plater::extract_config_from_project() void Plater::load_files(const std::vector& input_files, bool load_model, bool load_config) { p->load_files(input_files, load_model, load_config); } +// To be called when providing a list of files to the GUI slic3r on command line. +void Plater::load_files(const std::vector& input_files, bool load_model, bool load_config) +{ + std::vector paths; + paths.reserve(input_files.size()); + for (const std::string &path : input_files) + paths.emplace_back(path); + p->load_files(paths, load_model, load_config); +} + void Plater::update() { p->update(); } void Plater::update_ui_from_settings() { p->update_ui_from_settings(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index f433d655d..11a4f0453 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -116,6 +116,8 @@ public: void extract_config_from_project(); void load_files(const std::vector& input_files, bool load_model = true, bool load_config = true); + // To be called when providing a list of files to the GUI slic3r on command line. + void load_files(const std::vector& input_files, bool load_model = true, bool load_config = true); void update(); void select_view(const std::string& direction); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 162e62155..4601d05d3 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2283,7 +2283,7 @@ void TabPrinter::update_sla() // Initialize the UI from the current preset void Tab::load_current_preset() { - auto preset = m_presets->get_edited_preset(); + const Preset& preset = m_presets->get_edited_preset(); (preset.is_default || preset.is_system) ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true); @@ -2302,11 +2302,14 @@ void Tab::load_current_preset() m_undo_to_sys_btn->Enable(!preset.is_default); +#if 0 // use CallAfter because some field triggers schedule on_change calls using CallAfter, // and we don't want them to be called after this update_dirty() as they would mark the // preset dirty again // (not sure this is true anymore now that update_dirty is idempotent) - wxTheApp->CallAfter([this]{ + wxTheApp->CallAfter([this] +#endif + { // checking out if this Tab exists till this moment if (!wxGetApp().checked_tab(this)) return; @@ -2354,7 +2357,10 @@ void Tab::load_current_preset() init_options_list(); update_visibility(); update_changed_ui(); - }); + } +#if 0 + ); +#endif } //Regerenerate content of the page tree. @@ -2428,7 +2434,6 @@ void Tab::select_preset(std::string preset_name) bool print_tab = m_presets->type() == Preset::TYPE_PRINT || m_presets->type() == Preset::TYPE_SLA_PRINT; bool printer_tab = m_presets->type() == Preset::TYPE_PRINTER; bool canceled = false; -// m_reload_dependent_tabs = {}; m_dependent_tabs = {}; if (current_dirty && !may_discard_current_dirty_preset()) { canceled = true; diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 4263696d1..b3288a80d 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -185,7 +185,6 @@ protected: bool m_disable_tree_sel_changed_event; bool m_show_incompatible_presets; - std::vector m_reload_dependent_tabs = {}; std::vector m_dependent_tabs = {}; enum OptStatus { osSystemValue = 1, osInitValue = 2 }; std::map m_options_list; @@ -265,7 +264,6 @@ public: DynamicPrintConfig* get_config() { return m_config; } PresetCollection* get_presets() { return m_presets; } - std::vector get_dependent_tabs() { return m_reload_dependent_tabs; } size_t get_selected_preset_item() { return m_selected_preset_item; } void on_value_change(const std::string& opt_key, const boost::any& value); diff --git a/src/slic3r_app_msvc.cpp b/src/slic3r_app_msvc.cpp index 7cd97dfc3..ff5ad6cfa 100644 --- a/src/slic3r_app_msvc.cpp +++ b/src/slic3r_app_msvc.cpp @@ -21,6 +21,8 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; #include #include +#include + class OpenGLVersionCheck { public: @@ -44,8 +46,8 @@ public: if (RegisterClass(&wc)) { HWND hwnd = CreateWindowW(wc.lpszClassName, L"slic3r_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this); if (hwnd) { - this->message_pump_exit = false; - while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! this->message_pump_exit) + message_pump_exit = false; + while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit) DispatchMessage(&msg); } } @@ -55,13 +57,18 @@ public: void unload_opengl_dll() { if (this->hOpenGL) { - FreeLibrary(this->hOpenGL); + BOOL released = FreeLibrary(this->hOpenGL); + if (released) + printf("System OpenGL library released\n"); + else + printf("System OpenGL library NOT released\n"); this->hOpenGL = nullptr; } } bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { + // printf("is_version_greater_or_equal_to, version: %s\n", version.c_str()); std::vector tokens; boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); if (tokens.empty()) @@ -76,6 +83,7 @@ public: gl_major = ::atoi(numbers[0].c_str()); if (numbers.size() > 1) gl_minor = ::atoi(numbers[1].c_str()); + // printf("Major: %d, minor: %d\n", gl_major, gl_minor); if (gl_major < major) return false; else if (gl_major > major) @@ -85,7 +93,7 @@ public: } protected: - bool message_pump_exit = false; + static bool message_pump_exit; void check(HWND hWnd) { @@ -131,17 +139,18 @@ protected: }; HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd); - // Gdi32.dll + // Gdi32.dll int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); - // Gdi32.dll - SetPixelFormat(ourWindowHandleToDeviceContext,letWindowsChooseThisPixelFormat, &pfd); - // Opengl32.dll + // Gdi32.dll + SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd); + // Opengl32.dll HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext); wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext); // Opengl32.dll const char *data = (const char*)glGetString(GL_VERSION); if (data != nullptr) this->version = data; + // printf("check -version: %s\n", version.c_str()); data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION if (data != nullptr) this->glsl_version = data; @@ -153,6 +162,7 @@ protected: this->renderer = data; // Opengl32.dll wglDeleteContext(glcontext); + ::ReleaseDC(hWnd, ourWindowHandleToDeviceContext); this->success = true; } @@ -166,15 +176,19 @@ protected: OpenGLVersionCheck *ogl_data = reinterpret_cast(pCreate->lpCreateParams); ogl_data->check(hWnd); DestroyWindow(hWnd); - ogl_data->message_pump_exit = true; return 0; } + case WM_NCDESTROY: + message_pump_exit = true; + return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); } } }; +bool OpenGLVersionCheck::message_pump_exit = false; + extern "C" { typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv); Slic3rMainFunc slic3r_main = nullptr; @@ -190,6 +204,16 @@ int wmain(int argc, wchar_t **argv) { #endif + std::vector argv_extended; + argv_extended.emplace_back(argv[0]); +#ifdef SLIC3R_WRAPPER_GUI + std::wstring cmd_gui = L"--gui"; + argv_extended.emplace_back(const_cast(cmd_gui.data())); +#endif + for (int i = 1; i < argc; ++i) + argv_extended.emplace_back(argv[i]); + argv_extended.emplace_back(nullptr); + OpenGLVersionCheck opengl_version_check; bool load_mesa = ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0); @@ -213,7 +237,8 @@ int wmain(int argc, wchar_t **argv) HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0); if (hInstance_OpenGL == nullptr) { printf("MESA OpenGL library was not loaded\n"); - } + } else + printf("MESA OpenGL library was loaded sucessfully\n"); } wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 }; @@ -239,15 +264,6 @@ int wmain(int argc, wchar_t **argv) printf("could not locate the function slic3r_main in slic3r.dll\n"); return -1; } - - std::vector argv_extended; - argv_extended.emplace_back(argv[0]); -#ifdef SLIC3R_WRAPPER_GUI - std::wstring cmd_gui = L"--gui"; - argv_extended.emplace_back(const_cast(cmd_gui.data())); -#endif - for (int i = 1; i < argc; ++ i) - argv_extended.emplace_back(argv[i]); - argv_extended.emplace_back(nullptr); - return slic3r_main(argc, argv_extended.data()); + // argc minus the trailing nullptr of the argv + return slic3r_main(argv_extended.size() - 1, argv_extended.data()); }