Fixed conflicts after merge with master
This commit is contained in:
commit
ca34518bcc
264 changed files with 69447 additions and 49874 deletions
|
@ -125,7 +125,9 @@ void CopyrightsDialog::fill_entries()
|
|||
{ "lib_fts"
|
||||
, "Forrest Smith" , "https://www.forrestthewoods.com/" },
|
||||
{ "fast_float"
|
||||
, "Daniel Lemire, João Paulo Magalhaes and contributors", "https://github.com/fastfloat/fast_float" }
|
||||
, "Daniel Lemire, João Paulo Magalhaes and contributors", "https://github.com/fastfloat/fast_float" },
|
||||
{ "CuraEngine (Arachne, etc.)"
|
||||
, "Ultimaker", "https://github.com/Ultimaker/CuraEngine" }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -152,7 +154,7 @@ wxString CopyrightsDialog::get_html_text()
|
|||
, text_clr_str
|
||||
, header_str);
|
||||
|
||||
for (auto& entry : m_entries) {
|
||||
for (const auto& entry : m_entries) {
|
||||
text += wxString::Format(
|
||||
"<a href=\"%s\">%s</a><br/>"
|
||||
, entry.link, entry.lib_name);
|
||||
|
@ -276,7 +278,7 @@ AboutDialog::AboutDialog()
|
|||
"<html>"
|
||||
"<body bgcolor= %1% link= %2%>"
|
||||
"<font color=%3%>"
|
||||
"%4% © 2016-2021 Prusa Research. <br />"
|
||||
"%4% © 2016-2022 Prusa Research. <br />"
|
||||
"%5% © 2011-2018 Alessandro Ranellucci. <br />"
|
||||
"<a href=\"http://slic3r.org/\">Slic3r</a> %6% "
|
||||
"<a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">%7%</a>."
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "slic3r/GUI/GUI.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/format.hpp"
|
||||
#include "slic3r/Utils/Bonjour.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
@ -233,7 +234,49 @@ void BonjourDialog::on_timer_process()
|
|||
}
|
||||
}
|
||||
|
||||
IPListDialog::IPListDialog(wxWindow* parent, const wxString& hostname, const std::vector<boost::asio::ip::address>& ips, size_t& selected_index)
|
||||
: wxDialog(parent, wxID_ANY, _(L("Multiple resolved IP addresses")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
, m_list(new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSIMPLE_BORDER))
|
||||
, m_selected_index (selected_index)
|
||||
{
|
||||
const int em = GUI::wxGetApp().em_unit();
|
||||
m_list->SetMinSize(wxSize(40 * em, 30 * em));
|
||||
|
||||
wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto* label = new wxStaticText(this, wxID_ANY, GUI::format_wxstr(_L("There are several IP addresses resolving to hostname %1%.\nPlease select one that should be used."), hostname));
|
||||
vsizer->Add(label, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, em);
|
||||
|
||||
m_list->SetSingleStyle(wxLC_SINGLE_SEL);
|
||||
m_list->AppendColumn(_(L("Address")), wxLIST_FORMAT_LEFT, 40 * em);
|
||||
|
||||
for (size_t i = 0; i < ips.size(); i++)
|
||||
m_list->InsertItem(i, boost::nowide::widen(ips[i].to_string()));
|
||||
|
||||
m_list->Select(0);
|
||||
|
||||
vsizer->Add(m_list, 1, wxEXPAND | wxALL, em);
|
||||
|
||||
wxBoxSizer* button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
button_sizer->Add(new wxButton(this, wxID_OK, "OK"), 0, wxALL, em);
|
||||
button_sizer->Add(new wxButton(this, wxID_CANCEL, "Cancel"), 0, wxALL, em);
|
||||
|
||||
vsizer->Add(button_sizer, 0, wxALIGN_CENTER);
|
||||
SetSizerAndFit(vsizer);
|
||||
|
||||
GUI::wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
IPListDialog::~IPListDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void IPListDialog::EndModal(int retCode)
|
||||
{
|
||||
if (retCode == wxID_OK) {
|
||||
m_selected_index = (size_t)m_list->GetFirstSelected();
|
||||
}
|
||||
wxDialog::EndModal(retCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <memory>
|
||||
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
|
@ -11,7 +12,7 @@ class wxListView;
|
|||
class wxStaticText;
|
||||
class wxTimer;
|
||||
class wxTimerEvent;
|
||||
|
||||
class address;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -41,12 +42,26 @@ private:
|
|||
unsigned timer_state;
|
||||
Slic3r::PrinterTechnology tech;
|
||||
|
||||
void on_reply(BonjourReplyEvent &);
|
||||
virtual void on_reply(BonjourReplyEvent &);
|
||||
void on_timer(wxTimerEvent &);
|
||||
void on_timer_process();
|
||||
};
|
||||
|
||||
class IPListDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
IPListDialog(wxWindow* parent, const wxString& hostname, const std::vector<boost::asio::ip::address>& ips, size_t& selected_index);
|
||||
IPListDialog(IPListDialog&&) = delete;
|
||||
IPListDialog(const IPListDialog&) = delete;
|
||||
IPListDialog& operator=(IPListDialog&&) = delete;
|
||||
IPListDialog& operator=(const IPListDialog&) = delete;
|
||||
~IPListDialog();
|
||||
|
||||
virtual void EndModal(int retCode) wxOVERRIDE;
|
||||
private:
|
||||
wxListView* m_list;
|
||||
size_t& m_selected_index;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -317,6 +317,17 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
|||
|
||||
bool have_avoid_crossing_perimeters = config->opt_bool("avoid_crossing_perimeters");
|
||||
toggle_field("avoid_crossing_perimeters_max_detour", have_avoid_crossing_perimeters);
|
||||
|
||||
bool have_arachne = config->opt_enum<PerimeterGeneratorType>("perimeter_generator") == PerimeterGeneratorType::Arachne;
|
||||
toggle_field("wall_transition_length", have_arachne);
|
||||
toggle_field("wall_transition_filter_deviation", have_arachne);
|
||||
toggle_field("wall_transition_angle", have_arachne);
|
||||
toggle_field("wall_distribution_count", have_arachne);
|
||||
toggle_field("wall_split_middle_threshold", have_arachne);
|
||||
toggle_field("wall_add_middle_threshold", have_arachne);
|
||||
toggle_field("min_feature_size", have_arachne);
|
||||
toggle_field("min_bead_width", have_arachne);
|
||||
toggle_field("thin_walls", !have_arachne);
|
||||
}
|
||||
|
||||
void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)
|
||||
|
|
|
@ -1484,7 +1484,7 @@ PageDiameters::PageDiameters(ConfigWizard *parent)
|
|||
auto *unit_filam = new wxStaticText(this, wxID_ANY, _L("mm"));
|
||||
sizer_filam->AddGrowableCol(0, 1);
|
||||
sizer_filam->Add(text_filam, 0, wxALIGN_CENTRE_VERTICAL);
|
||||
sizer_filam->Add(diam_filam);
|
||||
sizer_filam->Add(diam_filam, 0, wxALIGN_CENTRE_VERTICAL);
|
||||
sizer_filam->Add(unit_filam, 0, wxALIGN_CENTRE_VERTICAL);
|
||||
append(sizer_filam);
|
||||
}
|
||||
|
|
|
@ -877,10 +877,10 @@ void SpinCtrl::BUILD() {
|
|||
|
||||
void SpinCtrl::propagate_value()
|
||||
{
|
||||
if (suppress_propagation)
|
||||
// check if value was really changed
|
||||
if (boost::any_cast<int>(m_value) == tmp_value)
|
||||
return;
|
||||
|
||||
suppress_propagation = true;
|
||||
if (tmp_value == UNDEF_VALUE) {
|
||||
on_kill_focus();
|
||||
} else {
|
||||
|
@ -894,7 +894,6 @@ void SpinCtrl::propagate_value()
|
|||
#endif
|
||||
on_change_field();
|
||||
}
|
||||
suppress_propagation = false;
|
||||
}
|
||||
|
||||
void SpinCtrl::msw_rescale()
|
||||
|
|
|
@ -319,7 +319,6 @@ class SpinCtrl : public Field {
|
|||
private:
|
||||
static const int UNDEF_VALUE = INT_MIN;
|
||||
|
||||
bool suppress_propagation {false};
|
||||
public:
|
||||
SpinCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id), tmp_value(UNDEF_VALUE) {}
|
||||
SpinCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id), tmp_value(UNDEF_VALUE) {}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/Layer.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
#include "libslic3r/Technologies.hpp"
|
||||
#include "libslic3r/Tesselate.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
|
@ -1126,13 +1127,13 @@ void GLCanvas3D::load_arrange_settings()
|
|||
wxGetApp().app_config->get("arrange", "enable_rotation_sla");
|
||||
|
||||
if (!dist_fff_str.empty())
|
||||
m_arrange_settings_fff.distance = std::stof(dist_fff_str);
|
||||
m_arrange_settings_fff.distance = string_to_float_decimal_point(dist_fff_str);
|
||||
|
||||
if (!dist_fff_seq_print_str.empty())
|
||||
m_arrange_settings_fff_seq_print.distance = std::stof(dist_fff_seq_print_str);
|
||||
m_arrange_settings_fff_seq_print.distance = string_to_float_decimal_point(dist_fff_seq_print_str);
|
||||
|
||||
if (!dist_sla_str.empty())
|
||||
m_arrange_settings_sla.distance = std::stof(dist_sla_str);
|
||||
m_arrange_settings_sla.distance = string_to_float_decimal_point(dist_sla_str);
|
||||
|
||||
if (!en_rot_fff_str.empty())
|
||||
m_arrange_settings_fff.enable_rotation = (en_rot_fff_str == "1" || en_rot_fff_str == "yes");
|
||||
|
@ -1818,6 +1819,10 @@ void GLCanvas3D::select_all()
|
|||
{
|
||||
m_selection.add_all();
|
||||
m_dirty = true;
|
||||
wxGetApp().obj_manipul()->set_dirty();
|
||||
m_gizmos.reset_all_states();
|
||||
m_gizmos.update_data();
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
}
|
||||
|
||||
void GLCanvas3D::deselect_all()
|
||||
|
@ -2954,6 +2959,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
m_rectangle_selection.stop_dragging();
|
||||
m_mouse.ignore_left_up = true;
|
||||
}
|
||||
m_shift_kar_filter.reset_count();
|
||||
m_dirty = true;
|
||||
// set_cursor(Standard);
|
||||
}
|
||||
|
@ -2979,6 +2985,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
m_mouse.set_start_position_3D_as_invalid();
|
||||
}
|
||||
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
m_ctrl_kar_filter.reset_count();
|
||||
m_dirty = true;
|
||||
}
|
||||
else if (m_gizmos.is_enabled() && !m_selection.is_empty()) {
|
||||
|
@ -3015,7 +3022,10 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
m_mouse.ignore_left_up = false;
|
||||
// set_cursor(Cross);
|
||||
}
|
||||
m_dirty = true;
|
||||
if (m_shift_kar_filter.is_first())
|
||||
m_dirty = true;
|
||||
|
||||
m_shift_kar_filter.increase_count();
|
||||
}
|
||||
else if (keyCode == WXK_ALT) {
|
||||
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports)) {
|
||||
|
@ -3023,8 +3033,12 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
// set_cursor(Cross);
|
||||
}
|
||||
}
|
||||
else if (keyCode == WXK_CONTROL)
|
||||
m_dirty = true;
|
||||
else if (keyCode == WXK_CONTROL) {
|
||||
if (m_ctrl_kar_filter.is_first())
|
||||
m_dirty = true;
|
||||
|
||||
m_ctrl_kar_filter.increase_count();
|
||||
}
|
||||
else if (m_gizmos.is_enabled() && !m_selection.is_empty()) {
|
||||
auto do_rotate = [this](double angle_z_rad) {
|
||||
m_selection.setup_cache();
|
||||
|
@ -5515,7 +5529,7 @@ void GLCanvas3D::_picking_pass()
|
|||
#else
|
||||
void GLCanvas3D::_picking_pass()
|
||||
{
|
||||
if (m_picking_enabled && !m_mouse.dragging && m_mouse.position != Vec2d(DBL_MAX, DBL_MAX)) {
|
||||
if (m_picking_enabled && !m_mouse.dragging && m_mouse.position != Vec2d(DBL_MAX, DBL_MAX) && !m_gizmos.is_dragging()) {
|
||||
m_hover_volume_idxs.clear();
|
||||
|
||||
// Render the object for picking.
|
||||
|
|
|
@ -135,6 +135,15 @@ private:
|
|||
wxTimer* m_timer;
|
||||
};
|
||||
|
||||
class KeyAutoRepeatFilter
|
||||
{
|
||||
size_t m_count{ 0 };
|
||||
|
||||
public:
|
||||
void increase_count() { ++m_count; }
|
||||
void reset_count() { m_count = 0; }
|
||||
bool is_first() const { return m_count == 0; }
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
|
||||
|
||||
|
@ -472,7 +481,8 @@ public:
|
|||
|
||||
struct ArrangeSettings
|
||||
{
|
||||
float distance = 6.;
|
||||
float distance = 6.f;
|
||||
float distance_from_bed = 0.f;
|
||||
// float distance_seq_print = 6.; // Used when sequential print is ON
|
||||
// float distance_sla = 6.;
|
||||
float accuracy = 0.65f; // Unused currently
|
||||
|
@ -539,6 +549,13 @@ private:
|
|||
|
||||
bool m_reload_delayed;
|
||||
|
||||
#if ENABLE_RENDER_PICKING_PASS
|
||||
bool m_show_picking_texture;
|
||||
#endif // ENABLE_RENDER_PICKING_PASS
|
||||
|
||||
KeyAutoRepeatFilter m_shift_kar_filter;
|
||||
KeyAutoRepeatFilter m_ctrl_kar_filter;
|
||||
|
||||
RenderStats m_render_stats;
|
||||
|
||||
int m_imgui_undo_redo_hovered_pos{ -1 };
|
||||
|
@ -870,7 +887,6 @@ public:
|
|||
// Returns the view ray line, in world coordinate, at the given mouse position.
|
||||
Linef3 mouse_ray(const Point& mouse_pos);
|
||||
|
||||
void set_mouse_as_dragging() { m_mouse.dragging = true; }
|
||||
bool is_mouse_dragging() const { return m_mouse.dragging; }
|
||||
|
||||
double get_size_proportional_to_max_bed_size(double factor) const;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "GUI_App.hpp"
|
||||
#include "GLModel.hpp"
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#include "BitmapCache.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
|
@ -204,7 +205,7 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
|||
if (!boost::algorithm::iends_with(filename, ".svg"))
|
||||
continue;
|
||||
|
||||
NSVGimage* image = nsvgParseFromFile(filename.c_str(), "px", 96.0f);
|
||||
NSVGimage* image = BitmapCache::nsvgParseFromFileWithReplace(filename.c_str(), "px", 96.0f, {});
|
||||
if (image == nullptr)
|
||||
continue;
|
||||
|
||||
|
@ -540,7 +541,7 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, boo
|
|||
{
|
||||
bool compression_enabled = compress && OpenGLManager::are_compressed_textures_supported();
|
||||
|
||||
NSVGimage* image = nsvgParseFromFile(filename.c_str(), "px", 96.0f);
|
||||
NSVGimage* image = BitmapCache::nsvgParseFromFileWithReplace(filename.c_str(), "px", 96.0f, {});
|
||||
if (image == nullptr) {
|
||||
reset();
|
||||
return false;
|
||||
|
|
|
@ -266,12 +266,12 @@ private:
|
|||
version = _L("Version") + " " + std::string(SLIC3R_VERSION);
|
||||
|
||||
// credits infornation
|
||||
credits = title + " " +
|
||||
_L("is based on Slic3r by Alessandro Ranellucci and the RepRap community.") + "\n" +
|
||||
_L("Developed by Prusa Research.")+ "\n\n" +
|
||||
title + " " + _L("is licensed under the") + " " + _L("GNU Affero General Public License, version 3") + "\n\n" +
|
||||
_L("Contributions by Vojtech Bubnik, Enrico Turri, Oleksandra Iushchenko, Tamas Meszaros, Lukas Matena, Vojtech Kral, David Kocik and numerous others.") + "\n\n" +
|
||||
_L("Artwork model by M Boyer");
|
||||
credits = title + " " +
|
||||
_L("is based on Slic3r by Alessandro Ranellucci and the RepRap community.") + "\n" +
|
||||
_L("Developed by Prusa Research.") + "\n\n" +
|
||||
title + " " + _L("is licensed under the") + " " + _L("GNU Affero General Public License, version 3") + ".\n\n" +
|
||||
_L("Contributions by Vojtech Bubnik, Enrico Turri, Oleksandra Iushchenko, Tamas Meszaros, Lukas Matena, Vojtech Kral, David Kocik and numerous others.") + "\n\n" +
|
||||
_L("Artwork model by Leslie Ing");
|
||||
|
||||
title_font = version_font = credits_font = init_font;
|
||||
}
|
||||
|
@ -738,7 +738,7 @@ void GUI_App::post_init()
|
|||
if (! this->initialized())
|
||||
throw Slic3r::RuntimeError("Calling post_init() while not yet initialized");
|
||||
|
||||
if (this->init_params->start_as_gcodeviewer) {
|
||||
if (this->is_gcode_viewer()) {
|
||||
if (! this->init_params->input_files.empty())
|
||||
this->plater()->load_gcode(wxString::FromUTF8(this->init_params->input_files[0].c_str()));
|
||||
}
|
||||
|
@ -1971,15 +1971,17 @@ static const wxLanguageInfo* linux_get_existing_locale_language(const wxLanguage
|
|||
}),
|
||||
locales.end());
|
||||
|
||||
// Is there a candidate matching a country code of a system language? Move it to the end,
|
||||
// while maintaining the order of matches, so that the best match ends up at the very end.
|
||||
std::string system_country = "_" + into_u8(system_language->CanonicalName.AfterFirst('_')).substr(0, 2);
|
||||
int cnt = locales.size();
|
||||
for (int i=0; i<cnt; ++i)
|
||||
if (locales[i].find(system_country) != std::string::npos) {
|
||||
locales.emplace_back(std::move(locales[i]));
|
||||
locales[i].clear();
|
||||
}
|
||||
if (system_language) {
|
||||
// Is there a candidate matching a country code of a system language? Move it to the end,
|
||||
// while maintaining the order of matches, so that the best match ends up at the very end.
|
||||
std::string system_country = "_" + into_u8(system_language->CanonicalName.AfterFirst('_')).substr(0, 2);
|
||||
int cnt = locales.size();
|
||||
for (int i = 0; i < cnt; ++i)
|
||||
if (locales[i].find(system_country) != std::string::npos) {
|
||||
locales.emplace_back(std::move(locales[i]));
|
||||
locales[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Now try them one by one.
|
||||
for (auto it = locales.rbegin(); it != locales.rend(); ++ it)
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
const std::vector<std::string> OpenGLVersions::core_str = { "3.2", "3.3", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6" };
|
||||
const std::vector<std::string> OpenGLVersions::precore_str = { "2.0", "2.1", "3.0", "3.1" };
|
||||
|
||||
const std::vector<std::pair<int, int>> OpenGLVersions::core = { {3,2}, {3,3}, {4,0}, {4,1}, {4,2}, {4,3}, {4,4}, {4,5}, {4,6} };
|
||||
const std::vector<std::pair<int, int>> OpenGLVersions::precore = { {2,0}, {2,1}, {3,0}, {3,1} };
|
||||
|
||||
int GUI_Run(GUI_InitParams ¶ms)
|
||||
{
|
||||
#if __APPLE__
|
||||
|
|
|
@ -8,6 +8,15 @@ namespace Slic3r {
|
|||
|
||||
namespace GUI {
|
||||
|
||||
struct OpenGLVersions
|
||||
{
|
||||
static const std::vector<std::string> core_str;
|
||||
static const std::vector<std::string> precore_str;
|
||||
|
||||
static const std::vector<std::pair<int, int>> core;
|
||||
static const std::vector<std::pair<int, int>> precore;
|
||||
};
|
||||
|
||||
struct GUI_InitParams
|
||||
{
|
||||
int argc;
|
||||
|
|
|
@ -342,18 +342,26 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent,
|
|||
this->Bind(wxEVT_TEXT_ENTER, [this, edit_fn](wxEvent&)
|
||||
{
|
||||
m_enter_pressed = true;
|
||||
// If LayersList wasn't updated/recreated, we can call wxEVT_KILL_FOCUS.Skip()
|
||||
if (m_type&etLayerHeight) {
|
||||
if (!edit_fn(get_value(), true, false))
|
||||
// Workaround! Under Linux we have to use CallAfter() to avoid crash after pressing ENTER key
|
||||
// see #7531, #8055, #8408
|
||||
#ifdef __linux__
|
||||
wxTheApp->CallAfter([this, edit_fn]() {
|
||||
#endif
|
||||
// If LayersList wasn't updated/recreated, we can call wxEVT_KILL_FOCUS.Skip()
|
||||
if (m_type & etLayerHeight) {
|
||||
if (!edit_fn(get_value(), true, false))
|
||||
SetValue(m_valid_value);
|
||||
else
|
||||
m_valid_value = double_to_string(get_value());
|
||||
m_call_kill_focus = true;
|
||||
}
|
||||
else if (!edit_fn(get_value(), true, false)) {
|
||||
SetValue(m_valid_value);
|
||||
else
|
||||
m_valid_value = double_to_string(get_value());
|
||||
m_call_kill_focus = true;
|
||||
}
|
||||
else if (!edit_fn(get_value(), true, false)) {
|
||||
SetValue(m_valid_value);
|
||||
m_call_kill_focus = true;
|
||||
}
|
||||
m_call_kill_focus = true;
|
||||
}
|
||||
#ifdef __linux__
|
||||
});
|
||||
#endif
|
||||
}, this->GetId());
|
||||
|
||||
this->Bind(wxEVT_KILL_FOCUS, [this, edit_fn](wxFocusEvent& e)
|
||||
|
@ -419,16 +427,13 @@ coordf_t LayerRangeEditor::get_value()
|
|||
const char dec_sep = is_decimal_separator_point() ? '.' : ',';
|
||||
const char dec_sep_alt = dec_sep == '.' ? ',' : '.';
|
||||
// Replace the first incorrect separator in decimal number.
|
||||
if (str.Replace(dec_sep_alt, dec_sep, false) != 0)
|
||||
SetValue(str);
|
||||
str.Replace(dec_sep_alt, dec_sep, false);
|
||||
|
||||
if (str == ".")
|
||||
layer_height = 0.0;
|
||||
else {
|
||||
if (!str.ToDouble(&layer_height) || layer_height < 0.0f) {
|
||||
show_error(m_parent, _L("Invalid numeric input."));
|
||||
SetValue(double_to_string(layer_height));
|
||||
}
|
||||
else if (!str.ToDouble(&layer_height) || layer_height < 0.0f) {
|
||||
show_error(m_parent, _L("Invalid numeric input."));
|
||||
assert(m_valid_value.ToDouble(&layer_height));
|
||||
}
|
||||
|
||||
return layer_height;
|
||||
|
|
|
@ -3284,7 +3284,7 @@ void ObjectList::update_selections()
|
|||
{
|
||||
const auto item = GetSelection();
|
||||
if (selection.is_single_full_object()) {
|
||||
if (m_objects_model->GetItemType(m_objects_model->GetParent(item)) & itObject &&
|
||||
if (m_objects_model->GetItemType(m_objects_model->GetParent(item)) & (itObject | itLayerRoot | itLayer) &&
|
||||
m_objects_model->GetObjectIdByItem(item) == selection.get_object_idx() )
|
||||
return;
|
||||
sels.Add(m_objects_model->GetItemById(selection.get_object_idx()));
|
||||
|
|
|
@ -413,8 +413,6 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
|
|||
if (!m_grabbers.empty() && m_hover_id < int(m_grabbers.size()))
|
||||
m_grabbers[m_hover_id].dragging = true;
|
||||
|
||||
// prevent change of hover_id during dragging
|
||||
m_parent.set_mouse_as_dragging();
|
||||
on_start_dragging();
|
||||
|
||||
// Let the plater know that the dragging started
|
||||
|
@ -426,7 +424,6 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
|
|||
// when mouse cursor leave window than finish actual dragging operation
|
||||
bool is_leaving = mouse_event.Leaving();
|
||||
if (mouse_event.Dragging()) {
|
||||
m_parent.set_mouse_as_dragging();
|
||||
Point mouse_coord(mouse_event.GetX(), mouse_event.GetY());
|
||||
auto ray = m_parent.mouse_ray(mouse_coord);
|
||||
UpdateData data(ray, mouse_coord);
|
||||
|
@ -511,9 +508,12 @@ void GLGizmoBase::render_input_window(float x, float y, float bottom_limit)
|
|||
{
|
||||
on_render_input_window(x, y, bottom_limit);
|
||||
if (m_first_input_window_render) {
|
||||
// for some reason, the imgui dialogs are not shown on screen in the 1st frame where they are rendered, but show up only with the 2nd rendered frame
|
||||
// so, we forces another frame rendering the first time the imgui window is shown
|
||||
// imgui windows that don't have an initial size needs to be processed once to get one
|
||||
// and are not rendered in the first frame
|
||||
// so, we forces to render another frame the first time the imgui window is shown
|
||||
// https://github.com/ocornut/imgui/issues/2949
|
||||
m_parent.set_as_dirty();
|
||||
m_parent.request_extra_frame();
|
||||
m_first_input_window_render = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -416,16 +416,29 @@ void GLGizmoCut::update_contours()
|
|||
const ModelObject* model_object = wxGetApp().model().objects[selection.get_object_idx()];
|
||||
const int instance_idx = selection.get_instance_idx();
|
||||
std::vector<ObjectID> volumes_idxs = std::vector<ObjectID>(model_object->volumes.size());
|
||||
std::vector<Transform3d> volumes_trafos = std::vector<Transform3d>(model_object->volumes.size());
|
||||
for (size_t i = 0; i < model_object->volumes.size(); ++i) {
|
||||
volumes_idxs[i] = model_object->volumes[i]->id();
|
||||
volumes_trafos[i] = model_object->volumes[i]->get_matrix();
|
||||
}
|
||||
|
||||
bool trafos_match = volumes_trafos.size() == m_cut_contours.volumes_trafos.size();
|
||||
if (trafos_match) {
|
||||
for (size_t i = 0; i < model_object->volumes.size(); ++i) {
|
||||
if (!volumes_trafos[i].isApprox(m_cut_contours.volumes_trafos[i])) {
|
||||
trafos_match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0.0 < m_cut_z && m_cut_z < m_max_z) {
|
||||
if (m_cut_contours.cut_z != m_cut_z || m_cut_contours.object_id != model_object->id() ||
|
||||
m_cut_contours.instance_idx != instance_idx || m_cut_contours.volumes_idxs != volumes_idxs) {
|
||||
m_cut_contours.instance_idx != instance_idx || m_cut_contours.volumes_idxs != volumes_idxs ||
|
||||
!trafos_match) {
|
||||
m_cut_contours.cut_z = m_cut_z;
|
||||
|
||||
if (m_cut_contours.object_id != model_object->id() || m_cut_contours.volumes_idxs != volumes_idxs)
|
||||
if (m_cut_contours.object_id != model_object->id() || m_cut_contours.volumes_idxs != volumes_idxs || !trafos_match)
|
||||
m_cut_contours.mesh = model_object->raw_mesh();
|
||||
|
||||
m_cut_contours.position = box.center();
|
||||
|
@ -433,6 +446,7 @@ void GLGizmoCut::update_contours()
|
|||
m_cut_contours.object_id = model_object->id();
|
||||
m_cut_contours.instance_idx = instance_idx;
|
||||
m_cut_contours.volumes_idxs = volumes_idxs;
|
||||
m_cut_contours.volumes_trafos = volumes_trafos;
|
||||
m_cut_contours.contours.reset();
|
||||
|
||||
MeshSlicingParams slicing_params;
|
||||
|
|
|
@ -39,6 +39,7 @@ class GLGizmoCut : public GLGizmoBase
|
|||
ObjectID object_id;
|
||||
int instance_idx{ -1 };
|
||||
std::vector<ObjectID> volumes_idxs;
|
||||
std::vector<Transform3d> volumes_trafos;
|
||||
};
|
||||
|
||||
CutContours m_cut_contours;
|
||||
|
|
|
@ -50,9 +50,14 @@ bool GLGizmoFlatten::on_mouse(const wxMouseEvent &mouse_event)
|
|||
|
||||
} else if (mouse_event.LeftUp()) {
|
||||
if (m_mouse_left_down) {
|
||||
// responsible for mouse left up after selecting plane
|
||||
m_mouse_left_down = false;
|
||||
return true;
|
||||
if (m_hover_id == -1)
|
||||
// no plane hovered
|
||||
return false;
|
||||
else {
|
||||
// responsible for mouse left up after selecting plane
|
||||
m_mouse_left_down = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (mouse_event.Leaving()) {
|
||||
m_mouse_left_down = false;
|
||||
|
|
|
@ -1054,7 +1054,7 @@ void GLGizmoHollow::select_point(int i)
|
|||
m_selected.assign(m_selected.size(), i == AllPoints);
|
||||
m_selection_empty = (i == NoPoints);
|
||||
|
||||
if (i == AllPoints) {
|
||||
if (i == AllPoints && !drain_holes.empty()) {
|
||||
m_new_hole_radius = drain_holes[0].radius;
|
||||
m_new_hole_height = drain_holes[0].height;
|
||||
}
|
||||
|
|
|
@ -115,7 +115,11 @@ void GLGizmoRotate::on_start_dragging()
|
|||
|
||||
void GLGizmoRotate::on_dragging(const UpdateData &data)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray));
|
||||
#else
|
||||
const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray, m_parent.get_selection()));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
const Vec2d orig_dir = Vec2d::UnitX();
|
||||
const Vec2d new_dir = mouse_pos.normalized();
|
||||
|
@ -725,7 +729,11 @@ void GLGizmoRotate::transform_to_local(const Selection& selection) const
|
|||
}
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) const
|
||||
#else
|
||||
Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
{
|
||||
double half_pi = 0.5 * double(PI);
|
||||
|
||||
|
@ -762,7 +770,20 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, cons
|
|||
|
||||
m.translate(-m_center);
|
||||
|
||||
return transform(mouse_ray, m).intersect_plane(0.0);
|
||||
const Linef3 local_mouse_ray = transform(mouse_ray, m);
|
||||
if (std::abs(local_mouse_ray.vector().dot(Vec3d::UnitZ())) < EPSILON) {
|
||||
// if the ray is parallel to the plane containing the circle
|
||||
if (std::abs(local_mouse_ray.vector().dot(Vec3d::UnitY())) > 1.0 - EPSILON)
|
||||
// if the ray is parallel to grabber direction
|
||||
return Vec3d::UnitX();
|
||||
else {
|
||||
const Vec3d world_pos = (local_mouse_ray.a.x() >= 0.0) ? mouse_ray.a - m_center : mouse_ray.b - m_center;
|
||||
m.translate(m_center);
|
||||
return m * world_pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
return local_mouse_ray.intersect_plane(0.0);
|
||||
}
|
||||
|
||||
GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
|
|
|
@ -120,7 +120,11 @@ private:
|
|||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray) const;
|
||||
#else
|
||||
Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const;
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void init_data_from_selection(const Selection& selection);
|
||||
|
|
|
@ -1181,7 +1181,7 @@ void GLGizmoSlaSupports::select_point(int i)
|
|||
point_and_selection.selected = ( i == AllPoints );
|
||||
m_selection_empty = (i == NoPoints);
|
||||
|
||||
if (i == AllPoints)
|
||||
if (i == AllPoints && !m_editing_cache.empty())
|
||||
m_new_point_head_diameter = m_editing_cache[0].support_point.head_front_radius * 2.f;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -444,7 +444,7 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
|
|||
};
|
||||
m_loaded_hints.emplace_back(hint_data);
|
||||
} else if (dict["hypertext_type"] == "menubar") {
|
||||
wxString menu(_("&" + dict["hypertext_menubar_menu_name"]));
|
||||
wxString menu(_(dict["hypertext_menubar_menu_name"]));
|
||||
wxString item(_(dict["hypertext_menubar_item_name"]));
|
||||
HintData hint_data{ id_string, text1, weight, was_displayed, hypertext_text, follow_text, disabled_tags, enabled_tags, true, documentation_link, [menu, item]() { wxGetApp().mainframe->open_menubar_item(menu, item); } };
|
||||
m_loaded_hints.emplace_back(hint_data);
|
||||
|
|
|
@ -286,6 +286,7 @@ arrangement::ArrangeParams get_arrange_params(Plater *p)
|
|||
arrangement::ArrangeParams params;
|
||||
params.allow_rotations = settings.enable_rotation;
|
||||
params.min_obj_distance = scaled(settings.distance);
|
||||
params.min_bed_distance = scaled(settings.distance_from_bed);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <wx/debug.h>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "libslic3r/Print.hpp"
|
||||
|
@ -637,7 +638,9 @@ void MainFrame::update_title()
|
|||
}
|
||||
}
|
||||
|
||||
std::string build_id = wxGetApp().is_editor() ? SLIC3R_BUILD_ID : GCODEVIEWER_BUILD_ID;
|
||||
std::string build_id = SLIC3R_BUILD_ID;
|
||||
if (! wxGetApp().is_editor())
|
||||
boost::replace_first(build_id, SLIC3R_APP_NAME, GCODEVIEWER_APP_NAME);
|
||||
size_t idx_plus = build_id.find('+');
|
||||
if (idx_plus != build_id.npos) {
|
||||
// Parse what is behind the '+'. If there is a number, then it is a build number after the label, and full build ID is shown.
|
||||
|
@ -1104,7 +1107,11 @@ static wxMenu* generate_help_menu()
|
|||
else
|
||||
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), GCODEVIEWER_APP_NAME), _L("Show about dialog"),
|
||||
[](wxCommandEvent&) { Slic3r::GUI::about(); });
|
||||
append_menu_item(helpMenu, wxID_ANY, _L("Show Tip of the Day"), _L("Opens Tip of the day notification in bottom right corner or shows another tip if already opened."),
|
||||
append_menu_item(helpMenu, wxID_ANY, _L("Show Tip of the Day")
|
||||
#if 0//debug
|
||||
+ "\tCtrl+Shift+T"
|
||||
#endif
|
||||
,_L("Opens Tip of the day notification in bottom right corner or shows another tip if already opened."),
|
||||
[](wxCommandEvent&) { wxGetApp().plater()->get_notification_manager()->push_hint_notification(false); });
|
||||
helpMenu->AppendSeparator();
|
||||
append_menu_item(helpMenu, wxID_ANY, _L("Keyboard Shortcuts") + sep + "&?", _L("Show the list of the keyboard shortcuts"),
|
||||
|
|
|
@ -270,7 +270,7 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
|
|||
Vec3d direction;
|
||||
line_from_mouse_pos(mouse_pos, trafo, camera, point, direction);
|
||||
|
||||
std::vector<sla::IndexedMesh::hit_result> hits = m_emesh.query_ray_hits(point, direction);
|
||||
std::vector<AABBMesh::hit_result> hits = m_emesh.query_ray_hits(point, direction);
|
||||
|
||||
if (hits.empty())
|
||||
return false; // no intersection found
|
||||
|
@ -325,7 +325,7 @@ std::vector<unsigned> MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo
|
|||
|
||||
bool is_obscured = false;
|
||||
// Cast a ray in the direction of the camera and look for intersection with the mesh:
|
||||
std::vector<sla::IndexedMesh::hit_result> hits;
|
||||
std::vector<AABBMesh::hit_result> hits;
|
||||
// Offset the start of the ray by EPSILON to account for numerical inaccuracies.
|
||||
hits = m_emesh.query_ray_hits((inverse_trafo * pt.cast<double>() + direction_to_camera_mesh * EPSILON),
|
||||
direction_to_camera_mesh);
|
||||
|
@ -363,7 +363,7 @@ bool MeshRaycaster::closest_hit(const Vec2d& mouse_pos, const Transform3d& trafo
|
|||
Vec3d direction;
|
||||
line_from_mouse_pos(mouse_pos, trafo, camera, point, direction);
|
||||
|
||||
const std::vector<sla::IndexedMesh::hit_result> hits = m_emesh.query_ray_hits(point, direction.normalized());
|
||||
const std::vector<AABBMesh::hit_result> hits = m_emesh.query_ray_hits(point, direction.normalized());
|
||||
|
||||
if (hits.empty())
|
||||
return false; // no intersection found
|
||||
|
@ -378,7 +378,7 @@ bool MeshRaycaster::closest_hit(const Vec2d& mouse_pos, const Transform3d& trafo
|
|||
if (hit_id == hits.size())
|
||||
return false; // all points are obscured or cut by the clipping plane.
|
||||
|
||||
const sla::IndexedMesh::hit_result& hit = hits[hit_id];
|
||||
const AABBMesh::hit_result& hit = hits[hit_id];
|
||||
|
||||
position = hit.position().cast<float>();
|
||||
normal = hit.normal().cast<float>();
|
||||
|
@ -394,8 +394,10 @@ Vec3f MeshRaycaster::get_closest_point(const Vec3f& point, Vec3f* normal) const
|
|||
{
|
||||
int idx = 0;
|
||||
Vec3d closest_point;
|
||||
m_emesh.squared_distance(point.cast<double>(), idx, closest_point);
|
||||
Vec3d pointd = point.cast<double>();
|
||||
m_emesh.squared_distance(pointd, idx, closest_point);
|
||||
if (normal)
|
||||
// TODO: consider: get_normal(m_emesh, pointd).cast<float>();
|
||||
*normal = m_normals[idx];
|
||||
|
||||
return closest_point.cast<float>();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "libslic3r/SLA/IndexedMesh.hpp"
|
||||
#include "libslic3r/AABBMesh.hpp"
|
||||
#include "admesh/stl.h"
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
@ -204,7 +204,7 @@ private:
|
|||
#if ENABLE_RAYCAST_PICKING
|
||||
std::shared_ptr<const TriangleMesh> m_mesh;
|
||||
#endif // ENABLE_RAYCAST_PICKING
|
||||
sla::IndexedMesh m_emesh;
|
||||
AABBMesh m_emesh;
|
||||
std::vector<stl_normal> m_normals;
|
||||
};
|
||||
|
||||
|
|
|
@ -1823,7 +1823,7 @@ void NotificationManager::push_upload_job_notification(int id, float filesize,
|
|||
}
|
||||
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
|
||||
NotificationData data{ NotificationType::PrintHostUpload, NotificationLevel::ProgressBarNotificationLevel, 10, text };
|
||||
push_notification_data(std::make_unique<NotificationManager::PrintHostUploadNotification>(data, m_id_provider, m_evt_handler, 0, id, filesize), 0);
|
||||
push_notification_data(std::make_unique<NotificationManager::PrintHostUploadNotification>(data, m_id_provider, m_evt_handler, 0, id, filesize, filename, host), 0);
|
||||
}
|
||||
void NotificationManager::set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage)
|
||||
{
|
||||
|
@ -1832,6 +1832,21 @@ void NotificationManager::set_upload_job_notification_percentage(int id, const s
|
|||
PrintHostUploadNotification* phun = dynamic_cast<PrintHostUploadNotification*>(notification.get());
|
||||
if (phun->compare_job_id(id)) {
|
||||
phun->set_percentage(percentage);
|
||||
if (phun->get_host() != host)
|
||||
phun->set_host(host);
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::set_upload_job_notification_host(int id, const std::string& host)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::PrintHostUpload) {
|
||||
PrintHostUploadNotification* phun = dynamic_cast<PrintHostUploadNotification*>(notification.get());
|
||||
if (phun->compare_job_id(id)) {
|
||||
phun->set_host(host);
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||
break;
|
||||
}
|
||||
|
@ -1845,6 +1860,8 @@ void NotificationManager::upload_job_notification_show_canceled(int id, const st
|
|||
PrintHostUploadNotification* phun = dynamic_cast<PrintHostUploadNotification*>(notification.get());
|
||||
if (phun->compare_job_id(id)) {
|
||||
phun->cancel();
|
||||
if (phun->get_host() != host)
|
||||
phun->set_host(host);
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||
break;
|
||||
}
|
||||
|
@ -1858,6 +1875,8 @@ void NotificationManager::upload_job_notification_show_error(int id, const std::
|
|||
PrintHostUploadNotification* phun = dynamic_cast<PrintHostUploadNotification*>(notification.get());
|
||||
if(phun->compare_job_id(id)) {
|
||||
phun->error();
|
||||
if (phun->get_host() != host)
|
||||
phun->set_host(host);
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -203,6 +203,7 @@ public:
|
|||
// print host upload
|
||||
void push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage = 0);
|
||||
void set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage);
|
||||
void set_upload_job_notification_host(int id, const std::string& host);
|
||||
void upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host);
|
||||
void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host);
|
||||
// Download App progress
|
||||
|
@ -505,10 +506,12 @@ private:
|
|||
PB_CANCELLED,
|
||||
PB_COMPLETED
|
||||
};
|
||||
PrintHostUploadNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, float percentage, int job_id, float filesize)
|
||||
PrintHostUploadNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, float percentage, int job_id, float filesize, const std::string& filename, const std::string& host)
|
||||
:ProgressBarNotification(n, id_provider, evt_handler)
|
||||
, m_job_id(job_id)
|
||||
, m_file_size(filesize)
|
||||
, m_filename(filename)
|
||||
, m_host(host)
|
||||
{
|
||||
m_has_cancel_button = true;
|
||||
set_percentage(percentage);
|
||||
|
@ -519,6 +522,8 @@ private:
|
|||
void error() { m_uj_state = UploadJobState::PB_ERROR; m_has_cancel_button = false; init(); }
|
||||
bool compare_job_id(const int other_id) const { return m_job_id == other_id; }
|
||||
bool compare_text(const std::string& text) const override { return false; }
|
||||
void set_host(const std::string& host) { m_host = host; update({ NotificationType::PrintHostUpload, NotificationLevel::ProgressBarNotificationLevel, 10, get_upload_job_text(m_id, m_filename, m_host)}); }
|
||||
std::string get_host() const { return m_host; }
|
||||
protected:
|
||||
void init() override;
|
||||
void count_spaces() override;
|
||||
|
@ -536,6 +541,8 @@ private:
|
|||
float m_file_size;
|
||||
long m_hover_time{ 0 };
|
||||
UploadJobState m_uj_state{ UploadJobState::PB_PROGRESS };
|
||||
std::string m_filename;
|
||||
std::string m_host;
|
||||
};
|
||||
|
||||
class SlicingProgressNotification : public ProgressBarNotification
|
||||
|
|
|
@ -708,7 +708,7 @@ wxCoord OG_CustomCtrl::CtrlLine::draw_text(wxDC& dc, wxPoint pos, const wxStr
|
|||
dc.GetMultiLineTextExtent(out_text, &text_width, &text_height);
|
||||
|
||||
pos.y = pos.y + lround((height - text_height) / 2);
|
||||
if (width > 0)
|
||||
if (rect_label.GetWidth() == 0)
|
||||
rect_label = wxRect(pos, wxSize(text_width, text_height));
|
||||
|
||||
wxColour old_clr = dc.GetTextForeground();
|
||||
|
|
|
@ -1706,8 +1706,10 @@ void ObjectDataViewModel::Rescale()
|
|||
break;
|
||||
case itLayerRoot:
|
||||
node->m_bmp = create_scaled_bitmap(LayerRootIcon);
|
||||
break;
|
||||
case itLayer:
|
||||
node->m_bmp = create_scaled_bitmap(LayerIcon);
|
||||
break;
|
||||
case itInfo:
|
||||
node->m_bmp = m_info_bmps.at(node->m_info_item_type);
|
||||
break;
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#include "OpenGLManager.hpp"
|
||||
|
||||
#include "GUI.hpp"
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
#include "GUI_Init.hpp"
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
#include "I18N.hpp"
|
||||
#include "3DScene.hpp"
|
||||
|
||||
|
@ -416,52 +419,65 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas)
|
|||
m_debug_enabled = enable_debug;
|
||||
#endif // ENABLE_OPENGL_DEBUG_OPTION
|
||||
|
||||
if (required_opengl_version != std::make_pair(0, 0)) { // the user specified a required version in the command line using --opengl-core=M.m
|
||||
const bool supports_core_profile = (required_opengl_version.first < 3) ? false :
|
||||
(required_opengl_version.first > 3) ? true : required_opengl_version.second >= 2;
|
||||
const int gl_major = required_opengl_version.first;
|
||||
const int gl_minor = required_opengl_version.second;
|
||||
const bool supports_core_profile = (gl_major < 3) ? false : (gl_major > 3) ? true : gl_minor >= 2;
|
||||
|
||||
if (gl_major == 0) {
|
||||
// search for highest supported core profile version
|
||||
// disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context
|
||||
wxLogNull logNo;
|
||||
for (auto v = OpenGLVersions::core.rbegin(); v != OpenGLVersions::core.rend(); ++v) {
|
||||
wxGLContextAttrs attrs;
|
||||
#if ENABLE_OPENGL_DEBUG_OPTION
|
||||
attrs.PlatformDefaults().MajorVersion(v->first).MinorVersion(v->second).CoreProfile().ForwardCompatible();
|
||||
if (m_debug_enabled)
|
||||
attrs.DebugCtx();
|
||||
attrs.EndList();
|
||||
#else
|
||||
attrs.PlatformDefaults().MajorVersion(gl_major).MinorVersion(gl_minor).CoreProfile().ForwardCompatible().EndList();
|
||||
#endif // ENABLE_OPENGL_DEBUG_OPTION
|
||||
m_context = new wxGLContext(&canvas, nullptr, &attrs);
|
||||
if (m_context->IsOK()) {
|
||||
s_gl_info.set_core_profile(true);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_context == nullptr) {
|
||||
// search for requested core profile version
|
||||
if (supports_core_profile) {
|
||||
// disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context
|
||||
wxLogNull logNo;
|
||||
wxGLContextAttrs attrs;
|
||||
#if ENABLE_OPENGL_DEBUG_OPTION
|
||||
attrs.MajorVersion(required_opengl_version.first).MinorVersion(required_opengl_version.second).CoreProfile().ForwardCompatible();
|
||||
attrs.PlatformDefaults().MajorVersion(gl_major).MinorVersion(gl_minor).CoreProfile().ForwardCompatible();
|
||||
if (m_debug_enabled)
|
||||
attrs.DebugCtx();
|
||||
attrs.EndList();
|
||||
#else
|
||||
attrs.MajorVersion(required_opengl_version.first).MinorVersion(required_opengl_version.second).CoreProfile().ForwardCompatible().EndList();
|
||||
attrs.PlatformDefaults().MajorVersion(gl_major).MinorVersion(gl_minor).CoreProfile().ForwardCompatible().EndList();
|
||||
#endif // ENABLE_OPENGL_DEBUG_OPTION
|
||||
m_context = new wxGLContext(&canvas, nullptr, &attrs);
|
||||
if (!m_context->IsOK()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Unable to create context for required OpenGL " << required_opengl_version.first << "." << required_opengl_version.second;
|
||||
BOOST_LOG_TRIVIAL(error) << "Unable to create context for required OpenGL " << gl_major << "." << gl_minor;
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
}
|
||||
else
|
||||
s_gl_info.set_core_profile(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
//else {
|
||||
// // try to get the highest supported OpenGL version with core profile
|
||||
// static const std::vector<std::pair<int, int>> valid_core_versions = { {4,6}, {4,5}, {4,4}, {4,3}, {4,2}, {4,1}, {4,0}, {3,3}, {3,2} };
|
||||
// // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context
|
||||
// wxLogNull logNo;
|
||||
// for (const auto& [major, minor] : valid_core_versions) {
|
||||
// wxGLContextAttrs attrs;
|
||||
// attrs.CoreProfile().ForwardCompatible().OGLVersion(major, minor).EndList();
|
||||
// m_context = new wxGLContext(&canvas, nullptr, &attrs);
|
||||
// if (m_context->IsOK())
|
||||
// break;
|
||||
// else {
|
||||
// delete m_context;
|
||||
// m_context = nullptr;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
#if ENABLE_OPENGL_DEBUG_OPTION
|
||||
if (m_context == nullptr) {
|
||||
wxGLContextAttrs attrs;
|
||||
attrs.PlatformDefaults();
|
||||
if (m_debug_enabled)
|
||||
attrs.DebugCtx();
|
||||
attrs.EndList();
|
||||
|
|
|
@ -631,7 +631,7 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
|
|||
return;
|
||||
}
|
||||
if (printer_name == m_default_name) {
|
||||
warning_catcher(this, _L("You should change the name of your printer device."));
|
||||
warning_catcher(this, _L("You have to enter a printer name."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1586,12 +1586,15 @@ std::string& Sidebar::get_search_line()
|
|||
class PlaterDropTarget : public wxFileDropTarget
|
||||
{
|
||||
public:
|
||||
PlaterDropTarget(Plater* plater) : m_plater(plater) { this->SetDefaultAction(wxDragCopy); }
|
||||
PlaterDropTarget(MainFrame& mainframe, Plater& plater) : m_mainframe(mainframe), m_plater(plater) {
|
||||
this->SetDefaultAction(wxDragCopy);
|
||||
}
|
||||
|
||||
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames);
|
||||
|
||||
private:
|
||||
Plater* m_plater;
|
||||
MainFrame& m_mainframe;
|
||||
Plater& m_plater;
|
||||
};
|
||||
|
||||
bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
|
||||
|
@ -1601,8 +1604,11 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
|
|||
this->MSWUpdateDragImageOnLeave();
|
||||
#endif // WIN32
|
||||
|
||||
bool res = (m_plater != nullptr) ? m_plater->load_files(filenames) : false;
|
||||
wxGetApp().mainframe->update_title();
|
||||
m_mainframe.Raise();
|
||||
m_mainframe.select_tab(size_t(0));
|
||||
m_plater.select_view_3D("3D");
|
||||
bool res = m_plater.load_files(filenames);
|
||||
m_mainframe.update_title();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2144,7 +2150,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
}
|
||||
|
||||
// Drop target:
|
||||
q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership
|
||||
main_frame->SetDropTarget(new PlaterDropTarget(*main_frame, *q)); // if my understanding is right, wxWindow takes the owenership
|
||||
q->Layout();
|
||||
|
||||
set_current_panel(wxGetApp().is_editor() ? static_cast<wxPanel*>(view3D) : static_cast<wxPanel*>(preview));
|
||||
|
|
|
@ -697,7 +697,6 @@ void PreferencesDialog::revert(wxEvent&)
|
|||
|
||||
|
||||
for (auto value : m_values) {
|
||||
bool reverted = false;
|
||||
const std::string& key = value.first;
|
||||
|
||||
if (key == "default_action_on_dirty_project") {
|
||||
|
@ -714,14 +713,17 @@ void PreferencesDialog::revert(wxEvent&)
|
|||
}
|
||||
if (key == "old_settings_layout_mode") {
|
||||
m_rb_old_settings_layout_mode->SetValue(app_config->get(key) == "1");
|
||||
m_settings_layout_changed = false;
|
||||
continue;
|
||||
}
|
||||
if (key == "new_settings_layout_mode") {
|
||||
m_rb_new_settings_layout_mode->SetValue(app_config->get(key) == "1");
|
||||
m_settings_layout_changed = false;
|
||||
continue;
|
||||
}
|
||||
if (key == "dlg_settings_layout_mode") {
|
||||
m_rb_dlg_settings_layout_mode->SetValue(app_config->get(key) == "1");
|
||||
m_settings_layout_changed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,6 +190,7 @@ void PrintHostSendDialog::EndModal(int ret)
|
|||
wxDEFINE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event);
|
||||
wxDEFINE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event);
|
||||
wxDEFINE_EVENT(EVT_PRINTHOST_CANCEL, PrintHostQueueDialog::Event);
|
||||
wxDEFINE_EVENT(EVT_PRINTHOST_RESOLVE, PrintHostQueueDialog::Event);
|
||||
|
||||
PrintHostQueueDialog::Event::Event(wxEventType eventType, int winid, size_t job_id)
|
||||
: wxEvent(winid, eventType)
|
||||
|
@ -218,6 +219,7 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
|
|||
, on_progress_evt(this, EVT_PRINTHOST_PROGRESS, &PrintHostQueueDialog::on_progress, this)
|
||||
, on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this)
|
||||
, on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this)
|
||||
, on_resolve_evt(this, EVT_PRINTHOST_RESOLVE, &PrintHostQueueDialog::on_resolve, this)
|
||||
{
|
||||
const auto em = GetTextExtent("m").x;
|
||||
|
||||
|
@ -450,6 +452,17 @@ void PrintHostQueueDialog::on_cancel(Event &evt)
|
|||
wxGetApp().notification_manager()->upload_job_notification_show_canceled(evt.job_id + 1, boost::nowide::narrow(nm.GetString()), boost::nowide::narrow(hst.GetString()));
|
||||
}
|
||||
|
||||
void PrintHostQueueDialog::on_resolve(Event& evt)
|
||||
{
|
||||
wxCHECK_RET(evt.job_id < (size_t)job_list->GetItemCount(), "Out of bounds access to job list");
|
||||
|
||||
// wxstring in event is called error, but it should contain new host string.
|
||||
wxVariant hst(evt.error);
|
||||
// todo: set variant
|
||||
job_list->SetValue(hst,evt.job_id,COL_HOST);
|
||||
wxGetApp().notification_manager()->set_upload_job_notification_host(evt.job_id + 1, boost::nowide::narrow(evt.error));
|
||||
}
|
||||
|
||||
void PrintHostQueueDialog::get_active_jobs(std::vector<std::pair<std::string, std::string>>& ret)
|
||||
{
|
||||
int ic = job_list->GetItemCount();
|
||||
|
|
|
@ -108,6 +108,7 @@ private:
|
|||
EventGuard on_progress_evt;
|
||||
EventGuard on_error_evt;
|
||||
EventGuard on_cancel_evt;
|
||||
EventGuard on_resolve_evt;
|
||||
|
||||
JobState get_state(int idx);
|
||||
void set_state(int idx, JobState);
|
||||
|
@ -115,6 +116,7 @@ private:
|
|||
void on_progress(Event&);
|
||||
void on_error(Event&);
|
||||
void on_cancel(Event&);
|
||||
void on_resolve(Event&);
|
||||
// This vector keep adress and filename of uploads. It is used when checking for running uploads during exit.
|
||||
std::vector<std::pair<std::string, std::string>> upload_names;
|
||||
void save_user_data(int);
|
||||
|
@ -124,7 +126,7 @@ private:
|
|||
wxDECLARE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event);
|
||||
wxDECLARE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event);
|
||||
wxDECLARE_EVENT(EVT_PRINTHOST_CANCEL, PrintHostQueueDialog::Event);
|
||||
|
||||
wxDECLARE_EVENT(EVT_PRINTHOST_RESOLVE, PrintHostQueueDialog::Event);
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -311,6 +311,9 @@ void OptionsSearcher::check_and_update(PrinterTechnology pt_in, ConfigOptionMode
|
|||
|
||||
for (auto i : input_values)
|
||||
append_options(i.config, i.type);
|
||||
|
||||
options.insert(options.end(), preferences_options.begin(), preferences_options.end());
|
||||
|
||||
sort_options();
|
||||
|
||||
search(search_line, true);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
#include <Eigen/Core>
|
||||
|
||||
#include <wx/clipbrd.h>
|
||||
|
@ -40,7 +42,12 @@ std::string get_main_info(bool format_as_html)
|
|||
if (!format_as_html)
|
||||
out << b_start << (wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME) << b_end << line_end;
|
||||
out << b_start << "Version: " << b_end << SLIC3R_VERSION << line_end;
|
||||
out << b_start << "Build: " << b_end << (wxGetApp().is_editor() ? SLIC3R_BUILD_ID : GCODEVIEWER_BUILD_ID) << line_end;
|
||||
|
||||
std::string build_id = SLIC3R_BUILD_ID;
|
||||
if (! wxGetApp().is_editor())
|
||||
boost::replace_first(build_id, SLIC3R_APP_NAME, GCODEVIEWER_APP_NAME);
|
||||
out << b_start << "Build: " << b_end << build_id << line_end;
|
||||
|
||||
out << line_end;
|
||||
out << b_start << "Operating System: " << b_end << wxPlatformInfo::Get().GetOperatingSystemFamilyName() << line_end;
|
||||
out << b_start << "System Architecture: " << b_end << wxPlatformInfo::Get().GetArchName() << line_end;
|
||||
|
|
|
@ -1450,6 +1450,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("seam_position", category_path + "seam-position");
|
||||
optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first");
|
||||
optgroup->append_single_option_line("gap_fill_enabled", category_path + "fill-gaps");
|
||||
optgroup->append_single_option_line("perimeter_generator");
|
||||
|
||||
optgroup = page->new_optgroup(L("Fuzzy skin (experimental)"));
|
||||
category_path = "fuzzy-skin_246186/#";
|
||||
|
@ -1568,10 +1569,10 @@ void TabPrint::build()
|
|||
optgroup = page->new_optgroup(L("Autospeed (advanced)"));
|
||||
optgroup->append_single_option_line("max_print_speed", "max-volumetric-speed_127176");
|
||||
optgroup->append_single_option_line("max_volumetric_speed", "max-volumetric-speed_127176");
|
||||
#ifdef HAS_PRESSURE_EQUALIZER
|
||||
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive");
|
||||
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative");
|
||||
#endif /* HAS_PRESSURE_EQUALIZER */
|
||||
|
||||
optgroup = page->new_optgroup(L("Pressure equalizer (experimental)"));
|
||||
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive", "pressure-equlizer_331504");
|
||||
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative", "pressure-equlizer_331504");
|
||||
|
||||
page = add_options_page(L("Multiple Extruders"), "funnel");
|
||||
optgroup = page->new_optgroup(L("Extruders"));
|
||||
|
@ -1628,6 +1629,16 @@ void TabPrint::build()
|
|||
optgroup = page->new_optgroup(L("Other"));
|
||||
optgroup->append_single_option_line("clip_multipart_objects");
|
||||
|
||||
optgroup = page->new_optgroup(L("Arachne perimeter generator"));
|
||||
optgroup->append_single_option_line("wall_add_middle_threshold");
|
||||
optgroup->append_single_option_line("wall_split_middle_threshold");
|
||||
optgroup->append_single_option_line("wall_transition_angle");
|
||||
optgroup->append_single_option_line("wall_transition_filter_deviation");
|
||||
optgroup->append_single_option_line("wall_transition_length");
|
||||
optgroup->append_single_option_line("wall_distribution_count");
|
||||
optgroup->append_single_option_line("min_bead_width");
|
||||
optgroup->append_single_option_line("min_feature_size");
|
||||
|
||||
page = add_options_page(L("Output options"), "output+page_white");
|
||||
optgroup = page->new_optgroup(L("Sequential printing"));
|
||||
optgroup->append_single_option_line("complete_objects", "sequential-printing_124589");
|
||||
|
@ -2492,6 +2503,7 @@ void TabPrinter::build_sla()
|
|||
line = { L("Tilt time"), "" };
|
||||
line.append_option(optgroup->get_option("fast_tilt_time"));
|
||||
line.append_option(optgroup->get_option("slow_tilt_time"));
|
||||
line.append_option(optgroup->get_option("high_viscosity_tilt_time"));
|
||||
optgroup->append_line(line);
|
||||
optgroup->append_single_option_line("area_fill");
|
||||
|
||||
|
@ -3605,8 +3617,15 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach)
|
|||
name = dlg.get_name();
|
||||
}
|
||||
|
||||
if (detach && m_type == Preset::TYPE_PRINTER)
|
||||
m_config->opt_string("printer_model", true) = "";
|
||||
|
||||
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
|
||||
m_presets->save_current_preset(name, detach);
|
||||
|
||||
if (detach && m_type == Preset::TYPE_PRINTER)
|
||||
wxGetApp().mainframe->on_config_changed(m_config);
|
||||
|
||||
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
||||
// If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible.
|
||||
m_preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
|
||||
|
@ -3659,6 +3678,9 @@ void Tab::save_preset(std::string name /*= ""*/, bool detach)
|
|||
|
||||
// update preset comboboxes in DiffPresetDlg
|
||||
wxGetApp().mainframe->diff_dialog.update_presets(m_type);
|
||||
|
||||
if (detach)
|
||||
update_description_lines();
|
||||
}
|
||||
|
||||
// Called for a currently selected preset.
|
||||
|
|
|
@ -1300,6 +1300,9 @@ void UnsavedChangesDialog::update_tree(Preset::Type type, PresetCollection* pres
|
|||
get_string_value(opt_key, old_config), get_string_value(opt_key, new_config), category_icon_map.at(option.category));
|
||||
}
|
||||
}
|
||||
|
||||
// Revert sort of searcher back
|
||||
searcher.sort_options_by_label();
|
||||
}
|
||||
|
||||
void UnsavedChangesDialog::on_dpi_changed(const wxRect& suggested_rect)
|
||||
|
@ -1709,6 +1712,9 @@ void DiffPresetDialog::update_tree()
|
|||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
// Revert sort of searcher back
|
||||
searcher.sort_options_by_label();
|
||||
}
|
||||
|
||||
void DiffPresetDialog::on_dpi_changed(const wxRect&)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue