Fixed conflicts after merge with master

This commit is contained in:
enricoturri1966 2022-07-21 08:55:52 +02:00
commit ca34518bcc
264 changed files with 69447 additions and 49874 deletions

View file

@ -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% &copy; 2016-2021 Prusa Research. <br />"
"%4% &copy; 2016-2022 Prusa Research. <br />"
"%5% &copy; 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>."

View file

@ -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);
}
}

View file

@ -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;
};
}

View file

@ -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*/)

View file

@ -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);
}

View file

@ -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()

View file

@ -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) {}

View file

@ -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.

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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 &params)
{
#if __APPLE__

View file

@ -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;

View file

@ -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;

View file

@ -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()));

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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 {

View file

@ -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);

View file

@ -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;
}

View file

@ -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"),

View file

@ -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>();

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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

View file

@ -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();

View file

@ -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;

View file

@ -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();

View file

@ -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;
}

View file

@ -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));

View file

@ -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;
}

View file

@ -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();

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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.

View file

@ -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&)