mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-21 06:21:16 +00:00
Keep a Decimal Point in the Wipe Tower's Travel Feedrate
merge_tcr formatted the feedrate of the travel that joins two wipe tower blocks with std::to_string, which follows the numeric locale. The GUI slices on a thread that keeps the user's locale, so a comma-decimal locale wrote moves such as 'G1 Y249.463 F5400,000000', which Klipper rejects. Format it with float_to_string_decimal_point like the X and Y beside it; the output in the C locale is unchanged. The comma-locale test helper moves to the shared test header so the wipe tower test can use it.
This commit is contained in:
1 parent
069bd402d9
commit
ebbf27147e
4 files changed
+60
-40
No files matched your search
@@ -3349,7 +3349,7 @@ WipeTower::ToolChangeResult WipeTower::merge_tcr(ToolChangeResult &first, ToolCh
|
||||
WipeTower::ToolChangeResult out = first;
|
||||
if ((first.end_pos - second.start_pos).norm() > (float)EPSILON) {
|
||||
std::string travel_gcode = "G1 X" + Slic3r::float_to_string_decimal_point(second.start_pos.x(), 3) + " Y" +
|
||||
Slic3r::float_to_string_decimal_point(second.start_pos.y(), 3) + " F" + std::to_string(m_max_speed) + "\n";
|
||||
Slic3r::float_to_string_decimal_point(second.start_pos.y(), 3) + " F" + Slic3r::float_to_string_decimal_point(m_max_speed, 6) + "\n";
|
||||
bool need_insert_travel = true;
|
||||
if (second.is_tool_change
|
||||
&& is_approx(second.start_pos.x(), second.tool_change_start_pos.x())
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <cstddef>
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -22,9 +23,11 @@
|
||||
#include "libslic3r/ClipperUtils.hpp"
|
||||
#include "libslic3r/GCode/GCodeProcessor.hpp"
|
||||
#include "libslic3r/GCode/WipeTower.hpp"
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
#include "test_helpers.hpp"
|
||||
#include "test_utils.hpp"
|
||||
#include "libslic3r/PrintBase.hpp"
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
|
||||
@@ -219,6 +222,24 @@ TEST_CASE("The wipe tower sets Klipper's acceleration and accel_to_decel on one
|
||||
!Catch::Matchers::ContainsSubstring("M204"));
|
||||
}
|
||||
|
||||
TEST_CASE("The wipe tower's G-code moves keep a decimal point in a comma-decimal locale", "[WipeTower]")
|
||||
{
|
||||
// The GUI slices on a thread that keeps the user's numeric locale.
|
||||
CommaNumericLocale comma;
|
||||
CNumericLocalesSetter restore;
|
||||
if (! comma.apply())
|
||||
SKIP("no locale with a comma decimal separator is installed");
|
||||
DynamicPrintConfig config = wipe_tower_toolchange_config("klipper");
|
||||
// Type 1 towers join their toolchange blocks with a travel move of their own.
|
||||
config.set_deserialize_strict({ { "wipe_tower_type", "type1" } });
|
||||
const std::string gcode = slice_with_prime_tower(config);
|
||||
REQUIRE_FALSE(wipe_tower_regions(gcode).empty());
|
||||
std::istringstream lines(gcode);
|
||||
for (std::string line; std::getline(lines, line);)
|
||||
if (! line.empty() && line.front() == 'G' && line.find(',') != std::string::npos)
|
||||
FAIL_CHECK(line);
|
||||
}
|
||||
|
||||
// What Print feeds the shared estimate. The libslic3r WipeTowerEstimate cases cannot see this:
|
||||
// they call the estimator directly. The estimate counts the filaments the print really uses,
|
||||
// so the two-filament shape gives the outer wall the second one.
|
||||
@@ -476,3 +497,4 @@ TEST_CASE("A tower printed without a tool change is still validated against the
|
||||
CHECK(print.wipe_tower_data(1).depth > 0.f);
|
||||
CHECK_THAT(print.validate().string, Catch::Matchers::ContainsSubstring("printable area"));
|
||||
}
|
||||
|
||||
@@ -1,55 +1,17 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include <clocale>
|
||||
#include <locale.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
#include <catch2/catch_message.hpp>
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
namespace {
|
||||
|
||||
// Switches this thread's numeric locale to one whose decimal separator is a comma,
|
||||
// when the system has one installed.
|
||||
struct CommaNumericLocale
|
||||
{
|
||||
#ifdef _WIN32
|
||||
bool apply()
|
||||
{
|
||||
for (const char* name : { "de-DE", "German_Germany.1252" })
|
||||
if (std::setlocale(LC_NUMERIC, name) != nullptr)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
locale_t locale { (locale_t) 0 };
|
||||
bool apply()
|
||||
{
|
||||
for (const char* name : { "de_DE.UTF-8", "de_DE.utf8", "de_DE" })
|
||||
if ((locale = newlocale(LC_NUMERIC_MASK, name, (locale_t) 0)) != (locale_t) 0) {
|
||||
uselocale(locale);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Freed once the setters around apply() have put the thread's own locale back.
|
||||
~CommaNumericLocale()
|
||||
{
|
||||
if (locale != (locale_t) 0)
|
||||
freelocale(locale);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Floats print as printf prints them in the C locale", "[LocalesUtils]")
|
||||
{
|
||||
const auto [value, precision, text] = GENERATE(table<double, int, std::string>({
|
||||
|
||||
@@ -12,12 +12,16 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/nowide/cstdlib.hpp>
|
||||
|
||||
#include <clocale>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <initializer_list>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#define PATH_SEPARATOR R"(\)"
|
||||
#else
|
||||
@@ -223,4 +227,36 @@ private:
|
||||
std::optional<std::string> m_previous;
|
||||
};
|
||||
|
||||
// Switches this thread's numeric locale to one whose decimal separator is a comma,
|
||||
// when the system has one installed.
|
||||
struct CommaNumericLocale
|
||||
{
|
||||
#ifdef _WIN32
|
||||
bool apply()
|
||||
{
|
||||
for (const char* name : { "de-DE", "German_Germany.1252" })
|
||||
if (std::setlocale(LC_NUMERIC, name) != nullptr)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
locale_t locale { (locale_t) 0 };
|
||||
bool apply()
|
||||
{
|
||||
for (const char* name : { "de_DE.UTF-8", "de_DE.utf8", "de_DE" })
|
||||
if ((locale = newlocale(LC_NUMERIC_MASK, name, (locale_t) 0)) != (locale_t) 0) {
|
||||
uselocale(locale);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Freed once the setters around apply() have put the thread's own locale back.
|
||||
~CommaNumericLocale()
|
||||
{
|
||||
if (locale != (locale_t) 0)
|
||||
freelocale(locale);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // SLIC3R_TEST_UTILS
|
||||
Reference in new issue
Block a user