Merge remote-tracking branch 'origin/master' into tm_pad_speedup
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 |
|
@ -1333,6 +1333,8 @@ void Transformation::set_rotation(const Vec3d& rotation)
|
|||
void Transformation::set_rotation(Axis axis, double 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)
|
||||
{
|
||||
|
|
|
@ -1445,7 +1445,7 @@ int ModelVolume::extruder_id() const
|
|||
int extruder_id = -1;
|
||||
if (this->is_model_part()) {
|
||||
const ConfigOption *opt = this->config.option("extruder");
|
||||
if (opt == nullptr)
|
||||
if ((opt == nullptr) || (opt->getInt() == 0))
|
||||
opt = this->object->config.option("extruder");
|
||||
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.
|
||||
object->model_object()->instances.front()->transform_polygon(&convex_hull);
|
||||
// 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();
|
||||
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
|
||||
for (const Point © : object->m_copies) {
|
||||
|
|
|
@ -16,30 +16,30 @@ namespace GUI {
|
|||
class ConfigWizard: public wxDialog
|
||||
{
|
||||
public:
|
||||
// Why is the Wizard run
|
||||
enum RunReason {
|
||||
RR_DATA_EMPTY, // No or empty datadir
|
||||
RR_DATA_LEGACY, // Pre-updating datadir
|
||||
RR_DATA_INCOMPAT, // Incompatible datadir - Slic3r downgrade situation
|
||||
RR_USER, // User requested the Wizard from the menus
|
||||
};
|
||||
// Why is the Wizard run
|
||||
enum RunReason {
|
||||
RR_DATA_EMPTY, // No or empty datadir
|
||||
RR_DATA_LEGACY, // Pre-updating datadir
|
||||
RR_DATA_INCOMPAT, // Incompatible datadir - Slic3r downgrade situation
|
||||
RR_USER, // User requested the Wizard from the menus
|
||||
};
|
||||
|
||||
ConfigWizard(wxWindow *parent, RunReason run_reason);
|
||||
ConfigWizard(ConfigWizard &&) = delete;
|
||||
ConfigWizard(const ConfigWizard &) = delete;
|
||||
ConfigWizard &operator=(ConfigWizard &&) = delete;
|
||||
ConfigWizard &operator=(const ConfigWizard &) = delete;
|
||||
~ConfigWizard();
|
||||
ConfigWizard(wxWindow *parent, RunReason run_reason);
|
||||
ConfigWizard(ConfigWizard &&) = delete;
|
||||
ConfigWizard(const ConfigWizard &) = delete;
|
||||
ConfigWizard &operator=(ConfigWizard &&) = delete;
|
||||
ConfigWizard &operator=(const ConfigWizard &) = delete;
|
||||
~ConfigWizard();
|
||||
|
||||
// Run the Wizard. Return whether it was completed.
|
||||
bool run(PresetBundle *preset_bundle, const PresetUpdater *updater);
|
||||
// Run the Wizard. Return whether it was completed.
|
||||
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:
|
||||
struct priv;
|
||||
std::unique_ptr<priv> p;
|
||||
struct priv;
|
||||
std::unique_ptr<priv> p;
|
||||
|
||||
friend struct ConfigWizardPage;
|
||||
friend struct ConfigWizardPage;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <vector>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <wx/sizer.h>
|
||||
|
@ -13,6 +14,7 @@
|
|||
#include <wx/button.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "slic3r/Utils/PresetUpdater.hpp"
|
||||
|
@ -26,211 +28,264 @@ namespace Slic3r {
|
|||
namespace GUI {
|
||||
|
||||
enum {
|
||||
WRAP_WIDTH = 500,
|
||||
MODEL_MIN_WRAP = 150,
|
||||
WRAP_WIDTH = 500,
|
||||
MODEL_MIN_WRAP = 150,
|
||||
|
||||
DIALOG_MARGIN = 15,
|
||||
INDEX_MARGIN = 40,
|
||||
BTN_SPACING = 10,
|
||||
INDENT_SPACING = 30,
|
||||
VERTICAL_SPACING = 10,
|
||||
DIALOG_MARGIN = 15,
|
||||
INDEX_MARGIN = 40,
|
||||
BTN_SPACING = 10,
|
||||
INDENT_SPACING = 30,
|
||||
VERTICAL_SPACING = 10,
|
||||
|
||||
MAX_COLS = 4,
|
||||
ROW_SPACING = 75,
|
||||
};
|
||||
|
||||
typedef std::function<bool(const VendorProfile::PrinterModel&)> ModelFilter;
|
||||
|
||||
struct PrinterPicker: wxPanel
|
||||
{
|
||||
struct Checkbox : wxCheckBox
|
||||
{
|
||||
Checkbox(wxWindow *parent, const wxString &label, const std::string &model, const std::string &variant) :
|
||||
wxCheckBox(parent, wxID_ANY, label),
|
||||
model(model),
|
||||
variant(variant)
|
||||
{}
|
||||
struct Checkbox : wxCheckBox
|
||||
{
|
||||
Checkbox(wxWindow *parent, const wxString &label, const std::string &model, const std::string &variant) :
|
||||
wxCheckBox(parent, wxID_ANY, label),
|
||||
model(model),
|
||||
variant(variant)
|
||||
{}
|
||||
|
||||
std::string model;
|
||||
std::string variant;
|
||||
};
|
||||
std::string model;
|
||||
std::string variant;
|
||||
};
|
||||
|
||||
const std::string vendor_id;
|
||||
std::vector<Checkbox*> cboxes;
|
||||
unsigned variants_checked;
|
||||
const std::string vendor_id;
|
||||
std::vector<Checkbox*> cboxes;
|
||||
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_one(size_t i, bool select);
|
||||
void on_checkbox(const Checkbox *cbox, bool checked);
|
||||
void select_all(bool select, bool alternates = false);
|
||||
void select_one(size_t i, bool select);
|
||||
void on_checkbox(const Checkbox *cbox, bool checked);
|
||||
|
||||
int get_width() const { return width; }
|
||||
private:
|
||||
int width;
|
||||
};
|
||||
|
||||
struct ConfigWizardPage: wxPanel
|
||||
{
|
||||
ConfigWizard *parent;
|
||||
const wxString shortname;
|
||||
wxBoxSizer *content;
|
||||
ConfigWizard *parent;
|
||||
const wxString shortname;
|
||||
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; }
|
||||
ConfigWizardPage* page_next() const { return p_next; }
|
||||
ConfigWizardPage* chain(ConfigWizardPage *page);
|
||||
void append_text(wxString text);
|
||||
void append_spacer(int space);
|
||||
|
||||
template<class T>
|
||||
void append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
|
||||
{
|
||||
content->Add(thing, proportion, flag, border);
|
||||
}
|
||||
ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
|
||||
|
||||
void append_text(wxString text);
|
||||
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;
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config) {}
|
||||
};
|
||||
|
||||
struct PageWelcome: ConfigWizardPage
|
||||
{
|
||||
PrinterPicker *printer_picker;
|
||||
wxPanel *others_buttons;
|
||||
wxCheckBox *cbox_reset;
|
||||
wxCheckBox *cbox_reset;
|
||||
|
||||
PageWelcome(ConfigWizard *parent, bool check_first_variant);
|
||||
PageWelcome(ConfigWizard *parent);
|
||||
|
||||
virtual wxPanel* extra_buttons() { return others_buttons; }
|
||||
virtual void on_page_set();
|
||||
bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; }
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
bool version_check;
|
||||
bool preset_update;
|
||||
bool version_check;
|
||||
bool preset_update;
|
||||
|
||||
PageUpdate(ConfigWizard *parent);
|
||||
PageUpdate(ConfigWizard *parent);
|
||||
};
|
||||
|
||||
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_variant_checked();
|
||||
void on_vendor_pick(size_t i);
|
||||
};
|
||||
|
||||
struct PageFirmware: ConfigWizardPage
|
||||
{
|
||||
const ConfigOptionDef &gcode_opt;
|
||||
wxChoice *gcode_picker;
|
||||
const ConfigOptionDef &gcode_opt;
|
||||
wxChoice *gcode_picker;
|
||||
|
||||
PageFirmware(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
PageFirmware(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
};
|
||||
|
||||
struct PageBedShape: ConfigWizardPage
|
||||
{
|
||||
BedShapePanel *shape_panel;
|
||||
BedShapePanel *shape_panel;
|
||||
|
||||
PageBedShape(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
PageBedShape(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
};
|
||||
|
||||
struct PageDiameters: ConfigWizardPage
|
||||
{
|
||||
wxSpinCtrlDouble *spin_nozzle;
|
||||
wxSpinCtrlDouble *spin_filam;
|
||||
wxSpinCtrlDouble *spin_nozzle;
|
||||
wxSpinCtrlDouble *spin_filam;
|
||||
|
||||
PageDiameters(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
PageDiameters(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
};
|
||||
|
||||
struct PageTemperatures: ConfigWizardPage
|
||||
{
|
||||
wxSpinCtrlDouble *spin_extr;
|
||||
wxSpinCtrlDouble *spin_bed;
|
||||
wxSpinCtrlDouble *spin_extr;
|
||||
wxSpinCtrlDouble *spin_bed;
|
||||
|
||||
PageTemperatures(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
PageTemperatures(ConfigWizard *parent);
|
||||
virtual void apply_custom_config(DynamicPrintConfig &config);
|
||||
};
|
||||
|
||||
|
||||
class ConfigWizardIndex: public wxPanel
|
||||
{
|
||||
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:
|
||||
const wxBitmap bg;
|
||||
const wxBitmap bullet_black;
|
||||
const wxBitmap bullet_blue;
|
||||
const wxBitmap bullet_white;
|
||||
int text_height;
|
||||
struct Item
|
||||
{
|
||||
wxString label;
|
||||
unsigned indent;
|
||||
ConfigWizardPage *page; // nullptr page => label-only item
|
||||
|
||||
std::vector<wxString> items;
|
||||
std::vector<wxString>::const_iterator item_active;
|
||||
bool operator==(ConfigWizardPage *page) const { return this->page == page; }
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
ConfigWizard *q;
|
||||
ConfigWizard::RunReason run_reason;
|
||||
AppConfig appconfig_vendors;
|
||||
std::unordered_map<std::string, VendorProfile> vendors;
|
||||
std::unordered_map<std::string, std::string> vendors_rsrc;
|
||||
std::unique_ptr<DynamicPrintConfig> custom_config;
|
||||
ConfigWizard *q;
|
||||
ConfigWizard::RunReason run_reason;
|
||||
AppConfig appconfig_vendors;
|
||||
std::unordered_map<std::string, VendorProfile> vendors;
|
||||
std::unordered_map<std::string, std::string> vendors_rsrc;
|
||||
std::unique_ptr<DynamicPrintConfig> custom_config;
|
||||
|
||||
wxScrolledWindow *hscroll = nullptr;
|
||||
wxBoxSizer *hscroll_sizer = nullptr;
|
||||
wxBoxSizer *btnsizer = nullptr;
|
||||
ConfigWizardPage *page_current = nullptr;
|
||||
ConfigWizardIndex *index = nullptr;
|
||||
wxButton *btn_prev = nullptr;
|
||||
wxButton *btn_next = nullptr;
|
||||
wxButton *btn_finish = nullptr;
|
||||
wxButton *btn_cancel = nullptr;
|
||||
wxScrolledWindow *hscroll = nullptr;
|
||||
wxBoxSizer *hscroll_sizer = nullptr;
|
||||
wxBoxSizer *btnsizer = nullptr;
|
||||
ConfigWizardPage *page_current = nullptr;
|
||||
ConfigWizardIndex *index = nullptr;
|
||||
wxButton *btn_prev = nullptr;
|
||||
wxButton *btn_next = nullptr;
|
||||
wxButton *btn_finish = nullptr;
|
||||
wxButton *btn_cancel = nullptr;
|
||||
|
||||
PageWelcome *page_welcome = nullptr;
|
||||
PageUpdate *page_update = nullptr;
|
||||
PageVendors *page_vendors = nullptr;
|
||||
PageFirmware *page_firmware = nullptr;
|
||||
PageBedShape *page_bed = nullptr;
|
||||
PageDiameters *page_diams = nullptr;
|
||||
PageTemperatures *page_temps = nullptr;
|
||||
PageWelcome *page_welcome = nullptr;
|
||||
PagePrinters *page_fff = nullptr;
|
||||
PagePrinters *page_msla = nullptr;
|
||||
PageCustom *page_custom = nullptr;
|
||||
PageUpdate *page_update = nullptr;
|
||||
PageVendors *page_vendors = nullptr; // XXX: ?
|
||||
|
||||
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();
|
||||
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);
|
||||
priv(ConfigWizard *q) : q(q) {}
|
||||
|
||||
void on_other_vendors();
|
||||
void on_custom_setup();
|
||||
void load_pages(bool 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;
|
||||
// Replace the first occurence of comma in decimal number.
|
||||
str.Replace(",", ".", false);
|
||||
if(!str.ToCDouble(&val))
|
||||
{
|
||||
show_error(m_parent, _(L("Invalid numeric input.")));
|
||||
set_value(double_to_string(val), true);
|
||||
}
|
||||
if (m_opt.min > val || val > m_opt.max)
|
||||
{
|
||||
show_error(m_parent, _(L("Input value is out of range")));
|
||||
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;
|
||||
if (str == ".")
|
||||
val = 0.0;
|
||||
else
|
||||
{
|
||||
if (!str.ToCDouble(&val))
|
||||
{
|
||||
show_error(m_parent, _(L("Invalid numeric input.")));
|
||||
set_value(double_to_string(val), true);
|
||||
}
|
||||
if (m_opt.min > val || val > m_opt.max)
|
||||
{
|
||||
show_error(m_parent, _(L("Input value is out of range")));
|
||||
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; }
|
||||
case coString:
|
||||
case coStrings:
|
||||
|
@ -459,7 +464,7 @@ void SpinCtrl::BUILD() {
|
|||
// # 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
|
||||
std::string value = e.GetString().utf8_str().data();
|
||||
if (is_matched(value, "^\\d+$"))
|
||||
if (is_matched(value, "^\\-?\\d+$"))
|
||||
tmp_value = std::stoi(value);
|
||||
else tmp_value = -9999;
|
||||
#ifdef __WXOSX__
|
||||
|
@ -475,7 +480,7 @@ void SpinCtrl::BUILD() {
|
|||
|
||||
void SpinCtrl::propagate_value()
|
||||
{
|
||||
if (tmp_value < 0)
|
||||
if (tmp_value == -9999)
|
||||
on_kill_focus();
|
||||
else if (boost::any_cast<int>(m_value) != tmp_value)
|
||||
on_change_field();
|
||||
|
@ -867,8 +872,8 @@ void StaticText::BUILD()
|
|||
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
|
||||
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
|
||||
|
||||
wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value);
|
||||
auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size);
|
||||
const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value);
|
||||
auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE);
|
||||
temp->SetFont(wxGetApp().bold_font());
|
||||
|
||||
// // 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;
|
||||
for (unsigned int i = 0; i < m_tex_coords.size(); i += 2)
|
||||
{
|
||||
m_tex_coords[i] *= inv_size_x;
|
||||
m_tex_coords[i + 1] *= inv_size_y;
|
||||
m_tex_coords[i] = (m_tex_coords[i] - min_x) * inv_size_x;
|
||||
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
|
||||
{
|
||||
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
|
||||
std::string model_path = resources_dir() + "/models/" + key;
|
||||
#endif // ENABLE_PRINT_BED_MODELS
|
||||
|
||||
#if ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES
|
||||
// use anisotropic filter if graphic card allows
|
||||
GLfloat max_anisotropy = 0.0f;
|
||||
if (glewIsSupported("GL_EXT_texture_filter_anisotropic"))
|
||||
::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";
|
||||
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")
|
||||
offset.y() += 15. / 2.;
|
||||
// hardcoded value to match the stl model
|
||||
offset += Vec3d(0.0, 7.5, -0.03);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -5790,7 +5810,7 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip) const
|
|||
else
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -355,21 +355,6 @@ boost::filesystem::path into_path(const wxString &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()
|
||||
{
|
||||
AboutDialog dlg;
|
||||
|
|
|
@ -71,9 +71,6 @@ wxString from_path(const boost::filesystem::path &path);
|
|||
// boost path from wxString
|
||||
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
|
||||
extern void about();
|
||||
// Ask the destop to open the datadir using the default file explorer.
|
||||
|
|
|
@ -351,21 +351,10 @@ void GUI_App::persist_window_geometry(wxTopLevelWindow *window)
|
|||
});
|
||||
|
||||
window_pos_restore(window, name);
|
||||
#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
|
||||
// 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();
|
||||
|
||||
on_window_geometry(window, [=]() {
|
||||
window_pos_sanitize(window);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void GUI_App::load_project(wxWindow *parent, wxString& input_file)
|
||||
|
|
|
@ -42,10 +42,9 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
|
||||
// Objects(sub-objects) name
|
||||
def.label = L("Name");
|
||||
// def.type = coString;
|
||||
def.gui_type = "legend";
|
||||
def.tooltip = L("Object name");
|
||||
def.full_width = true;
|
||||
def.width = 200;
|
||||
def.default_value = new ConfigOptionString{ " " };
|
||||
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.width = 50;
|
||||
|
||||
if (option_name == "Rotation")
|
||||
{
|
||||
def.min = -360;
|
||||
def.max = 360;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
auto btn = new PrusaLockButton(parent, wxID_ANY);
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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_cache.rotation = deg_rotation;
|
||||
|
|
|
@ -26,6 +26,28 @@ wxTopLevelWindow* find_toplevel_parent(wxWindow *window)
|
|||
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)
|
||||
: wxPanel(parent, wxID_ANY)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
|
@ -24,6 +25,8 @@ namespace GUI {
|
|||
|
||||
wxTopLevelWindow* find_toplevel_parent(wxWindow *window);
|
||||
|
||||
void on_window_geometry(wxTopLevelWindow *tlw, std::function<void()> callback);
|
||||
|
||||
|
||||
class EventGuard
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
#include <wx/statbox.h>
|
||||
|
@ -1092,7 +1091,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
: q(q)
|
||||
, main_frame(main_frame)
|
||||
, 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",
|
||||
"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",
|
||||
|
@ -1774,8 +1773,11 @@ void Plater::priv::arrange()
|
|||
// 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.
|
||||
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");
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
#include <Windows.h>
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/filesystem.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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
model.id = section.first.substr(printer_model_key.size());
|
||||
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)) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Invalid printer technology field: `%2%`") % id % technology_field;
|
||||
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
|
||||
// Remove SLA printers from the initial alpha.
|
||||
if (model.technology == ptSLA)
|
||||
|
@ -157,6 +179,20 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
|
|||
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.
|
||||
static std::string g_suffix_modified = " (modified)";
|
||||
|
|
|
@ -54,13 +54,16 @@ public:
|
|||
std::string id;
|
||||
std::string name;
|
||||
PrinterTechnology technology;
|
||||
std::string family;
|
||||
std::vector<PrinterVariant> variants;
|
||||
|
||||
PrinterVariant* variant(const std::string &name) {
|
||||
for (auto &v : this->variants)
|
||||
if (v.name == name)
|
||||
return &v;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
|
||||
};
|
||||
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);
|
||||
|
||||
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; }
|
||||
|
|