Merge branch 'dev' of https://github.com/prusa3d/PrusaSlicer into dev
This commit is contained in:
commit
0a177d0e06
54 changed files with 240832 additions and 41135 deletions
|
@ -2,6 +2,7 @@
|
|||
#include "../Utils.hpp"
|
||||
|
||||
#include <cctype> // isalpha
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
|
|
@ -910,6 +910,12 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
|
|||
if (spiral_vase != nullptr)
|
||||
m_spiral_vase_active = spiral_vase->value;
|
||||
#endif // ENABLE_SPIRAL_VASE_LAYERS
|
||||
|
||||
#if ENABLE_Z_OFFSET_CORRECTION
|
||||
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
||||
if (z_offset != nullptr)
|
||||
m_z_offset = z_offset->value;
|
||||
#endif // ENABLE_Z_OFFSET_CORRECTION
|
||||
}
|
||||
|
||||
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||
|
@ -1159,6 +1165,12 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
|||
if (spiral_vase != nullptr)
|
||||
m_spiral_vase_active = spiral_vase->value;
|
||||
#endif // ENABLE_SPIRAL_VASE_LAYERS
|
||||
|
||||
#if ENABLE_Z_OFFSET_CORRECTION
|
||||
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
|
||||
if (z_offset != nullptr)
|
||||
m_z_offset = z_offset->value;
|
||||
#endif // ENABLE_Z_OFFSET_CORRECTION
|
||||
}
|
||||
|
||||
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
|
||||
|
@ -1189,6 +1201,9 @@ void GCodeProcessor::reset()
|
|||
m_forced_height = 0.0f;
|
||||
m_mm3_per_mm = 0.0f;
|
||||
m_fan_speed = 0.0f;
|
||||
#if ENABLE_Z_OFFSET_CORRECTION
|
||||
m_z_offset = 0.0f;
|
||||
#endif // ENABLE_Z_OFFSET_CORRECTION
|
||||
|
||||
m_extrusion_role = erNone;
|
||||
m_extruder_id = 0;
|
||||
|
@ -2727,7 +2742,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
// the threshold value = 0.0625f == 0.25 * 0.25 is arbitrary, we may find some smarter condition later
|
||||
|
||||
if ((new_pos - *first_vertex).squaredNorm() < 0.0625f) {
|
||||
#if ENABLE_Z_OFFSET_CORRECTION
|
||||
set_end_position(0.5f * (new_pos + *first_vertex) + m_z_offset * Vec3f::UnitZ());
|
||||
#else
|
||||
set_end_position(0.5f * (new_pos + *first_vertex));
|
||||
#endif // ENABLE_Z_OFFSET_CORRECTION
|
||||
store_move_vertex(EMoveType::Seam);
|
||||
set_end_position(curr_pos);
|
||||
}
|
||||
|
@ -3210,7 +3229,11 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
|
|||
m_extrusion_role,
|
||||
m_extruder_id,
|
||||
m_cp_color.current,
|
||||
#if ENABLE_Z_OFFSET_CORRECTION
|
||||
Vec3f(m_end_position[X], m_end_position[Y], m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z] - m_z_offset) + m_extruder_offsets[m_extruder_id],
|
||||
#else
|
||||
Vec3f(m_end_position[X], m_end_position[Y], m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
|
||||
#endif // ENABLE_Z_OFFSET_CORRECTION
|
||||
m_end_position[E] - m_start_position[E],
|
||||
m_feedrate,
|
||||
m_width,
|
||||
|
|
|
@ -530,6 +530,9 @@ namespace Slic3r {
|
|||
float m_forced_height; // mm
|
||||
float m_mm3_per_mm;
|
||||
float m_fan_speed; // percentage
|
||||
#if ENABLE_Z_OFFSET_CORRECTION
|
||||
float m_z_offset; // mm
|
||||
#endif // ENABLE_Z_OFFSET_CORRECTION
|
||||
ExtrusionRole m_extrusion_role;
|
||||
unsigned char m_extruder_id;
|
||||
ExtruderColors m_extruder_colors;
|
||||
|
|
|
@ -74,7 +74,8 @@ const char* GCodeReader::parse_line_internal(const char *ptr, const char *end, G
|
|||
if (axis != NUM_AXES_WITH_UNKNOWN) {
|
||||
// Try to parse the numeric value.
|
||||
double v;
|
||||
auto [pend, ec] = fast_float::from_chars(++ c, end, v);
|
||||
c = skip_whitespaces(++c);
|
||||
auto [pend, ec] = fast_float::from_chars(c, end, v);
|
||||
if (pend != c && is_end_of_word(*pend)) {
|
||||
// The axis value has been parsed correctly.
|
||||
if (axis != UNKNOWN_AXIS)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <charconv>
|
||||
#endif
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
#include <fast_float/fast_float.h>
|
||||
|
||||
|
|
|
@ -1136,6 +1136,7 @@ void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys&
|
|||
// list of options with vector variable, which is independent from number of extruders
|
||||
static const std::vector<std::string> independent_from_extruder_number_options = {
|
||||
"bed_shape",
|
||||
"thumbnails",
|
||||
"filament_ramming_parameters",
|
||||
"gcode_substitutions",
|
||||
"compatible_prints",
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
// Enable detection of layers for spiral vase prints
|
||||
#define ENABLE_SPIRAL_VASE_LAYERS (1 && ENABLE_2_4_1_RC)
|
||||
// Enable correction of toolpaths when z offset is set
|
||||
#define ENABLE_Z_OFFSET_CORRECTION (1 && ENABLE_2_4_1_RC)
|
||||
|
||||
|
||||
//====================
|
||||
|
|
|
@ -157,7 +157,7 @@ void ImGuiWrapper::set_language(const std::string &language)
|
|||
0,
|
||||
};
|
||||
m_font_cjk = false;
|
||||
if (lang == "cs" || lang == "pl") {
|
||||
if (lang == "cs" || lang == "pl" || lang == "hu") {
|
||||
ranges = ranges_latin2;
|
||||
} else if (lang == "ru" || lang == "uk") {
|
||||
ranges = ImGui::GetIO().Fonts->GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters
|
||||
|
|
|
@ -246,7 +246,7 @@ MessageDialog::MessageDialog(wxWindow* parent,
|
|||
long style/* = wxOK*/)
|
||||
: MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, style)
|
||||
{
|
||||
add_msg_content(this, content_sizer, message);
|
||||
add_msg_content(this, content_sizer, get_wraped_wxString(message));
|
||||
finalize();
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ RichMessageDialog::RichMessageDialog(wxWindow* parent,
|
|||
long style/* = wxOK*/)
|
||||
: MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, style)
|
||||
{
|
||||
add_msg_content(this, content_sizer, message);
|
||||
add_msg_content(this, content_sizer, get_wraped_wxString(message));
|
||||
|
||||
m_checkBox = new wxCheckBox(this, wxID_ANY, m_checkBoxText);
|
||||
wxGetApp().UpdateDarkUI(m_checkBox);
|
||||
|
@ -292,6 +292,43 @@ InfoDialog::InfoDialog(wxWindow* parent, const wxString &title, const wxString&
|
|||
finalize();
|
||||
}
|
||||
|
||||
wxString get_wraped_wxString(const wxString& text_in, size_t line_len /*=80*/)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
char slash = '\\';
|
||||
#else
|
||||
char slash = '/';
|
||||
#endif
|
||||
char space = ' ';
|
||||
char new_line = '\n';
|
||||
|
||||
wxString text = text_in;
|
||||
|
||||
int idx = -1;
|
||||
size_t cur_len = 0;
|
||||
size_t text_len = text.Len();
|
||||
|
||||
for (size_t i = 0; i < text_len; i++) {
|
||||
cur_len++;
|
||||
if (text[i] == space || text[i] == slash)
|
||||
idx = i;
|
||||
if (text[i] == new_line) {
|
||||
idx = -1;
|
||||
cur_len = 0;
|
||||
continue;
|
||||
}
|
||||
if (cur_len >= line_len && idx >= 0) {
|
||||
if (text[idx] == slash) {
|
||||
text.insert(static_cast<size_t>(idx) + 1, 1, new_line);
|
||||
text_len++;
|
||||
}
|
||||
else // space
|
||||
text[idx] = new_line;
|
||||
cur_len = i - static_cast<size_t>(idx);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
virtual ~WarningDialog() = default;
|
||||
};
|
||||
|
||||
wxString get_wraped_wxString(const wxString& text_in, size_t line_len = 80);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Generic static line, used intead of wxStaticLine
|
||||
class StaticLine: public wxTextCtrl
|
||||
|
@ -283,7 +285,7 @@ public:
|
|||
const wxString& message,
|
||||
const wxString& caption = wxEmptyString,
|
||||
long style = wxOK)
|
||||
: wxMessageDialog(parent, message, caption, style) {}
|
||||
: wxMessageDialog(parent, get_wraped_wxString(message), caption, style) {}
|
||||
~MessageDialog() {}
|
||||
};
|
||||
|
||||
|
@ -295,7 +297,7 @@ public:
|
|||
const wxString& message,
|
||||
const wxString& caption = wxEmptyString,
|
||||
long style = wxOK)
|
||||
: wxRichMessageDialog(parent, message, caption, style) {
|
||||
: wxRichMessageDialog(parent, get_wraped_wxString(message), caption, style) {
|
||||
this->SetEscapeId(wxID_CANCEL);
|
||||
}
|
||||
~RichMessageDialog() {}
|
||||
|
|
|
@ -993,11 +993,11 @@ void NotificationManager::UpdatedItemsInfoNotification::add_type(InfoItemType ty
|
|||
if ((*it).second == 0)
|
||||
continue;
|
||||
switch ((*it).first) {
|
||||
case InfoItemType::CustomSupports: text += format(_L_PLURAL("%1$d Object was loaded with custom supports.", "%1$d Objects were loaded with custom supports.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::CustomSeam: text += format(_L_PLURAL("%1$d Object was loaded with custom seam.", "%1$d Objects were loaded with custom seam.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::MmuSegmentation: text += format(_L_PLURAL("%1$d Object was loaded with multimaterial painting.", "%1$d Objects were loaded with multimaterial painting.",(*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::VariableLayerHeight: text += format(_L_PLURAL("%1$d Object was loaded with variable layer height.", "%1$d Objects were loaded with variable layer height.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::Sinking: text += format(_L_PLURAL("%1$d Object was loaded with partial sinking.", "%1$d Objects were loaded with partial sinking.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::CustomSupports: text += format(_L_PLURAL("%1$d object was loaded with custom supports.", "%1$d objects were loaded with custom supports.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::CustomSeam: text += format(_L_PLURAL("%1$d object was loaded with custom seam.", "%1$d objects were loaded with custom seam.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::MmuSegmentation: text += format(_L_PLURAL("%1$d object was loaded with multimaterial painting.", "%1$d objects were loaded with multimaterial painting.",(*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::VariableLayerHeight: text += format(_L_PLURAL("%1$d object was loaded with variable layer height.", "%1$d objects were loaded with variable layer height.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::Sinking: text += format(_L_PLURAL("%1$d object was loaded with partial sinking.", "%1$d objects were loaded with partial sinking.", (*it).second), (*it).second) + "\n"; break;
|
||||
default: BOOST_LOG_TRIVIAL(error) << "Unknown InfoItemType: " << (*it).second; break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -596,8 +596,8 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
|
|||
value = int(nozzle_diameter->values.size());
|
||||
}
|
||||
else if (m_opt_map.find(opt_key) == m_opt_map.end() ||
|
||||
// This option don't have corresponded field
|
||||
PresetCollection::is_independent_from_extruder_number_option(opt_key) ) {
|
||||
// This option doesn't have corresponded field
|
||||
is_option_without_field(opt_key) ) {
|
||||
value = get_config_value(config, opt_key);
|
||||
this->change_opt_value(opt_key, value);
|
||||
OptionsGroup::on_change_OG(opt_key, value);
|
||||
|
@ -981,6 +981,11 @@ bool OptionsGroup::launch_browser(const std::string& path_end)
|
|||
return wxGetApp().open_browser_with_warning_dialog(OptionsGroup::get_url(path_end), wxGetApp().mainframe->m_tabpanel);
|
||||
}
|
||||
|
||||
bool OptionsGroup::is_option_without_field(const std::string& opt_key)
|
||||
{
|
||||
return opt_key!= "thumbnails" // "thumbnails" has related field
|
||||
&& PresetCollection::is_independent_from_extruder_number_option(opt_key);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -240,6 +240,7 @@ protected:
|
|||
public:
|
||||
static wxString get_url(const std::string& path_end);
|
||||
static bool launch_browser(const std::string& path_end);
|
||||
static bool is_option_without_field(const std::string& opt_key);
|
||||
};
|
||||
|
||||
class ConfigOptionsGroup: public OptionsGroup {
|
||||
|
|
|
@ -5253,7 +5253,7 @@ ProjectDropDialog::ProjectDropDialog(const std::string& filename)
|
|||
_L("Import config only") };
|
||||
|
||||
main_sizer->Add(new wxStaticText(this, wxID_ANY,
|
||||
_L("Select an action to apply to the file") + ": " + from_u8(filename)), 0, wxEXPAND | wxALL, 10);
|
||||
get_wraped_wxString(_L("Select an action to apply to the file") + ": " + from_u8(filename))), 0, wxEXPAND | wxALL, 10);
|
||||
|
||||
m_action = std::clamp(std::stoi(wxGetApp().app_config->get("drop_project_action")),
|
||||
static_cast<int>(LoadType::OpenProject), static_cast<int>(LoadType::LoadConfig)) - 1;
|
||||
|
|
|
@ -479,7 +479,7 @@ void Tab::update_label_colours()
|
|||
else
|
||||
color = &m_modified_label_clr;
|
||||
}
|
||||
if (PresetCollection::is_independent_from_extruder_number_option(opt.first)) {
|
||||
if (OptionsGroup::is_option_without_field(opt.first)) {
|
||||
if (Line* line = get_line(opt.first))
|
||||
line->set_label_colour(color);
|
||||
continue;
|
||||
|
@ -520,7 +520,7 @@ void Tab::decorate()
|
|||
Field* field = nullptr;
|
||||
bool option_without_field = false;
|
||||
|
||||
if(PresetCollection::is_independent_from_extruder_number_option(opt.first))
|
||||
if(OptionsGroup::is_option_without_field(opt.first))
|
||||
option_without_field = true;
|
||||
|
||||
if (!option_without_field) {
|
||||
|
@ -1659,7 +1659,7 @@ void TabPrint::build()
|
|||
option.opt.height = 5;//50;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("G-code Substitutions"));
|
||||
optgroup = page->new_optgroup(L("Other"));
|
||||
|
||||
create_line_with_widget(optgroup.get(), "gcode_substitutions", "", [this](wxWindow* parent) {
|
||||
return create_manage_substitution_widget(parent);
|
||||
|
@ -3865,7 +3865,7 @@ void SubstitutionManager::create_legend()
|
|||
// name of the first column is empty
|
||||
m_grid_sizer->Add(new wxStaticText(m_parent, wxID_ANY, wxEmptyString));
|
||||
// Legend for another columns
|
||||
for (const std::string col : { L("Plain pattern"), L("Format"), L("Params") }) {
|
||||
for (const std::string col : { L("Find"), L("Replace with"), L("Options") }) {
|
||||
auto temp = new wxStaticText(m_parent, wxID_ANY, _(col), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_MIDDLE);
|
||||
// temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
m_grid_sizer->Add(temp);
|
||||
|
@ -3880,7 +3880,7 @@ void SubstitutionManager::delete_substitution(int substitution_id)
|
|||
if ((substitutions.size() % 3) != 0)
|
||||
throw RuntimeError("Invalid length of gcode_substitutions parameter");
|
||||
|
||||
if ((substitutions.size() / 3) < substitution_id)
|
||||
if (int(substitutions.size() / 3) < substitution_id)
|
||||
throw RuntimeError("Invalid substitution_id to delete");
|
||||
|
||||
substitutions.erase(std::next(substitutions.begin(), substitution_id * 3), std::next(substitutions.begin(), substitution_id * 3 + 3));
|
||||
|
@ -4021,10 +4021,10 @@ void SubstitutionManager::edit_substitution(int substitution_id, int opt_pos, co
|
|||
if ((substitutions.size() % 3) != 0)
|
||||
throw RuntimeError("Invalid length of gcode_substitutions parameter");
|
||||
|
||||
if ((substitutions.size() / 3) != m_grid_sizer->GetEffectiveRowsCount()-1)
|
||||
if (int(substitutions.size() / 3) != m_grid_sizer->GetEffectiveRowsCount()-1)
|
||||
throw RuntimeError("Invalid compatibility between UI and BE");
|
||||
|
||||
if ((substitutions.size() / 3) < substitution_id)
|
||||
if (int(substitutions.size() / 3) < substitution_id)
|
||||
throw RuntimeError("Invalid substitution_id to edit");
|
||||
|
||||
substitutions[substitution_id * 3 + opt_pos] = value;
|
||||
|
@ -4047,13 +4047,13 @@ wxSizer* TabPrint::create_manage_substitution_widget(wxWindow* parent)
|
|||
};
|
||||
|
||||
ScalableButton* add_substitution_btn;
|
||||
create_btn(&add_substitution_btn, _L("Add G-code substitution"), "add_copies");
|
||||
create_btn(&add_substitution_btn, _L("Add"), "add_copies");
|
||||
add_substitution_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {
|
||||
m_subst_manager.add_substitution();
|
||||
m_del_all_substitutions_btn->Show();
|
||||
});
|
||||
|
||||
create_btn(&m_del_all_substitutions_btn, _L("Delete all G-code substitution"), "cross");
|
||||
create_btn(&m_del_all_substitutions_btn, _L("Delete all"), "cross");
|
||||
m_del_all_substitutions_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {
|
||||
m_subst_manager.delete_all();
|
||||
m_del_all_substitutions_btn->Hide();
|
||||
|
|
|
@ -589,8 +589,10 @@ void LockButton::OnButton(wxCommandEvent& event)
|
|||
|
||||
void LockButton::SetLock(bool lock)
|
||||
{
|
||||
m_is_pushed = lock;
|
||||
update_button_bitmaps();
|
||||
if (m_is_pushed != lock) {
|
||||
m_is_pushed = lock;
|
||||
update_button_bitmaps();
|
||||
}
|
||||
}
|
||||
|
||||
void LockButton::msw_rescale()
|
||||
|
@ -605,7 +607,6 @@ void LockButton::msw_rescale()
|
|||
|
||||
void LockButton::update_button_bitmaps()
|
||||
{
|
||||
Slic3r::GUI::wxGetApp().UpdateDarkUI(this);
|
||||
SetBitmap(m_is_pushed ? m_bmp_lock_closed.bmp() : m_bmp_lock_open.bmp());
|
||||
SetBitmapHover(m_is_pushed ? m_bmp_lock_closed_f.bmp() : m_bmp_lock_open_f.bmp());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue