mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-04 12:34:05 -06:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_sequential_limits
This commit is contained in:
commit
7a14005f5a
36 changed files with 338 additions and 155 deletions
|
@ -266,7 +266,7 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_
|
|||
std::string bitmap_key = bitmap_name + ( target_height !=0 ?
|
||||
"-h" + std::to_string(target_height) :
|
||||
"-w" + std::to_string(target_width))
|
||||
+ (m_scale != 1.0f ? "-s" + std::to_string(m_scale) : "")
|
||||
+ (m_scale != 1.0f ? "-s" + float_to_string_decimal_point(m_scale) : "")
|
||||
+ (grayscale ? "-gs" : "");
|
||||
|
||||
/* For the Dark mode of any platform, we should draw icons in respect to OS background
|
||||
|
|
|
@ -1388,17 +1388,21 @@ static void focus_event(wxFocusEvent& e, wxTextCtrl* ctrl, double def_value)
|
|||
{
|
||||
e.Skip();
|
||||
wxString str = ctrl->GetValue();
|
||||
// Replace the first occurence of comma in decimal number.
|
||||
bool was_replace = str.Replace(",", ".", false) > 0;
|
||||
|
||||
const char dec_sep = is_decimal_separator_point() ? '.' : ',';
|
||||
const char dec_sep_alt = dec_sep == '.' ? ',' : '.';
|
||||
// Replace the first incorrect separator in decimal number.
|
||||
bool was_replaced = str.Replace(dec_sep_alt, dec_sep, false) != 0;
|
||||
|
||||
double val = 0.0;
|
||||
if (!str.ToCDouble(&val)) {
|
||||
if (!str.ToDouble(&val)) {
|
||||
if (val == 0.0)
|
||||
val = def_value;
|
||||
ctrl->SetValue(double_to_string(val));
|
||||
show_error(nullptr, _L("Invalid numeric input."));
|
||||
ctrl->SetFocus();
|
||||
}
|
||||
else if (was_replace)
|
||||
else if (was_replaced)
|
||||
ctrl->SetValue(double_to_string(val));
|
||||
}
|
||||
|
||||
|
@ -1447,17 +1451,17 @@ PageDiameters::PageDiameters(ConfigWizard *parent)
|
|||
void PageDiameters::apply_custom_config(DynamicPrintConfig &config)
|
||||
{
|
||||
double val = 0.0;
|
||||
diam_nozzle->GetValue().ToCDouble(&val);
|
||||
diam_nozzle->GetValue().ToDouble(&val);
|
||||
auto *opt_nozzle = new ConfigOptionFloats(1, val);
|
||||
config.set_key_value("nozzle_diameter", opt_nozzle);
|
||||
|
||||
val = 0.0;
|
||||
diam_filam->GetValue().ToCDouble(&val);
|
||||
diam_filam->GetValue().ToDouble(&val);
|
||||
auto * opt_filam = new ConfigOptionFloats(1, val);
|
||||
config.set_key_value("filament_diameter", opt_filam);
|
||||
|
||||
auto set_extrusion_width = [&config, opt_nozzle](const char *key, double dmr) {
|
||||
char buf[64];
|
||||
char buf[64]; // locales don't matter here (sprintf/atof)
|
||||
sprintf(buf, "%.2lf", dmr * opt_nozzle->values.front() / 0.4);
|
||||
config.set_key_value(key, new ConfigOptionFloatOrPercent(atof(buf), false));
|
||||
};
|
||||
|
|
|
@ -2162,7 +2162,7 @@ static void upgrade_text_entry_dialog(wxTextEntryDialog* dlg, double min = -1.0,
|
|||
bool disable = textctrl->IsEmpty();
|
||||
if (!disable && min >= 0.0 && max >= 0.0) {
|
||||
double value = -1.0;
|
||||
if (!textctrl->GetValue().ToCDouble(&value)) // input value couldn't be converted to double
|
||||
if (!textctrl->GetValue().ToDouble(&value)) // input value couldn't be converted to double
|
||||
disable = true;
|
||||
else
|
||||
disable = value < min - epsilon() || value > max + epsilon(); // is input value is out of valid range ?
|
||||
|
@ -2231,7 +2231,7 @@ static double get_value_to_jump(double active_value, double min_z, double max_z,
|
|||
return -1.0;
|
||||
|
||||
double value = -1.0;
|
||||
return dlg.GetValue().ToCDouble(&value) ? value : -1.0;
|
||||
return dlg.GetValue().ToDouble(&value) ? value : -1.0;
|
||||
}
|
||||
|
||||
void Control::add_code_as_tick(Type type, int selected_extruder/* = -1*/)
|
||||
|
|
|
@ -98,9 +98,14 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
|
|||
return;
|
||||
}
|
||||
|
||||
str.Replace(",", ".", false);
|
||||
char dec_sep = '.';
|
||||
if (! is_decimal_separator_point()) {
|
||||
str.Replace(".", ",", false);
|
||||
dec_sep = ',';
|
||||
}
|
||||
|
||||
double val;
|
||||
if (str == "." || !str.ToCDouble(&val) || val <= 0.0)
|
||||
if (str == dec_sep || !str.ToDouble(&val) || val <= 0.0)
|
||||
val = 3.0; // default value
|
||||
|
||||
if (fabs(m_sequence.interval_by_layers - val) < 0.001)
|
||||
|
|
|
@ -37,12 +37,13 @@ wxString double_to_string(double const value, const int max_precision /*= 4*/)
|
|||
// with the exception that here one sets the decimal separator explicitely to dot.
|
||||
// If number is in scientific format, trailing zeroes belong to the exponent and cannot be removed.
|
||||
if (s.find_first_of("eE") == wxString::npos) {
|
||||
const size_t posDecSep = s.find(".");
|
||||
char dec_sep = is_decimal_separator_point() ? '.' : ',';
|
||||
const size_t posDecSep = s.find(dec_sep);
|
||||
// No decimal point => removing trailing zeroes irrelevant for integer number.
|
||||
if (posDecSep != wxString::npos) {
|
||||
// Find the last character to keep.
|
||||
size_t posLastNonZero = s.find_last_not_of("0");
|
||||
// If it's the decimal separator itself, don't keep it neither.
|
||||
// If it's the decimal separator itself, don't keep it either.
|
||||
if (posLastNonZero == posDecSep)
|
||||
-- posLastNonZero;
|
||||
s.erase(posLastNonZero + 1);
|
||||
|
@ -236,16 +237,22 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
|
|||
m_value = double(m_opt.min);
|
||||
break;
|
||||
}
|
||||
double val;
|
||||
// Replace the first occurence of comma in decimal number.
|
||||
str.Replace(",", ".", false);
|
||||
if (str == ".")
|
||||
double val;
|
||||
|
||||
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)
|
||||
set_value(str, false);
|
||||
|
||||
|
||||
if (str == dec_sep)
|
||||
val = 0.0;
|
||||
else
|
||||
{
|
||||
if (m_opt.nullable && str == na_value())
|
||||
val = ConfigOptionFloatsNullable::nil_value();
|
||||
else if (!str.ToCDouble(&val))
|
||||
else if (!str.ToDouble(&val))
|
||||
{
|
||||
if (!check_value) {
|
||||
m_value.clear();
|
||||
|
@ -293,14 +300,18 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
|
|||
if (m_opt.type == coFloatOrPercent && !str.IsEmpty() && str.Last() != '%')
|
||||
{
|
||||
double val = 0.;
|
||||
// Replace the first occurence of comma in decimal number.
|
||||
str.Replace(",", ".", false);
|
||||
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)
|
||||
set_value(str, false);
|
||||
|
||||
|
||||
// remove space and "mm" substring, if any exists
|
||||
str.Replace(" ", "", true);
|
||||
str.Replace("m", "", true);
|
||||
|
||||
if (!str.ToCDouble(&val))
|
||||
if (!str.ToDouble(&val))
|
||||
{
|
||||
if (!check_value) {
|
||||
m_value.clear();
|
||||
|
@ -1215,8 +1226,8 @@ boost::any& Choice::get_value()
|
|||
return m_value;
|
||||
}
|
||||
|
||||
void Choice::enable() { dynamic_cast<choice_ctrl*>(window)->Enable(); };
|
||||
void Choice::disable() { dynamic_cast<choice_ctrl*>(window)->Disable(); };
|
||||
void Choice::enable() { dynamic_cast<choice_ctrl*>(window)->Enable(); }
|
||||
void Choice::disable() { dynamic_cast<choice_ctrl*>(window)->Disable(); }
|
||||
|
||||
void Choice::msw_rescale()
|
||||
{
|
||||
|
@ -1478,7 +1489,7 @@ boost::any& PointCtrl::get_value()
|
|||
!y_textctrl->GetValue().ToDouble(&y))
|
||||
{
|
||||
set_value(m_value.empty() ? Vec2d(0.0, 0.0) : m_value, true);
|
||||
show_error(m_parent, _L("Invalid numeric input."));
|
||||
show_error(m_parent, _L("Invalid numeric input."));
|
||||
}
|
||||
else
|
||||
if (m_opt.min > x || x > m_opt.max ||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "libslic3r/Geometry.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "Plater.hpp"
|
||||
|
@ -78,6 +79,7 @@ static float round_to_nearest(float value, unsigned int decimals)
|
|||
res = std::round(value);
|
||||
else {
|
||||
char buf[64];
|
||||
// locales should not matter, both sprintf and stof are sensitive, so...
|
||||
sprintf(buf, "%.*g", decimals, value);
|
||||
res = std::stof(buf);
|
||||
}
|
||||
|
@ -995,6 +997,9 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
|
|||
// save materials file
|
||||
boost::filesystem::path mat_filename(filename);
|
||||
mat_filename.replace_extension("mtl");
|
||||
|
||||
CNumericLocalesSetter locales_setter;
|
||||
|
||||
FILE* fp = boost::nowide::fopen(mat_filename.string().c_str(), "w");
|
||||
if (fp == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << "GCodeViewer::export_toolpaths_to_obj: Couldn't open " << mat_filename.string().c_str() << " for writing";
|
||||
|
@ -3470,18 +3475,16 @@ void GCodeViewer::render_statistics() const
|
|||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
|
||||
auto add_time = [this, &imgui](const std::string& label, int64_t time) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%lld ms (%s)", time, get_time_dhms(static_cast<float>(time) * 0.001f).c_str());
|
||||
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
|
||||
ImGui::SameLine(offset);
|
||||
imgui.text(buf);
|
||||
imgui.text(std::to_string(time) + " ms (" + get_time_dhms(static_cast<float>(time) * 0.001f) + ")");
|
||||
};
|
||||
|
||||
auto add_memory = [this, &imgui](const std::string& label, int64_t memory) {
|
||||
auto format_string = [memory](const std::string& units, float value) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%lld bytes (%.3f %s)", memory, static_cast<float>(memory) * value, units.c_str());
|
||||
return std::string(buf);
|
||||
auto format_string = [memory](const std::string& units, float value) {
|
||||
return std::to_string(memory) + " bytes (" +
|
||||
Slic3r::float_to_string_decimal_point(float(memory) * value, 3)
|
||||
+ " " + units + ")";
|
||||
};
|
||||
|
||||
static const float kb = 1024.0f;
|
||||
|
@ -3501,11 +3504,9 @@ void GCodeViewer::render_statistics() const
|
|||
};
|
||||
|
||||
auto add_counter = [this, &imgui](const std::string& label, int64_t counter) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%lld", counter);
|
||||
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
|
||||
ImGui::SameLine(offset);
|
||||
imgui.text(buf);
|
||||
imgui.text(std::to_string(counter));
|
||||
};
|
||||
|
||||
imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f);
|
||||
|
|
|
@ -4008,7 +4008,7 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
|
|||
if (imgui->slider_float(_L("Spacing"), &settings.distance, dist_min, 100.0f, "%5.2f") || dist_min > settings.distance) {
|
||||
settings.distance = std::max(dist_min, settings.distance);
|
||||
settings_out.distance = settings.distance;
|
||||
appcfg->set("arrange", dist_key.c_str(), std::to_string(settings_out.distance));
|
||||
appcfg->set("arrange", dist_key.c_str(), float_to_string_decimal_point(settings_out.distance));
|
||||
settings_changed = true;
|
||||
}
|
||||
|
||||
|
@ -4023,7 +4023,7 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
|
|||
if (imgui->button(_L("Reset"))) {
|
||||
settings_out = ArrangeSettings{};
|
||||
settings_out.distance = std::max(dist_min, settings_out.distance);
|
||||
appcfg->set("arrange", dist_key.c_str(), std::to_string(settings_out.distance));
|
||||
appcfg->set("arrange", dist_key.c_str(), float_to_string_decimal_point(settings_out.distance));
|
||||
appcfg->set("arrange", rot_key.c_str(), settings_out.enable_rotation? "1" : "0");
|
||||
settings_changed = true;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "GUI_App.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
@ -113,7 +115,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
|||
str.pop_back();
|
||||
percent = true;
|
||||
}
|
||||
double val = stod(str);
|
||||
double val = std::stod(str); // locale-dependent (on purpose - the input is the actual content of the field)
|
||||
config.set_key_value(opt_key, new ConfigOptionFloatOrPercent(val, percent));
|
||||
break;}
|
||||
case coPercent:
|
||||
|
|
|
@ -1586,7 +1586,7 @@ bool GUI_App::load_language(wxString language, bool initial)
|
|||
m_wxLocale->AddCatalog(SLIC3R_APP_KEY);
|
||||
m_imgui->set_language(into_u8(language_info->CanonicalName));
|
||||
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
|
||||
wxSetlocale(LC_NUMERIC, "C");
|
||||
//wxSetlocale(LC_NUMERIC, "C");
|
||||
Preset::update_suffix_modified((" (" + _L("modified") + ")").ToUTF8().data());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -397,12 +397,16 @@ coordf_t LayerRangeEditor::get_value()
|
|||
wxString str = GetValue();
|
||||
|
||||
coordf_t layer_height;
|
||||
// Replace the first occurence of comma in decimal number.
|
||||
str.Replace(",", ".", false);
|
||||
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);
|
||||
|
||||
if (str == ".")
|
||||
layer_height = 0.0;
|
||||
else {
|
||||
if (!str.ToCDouble(&layer_height) || layer_height < 0.0f) {
|
||||
if (!str.ToDouble(&layer_height) || layer_height < 0.0f) {
|
||||
show_error(m_parent, _L("Invalid numeric input."));
|
||||
SetValue(double_to_string(layer_height));
|
||||
}
|
||||
|
|
|
@ -1095,15 +1095,19 @@ double ManipulationEditor::get_value()
|
|||
wxString str = GetValue();
|
||||
|
||||
double value;
|
||||
// Replace the first occurence of comma in decimal number.
|
||||
str.Replace(",", ".", false);
|
||||
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);
|
||||
|
||||
if (str == ".")
|
||||
value = 0.0;
|
||||
|
||||
if ((str.IsEmpty() || !str.ToCDouble(&value)) && !m_valid_value.IsEmpty()) {
|
||||
if ((str.IsEmpty() || !str.ToDouble(&value)) && !m_valid_value.IsEmpty()) {
|
||||
str = m_valid_value;
|
||||
SetValue(str);
|
||||
str.ToCDouble(&value);
|
||||
str.ToDouble(&value);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Camera.hpp"
|
||||
#include "Plater.hpp"
|
||||
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
|
@ -1982,7 +1983,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
if (pos == std::string::npos)
|
||||
return;
|
||||
|
||||
double max_z = std::stod(field.substr(pos + 1));
|
||||
double max_z = string_to_double_decimal_point(field.substr(pos + 1));
|
||||
|
||||
// extract min_z
|
||||
field = field.substr(0, pos);
|
||||
|
@ -1990,7 +1991,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
|
|||
if (pos == std::string::npos)
|
||||
return;
|
||||
|
||||
const double min_z = std::stod(field.substr(pos + 1));
|
||||
const double min_z = string_to_double_decimal_point(field.substr(pos + 1));
|
||||
|
||||
// extract type
|
||||
field = field.substr(0, pos);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue