Merge branch 'master' into lm_sla_supports_auto2
BIN
resources/icons/bed/mk2_4096_bottom.png
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
resources/icons/bed/mk2_4096_top.png
Normal file
After Width: | Height: | Size: 364 KiB |
BIN
resources/icons/bed/mk2_8192_bottom.png
Normal file
After Width: | Height: | Size: 398 KiB |
BIN
resources/icons/bed/mk2_8192_top.png
Normal file
After Width: | Height: | Size: 794 KiB |
BIN
resources/icons/bed/mk3_4096_bottom.png
Normal file
After Width: | Height: | Size: 143 KiB |
BIN
resources/icons/bed/mk3_4096_top.png
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
resources/icons/bed/mk3_8192_bottom.png
Normal file
After Width: | Height: | Size: 396 KiB |
BIN
resources/icons/bed/mk3_8192_top.png
Normal file
After Width: | Height: | Size: 790 KiB |
BIN
resources/icons/bed/sl1_4096_bottom.png
Normal file
After Width: | Height: | Size: 105 KiB |
BIN
resources/icons/bed/sl1_4096_top.png
Normal file
After Width: | Height: | Size: 277 KiB |
BIN
resources/icons/bed/sl1_8192_bottom.png
Normal file
After Width: | Height: | Size: 324 KiB |
BIN
resources/icons/bed/sl1_8192_top.png
Normal file
After Width: | Height: | Size: 674 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 58 KiB |
BIN
resources/icons/printers/PrusaResearch_MK2.5S.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
resources/icons/printers/PrusaResearch_MK2.5SMMU2S.png
Normal file
After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 65 KiB |
BIN
resources/icons/printers/PrusaResearch_MK3S.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
resources/icons/printers/PrusaResearch_MK3SMMU2S.png
Normal file
After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 55 KiB |
|
@ -1,8 +1,14 @@
|
||||||
|
min_slic3r_version = 1.42.0-alpha6
|
||||||
|
0.8.0-alpha6
|
||||||
min_slic3r_version = 1.42.0-alpha
|
min_slic3r_version = 1.42.0-alpha
|
||||||
|
0.8.0-alpha
|
||||||
0.4.0-alpha4 Updated SLA profiles
|
0.4.0-alpha4 Updated SLA profiles
|
||||||
0.4.0-alpha3 Update of SLA profiles
|
0.4.0-alpha3 Update of SLA profiles
|
||||||
0.4.0-alpha2 First SLA profiles
|
0.4.0-alpha2 First SLA profiles
|
||||||
|
min_slic3r_version = 1.41.3-alpha
|
||||||
|
0.4.0 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||||
min_slic3r_version = 1.41.1
|
min_slic3r_version = 1.41.1
|
||||||
|
0.3.4 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
|
||||||
0.3.3 Prusament PETG released
|
0.3.3 Prusament PETG released
|
||||||
0.3.2 New MK2.5 and MK3 FW versions
|
0.3.2 New MK2.5 and MK3 FW versions
|
||||||
0.3.1 New MK2.5 and MK3 FW versions
|
0.3.1 New MK2.5 and MK3 FW versions
|
||||||
|
@ -34,6 +40,7 @@ min_slic3r_version = 1.41.0-alpha
|
||||||
0.2.0-alpha1 added initial profiles for the i3 MK3 Multi Material Upgrade 2.0
|
0.2.0-alpha1 added initial profiles for the i3 MK3 Multi Material Upgrade 2.0
|
||||||
0.2.0-alpha moved machine limits from the start G-code to the new print profile parameters
|
0.2.0-alpha moved machine limits from the start G-code to the new print profile parameters
|
||||||
min_slic3r_version = 1.40.0
|
min_slic3r_version = 1.40.0
|
||||||
|
0.1.12 New MK2.5 and MK3 FW versions
|
||||||
0.1.11 fw version changed to 3.3.1
|
0.1.11 fw version changed to 3.3.1
|
||||||
0.1.10 MK3 jerk and acceleration update
|
0.1.10 MK3 jerk and acceleration update
|
||||||
0.1.9 edited support extrusion width for 0.25 and 0.6 nozzles
|
0.1.9 edited support extrusion width for 0.25 and 0.6 nozzles
|
||||||
|
|
|
@ -1333,6 +1333,8 @@ void Transformation::set_rotation(const Vec3d& rotation)
|
||||||
void Transformation::set_rotation(Axis axis, double rotation)
|
void Transformation::set_rotation(Axis axis, double rotation)
|
||||||
{
|
{
|
||||||
rotation = angle_to_0_2PI(rotation);
|
rotation = angle_to_0_2PI(rotation);
|
||||||
|
if (is_approx(std::abs(rotation), 2.0 * (double)PI))
|
||||||
|
rotation = 0.0;
|
||||||
|
|
||||||
if (m_rotation(axis) != rotation)
|
if (m_rotation(axis) != rotation)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1445,7 +1445,7 @@ int ModelVolume::extruder_id() const
|
||||||
int extruder_id = -1;
|
int extruder_id = -1;
|
||||||
if (this->is_model_part()) {
|
if (this->is_model_part()) {
|
||||||
const ConfigOption *opt = this->config.option("extruder");
|
const ConfigOption *opt = this->config.option("extruder");
|
||||||
if (opt == nullptr)
|
if ((opt == nullptr) || (opt->getInt() == 0))
|
||||||
opt = this->object->config.option("extruder");
|
opt = this->object->config.option("extruder");
|
||||||
extruder_id = (opt == nullptr) ? 0 : opt->getInt();
|
extruder_id = (opt == nullptr) ? 0 : opt->getInt();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1137,6 +1137,9 @@ std::string Print::validate() const
|
||||||
// Apply the same transformations we apply to the actual meshes when slicing them.
|
// Apply the same transformations we apply to the actual meshes when slicing them.
|
||||||
object->model_object()->instances.front()->transform_polygon(&convex_hull);
|
object->model_object()->instances.front()->transform_polygon(&convex_hull);
|
||||||
// Grow convex hull with the clearance margin.
|
// Grow convex hull with the clearance margin.
|
||||||
|
// FIXME: Arrangement has different parameters for offsetting (jtMiter, limit 2)
|
||||||
|
// which causes that the warning will be showed after arrangement with the
|
||||||
|
// appropriate object distance. Even if I set this to jtMiter the warning still shows up.
|
||||||
convex_hull = offset(convex_hull, scale_(m_config.extruder_clearance_radius.value)/2, jtRound, scale_(0.1)).front();
|
convex_hull = offset(convex_hull, scale_(m_config.extruder_clearance_radius.value)/2, jtRound, scale_(0.1)).front();
|
||||||
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
|
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
|
||||||
for (const Point © : object->m_copies) {
|
for (const Point © : object->m_copies) {
|
||||||
|
|
|
@ -42,22 +42,27 @@ namespace Slic3r {
|
||||||
|
|
||||||
static boost::log::trivial::severity_level logSeverity = boost::log::trivial::error;
|
static boost::log::trivial::severity_level logSeverity = boost::log::trivial::error;
|
||||||
|
|
||||||
void set_logging_level(unsigned int level)
|
static boost::log::trivial::severity_level level_to_boost(unsigned level)
|
||||||
{
|
{
|
||||||
switch (level) {
|
switch (level) {
|
||||||
// Report fatal errors only.
|
// Report fatal errors only.
|
||||||
case 0: logSeverity = boost::log::trivial::fatal; break;
|
case 0: return boost::log::trivial::fatal;
|
||||||
// Report fatal errors and errors.
|
// Report fatal errors and errors.
|
||||||
case 1: logSeverity = boost::log::trivial::error; break;
|
case 1: return boost::log::trivial::error;
|
||||||
// Report fatal errors, errors and warnings.
|
// Report fatal errors, errors and warnings.
|
||||||
case 2: logSeverity = boost::log::trivial::warning; break;
|
case 2: return boost::log::trivial::warning;
|
||||||
// Report all errors, warnings and infos.
|
// Report all errors, warnings and infos.
|
||||||
case 3: logSeverity = boost::log::trivial::info; break;
|
case 3: return boost::log::trivial::info;
|
||||||
// Report all errors, warnings, infos and debugging.
|
// Report all errors, warnings, infos and debugging.
|
||||||
case 4: logSeverity = boost::log::trivial::debug; break;
|
case 4: return boost::log::trivial::debug;
|
||||||
// Report everyting including fine level tracing information.
|
// Report everyting including fine level tracing information.
|
||||||
default: logSeverity = boost::log::trivial::trace; break;
|
default: return boost::log::trivial::trace;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_logging_level(unsigned int level)
|
||||||
|
{
|
||||||
|
logSeverity = level_to_boost(level);
|
||||||
|
|
||||||
boost::log::core::get()->set_filter
|
boost::log::core::get()->set_filter
|
||||||
(
|
(
|
||||||
|
@ -73,6 +78,7 @@ unsigned get_logging_level()
|
||||||
case boost::log::trivial::warning : return 2;
|
case boost::log::trivial::warning : return 2;
|
||||||
case boost::log::trivial::info : return 3;
|
case boost::log::trivial::info : return 3;
|
||||||
case boost::log::trivial::debug : return 4;
|
case boost::log::trivial::debug : return 4;
|
||||||
|
case boost::log::trivial::trace : return 5;
|
||||||
default: return 1;
|
default: return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,21 +94,7 @@ static struct RunOnInit {
|
||||||
|
|
||||||
void trace(unsigned int level, const char *message)
|
void trace(unsigned int level, const char *message)
|
||||||
{
|
{
|
||||||
boost::log::trivial::severity_level severity = boost::log::trivial::trace;
|
boost::log::trivial::severity_level severity = level_to_boost(level);
|
||||||
switch (level) {
|
|
||||||
// Report fatal errors only.
|
|
||||||
case 0: severity = boost::log::trivial::fatal; break;
|
|
||||||
// Report fatal errors and errors.
|
|
||||||
case 1: severity = boost::log::trivial::error; break;
|
|
||||||
// Report fatal errors, errors and warnings.
|
|
||||||
case 2: severity = boost::log::trivial::warning; break;
|
|
||||||
// Report all errors, warnings and infos.
|
|
||||||
case 3: severity = boost::log::trivial::info; break;
|
|
||||||
// Report all errors, warnings, infos and debugging.
|
|
||||||
case 4: severity = boost::log::trivial::debug; break;
|
|
||||||
// Report everyting including fine level tracing information.
|
|
||||||
default: severity = boost::log::trivial::trace; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_LOG_STREAM_WITH_PARAMS(::boost::log::trivial::logger::get(),\
|
BOOST_LOG_STREAM_WITH_PARAMS(::boost::log::trivial::logger::get(),\
|
||||||
(::boost::log::keywords::severity = severity)) << message;
|
(::boost::log::keywords::severity = severity)) << message;
|
||||||
|
|
|
@ -16,30 +16,30 @@ namespace GUI {
|
||||||
class ConfigWizard: public wxDialog
|
class ConfigWizard: public wxDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Why is the Wizard run
|
// Why is the Wizard run
|
||||||
enum RunReason {
|
enum RunReason {
|
||||||
RR_DATA_EMPTY, // No or empty datadir
|
RR_DATA_EMPTY, // No or empty datadir
|
||||||
RR_DATA_LEGACY, // Pre-updating datadir
|
RR_DATA_LEGACY, // Pre-updating datadir
|
||||||
RR_DATA_INCOMPAT, // Incompatible datadir - Slic3r downgrade situation
|
RR_DATA_INCOMPAT, // Incompatible datadir - Slic3r downgrade situation
|
||||||
RR_USER, // User requested the Wizard from the menus
|
RR_USER, // User requested the Wizard from the menus
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigWizard(wxWindow *parent, RunReason run_reason);
|
ConfigWizard(wxWindow *parent, RunReason run_reason);
|
||||||
ConfigWizard(ConfigWizard &&) = delete;
|
ConfigWizard(ConfigWizard &&) = delete;
|
||||||
ConfigWizard(const ConfigWizard &) = delete;
|
ConfigWizard(const ConfigWizard &) = delete;
|
||||||
ConfigWizard &operator=(ConfigWizard &&) = delete;
|
ConfigWizard &operator=(ConfigWizard &&) = delete;
|
||||||
ConfigWizard &operator=(const ConfigWizard &) = delete;
|
ConfigWizard &operator=(const ConfigWizard &) = delete;
|
||||||
~ConfigWizard();
|
~ConfigWizard();
|
||||||
|
|
||||||
// Run the Wizard. Return whether it was completed.
|
// Run the Wizard. Return whether it was completed.
|
||||||
bool run(PresetBundle *preset_bundle, const PresetUpdater *updater);
|
bool run(PresetBundle *preset_bundle, const PresetUpdater *updater);
|
||||||
|
|
||||||
static const wxString& name(const bool from_menu = false);
|
static const wxString& name(const bool from_menu = false);
|
||||||
private:
|
private:
|
||||||
struct priv;
|
struct priv;
|
||||||
std::unique_ptr<priv> p;
|
std::unique_ptr<priv> p;
|
||||||
|
|
||||||
friend struct ConfigWizardPage;
|
friend struct ConfigWizardPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <functional>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
#include <wx/choice.h>
|
#include <wx/choice.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
|
||||||
#include "libslic3r/PrintConfig.hpp"
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
#include "slic3r/Utils/PresetUpdater.hpp"
|
#include "slic3r/Utils/PresetUpdater.hpp"
|
||||||
|
@ -26,211 +28,264 @@ namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
WRAP_WIDTH = 500,
|
WRAP_WIDTH = 500,
|
||||||
MODEL_MIN_WRAP = 150,
|
MODEL_MIN_WRAP = 150,
|
||||||
|
|
||||||
DIALOG_MARGIN = 15,
|
DIALOG_MARGIN = 15,
|
||||||
INDEX_MARGIN = 40,
|
INDEX_MARGIN = 40,
|
||||||
BTN_SPACING = 10,
|
BTN_SPACING = 10,
|
||||||
INDENT_SPACING = 30,
|
INDENT_SPACING = 30,
|
||||||
VERTICAL_SPACING = 10,
|
VERTICAL_SPACING = 10,
|
||||||
|
|
||||||
|
MAX_COLS = 4,
|
||||||
|
ROW_SPACING = 75,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::function<bool(const VendorProfile::PrinterModel&)> ModelFilter;
|
||||||
|
|
||||||
struct PrinterPicker: wxPanel
|
struct PrinterPicker: wxPanel
|
||||||
{
|
{
|
||||||
struct Checkbox : wxCheckBox
|
struct Checkbox : wxCheckBox
|
||||||
{
|
{
|
||||||
Checkbox(wxWindow *parent, const wxString &label, const std::string &model, const std::string &variant) :
|
Checkbox(wxWindow *parent, const wxString &label, const std::string &model, const std::string &variant) :
|
||||||
wxCheckBox(parent, wxID_ANY, label),
|
wxCheckBox(parent, wxID_ANY, label),
|
||||||
model(model),
|
model(model),
|
||||||
variant(variant)
|
variant(variant)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string model;
|
std::string model;
|
||||||
std::string variant;
|
std::string variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string vendor_id;
|
const std::string vendor_id;
|
||||||
std::vector<Checkbox*> cboxes;
|
std::vector<Checkbox*> cboxes;
|
||||||
unsigned variants_checked;
|
std::vector<Checkbox*> cboxes_alt;
|
||||||
|
|
||||||
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors);
|
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors, const ModelFilter &filter);
|
||||||
|
PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors);
|
||||||
|
|
||||||
void select_all(bool select);
|
void select_all(bool select, bool alternates = false);
|
||||||
void select_one(size_t i, bool select);
|
void select_one(size_t i, bool select);
|
||||||
void on_checkbox(const Checkbox *cbox, bool checked);
|
void on_checkbox(const Checkbox *cbox, bool checked);
|
||||||
|
|
||||||
|
int get_width() const { return width; }
|
||||||
|
private:
|
||||||
|
int width;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConfigWizardPage: wxPanel
|
struct ConfigWizardPage: wxPanel
|
||||||
{
|
{
|
||||||
ConfigWizard *parent;
|
ConfigWizard *parent;
|
||||||
const wxString shortname;
|
const wxString shortname;
|
||||||
wxBoxSizer *content;
|
wxBoxSizer *content;
|
||||||
|
const unsigned indent;
|
||||||
|
|
||||||
ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname);
|
ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname, unsigned indent = 0);
|
||||||
|
virtual ~ConfigWizardPage();
|
||||||
|
|
||||||
virtual ~ConfigWizardPage();
|
template<class T>
|
||||||
|
void append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
|
||||||
|
{
|
||||||
|
content->Add(thing, proportion, flag, border);
|
||||||
|
}
|
||||||
|
|
||||||
ConfigWizardPage* page_prev() const { return p_prev; }
|
void append_text(wxString text);
|
||||||
ConfigWizardPage* page_next() const { return p_next; }
|
void append_spacer(int space);
|
||||||
ConfigWizardPage* chain(ConfigWizardPage *page);
|
|
||||||
|
|
||||||
template<class T>
|
ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
|
||||||
void append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
|
|
||||||
{
|
|
||||||
content->Add(thing, proportion, flag, border);
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_text(wxString text);
|
virtual void apply_custom_config(DynamicPrintConfig &config) {}
|
||||||
void append_spacer(int space);
|
|
||||||
|
|
||||||
ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
|
|
||||||
|
|
||||||
virtual bool Show(bool show = true);
|
|
||||||
virtual bool Hide() { return Show(false); }
|
|
||||||
virtual wxPanel* extra_buttons() { return nullptr; }
|
|
||||||
virtual void on_page_set() {}
|
|
||||||
virtual void apply_custom_config(DynamicPrintConfig &config) {}
|
|
||||||
|
|
||||||
void enable_next(bool enable);
|
|
||||||
private:
|
|
||||||
ConfigWizardPage *p_prev;
|
|
||||||
ConfigWizardPage *p_next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageWelcome: ConfigWizardPage
|
struct PageWelcome: ConfigWizardPage
|
||||||
{
|
{
|
||||||
PrinterPicker *printer_picker;
|
wxCheckBox *cbox_reset;
|
||||||
wxPanel *others_buttons;
|
|
||||||
wxCheckBox *cbox_reset;
|
|
||||||
|
|
||||||
PageWelcome(ConfigWizard *parent, bool check_first_variant);
|
PageWelcome(ConfigWizard *parent);
|
||||||
|
|
||||||
virtual wxPanel* extra_buttons() { return others_buttons; }
|
bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; }
|
||||||
virtual void on_page_set();
|
};
|
||||||
|
|
||||||
|
struct PagePrinters: ConfigWizardPage
|
||||||
|
{
|
||||||
|
enum Technology {
|
||||||
|
// Bitflag equivalent of PrinterTechnology
|
||||||
|
T_FFF = 0x1,
|
||||||
|
T_SLA = 0x2,
|
||||||
|
T_Any = ~0,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<PrinterPicker *> printer_pickers;
|
||||||
|
|
||||||
|
PagePrinters(ConfigWizard *parent, wxString title, wxString shortname, const VendorProfile &vendor, unsigned indent, Technology technology);
|
||||||
|
|
||||||
|
void select_all(bool select, bool alternates = false);
|
||||||
|
int get_width() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PageCustom: ConfigWizardPage
|
||||||
|
{
|
||||||
|
PageCustom(ConfigWizard *parent);
|
||||||
|
|
||||||
|
bool custom_wanted() const { return cb_custom->GetValue(); }
|
||||||
|
std::string profile_name() const { return into_u8(tc_profile_name->GetValue()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char* default_profile_name;
|
||||||
|
|
||||||
|
wxCheckBox *cb_custom;
|
||||||
|
wxTextCtrl *tc_profile_name;
|
||||||
|
wxString profile_name_prev;
|
||||||
|
|
||||||
bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; }
|
|
||||||
void on_variant_checked();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageUpdate: ConfigWizardPage
|
struct PageUpdate: ConfigWizardPage
|
||||||
{
|
{
|
||||||
bool version_check;
|
bool version_check;
|
||||||
bool preset_update;
|
bool preset_update;
|
||||||
|
|
||||||
PageUpdate(ConfigWizard *parent);
|
PageUpdate(ConfigWizard *parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageVendors: ConfigWizardPage
|
struct PageVendors: ConfigWizardPage
|
||||||
{
|
{
|
||||||
std::vector<PrinterPicker*> pickers;
|
std::vector<PrinterPicker*> pickers;
|
||||||
|
|
||||||
PageVendors(ConfigWizard *parent);
|
PageVendors(ConfigWizard *parent);
|
||||||
|
|
||||||
virtual void on_page_set();
|
void on_vendor_pick(size_t i);
|
||||||
|
|
||||||
void on_vendor_pick(size_t i);
|
|
||||||
void on_variant_checked();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageFirmware: ConfigWizardPage
|
struct PageFirmware: ConfigWizardPage
|
||||||
{
|
{
|
||||||
const ConfigOptionDef &gcode_opt;
|
const ConfigOptionDef &gcode_opt;
|
||||||
wxChoice *gcode_picker;
|
wxChoice *gcode_picker;
|
||||||
|
|
||||||
PageFirmware(ConfigWizard *parent);
|
PageFirmware(ConfigWizard *parent);
|
||||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageBedShape: ConfigWizardPage
|
struct PageBedShape: ConfigWizardPage
|
||||||
{
|
{
|
||||||
BedShapePanel *shape_panel;
|
BedShapePanel *shape_panel;
|
||||||
|
|
||||||
PageBedShape(ConfigWizard *parent);
|
PageBedShape(ConfigWizard *parent);
|
||||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageDiameters: ConfigWizardPage
|
struct PageDiameters: ConfigWizardPage
|
||||||
{
|
{
|
||||||
wxSpinCtrlDouble *spin_nozzle;
|
wxSpinCtrlDouble *spin_nozzle;
|
||||||
wxSpinCtrlDouble *spin_filam;
|
wxSpinCtrlDouble *spin_filam;
|
||||||
|
|
||||||
PageDiameters(ConfigWizard *parent);
|
PageDiameters(ConfigWizard *parent);
|
||||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PageTemperatures: ConfigWizardPage
|
struct PageTemperatures: ConfigWizardPage
|
||||||
{
|
{
|
||||||
wxSpinCtrlDouble *spin_extr;
|
wxSpinCtrlDouble *spin_extr;
|
||||||
wxSpinCtrlDouble *spin_bed;
|
wxSpinCtrlDouble *spin_bed;
|
||||||
|
|
||||||
PageTemperatures(ConfigWizard *parent);
|
PageTemperatures(ConfigWizard *parent);
|
||||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ConfigWizardIndex: public wxPanel
|
class ConfigWizardIndex: public wxPanel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConfigWizardIndex(wxWindow *parent);
|
ConfigWizardIndex(wxWindow *parent);
|
||||||
|
|
||||||
|
void add_page(ConfigWizardPage *page);
|
||||||
|
void add_label(wxString label, unsigned indent = 0);
|
||||||
|
|
||||||
|
size_t active_item() const { return item_active; }
|
||||||
|
ConfigWizardPage* active_page() const;
|
||||||
|
bool active_is_last() const { return item_active < items.size() && item_active == last_page; }
|
||||||
|
|
||||||
|
void go_prev();
|
||||||
|
void go_next();
|
||||||
|
void go_to(size_t i);
|
||||||
|
void go_to(ConfigWizardPage *page);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
void load_items(ConfigWizardPage *firstpage);
|
|
||||||
void set_active(ConfigWizardPage *page);
|
|
||||||
private:
|
private:
|
||||||
const wxBitmap bg;
|
struct Item
|
||||||
const wxBitmap bullet_black;
|
{
|
||||||
const wxBitmap bullet_blue;
|
wxString label;
|
||||||
const wxBitmap bullet_white;
|
unsigned indent;
|
||||||
int text_height;
|
ConfigWizardPage *page; // nullptr page => label-only item
|
||||||
|
|
||||||
std::vector<wxString> items;
|
bool operator==(ConfigWizardPage *page) const { return this->page == page; }
|
||||||
std::vector<wxString>::const_iterator item_active;
|
};
|
||||||
|
|
||||||
void on_paint(wxPaintEvent &evt);
|
int em;
|
||||||
|
int em_h;
|
||||||
|
|
||||||
|
const wxBitmap bg;
|
||||||
|
const wxBitmap bullet_black;
|
||||||
|
const wxBitmap bullet_blue;
|
||||||
|
const wxBitmap bullet_white;
|
||||||
|
|
||||||
|
std::vector<Item> items;
|
||||||
|
size_t item_active;
|
||||||
|
ssize_t item_hover;
|
||||||
|
size_t last_page;
|
||||||
|
|
||||||
|
int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em) + em; }
|
||||||
|
|
||||||
|
void on_paint(wxPaintEvent &evt);
|
||||||
|
void on_mouse_move(wxMouseEvent &evt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wxDEFINE_EVENT(EVT_INDEX_PAGE, wxCommandEvent);
|
||||||
|
|
||||||
struct ConfigWizard::priv
|
struct ConfigWizard::priv
|
||||||
{
|
{
|
||||||
ConfigWizard *q;
|
ConfigWizard *q;
|
||||||
ConfigWizard::RunReason run_reason;
|
ConfigWizard::RunReason run_reason;
|
||||||
AppConfig appconfig_vendors;
|
AppConfig appconfig_vendors;
|
||||||
std::unordered_map<std::string, VendorProfile> vendors;
|
std::unordered_map<std::string, VendorProfile> vendors;
|
||||||
std::unordered_map<std::string, std::string> vendors_rsrc;
|
std::unordered_map<std::string, std::string> vendors_rsrc;
|
||||||
std::unique_ptr<DynamicPrintConfig> custom_config;
|
std::unique_ptr<DynamicPrintConfig> custom_config;
|
||||||
|
|
||||||
wxScrolledWindow *hscroll = nullptr;
|
wxScrolledWindow *hscroll = nullptr;
|
||||||
wxBoxSizer *hscroll_sizer = nullptr;
|
wxBoxSizer *hscroll_sizer = nullptr;
|
||||||
wxBoxSizer *btnsizer = nullptr;
|
wxBoxSizer *btnsizer = nullptr;
|
||||||
ConfigWizardPage *page_current = nullptr;
|
ConfigWizardPage *page_current = nullptr;
|
||||||
ConfigWizardIndex *index = nullptr;
|
ConfigWizardIndex *index = nullptr;
|
||||||
wxButton *btn_prev = nullptr;
|
wxButton *btn_prev = nullptr;
|
||||||
wxButton *btn_next = nullptr;
|
wxButton *btn_next = nullptr;
|
||||||
wxButton *btn_finish = nullptr;
|
wxButton *btn_finish = nullptr;
|
||||||
wxButton *btn_cancel = nullptr;
|
wxButton *btn_cancel = nullptr;
|
||||||
|
|
||||||
PageWelcome *page_welcome = nullptr;
|
PageWelcome *page_welcome = nullptr;
|
||||||
PageUpdate *page_update = nullptr;
|
PagePrinters *page_fff = nullptr;
|
||||||
PageVendors *page_vendors = nullptr;
|
PagePrinters *page_msla = nullptr;
|
||||||
PageFirmware *page_firmware = nullptr;
|
PageCustom *page_custom = nullptr;
|
||||||
PageBedShape *page_bed = nullptr;
|
PageUpdate *page_update = nullptr;
|
||||||
PageDiameters *page_diams = nullptr;
|
PageVendors *page_vendors = nullptr; // XXX: ?
|
||||||
PageTemperatures *page_temps = nullptr;
|
|
||||||
|
|
||||||
priv(ConfigWizard *q) : q(q) {}
|
// Custom setup pages
|
||||||
|
PageFirmware *page_firmware = nullptr;
|
||||||
|
PageBedShape *page_bed = nullptr;
|
||||||
|
PageDiameters *page_diams = nullptr;
|
||||||
|
PageTemperatures *page_temps = nullptr;
|
||||||
|
|
||||||
void load_vendors();
|
priv(ConfigWizard *q) : q(q) {}
|
||||||
void add_page(ConfigWizardPage *page);
|
|
||||||
void index_refresh();
|
|
||||||
void set_page(ConfigWizardPage *page);
|
|
||||||
void layout_fit();
|
|
||||||
void go_prev() { if (page_current != nullptr) { set_page(page_current->page_prev()); } }
|
|
||||||
void go_next() { if (page_current != nullptr) { set_page(page_current->page_next()); } }
|
|
||||||
void enable_next(bool enable);
|
|
||||||
|
|
||||||
void on_other_vendors();
|
void load_pages(bool custom_setup);
|
||||||
void on_custom_setup();
|
|
||||||
|
|
||||||
void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater);
|
bool check_first_variant() const;
|
||||||
|
void load_vendors();
|
||||||
|
void add_page(ConfigWizardPage *page);
|
||||||
|
void enable_next(bool enable);
|
||||||
|
|
||||||
|
void on_custom_setup(bool custom_wanted);
|
||||||
|
|
||||||
|
void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,19 +145,24 @@ void Field::get_value_by_opt_type(wxString& str)
|
||||||
double val;
|
double val;
|
||||||
// Replace the first occurence of comma in decimal number.
|
// Replace the first occurence of comma in decimal number.
|
||||||
str.Replace(",", ".", false);
|
str.Replace(",", ".", false);
|
||||||
if(!str.ToCDouble(&val))
|
if (str == ".")
|
||||||
{
|
val = 0.0;
|
||||||
show_error(m_parent, _(L("Invalid numeric input.")));
|
else
|
||||||
set_value(double_to_string(val), true);
|
{
|
||||||
}
|
if (!str.ToCDouble(&val))
|
||||||
if (m_opt.min > val || val > m_opt.max)
|
{
|
||||||
{
|
show_error(m_parent, _(L("Invalid numeric input.")));
|
||||||
show_error(m_parent, _(L("Input value is out of range")));
|
set_value(double_to_string(val), true);
|
||||||
if (m_opt.min > val) val = m_opt.min;
|
}
|
||||||
if (val > m_opt.max) val = m_opt.max;
|
if (m_opt.min > val || val > m_opt.max)
|
||||||
set_value(double_to_string(val), true);
|
{
|
||||||
}
|
show_error(m_parent, _(L("Input value is out of range")));
|
||||||
m_value = val;
|
if (m_opt.min > val) val = m_opt.min;
|
||||||
|
if (val > m_opt.max) val = m_opt.max;
|
||||||
|
set_value(double_to_string(val), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_value = val;
|
||||||
break; }
|
break; }
|
||||||
case coString:
|
case coString:
|
||||||
case coStrings:
|
case coStrings:
|
||||||
|
@ -459,7 +464,7 @@ void SpinCtrl::BUILD() {
|
||||||
// # As a workaround, we get the new value from $event->GetString and store
|
// # As a workaround, we get the new value from $event->GetString and store
|
||||||
// # here temporarily so that we can return it from $self->get_value
|
// # here temporarily so that we can return it from $self->get_value
|
||||||
std::string value = e.GetString().utf8_str().data();
|
std::string value = e.GetString().utf8_str().data();
|
||||||
if (is_matched(value, "^\\d+$"))
|
if (is_matched(value, "^\\-?\\d+$"))
|
||||||
tmp_value = std::stoi(value);
|
tmp_value = std::stoi(value);
|
||||||
else tmp_value = -9999;
|
else tmp_value = -9999;
|
||||||
#ifdef __WXOSX__
|
#ifdef __WXOSX__
|
||||||
|
@ -475,7 +480,7 @@ void SpinCtrl::BUILD() {
|
||||||
|
|
||||||
void SpinCtrl::propagate_value()
|
void SpinCtrl::propagate_value()
|
||||||
{
|
{
|
||||||
if (tmp_value < 0)
|
if (tmp_value == -9999)
|
||||||
on_kill_focus();
|
on_kill_focus();
|
||||||
else if (boost::any_cast<int>(m_value) != tmp_value)
|
else if (boost::any_cast<int>(m_value) != tmp_value)
|
||||||
on_change_field();
|
on_change_field();
|
||||||
|
@ -867,8 +872,8 @@ void StaticText::BUILD()
|
||||||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||||
|
|
||||||
wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value);
|
const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value);
|
||||||
auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size);
|
auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE);
|
||||||
temp->SetFont(wxGetApp().bold_font());
|
temp->SetFont(wxGetApp().bold_font());
|
||||||
|
|
||||||
// // recast as a wxWindow to fit the calling convention
|
// // recast as a wxWindow to fit the calling convention
|
||||||
|
|
|
@ -141,8 +141,8 @@ bool GeometryBuffer::set_from_triangles(const Polygons& triangles, float z, bool
|
||||||
float inv_size_y = -1.0f / size_y;
|
float inv_size_y = -1.0f / size_y;
|
||||||
for (unsigned int i = 0; i < m_tex_coords.size(); i += 2)
|
for (unsigned int i = 0; i < m_tex_coords.size(); i += 2)
|
||||||
{
|
{
|
||||||
m_tex_coords[i] *= inv_size_x;
|
m_tex_coords[i] = (m_tex_coords[i] - min_x) * inv_size_x;
|
||||||
m_tex_coords[i + 1] *= inv_size_y;
|
m_tex_coords[i + 1] = (m_tex_coords[i + 1] - min_y) * inv_size_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,11 +595,25 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const
|
||||||
#endif // ENABLE_PRINT_BED_MODELS
|
#endif // ENABLE_PRINT_BED_MODELS
|
||||||
{
|
{
|
||||||
std::string tex_path = resources_dir() + "/icons/bed/" + key;
|
std::string tex_path = resources_dir() + "/icons/bed/" + key;
|
||||||
|
|
||||||
|
// use higher resolution images if graphic card allows
|
||||||
|
GLint max_tex_size;
|
||||||
|
::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
|
||||||
|
|
||||||
|
// temporary set to lowest resolution
|
||||||
|
max_tex_size = 2048;
|
||||||
|
|
||||||
|
if (max_tex_size >= 8192)
|
||||||
|
tex_path += "_8192";
|
||||||
|
else if (max_tex_size >= 4096)
|
||||||
|
tex_path += "_4096";
|
||||||
|
|
||||||
#if ENABLE_PRINT_BED_MODELS
|
#if ENABLE_PRINT_BED_MODELS
|
||||||
std::string model_path = resources_dir() + "/models/" + key;
|
std::string model_path = resources_dir() + "/models/" + key;
|
||||||
#endif // ENABLE_PRINT_BED_MODELS
|
#endif // ENABLE_PRINT_BED_MODELS
|
||||||
|
|
||||||
#if ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES
|
#if ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES
|
||||||
|
// use anisotropic filter if graphic card allows
|
||||||
GLfloat max_anisotropy = 0.0f;
|
GLfloat max_anisotropy = 0.0f;
|
||||||
if (glewIsSupported("GL_EXT_texture_filter_anisotropic"))
|
if (glewIsSupported("GL_EXT_texture_filter_anisotropic"))
|
||||||
::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
|
::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
|
||||||
|
@ -646,11 +660,17 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const
|
||||||
{
|
{
|
||||||
filename = model_path + "_bed.stl";
|
filename = model_path + "_bed.stl";
|
||||||
if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) {
|
if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) {
|
||||||
Vec3d offset = m_bounding_box.center() - Vec3d(0.0, 0.0, 0.1 + 0.5 * m_model.get_bounding_box().size()(2));
|
Vec3d offset = m_bounding_box.center() - Vec3d(0.0, 0.0, 0.5 * m_model.get_bounding_box().size()(2));
|
||||||
if (key == "mk2")
|
if (key == "mk2")
|
||||||
offset.y() += 15. / 2.;
|
// hardcoded value to match the stl model
|
||||||
|
offset += Vec3d(0.0, 7.5, -0.03);
|
||||||
else if (key == "mk3")
|
else if (key == "mk3")
|
||||||
offset += Vec3d(0., (19. - 8.) / 2., 2.);
|
// hardcoded value to match the stl model
|
||||||
|
offset += Vec3d(0.0, 5.5, 2.43);
|
||||||
|
else if (key == "sl1")
|
||||||
|
// hardcoded value to match the stl model
|
||||||
|
offset += Vec3d(0.0, 0.0, -0.03);
|
||||||
|
|
||||||
m_model.center_around(offset);
|
m_model.center_around(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5343,14 +5363,21 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
// Set focus in order to remove it from sidebar fields
|
// Set focus in order to remove it from sidebar fields
|
||||||
if (m_canvas != nullptr) {
|
if (m_canvas != nullptr) {
|
||||||
// Only set focus, if the top level window of this canvas is active.
|
// Only set focus, if the top level window of this canvas is active.
|
||||||
auto p = dynamic_cast<wxWindow*>(evt.GetEventObject());
|
auto p = dynamic_cast<wxWindow*>(evt.GetEventObject());
|
||||||
while (p->GetParent())
|
while (p->GetParent())
|
||||||
p = p->GetParent();
|
p = p->GetParent();
|
||||||
auto *top_level_wnd = dynamic_cast<wxTopLevelWindow*>(p);
|
auto *top_level_wnd = dynamic_cast<wxTopLevelWindow*>(p);
|
||||||
if (top_level_wnd && top_level_wnd->IsActive())
|
if (top_level_wnd && top_level_wnd->IsActive())
|
||||||
|
{
|
||||||
m_canvas->SetFocus();
|
m_canvas->SetFocus();
|
||||||
}
|
|
||||||
|
|
||||||
|
// forces a frame render to ensure that m_hover_volume_id is updated even when the user right clicks while
|
||||||
|
// the context menu is shown, ensuring it to disappear if the mouse is outside any volume and to
|
||||||
|
// change the volume hover state if any is under the mouse
|
||||||
|
m_mouse.position = pos.cast<double>();
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
}
|
||||||
m_mouse.set_start_position_2D_as_invalid();
|
m_mouse.set_start_position_2D_as_invalid();
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
@ -5479,7 +5506,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// propagate event through callback
|
// propagate event through callback
|
||||||
|
|
||||||
if (m_hover_volume_id != -1)
|
if (m_hover_volume_id != -1)
|
||||||
{
|
{
|
||||||
if (evt.LeftDown() && m_moving_enabled && (m_mouse.drag.move_volume_idx == -1))
|
if (evt.LeftDown() && m_moving_enabled && (m_mouse.drag.move_volume_idx == -1))
|
||||||
|
@ -5498,9 +5524,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
}
|
}
|
||||||
else if (evt.RightDown())
|
else if (evt.RightDown())
|
||||||
{
|
{
|
||||||
|
m_mouse.position = pos.cast<double>();
|
||||||
// forces a frame render to ensure that m_hover_volume_id is updated even when the user right clicks while
|
// forces a frame render to ensure that m_hover_volume_id is updated even when the user right clicks while
|
||||||
// the context menu is already shown, ensuring it to disappear if the mouse is outside any volume
|
// the context menu is already shown
|
||||||
m_mouse.position = Vec2d((double)pos(0), (double)pos(1));
|
|
||||||
render();
|
render();
|
||||||
if (m_hover_volume_id != -1)
|
if (m_hover_volume_id != -1)
|
||||||
{
|
{
|
||||||
|
@ -5514,14 +5540,14 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||||
_update_gizmos_data();
|
_update_gizmos_data();
|
||||||
wxGetApp().obj_manipul()->update_settings_value(m_selection);
|
wxGetApp().obj_manipul()->update_settings_value(m_selection);
|
||||||
// forces a frame render to update the view before the context menu is shown
|
// // forces a frame render to update the view before the context menu is shown
|
||||||
render();
|
// render();
|
||||||
|
|
||||||
Vec2d logical_pos = pos.cast<double>();
|
Vec2d logical_pos = pos.cast<double>();
|
||||||
#if ENABLE_RETINA_GL
|
#if ENABLE_RETINA_GL
|
||||||
const float factor = m_retina_helper->get_scale_factor();
|
const float factor = m_retina_helper->get_scale_factor();
|
||||||
logical_pos = logical_pos.cwiseQuotient(Vec2d(factor, factor));
|
logical_pos = logical_pos.cwiseQuotient(Vec2d(factor, factor));
|
||||||
#endif
|
#endif // ENABLE_RETINA_GL
|
||||||
post_event(Vec2dEvent(EVT_GLCANVAS_RIGHT_CLICK, logical_pos));
|
post_event(Vec2dEvent(EVT_GLCANVAS_RIGHT_CLICK, logical_pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5817,7 +5843,7 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip) const
|
||||||
else
|
else
|
||||||
t->SetTip(tooltip);
|
t->SetTip(tooltip);
|
||||||
}
|
}
|
||||||
else
|
else if (!tooltip.empty()) // Avoid "empty" tooltips => unset of the empty tooltip leads to application crash under OSX
|
||||||
m_canvas->SetToolTip(tooltip);
|
m_canvas->SetToolTip(tooltip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6150,7 +6176,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "add";
|
item.name = "add";
|
||||||
item.tooltip = GUI::L_str("Add...") + " [" + GUI::shortkey_ctrl_prefix() + "I]";
|
item.tooltip = GUI::L_str("Add...") + " [" + GUI::shortkey_ctrl_prefix() + "I]";
|
||||||
item.sprite_id = 0;
|
item.sprite_id = 0;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_ADD;
|
item.action_event = EVT_GLTOOLBAR_ADD;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6158,7 +6183,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "delete";
|
item.name = "delete";
|
||||||
item.tooltip = GUI::L_str("Delete") + " [Del]";
|
item.tooltip = GUI::L_str("Delete") + " [Del]";
|
||||||
item.sprite_id = 1;
|
item.sprite_id = 1;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_DELETE;
|
item.action_event = EVT_GLTOOLBAR_DELETE;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6166,7 +6190,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "deleteall";
|
item.name = "deleteall";
|
||||||
item.tooltip = GUI::L_str("Delete all") + " [" + GUI::shortkey_ctrl_prefix() + "Del]";
|
item.tooltip = GUI::L_str("Delete all") + " [" + GUI::shortkey_ctrl_prefix() + "Del]";
|
||||||
item.sprite_id = 2;
|
item.sprite_id = 2;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_DELETE_ALL;
|
item.action_event = EVT_GLTOOLBAR_DELETE_ALL;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6174,7 +6197,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "arrange";
|
item.name = "arrange";
|
||||||
item.tooltip = GUI::L_str("Arrange [A]");
|
item.tooltip = GUI::L_str("Arrange [A]");
|
||||||
item.sprite_id = 3;
|
item.sprite_id = 3;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_ARRANGE;
|
item.action_event = EVT_GLTOOLBAR_ARRANGE;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6185,7 +6207,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "more";
|
item.name = "more";
|
||||||
item.tooltip = GUI::L_str("Add instance [+]");
|
item.tooltip = GUI::L_str("Add instance [+]");
|
||||||
item.sprite_id = 4;
|
item.sprite_id = 4;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_MORE;
|
item.action_event = EVT_GLTOOLBAR_MORE;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6193,7 +6214,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "fewer";
|
item.name = "fewer";
|
||||||
item.tooltip = GUI::L_str("Remove instance [-]");
|
item.tooltip = GUI::L_str("Remove instance [-]");
|
||||||
item.sprite_id = 5;
|
item.sprite_id = 5;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_FEWER;
|
item.action_event = EVT_GLTOOLBAR_FEWER;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6204,7 +6224,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "splitobjects";
|
item.name = "splitobjects";
|
||||||
item.tooltip = GUI::L_str("Split to objects");
|
item.tooltip = GUI::L_str("Split to objects");
|
||||||
item.sprite_id = 6;
|
item.sprite_id = 6;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_SPLIT_OBJECTS;
|
item.action_event = EVT_GLTOOLBAR_SPLIT_OBJECTS;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
@ -6212,7 +6231,6 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.name = "splitvolumes";
|
item.name = "splitvolumes";
|
||||||
item.tooltip = GUI::L_str("Split to parts");
|
item.tooltip = GUI::L_str("Split to parts");
|
||||||
item.sprite_id = 8;
|
item.sprite_id = 8;
|
||||||
item.is_toggable = false;
|
|
||||||
item.action_event = EVT_GLTOOLBAR_SPLIT_VOLUMES;
|
item.action_event = EVT_GLTOOLBAR_SPLIT_VOLUMES;
|
||||||
if (!m_toolbar.add_item(item))
|
if (!m_toolbar.add_item(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -355,21 +355,6 @@ boost::filesystem::path into_path(const wxString &str)
|
||||||
return boost::filesystem::path(str.wx_str());
|
return boost::filesystem::path(str.wx_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_current_screen_size(wxWindow *window, unsigned &width, unsigned &height)
|
|
||||||
{
|
|
||||||
const auto idx = wxDisplay::GetFromWindow(window);
|
|
||||||
if (idx == wxNOT_FOUND) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxDisplay display(idx);
|
|
||||||
const auto disp_size = display.GetClientArea();
|
|
||||||
width = disp_size.GetWidth();
|
|
||||||
height = disp_size.GetHeight();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void about()
|
void about()
|
||||||
{
|
{
|
||||||
AboutDialog dlg;
|
AboutDialog dlg;
|
||||||
|
|
|
@ -71,9 +71,6 @@ wxString from_path(const boost::filesystem::path &path);
|
||||||
// boost path from wxString
|
// boost path from wxString
|
||||||
boost::filesystem::path into_path(const wxString &str);
|
boost::filesystem::path into_path(const wxString &str);
|
||||||
|
|
||||||
// Returns the dimensions of the screen on which the main frame is displayed
|
|
||||||
bool get_current_screen_size(wxWindow *window, unsigned &width, unsigned &height);
|
|
||||||
|
|
||||||
// Display an About dialog
|
// Display an About dialog
|
||||||
extern void about();
|
extern void about();
|
||||||
// Ask the destop to open the datadir using the default file explorer.
|
// Ask the destop to open the datadir using the default file explorer.
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
#include "GUI_ObjectManipulation.hpp"
|
#include "GUI_ObjectManipulation.hpp"
|
||||||
#include "I18N.hpp"
|
#include "I18N.hpp"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
#include <wx/stdpaths.h>
|
#include <wx/stdpaths.h>
|
||||||
#include <wx/imagpng.h>
|
#include <wx/imagpng.h>
|
||||||
|
@ -125,6 +127,10 @@ bool GUI_App::OnInit()
|
||||||
app_config->save();
|
app_config->save();
|
||||||
|
|
||||||
preset_updater = new PresetUpdater();
|
preset_updater = new PresetUpdater();
|
||||||
|
Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent &evt) {
|
||||||
|
app_config->set("version_online", into_u8(evt.GetString()));
|
||||||
|
app_config->save();
|
||||||
|
});
|
||||||
|
|
||||||
load_language();
|
load_language();
|
||||||
|
|
||||||
|
@ -181,7 +187,6 @@ bool GUI_App::OnInit()
|
||||||
mainframe->Close();
|
mainframe->Close();
|
||||||
} catch (const std::exception &ex) {
|
} catch (const std::exception &ex) {
|
||||||
show_error(nullptr, ex.what());
|
show_error(nullptr, ex.what());
|
||||||
mainframe->Close();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -351,21 +356,10 @@ void GUI_App::persist_window_geometry(wxTopLevelWindow *window)
|
||||||
});
|
});
|
||||||
|
|
||||||
window_pos_restore(window, name);
|
window_pos_restore(window, name);
|
||||||
#ifdef _WIN32
|
|
||||||
// On windows, the wxEVT_SHOW is not received if the window is created maximized
|
on_window_geometry(window, [=]() {
|
||||||
// cf. https://groups.google.com/forum/#!topic/wx-users/c7ntMt6piRI
|
window_pos_sanitize(window);
|
||||||
// so we sanitize the position right away
|
|
||||||
window_pos_sanitize(window);
|
|
||||||
#else
|
|
||||||
// On other platforms on the other hand it's needed to wait before the window is actually on screen
|
|
||||||
// and some initial round of events is complete otherwise position / display index is not reported correctly.
|
|
||||||
window->Bind(wxEVT_SHOW, [=](wxShowEvent &event) {
|
|
||||||
CallAfter([=]() {
|
|
||||||
window_pos_sanitize(window);
|
|
||||||
});
|
|
||||||
event.Skip();
|
|
||||||
});
|
});
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI_App::load_project(wxWindow *parent, wxString& input_file)
|
void GUI_App::load_project(wxWindow *parent, wxString& input_file)
|
||||||
|
@ -573,7 +567,10 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
||||||
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("Simple")), _(L("Simple View Mode")));
|
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("Simple")), _(L("Simple View Mode")));
|
||||||
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _(L("Advanced")), _(L("Advanced View Mode")));
|
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _(L("Advanced")), _(L("Advanced View Mode")));
|
||||||
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("Expert")), _(L("Expert View Mode")));
|
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("Expert")), _(L("Expert View Mode")));
|
||||||
mode_menu->Check(config_id_base + ConfigMenuModeSimple + get_mode(), true);
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Check(get_mode() == comSimple); }, config_id_base + ConfigMenuModeSimple);
|
||||||
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Check(get_mode() == comAdvanced); }, config_id_base + ConfigMenuModeAdvanced);
|
||||||
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Check(get_mode() == comExpert); }, config_id_base + ConfigMenuModeExpert);
|
||||||
|
|
||||||
local_menu->AppendSubMenu(mode_menu, _(L("Mode")), _(L("Slic3r View Mode")));
|
local_menu->AppendSubMenu(mode_menu, _(L("Mode")), _(L("Slic3r View Mode")));
|
||||||
local_menu->AppendSeparator();
|
local_menu->AppendSeparator();
|
||||||
local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application &Language")));
|
local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application &Language")));
|
||||||
|
@ -692,6 +689,23 @@ void GUI_App::load_current_presets()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GUI_App::OnExceptionInMainLoop()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
throw;
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
const std::string error = (boost::format("Uncaught exception: %1%") % ex.what()).str();
|
||||||
|
BOOST_LOG_TRIVIAL(error) << error;
|
||||||
|
show_error(nullptr, from_u8(error));
|
||||||
|
} catch (...) {
|
||||||
|
const char *error = "Uncaught exception: Unknown error";
|
||||||
|
BOOST_LOG_TRIVIAL(error) << error;
|
||||||
|
show_error(nullptr, from_u8(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// wxWidgets override to get an event on open files.
|
// wxWidgets override to get an event on open files.
|
||||||
void GUI_App::MacOpenFiles(const wxArrayString &fileNames)
|
void GUI_App::MacOpenFiles(const wxArrayString &fileNames)
|
||||||
|
|
|
@ -137,6 +137,8 @@ public:
|
||||||
bool checked_tab(Tab* tab);
|
bool checked_tab(Tab* tab);
|
||||||
void load_current_presets();
|
void load_current_presets();
|
||||||
|
|
||||||
|
virtual bool OnExceptionInMainLoop();
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// wxWidgets override to get an event on open files.
|
// wxWidgets override to get an event on open files.
|
||||||
void MacOpenFiles(const wxArrayString &fileNames) override;
|
void MacOpenFiles(const wxArrayString &fileNames) override;
|
||||||
|
|
|
@ -42,10 +42,9 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
||||||
|
|
||||||
// Objects(sub-objects) name
|
// Objects(sub-objects) name
|
||||||
def.label = L("Name");
|
def.label = L("Name");
|
||||||
// def.type = coString;
|
|
||||||
def.gui_type = "legend";
|
def.gui_type = "legend";
|
||||||
def.tooltip = L("Object name");
|
def.tooltip = L("Object name");
|
||||||
def.full_width = true;
|
def.width = 200;
|
||||||
def.default_value = new ConfigOptionString{ " " };
|
def.default_value = new ConfigOptionString{ " " };
|
||||||
m_og->append_single_option_line(Option(def, "object_name"));
|
m_og->append_single_option_line(Option(def, "object_name"));
|
||||||
|
|
||||||
|
@ -73,14 +72,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
||||||
def.default_value = new ConfigOptionFloat(0.0);
|
def.default_value = new ConfigOptionFloat(0.0);
|
||||||
def.width = 50;
|
def.width = 50;
|
||||||
|
|
||||||
if (option_name == "Rotation")
|
|
||||||
{
|
|
||||||
def.min = -360;
|
|
||||||
def.max = 360;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add "uniform scaling" button in front of "Scale" option
|
// Add "uniform scaling" button in front of "Scale" option
|
||||||
else if (option_name == "Scale") {
|
if (option_name == "Scale") {
|
||||||
line.near_label_widget = [this](wxWindow* parent) {
|
line.near_label_widget = [this](wxWindow* parent) {
|
||||||
auto btn = new PrusaLockButton(parent, wxID_ANY);
|
auto btn = new PrusaLockButton(parent, wxID_ANY);
|
||||||
btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event){
|
btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event){
|
||||||
|
@ -293,13 +286,13 @@ void ObjectManipulation::update_if_dirty()
|
||||||
deg_rotation(i) = Geometry::rad2deg(m_new_rotation(i));
|
deg_rotation(i) = Geometry::rad2deg(m_new_rotation(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_cache.rotation(0) != m_new_rotation(0))
|
if ((m_cache.rotation(0) != m_new_rotation(0)) || (m_new_rotation(0) == 0.0))
|
||||||
m_og->set_value("rotation_x", double_to_string(deg_rotation(0), 2));
|
m_og->set_value("rotation_x", double_to_string(deg_rotation(0), 2));
|
||||||
|
|
||||||
if (m_cache.rotation(1) != m_new_rotation(1))
|
if ((m_cache.rotation(1) != m_new_rotation(1)) || (m_new_rotation(1) == 0.0))
|
||||||
m_og->set_value("rotation_y", double_to_string(deg_rotation(1), 2));
|
m_og->set_value("rotation_y", double_to_string(deg_rotation(1), 2));
|
||||||
|
|
||||||
if (m_cache.rotation(2) != m_new_rotation(2))
|
if ((m_cache.rotation(2) != m_new_rotation(2)) || (m_new_rotation(2) == 0.0))
|
||||||
m_og->set_value("rotation_z", double_to_string(deg_rotation(2), 2));
|
m_og->set_value("rotation_z", double_to_string(deg_rotation(2), 2));
|
||||||
|
|
||||||
m_cache.rotation = deg_rotation;
|
m_cache.rotation = deg_rotation;
|
||||||
|
|
|
@ -26,6 +26,28 @@ wxTopLevelWindow* find_toplevel_parent(wxWindow *window)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_window_geometry(wxTopLevelWindow *tlw, std::function<void()> callback)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
// On windows, the wxEVT_SHOW is not received if the window is created maximized
|
||||||
|
// cf. https://groups.google.com/forum/#!topic/wx-users/c7ntMt6piRI
|
||||||
|
// OTOH the geometry is available very soon, so we can call the callback right away
|
||||||
|
callback();
|
||||||
|
#elif defined __linux__
|
||||||
|
tlw->Bind(wxEVT_SHOW, [=](wxShowEvent &evt) {
|
||||||
|
// On Linux, the geometry is only available after wxEVT_SHOW + CallAfter
|
||||||
|
// cf. https://groups.google.com/forum/?pli=1#!topic/wx-users/fERSXdpVwAI
|
||||||
|
tlw->CallAfter([=]() { callback(); });
|
||||||
|
evt.Skip();
|
||||||
|
});
|
||||||
|
#elif defined __APPLE__
|
||||||
|
tlw->Bind(wxEVT_SHOW, [=](wxShowEvent &evt) {
|
||||||
|
callback();
|
||||||
|
evt.Skip();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent)
|
CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent)
|
||||||
: wxPanel(parent, wxID_ANY)
|
: wxPanel(parent, wxID_ANY)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
@ -24,6 +25,8 @@ namespace GUI {
|
||||||
|
|
||||||
wxTopLevelWindow* find_toplevel_parent(wxWindow *window);
|
wxTopLevelWindow* find_toplevel_parent(wxWindow *window);
|
||||||
|
|
||||||
|
void on_window_geometry(wxTopLevelWindow *tlw, std::function<void()> callback);
|
||||||
|
|
||||||
|
|
||||||
class EventGuard
|
class EventGuard
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/stattext.h>
|
#include <wx/stattext.h>
|
||||||
#include <wx/notebook.h>
|
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
#include <wx/bmpcbox.h>
|
#include <wx/bmpcbox.h>
|
||||||
#include <wx/statbox.h>
|
#include <wx/statbox.h>
|
||||||
|
@ -1092,7 +1091,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||||
: q(q)
|
: q(q)
|
||||||
, main_frame(main_frame)
|
, main_frame(main_frame)
|
||||||
, config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({
|
, config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({
|
||||||
"bed_shape", "complete_objects", "extruder_clearance_radius", "skirts", "skirt_distance",
|
"bed_shape", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance",
|
||||||
"brim_width", "variable_layer_height", "serial_port", "serial_speed", "host_type", "print_host",
|
"brim_width", "variable_layer_height", "serial_port", "serial_speed", "host_type", "print_host",
|
||||||
"printhost_apikey", "printhost_cafile", "nozzle_diameter", "single_extruder_multi_material",
|
"printhost_apikey", "printhost_cafile", "nozzle_diameter", "single_extruder_multi_material",
|
||||||
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle",
|
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle",
|
||||||
|
@ -1774,8 +1773,11 @@ void Plater::priv::arrange()
|
||||||
// FIXME: I don't know how to obtain the minimum distance, it depends
|
// FIXME: I don't know how to obtain the minimum distance, it depends
|
||||||
// on printer technology. I guess the following should work but it crashes.
|
// on printer technology. I guess the following should work but it crashes.
|
||||||
double dist = 6; //PrintConfig::min_object_distance(config);
|
double dist = 6; //PrintConfig::min_object_distance(config);
|
||||||
|
if(printer_technology == ptFFF) {
|
||||||
|
dist = PrintConfig::min_object_distance(config);
|
||||||
|
}
|
||||||
|
|
||||||
auto min_obj_distance = static_cast<coord_t>(dist/SCALING_FACTOR);
|
auto min_obj_distance = coord_t(dist/SCALING_FACTOR);
|
||||||
|
|
||||||
const auto *bed_shape_opt = config->opt<ConfigOptionPoints>("bed_shape");
|
const auto *bed_shape_opt = config->opt<ConfigOptionPoints>("bed_shape");
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,10 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <unordered_map>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
@ -83,6 +85,16 @@ VendorProfile VendorProfile::from_ini(const boost::filesystem::path &path, bool
|
||||||
return VendorProfile::from_ini(tree, path, load_all);
|
return VendorProfile::from_ini(tree, path, load_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, std::string> pre_family_model_map {{
|
||||||
|
{ "MK3", "MK3" },
|
||||||
|
{ "MK3MMU2", "MK3" },
|
||||||
|
{ "MK2.5", "MK2.5" },
|
||||||
|
{ "MK2.5MMU2", "MK2.5" },
|
||||||
|
{ "MK2S", "MK2" },
|
||||||
|
{ "MK2SMM", "MK2" },
|
||||||
|
{ "SL1", "SL1" },
|
||||||
|
}};
|
||||||
|
|
||||||
VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all)
|
VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all)
|
||||||
{
|
{
|
||||||
static const std::string printer_model_key = "printer_model:";
|
static const std::string printer_model_key = "printer_model:";
|
||||||
|
@ -128,11 +140,21 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
|
||||||
VendorProfile::PrinterModel model;
|
VendorProfile::PrinterModel model;
|
||||||
model.id = section.first.substr(printer_model_key.size());
|
model.id = section.first.substr(printer_model_key.size());
|
||||||
model.name = section.second.get<std::string>("name", model.id);
|
model.name = section.second.get<std::string>("name", model.id);
|
||||||
auto technology_field = section.second.get<std::string>("technology", "FFF");
|
|
||||||
|
const char *technology_fallback = boost::algorithm::starts_with(model.id, "SL") ? "SLA" : "FFF";
|
||||||
|
|
||||||
|
auto technology_field = section.second.get<std::string>("technology", technology_fallback);
|
||||||
if (! ConfigOptionEnum<PrinterTechnology>::from_string(technology_field, model.technology)) {
|
if (! ConfigOptionEnum<PrinterTechnology>::from_string(technology_field, model.technology)) {
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Invalid printer technology field: `%2%`") % id % technology_field;
|
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Invalid printer technology field: `%2%`") % id % technology_field;
|
||||||
model.technology = ptFFF;
|
model.technology = ptFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model.family = section.second.get<std::string>("family", std::string());
|
||||||
|
if (model.family.empty() && res.name == "Prusa Research") {
|
||||||
|
// If no family is specified, it can be inferred for known printers
|
||||||
|
const auto from_pre_map = pre_family_model_map.find(model.id);
|
||||||
|
if (from_pre_map != pre_family_model_map.end()) { model.family = from_pre_map->second; }
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
// Remove SLA printers from the initial alpha.
|
// Remove SLA printers from the initial alpha.
|
||||||
if (model.technology == ptSLA)
|
if (model.technology == ptSLA)
|
||||||
|
@ -157,6 +179,20 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> VendorProfile::families() const
|
||||||
|
{
|
||||||
|
std::vector<std::string> res;
|
||||||
|
unsigned num_familiies = 0;
|
||||||
|
|
||||||
|
for (auto &model : models) {
|
||||||
|
if (std::find(res.begin(), res.end(), model.family) == res.end()) {
|
||||||
|
res.push_back(model.family);
|
||||||
|
num_familiies++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// Suffix to be added to a modified preset name in the combo box.
|
// Suffix to be added to a modified preset name in the combo box.
|
||||||
static std::string g_suffix_modified = " (modified)";
|
static std::string g_suffix_modified = " (modified)";
|
||||||
|
|
|
@ -54,13 +54,16 @@ public:
|
||||||
std::string id;
|
std::string id;
|
||||||
std::string name;
|
std::string name;
|
||||||
PrinterTechnology technology;
|
PrinterTechnology technology;
|
||||||
|
std::string family;
|
||||||
std::vector<PrinterVariant> variants;
|
std::vector<PrinterVariant> variants;
|
||||||
|
|
||||||
PrinterVariant* variant(const std::string &name) {
|
PrinterVariant* variant(const std::string &name) {
|
||||||
for (auto &v : this->variants)
|
for (auto &v : this->variants)
|
||||||
if (v.name == name)
|
if (v.name == name)
|
||||||
return &v;
|
return &v;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
|
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
|
||||||
};
|
};
|
||||||
std::vector<PrinterModel> models;
|
std::vector<PrinterModel> models;
|
||||||
|
@ -72,6 +75,7 @@ public:
|
||||||
static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true);
|
static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true);
|
||||||
|
|
||||||
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
|
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
|
||||||
|
std::vector<std::string> families() const;
|
||||||
|
|
||||||
bool operator< (const VendorProfile &rhs) const { return this->id < rhs.id; }
|
bool operator< (const VendorProfile &rhs) const { return this->id < rhs.id; }
|
||||||
bool operator==(const VendorProfile &rhs) const { return this->id == rhs.id; }
|
bool operator==(const VendorProfile &rhs) const { return this->id == rhs.id; }
|
||||||
|
|
|
@ -244,7 +244,7 @@ void Http::priv::http_perform()
|
||||||
::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, static_cast<void*>(this));
|
::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, static_cast<void*>(this));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
::curl_easy_setopt(curl, CURLOPT_VERBOSE, get_logging_level() >= 4);
|
::curl_easy_setopt(curl, CURLOPT_VERBOSE, get_logging_level() >= 5);
|
||||||
|
|
||||||
if (headerlist != nullptr) {
|
if (headerlist != nullptr) {
|
||||||
::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
#include <wx/app.h>
|
#include <wx/app.h>
|
||||||
#include <wx/event.h>
|
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
|
|
||||||
#include "libslic3r/libslic3r.h"
|
#include "libslic3r/libslic3r.h"
|
||||||
|
@ -90,9 +89,25 @@ struct Updates
|
||||||
std::vector<Update> updates;
|
std::vector<Update> updates;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Semver get_slic3r_version()
|
||||||
|
{
|
||||||
|
auto res = Semver::parse(SLIC3R_VERSION);
|
||||||
|
|
||||||
|
if (! res) {
|
||||||
|
const char *error = "Could not parse Slic3r version string: " SLIC3R_VERSION;
|
||||||
|
BOOST_LOG_TRIVIAL(error) << error;
|
||||||
|
throw std::runtime_error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *res;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDEFINE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
|
||||||
|
|
||||||
|
|
||||||
struct PresetUpdater::priv
|
struct PresetUpdater::priv
|
||||||
{
|
{
|
||||||
|
const Semver ver_slic3r;
|
||||||
std::vector<Index> index_db;
|
std::vector<Index> index_db;
|
||||||
|
|
||||||
bool enabled_version_check;
|
bool enabled_version_check;
|
||||||
|
@ -122,12 +137,13 @@ struct PresetUpdater::priv
|
||||||
static void copy_file(const fs::path &from, const fs::path &to);
|
static void copy_file(const fs::path &from, const fs::path &to);
|
||||||
};
|
};
|
||||||
|
|
||||||
PresetUpdater::priv::priv() :
|
PresetUpdater::priv::priv()
|
||||||
had_config_update(false),
|
: ver_slic3r(get_slic3r_version())
|
||||||
cache_path(fs::path(Slic3r::data_dir()) / "cache"),
|
, had_config_update(false)
|
||||||
rsrc_path(fs::path(resources_dir()) / "profiles"),
|
, cache_path(fs::path(Slic3r::data_dir()) / "cache")
|
||||||
vendor_path(fs::path(Slic3r::data_dir()) / "vendor"),
|
, rsrc_path(fs::path(resources_dir()) / "profiles")
|
||||||
cancel(false)
|
, vendor_path(fs::path(Slic3r::data_dir()) / "vendor")
|
||||||
|
, cancel(false)
|
||||||
{
|
{
|
||||||
set_download_prefs(GUI::wxGetApp().app_config);
|
set_download_prefs(GUI::wxGetApp().app_config);
|
||||||
check_install_indices();
|
check_install_indices();
|
||||||
|
@ -209,11 +225,10 @@ void PresetUpdater::priv::sync_version() const
|
||||||
.on_complete([&](std::string body, unsigned /* http_status */) {
|
.on_complete([&](std::string body, unsigned /* http_status */) {
|
||||||
boost::trim(body);
|
boost::trim(body);
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("Got Slic3rPE online version: `%1%`. Sending to GUI thread...") % body;
|
BOOST_LOG_TRIVIAL(info) << boost::format("Got Slic3rPE online version: `%1%`. Sending to GUI thread...") % body;
|
||||||
// wxCommandEvent* evt = new wxCommandEvent(version_online_event);
|
|
||||||
// evt->SetString(body);
|
wxCommandEvent* evt = new wxCommandEvent(EVT_SLIC3R_VERSION_ONLINE);
|
||||||
// GUI::get_app()->QueueEvent(evt);
|
evt->SetString(GUI::from_u8(body));
|
||||||
GUI::wxGetApp().app_config->set("version_online", body);
|
GUI::wxGetApp().QueueEvent(evt);
|
||||||
GUI::wxGetApp().app_config->save();
|
|
||||||
})
|
})
|
||||||
.perform_sync();
|
.perform_sync();
|
||||||
}
|
}
|
||||||
|
@ -260,7 +275,7 @@ void PresetUpdater::priv::sync_config(const std::set<VendorProfile> vendors)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (new_index.version() < index.version()) {
|
if (new_index.version() < index.version()) {
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("The downloaded index %1% for vendor %2% is older than the active one. Ignoring the downloaded index.") % idx_path_temp % vendor.name;
|
BOOST_LOG_TRIVIAL(warning) << boost::format("The downloaded index %1% for vendor %2% is older than the active one. Ignoring the downloaded index.") % idx_path_temp % vendor.name;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Slic3r::rename_file(idx_path_temp, idx_path);
|
Slic3r::rename_file(idx_path_temp, idx_path);
|
||||||
|
@ -275,6 +290,7 @@ void PresetUpdater::priv::sync_config(const std::set<VendorProfile> vendors)
|
||||||
BOOST_LOG_TRIVIAL(error) << boost::format("No recommended version for vendor: %1%, invalid index?") % vendor.name;
|
BOOST_LOG_TRIVIAL(error) << boost::format("No recommended version for vendor: %1%, invalid index?") % vendor.name;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto recommended = recommended_it->config_version;
|
const auto recommended = recommended_it->config_version;
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << boost::format("Got index for vendor: %1%: current version: %2%, recommended version: %3%")
|
BOOST_LOG_TRIVIAL(debug) << boost::format("Got index for vendor: %1%: current version: %2%, recommended version: %3%")
|
||||||
|
@ -341,7 +357,8 @@ Updates PresetUpdater::priv::get_config_updates() const
|
||||||
if (ver_current == idx.end()) {
|
if (ver_current == idx.end()) {
|
||||||
auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str();
|
auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str();
|
||||||
BOOST_LOG_TRIVIAL(error) << message;
|
BOOST_LOG_TRIVIAL(error) << message;
|
||||||
throw std::runtime_error(message);
|
GUI::show_error(nullptr, GUI::from_u8(message));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getting a recommended version from the latest index, wich may have been downloaded
|
// Getting a recommended version from the latest index, wich may have been downloaded
|
||||||
|
@ -528,18 +545,14 @@ void PresetUpdater::slic3r_update_notify()
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* app_config = GUI::wxGetApp().app_config;
|
auto* app_config = GUI::wxGetApp().app_config;
|
||||||
const auto ver_slic3r = Semver::parse(SLIC3R_VERSION);
|
|
||||||
const auto ver_online_str = app_config->get("version_online");
|
const auto ver_online_str = app_config->get("version_online");
|
||||||
const auto ver_online = Semver::parse(ver_online_str);
|
const auto ver_online = Semver::parse(ver_online_str);
|
||||||
const auto ver_online_seen = Semver::parse(app_config->get("version_online_seen"));
|
const auto ver_online_seen = Semver::parse(app_config->get("version_online_seen"));
|
||||||
if (! ver_slic3r) {
|
|
||||||
throw std::runtime_error("Could not parse Slic3r version string: " SLIC3R_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ver_online) {
|
if (ver_online) {
|
||||||
// Only display the notification if the version available online is newer AND if we haven't seen it before
|
// Only display the notification if the version available online is newer AND if we haven't seen it before
|
||||||
if (*ver_online > *ver_slic3r && (! ver_online_seen || *ver_online_seen < *ver_online)) {
|
if (*ver_online > p->ver_slic3r && (! ver_online_seen || *ver_online_seen < *ver_online)) {
|
||||||
GUI::MsgUpdateSlic3r notification(*ver_slic3r, *ver_online);
|
GUI::MsgUpdateSlic3r notification(p->ver_slic3r, *ver_online);
|
||||||
notification.ShowModal();
|
notification.ShowModal();
|
||||||
if (notification.disable_version_check()) {
|
if (notification.disable_version_check()) {
|
||||||
app_config->set("version_check", "0");
|
app_config->set("version_check", "0");
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <wx/event.h>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +39,8 @@ private:
|
||||||
std::unique_ptr<priv> p;
|
std::unique_ptr<priv> p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wxDECLARE_EVENT(EVT_SLIC3R_VERSION_ONLINE, wxCommandEvent);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|