mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge remote-tracking branch 'remotes/origin/master' into vb_print_regions
This commit is contained in:
		
						commit
						0d081c90f0
					
				
					 46 changed files with 521 additions and 265 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); | ||||
|     } | ||||
|  | @ -591,7 +593,7 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& | |||
|     m_last_result_id = gcode_result.id; | ||||
| 
 | ||||
|     // release gpu memory, if used
 | ||||
|     reset(); | ||||
|     reset();  | ||||
| 
 | ||||
| #if ENABLE_GCODE_WINDOW | ||||
|     m_sequential_view.gcode_window.set_filename(gcode_result.filename); | ||||
|  | @ -990,6 +992,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"; | ||||
|  | @ -3465,18 +3470,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; | ||||
|  | @ -3496,11 +3499,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); | ||||
|  |  | |||
|  | @ -1356,7 +1356,7 @@ void GLCanvas3D::render() | |||
|         if (m_rectangle_selection.is_dragging()) | ||||
|             // picking pass using rectangle selection
 | ||||
|             _rectangular_selection_picking_pass(); | ||||
|         else | ||||
|         else if (!m_volumes.empty()) | ||||
|             // regular picking pass
 | ||||
|             _picking_pass(); | ||||
|     } | ||||
|  | @ -3800,7 +3800,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; | ||||
|     } | ||||
| 
 | ||||
|  | @ -3815,7 +3815,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; | ||||
|     } | ||||
|  | @ -4527,6 +4527,14 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) | |||
|     if (m_canvas == nullptr && m_context == nullptr) | ||||
|         return; | ||||
| 
 | ||||
| #if ENABLE_SCROLLABLE_LEGEND | ||||
|     const std::array<unsigned int, 2> new_size = { w, h }; | ||||
|     if (m_old_size == new_size) | ||||
|         return; | ||||
| 
 | ||||
|     m_old_size = new_size; | ||||
| #endif // ENABLE_SCROLLABLE_LEGEND
 | ||||
| 
 | ||||
|     auto *imgui = wxGetApp().imgui(); | ||||
|     imgui->set_display_size(static_cast<float>(w), static_cast<float>(h)); | ||||
|     const float font_size = 1.5f * wxGetApp().em_unit(); | ||||
|  |  | |||
|  | @ -425,6 +425,10 @@ private: | |||
|     Model* m_model; | ||||
|     BackgroundSlicingProcess *m_process; | ||||
| 
 | ||||
| #if ENABLE_SCROLLABLE_LEGEND | ||||
|     std::array<unsigned int, 2> m_old_size{ 0, 0 }; | ||||
| #endif // ENABLE_SCROLLABLE_LEGEND
 | ||||
| 
 | ||||
|     // Screen is only refreshed from the OnIdle handler if it is dirty.
 | ||||
|     bool m_dirty; | ||||
|     bool m_initialized; | ||||
|  | @ -733,6 +737,10 @@ public: | |||
| #endif | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_SCROLLABLE_LEGEND | ||||
|     void reset_old_size() { m_old_size = { 0, 0 }; } | ||||
| #endif // ENABLE_SCROLLABLE_LEGEND
 | ||||
| 
 | ||||
| private: | ||||
|     bool _is_shown_on_screen() const; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include "PrintHostDialogs.hpp" | ||||
| #include "wxExtensions.hpp" | ||||
| #include "../Utils/PrintHost.hpp" | ||||
| #include "libslic3r/Config.hpp" | ||||
| 
 | ||||
| #include <boost/algorithm/string.hpp> | ||||
| #include <boost/log/trivial.hpp> | ||||
|  | @ -304,8 +305,8 @@ void NotificationManager::PopNotification::count_lines() | |||
| 	} | ||||
| 	// hypertext calculation
 | ||||
| 	if (!m_hypertext.empty()) { | ||||
| 		int prev_end = m_endlines.size() > 1 ? m_endlines[m_endlines.size() - 2] : 0; | ||||
| 		if (ImGui::CalcTextSize((text.substr(prev_end, last_end - prev_end) + m_hypertext).c_str()).x > m_window_width - m_window_width_offset) { | ||||
| 		int prev_end = m_endlines.size() > 1 ? m_endlines[m_endlines.size() - 2] : 0; // m_endlines.size() - 2 because we are fitting hypertext instead of last endline
 | ||||
| 		if (ImGui::CalcTextSize((escape_string_cstyle(text.substr(prev_end, last_end - prev_end)) + m_hypertext).c_str()).x > m_window_width - m_window_width_offset) { | ||||
| 			m_endlines.push_back(last_end); | ||||
| 			m_lines_count++; | ||||
| 		} | ||||
|  | @ -366,7 +367,7 @@ void NotificationManager::PopNotification::render_text(ImGuiWrapper& imgui, cons | |||
| 			} | ||||
| 			//hyperlink text
 | ||||
| 			if (!m_hypertext.empty()) { | ||||
| 				render_hypertext(imgui, x_offset + ImGui::CalcTextSize((line + " ").c_str()).x, starting_y + (m_lines_count - 1) * shift_y, m_hypertext); | ||||
| 				render_hypertext(imgui, x_offset + ImGui::CalcTextSize((line + (line.empty() ? "" : " ")).c_str()).x, starting_y + (m_lines_count - 1) * shift_y, m_hypertext); | ||||
| 			} | ||||
| 			 | ||||
| 			 | ||||
|  |  | |||
|  | @ -3437,8 +3437,12 @@ void Plater::priv::set_current_panel(wxPanel* panel) | |||
| 
 | ||||
|         // sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably)
 | ||||
|         view3D->set_as_dirty(); | ||||
| #if ENABLE_SCROLLABLE_LEGEND | ||||
|         // reset cached size to force a resize on next call to render() to keep imgui in synch with canvas size
 | ||||
|         view3D->get_canvas3d()->reset_old_size(); | ||||
| #endif // ENABLE_SCROLLABLE_LEGEND
 | ||||
|         view_toolbar.select_item("3D"); | ||||
|         if(notification_manager != nullptr) | ||||
|         if (notification_manager != nullptr) | ||||
|             notification_manager->set_in_preview(false); | ||||
|     } | ||||
|     else if (current_panel == preview) { | ||||
|  | @ -3457,6 +3461,10 @@ void Plater::priv::set_current_panel(wxPanel* panel) | |||
|         preview->reload_print(true); | ||||
| 
 | ||||
|         preview->set_as_dirty(); | ||||
| #if ENABLE_SCROLLABLE_LEGEND | ||||
|         // reset cached size to force a resize on next call to render() to keep imgui in synch with canvas size
 | ||||
|         preview->get_canvas3d()->reset_old_size(); | ||||
| #endif // ENABLE_SCROLLABLE_LEGEND
 | ||||
|         view_toolbar.select_item("Preview"); | ||||
|         if (notification_manager != nullptr) | ||||
|             notification_manager->set_in_preview(true); | ||||
|  |  | |||
|  | @ -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" | ||||
|  | @ -1927,7 +1928,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); | ||||
|  | @ -1935,7 +1936,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
	
	 Vojtech Bubnik
						Vojtech Bubnik