Compare commits

...
Author SHA1 Message Date
Hanif Koh ebbf27147e 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.
2026-10-21 13:28:48 +08:00
SoftFever 069bd402d9 Forward CMake arguments after -- in the macOS build script (#16683)
Unknown options and missing option values now stop the script instead of being ignored.
2026-10-20 16:06:33 +08:00
5 changed files with 85 additions and 43 deletions

No files matched your search

+25 -3
View File
@@ -47,7 +47,7 @@ while getopts ":dpa:snt:xbc:i:j:Tuh" opt; do
u )
export BUILD_TARGET="universal"
;;
h ) echo "Usage: ./build_release_macos.sh [-d]"
h ) echo "Usage: ./build_release_macos.sh [-d] [-- CMAKE_ARGS...]"
echo " -d: Build deps only"
echo " -a: Set ARCHITECTURE (arm64 or x86_64 or universal)"
echo " -s: Build slicer only"
@@ -60,13 +60,33 @@ while getopts ":dpa:snt:xbc:i:j:Tuh" opt; do
echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew"
echo " -j: Set the number of parallel build jobs (CMAKE_BUILD_PARALLEL_LEVEL)"
echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)"
echo " -- CMAKE_ARGS...: pass everything after '--' to the cmake configure step of the deps (-d) and slicer (-s) builds,"
echo " e.g. -DDESTDIR=<dir> for the deps, -DCMAKE_PREFIX_PATH=<dir>/usr/local -DSLIC3R_PCH=OFF for the slicer, --fresh."
echo " They come last on the cmake command line. Use absolute paths: cmake runs in the build directory."
exit 0
;;
: )
echo "Option -${OPTARG} requires an argument, aborting."
exit 1
;;
* )
echo "Unknown option -${OPTARG}, aborting. CMake arguments must follow '--'."
exit 1
;;
esac
done
# getopts stops at '--'; whatever follows is handed to cmake unchanged.
if [[ ${OPTIND} -le $# ]] ; then
separator_index=$((OPTIND-1))
if [[ "${!separator_index}" != "--" ]] ; then
echo "Unexpected argument '${!OPTIND}': cmake arguments must follow '--', aborting."
exit 1
fi
fi
shift $((OPTIND-1))
EXTRA_CMAKE_ARGS=("$@")
# Set defaults
if [ -z "$ARCH" ]; then
@@ -211,7 +231,8 @@ function build_deps() {
-DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
-DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \
"${CMAKE_CCACHE_ARGS[@]}" \
${CMAKE_POLICY_COMPAT}
${CMAKE_POLICY_COMPAT} \
"${EXTRA_CMAKE_ARGS[@]}"
fi
cmake --build . --config "$BUILD_CONFIG" --target deps
)
@@ -314,7 +335,8 @@ function build_slicer() {
-DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
-DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \
"${CMAKE_CCACHE_ARGS[@]}" \
${CMAKE_POLICY_COMPAT}
${CMAKE_POLICY_COMPAT} \
"${EXTRA_CMAKE_ARGS[@]}"
fi
cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET"
)
+1 -1
View File
@@ -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())
+22
View File
@@ -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 -39
View File
@@ -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>({
+36
View File
@@ -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