From 6ed9b0817381042a63fa121c5f9b5cbcb11a3bfa Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Sat, 21 Jun 2025 19:08:59 +0800 Subject: [PATCH 01/13] Link libspnav statically (#9964) * Link libspnav statically * Find static libspnav * Force linking libspnav.a --- CMakeLists.txt | 6 ++---- src/slic3r/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5524e3a1e1..61efb2233c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -686,11 +686,9 @@ endif () find_path(SPNAV_INCLUDE_DIR spnav.h) if (SPNAV_INCLUDE_DIR) - find_library(HAVE_SPNAV spnav) - if (HAVE_SPNAV) + find_library(SPNAV_LIB NAMES libspnav.a) # Force linking libspnav statically + if (SPNAV_LIB) add_definitions(-DHAVE_SPNAV) - add_library(libspnav SHARED IMPORTED) - target_link_libraries(libspnav INTERFACE spnav) message(STATUS "SPNAV library found") else() message(STATUS "SPNAV library NOT found, Spacenavd not supported") diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 903b66368b..348557e679 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -658,8 +658,8 @@ if (SLIC3R_STATIC) target_compile_definitions(libslic3r_gui PUBLIC -DwxDEBUG_LEVEL=0) endif() -if (HAVE_SPNAV) - target_link_libraries(libslic3r_gui spnav) +if (SPNAV_LIB) + target_link_libraries(libslic3r_gui ${SPNAV_LIB}) endif() if (SLIC3R_STATIC AND NOT SLIC3R_STATIC_EXCLUDE_CURL AND UNIX AND NOT APPLE) From bd1281954d8ddfc33373d980ccb2798d15f3c2d6 Mon Sep 17 00:00:00 2001 From: Rodrigo <162915171+RF47@users.noreply.github.com> Date: Sun, 22 Jun 2025 02:52:12 -0300 Subject: [PATCH 02/13] Better TpmsD infill implementation (#9966) Better TpmsD implementation Better TpmsD Density Adjusted --- src/libslic3r/Fill/FillTpmsD.cpp | 548 ++++++++----------------------- src/libslic3r/Fill/FillTpmsD.hpp | 31 +- 2 files changed, 154 insertions(+), 425 deletions(-) diff --git a/src/libslic3r/Fill/FillTpmsD.cpp b/src/libslic3r/Fill/FillTpmsD.cpp index a750a61920..99692b4b68 100644 --- a/src/libslic3r/Fill/FillTpmsD.cpp +++ b/src/libslic3r/Fill/FillTpmsD.cpp @@ -1,445 +1,159 @@ -#include "../ClipperUtils.hpp" -#include "FillTpmsD.hpp" #include #include #include -#include -#include -#include -#include -// From Creality Print +//#include + +#include "../ClipperUtils.hpp" +#include "../ShortestPath.hpp" +#include "libslic3r/BoundingBox.hpp" +#include "libslic3r/Fill/FillBase.hpp" +#include "libslic3r/Point.hpp" +#include "libslic3r/Polygon.hpp" +#include "libslic3r/libslic3r.h" +#include "FillTpmsD.hpp" + namespace Slic3r { -using namespace std; -struct myPoint -{ - coord_t x, y; -}; -class LineSegmentMerger -{ -public: - void mergeSegments(const vector>& segments, vector>& polylines2) - { - std::unordered_map point_id_xy; - std::set> segment_ids; - std::unordered_map map_keyxy_pointid; - - auto get_itr = [&](coord_t x, coord_t y) { - for (auto i : {0}) //,-2,2 - { - for (auto j : {0}) //,-2,2 - { - int64_t combined_key1 = static_cast(x + i) << 32 | static_cast(y + j); - auto itr1 = map_keyxy_pointid.find(combined_key1); - if (itr1 != map_keyxy_pointid.end()) { - return itr1; - } - } - } - return map_keyxy_pointid.end(); - }; - - int pointid = 0; - for (const auto& segment : segments) { - coord_t x = segment.first.x; - coord_t y = segment.first.y; - auto itr = get_itr(x, y); - int segmentid0 = -1; - if (itr == map_keyxy_pointid.end()) { - int64_t combined_key = static_cast(x) << 32 | static_cast(y); - segmentid0 = pointid; - point_id_xy[pointid] = segment.first; - map_keyxy_pointid[combined_key] = pointid++; - } else { - segmentid0 = itr->second; - } - int segmentid1 = -1; - x = segment.second.x; - y = segment.second.y; - itr = get_itr(x, y); - if (itr == map_keyxy_pointid.end()) { - int64_t combined_key = static_cast(x) << 32 | static_cast(y); - segmentid1 = pointid; - point_id_xy[pointid] = segment.second; - map_keyxy_pointid[combined_key] = pointid++; - } else { - segmentid1 = itr->second; - } - - if (segmentid0 != segmentid1) { - segment_ids.insert(segmentid0 < segmentid1 ? std::make_pair(segmentid0, segmentid1) : - std::make_pair(segmentid1, segmentid0)); - } - } - - unordered_map> graph; - unordered_set visited; - vector> polylines; - - // Build the graph - for (const auto& segment : segment_ids) { - graph[segment.first].push_back(segment.second); - graph[segment.second].push_back(segment.first); - } - - vector startnodes; - for (const auto& node : graph) { - if (node.second.size() == 1) { - startnodes.push_back(node.first); - } - } - - // Find all connected components - for (const auto& point_first : startnodes) { - if (visited.find(point_first) == visited.end()) { - vector polyline; - dfs(point_first, graph, visited, polyline); - polylines.push_back(std::move(polyline)); - } - } - - for (const auto& point : graph) { - if (visited.find(point.first) == visited.end()) { - vector polyline; - dfs(point.first, graph, visited, polyline); - polylines.push_back(std::move(polyline)); - } - } - - for (auto& pl : polylines) { - vector tmpps; - for (auto& pid : pl) { - tmpps.push_back(point_id_xy[pid]); - } - polylines2.push_back(tmpps); - } - } - -private: - void dfs(const int& start_node, - std::unordered_map>& graph, - std::unordered_set& visited, - std::vector& polyline) - { - std::vector stack; - stack.reserve(graph.size()); - stack.push_back(start_node); - while (!stack.empty()) { - int node = stack.back(); - stack.pop_back(); - if (!visited.insert(node).second) { - continue; - } - polyline.push_back(node); - auto& neighbors = graph[node]; - for (const auto& neighbor : neighbors) { - if (visited.find(neighbor) == visited.end()) { - stack.push_back(neighbor); - } - } - } - } -}; - -namespace MarchingSquares { -struct Point -{ - double x, y; -}; - -vector getGridValues(int i, int j, vector>& data) -{ - vector values; - values.push_back(data[i][j + 1]); - values.push_back(data[i + 1][j + 1]); - values.push_back(data[i + 1][j]); - values.push_back(data[i][j]); - return values; -} -bool needContour(double value, double contourValue) { return value >= contourValue; } -Point interpolate(std::vector>& posxy, - std::vector p1ij, - std::vector p2ij, - double v1, - double v2, - double contourValue) -{ - Point p1; - p1.x = posxy[p1ij[0]][p1ij[1]].x; - p1.y = posxy[p1ij[0]][p1ij[1]].y; - Point p2; - p2.x = posxy[p2ij[0]][p2ij[1]].x; - p2.y = posxy[p2ij[0]][p2ij[1]].y; - - double mu = (contourValue - v1) / (v2 - v1); - Point p; - p.x = p1.x + mu * (p2.x - p1.x); - p.y = p1.y + mu * (p2.y - p1.y); - return p; +static double scaled_floor(double x,double scale){ + return std::floor(x/scale)*scale; } -void process_block(int i, - int j, - vector>& data, - double contourValue, - std::vector>& posxy, - vector& contourPoints) +static Polylines make_waves(double gridZ, double density_adjusted, double line_spacing, double width, double height) { - vector values = getGridValues(i, j, data); - vector isNeedContour; - for (double value : values) { - isNeedContour.push_back(needContour(value, contourValue)); - } - int index = 0; - if (isNeedContour[0]) - index |= 1; - if (isNeedContour[1]) - index |= 2; - if (isNeedContour[2]) - index |= 4; - if (isNeedContour[3]) - index |= 8; - vector points; - switch (index) { - case 0: - case 15: break; + const double scaleFactor = scale_(line_spacing) / density_adjusted; - case 1: - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); + // tolerance in scaled units. clamp the maximum tolerance as there's + // no processing-speed benefit to do so beyond a certain point + const double tolerance = std::min(line_spacing / 2, FillTpmsD::PatternTolerance) / unscale(scaleFactor); - break; - case 14: - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - break; + //scale factor for 5% : 8 712 388 + // 1z = 10^-6 mm ? + const double z = gridZ / scaleFactor; + Polylines result; - case 2: - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - - break; - case 13: - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - break; - case 3: - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); - - break; - case 12: - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - - break; - case 4: - points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - - break; - case 11: - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue)); - break; - case 5: - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); - points.push_back(interpolate(posxy, {i, j}, {i + 1, j}, values[3], values[2], contourValue)); - - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - break; - case 6: - points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue)); - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - - break; - case 9: - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue)); - break; - case 7: - points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue)); - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); - - break; - case 8: - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j}, {i, j}, values[2], values[3], contourValue)); - break; - case 10: - points.push_back(interpolate(posxy, {i, j}, {i, j + 1}, values[3], values[0], contourValue)); - points.push_back(interpolate(posxy, {i, j}, {i + 1, j}, values[3], values[2], contourValue)); - - points.push_back(interpolate(posxy, {i, j + 1}, {i + 1, j + 1}, values[0], values[1], contourValue)); - points.push_back(interpolate(posxy, {i + 1, j + 1}, {i + 1, j}, values[1], values[2], contourValue)); - break; - } - for (Point& p : points) { - contourPoints.push_back(p); - } + //sin(x)*sin(y)*sin(z)-cos(x)*cos(y)*cos(z)=0 + //2*sin(x)*sin(y)*sin(z)-2*cos(x)*cos(y)*cos(z)=0 + //(cos(x-y)-cos(x+y))*sin(z)-(cos(x-y)+cos(x+y))*cos(z)=0 + //(sin(z)-cos(z))*cos(x-y)-(sin(z)+cos(z))*cos(x+y)=0 + double a=sin(z)-cos(z); + double b=sin(z)+cos(z); + //a*cos(x-y)-b*cos(x+y)=0 + //u=x-y, v=x+y + double minU=0-height; + double maxU=width-0; + double minV=0+0; + double maxV=width+height; + //a*cos(u)-b*cos(v)=0 + //if abs(b)std::abs(b)); + if(swapUV) { + std::swap(a,b); + std::swap(minU,minV); + std::swap(maxU,maxV); + } + std::vector> wave; + {//fill one wave + const auto v=[&](double u){return acos(a/b*cos(u));}; + for(int c=0;c<=4;++c){ + const double u=minU+2*M_PI*c/4; + wave.emplace_back(u,v(u)); + } + {//refine + int current=0; + while(current+1tolerance) + wave.emplace(wave.begin()+current+1,middleU,middleV); + else + ++current; + } + } + for(int c=1;c>& data, - std::vector>& posxy, - Polylines& repls) +// FIXME: needed to fix build on Mac on buildserver +constexpr double FillTpmsD::PatternTolerance; + +void FillTpmsD::_fill_surface_single( + const FillParams ¶ms, + unsigned int thickness_layers, + const std::pair &direction, + ExPolygon expolygon, + Polylines &polylines_out) { - vector contourPoints; - int total_size = (gridSize_h - 1) * (gridSize_w - 1); - vector> contourPointss; - contourPointss.resize(total_size); - tbb::parallel_for(tbb::blocked_range(0, total_size), - [&contourValue, &posxy, &contourPointss, &data, &gridSize_w](const tbb::blocked_range& range) { - for (size_t k = range.begin(); k < range.end(); ++k) { - int i = k / (gridSize_w - 1); // - int j = k % (gridSize_w - 1); // - process_block(i, j, data, contourValue, posxy, contourPointss[k]); - } - }); - - vector> segments2; - myPoint p1, p2; - for (int k = 0; k < total_size; k++) { - for (int i = 0; i < contourPointss[k].size() / 2; i++) { - p1.x = scale_(contourPointss[k][i * 2].x); - p1.y = scale_(contourPointss[k][i * 2].y); - p2.x = scale_(contourPointss[k][i * 2 + 1].x); - p2.y = scale_(contourPointss[k][i * 2 + 1].y); - segments2.push_back({p1, p2}); - } - } - - LineSegmentMerger merger; - vector> result; - merger.mergeSegments(segments2, result); - - for (vector& p : result) { - Polyline repltmp; - for (myPoint& pt : p) { - repltmp.points.push_back(Slic3r::Point(pt.x, pt.y)); - } - repltmp.simplify(scale_(0.05f)); - repls.push_back(repltmp); - } -} -} // namespace MarchingSquares - -static float sin_table[360]; -static float cos_table[360]; -static bool g_is_init = false; - -#define PIratio 57.29577951308232 // 180/PI -static void initialize_lookup_tables() -{ - for (int i = 0; i < 360; ++i) { - float angle = i * (M_PI / 180.0); - sin_table[i] = std::sin(angle); - cos_table[i] = std::cos(angle); - } -} - -static float get_sin(float angle) -{ - angle = angle * PIratio; - int index = static_cast(std::fmod(angle, 360) + 360) % 360; - return sin_table[index]; -} - -static float get_cos(float angle) -{ - angle = angle * PIratio; - int index = static_cast(std::fmod(angle, 360) + 360) % 360; - return cos_table[index]; -} - -FillTpmsD::FillTpmsD() -{ - if (!g_is_init) { - initialize_lookup_tables(); - g_is_init = true; - } -} -void FillTpmsD::_fill_surface_single(const FillParams& params, - unsigned int thickness_layers, - const std::pair& direction, - ExPolygon expolygon, - Polylines& polylines_out) -{ - auto infill_angle = float(this->angle - (CorrectionAngle * 2 * M_PI) / 360.); - if (std::abs(infill_angle) >= EPSILON) + auto infill_angle = float(this->angle + (CorrectionAngle * 2*M_PI) / 360.); + if(std::abs(infill_angle) >= EPSILON) expolygon.rotate(-infill_angle); - float vari_T = 2.98 * spacing / params.density; // Infill density adjustment factor for TPMS-D + BoundingBox bb = expolygon.contour.bounding_box(); + // Density adjusted to have a good %of weight. + double density_adjusted = std::max(0., params.density * DensityAdjust); + // Distance between the gyroid waves in scaled coordinates. + coord_t distance = coord_t(scale_(this->spacing) / density_adjusted); - BoundingBox bb = expolygon.contour.bounding_box(); - auto cenpos = unscale(bb.center()); - auto boxsize = unscale(bb.size()); - float xlen = boxsize.x(); - float ylen = boxsize.y(); + // align bounding box to a multiple of our grid module + bb.merge(align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance))); - float delta = 0.25f; - float myperiod = 2 * PI / vari_T; - float c_z = myperiod * this->z; - float cos_z = get_cos(c_z); - float sin_z = get_sin(c_z); + // generate pattern + Polylines polylines = make_waves( + scale_(this->z), + density_adjusted, + this->spacing, + ceil(bb.size()(0) / distance) + 1., + ceil(bb.size()(1) / distance) + 1.); - auto scalar_field = [&](float x, float y) { - // TPMS-D - float a_x = myperiod * x; - float b_y = myperiod * y; - float r = get_cos(a_x) * get_cos(b_y) * cos_z - get_sin(a_x) * get_sin(b_y) * sin_z; - return r; - }; + // shift the polyline to the grid origin + for (Polyline &pl : polylines) + pl.translate(bb.min); + - std::vector> posxy; - int i = 0, j = 0; - std::vector allptpos; - for (float y = -(ylen) / 2.0f - 2; y < (ylen) / 2.0f + 2; y = y + delta, i++) { - j = 0; - std::vector colposxy; - for (float x = -(xlen) / 2.0f - 2; x < (xlen) / 2.0f + 2; x = x + delta, j++) { - MarchingSquares::Point pt; - pt.x = cenpos.x() + x; - pt.y = cenpos.y() + y; - colposxy.push_back(pt); - } - posxy.push_back(colposxy); + polylines = intersection_pl(polylines, expolygon); + + if (! polylines.empty()) { + // Remove very small bits, but be careful to not remove infill lines connecting thin walls! + // The infill perimeter lines should be separated by around a single infill line width. + const double minlength = scale_(0.8 * this->spacing); + polylines.erase( + std::remove_if(polylines.begin(), polylines.end(), [minlength](const Polyline &pl) { return pl.length() < minlength; }), + polylines.end()); } - std::vector> data(posxy.size(), std::vector(posxy[0].size())); - - int width = posxy[0].size(); - int height = posxy.size(); - int total_size = (height) * (width); - tbb::parallel_for(tbb::blocked_range(0, total_size), - [&width, &scalar_field, &data, &posxy](const tbb::blocked_range& range) { - for (size_t k = range.begin(); k < range.end(); ++k) { - int i = k / (width); - int j = k % (width); - data[i][j] = scalar_field(posxy[i][j].x, posxy[i][j].y); - } - }); - - Polylines polylines; - MarchingSquares::drawContour(0, j, i, data, posxy, polylines); - - polylines = intersection_pl(polylines, expolygon); - - if (!polylines.empty()) { - // connect lines - size_t polylines_out_first_idx = polylines_out.size(); - if (params.dont_connect()) - append(polylines_out, chain_polylines(polylines)); + if (! polylines.empty()) { + // connect lines + size_t polylines_out_first_idx = polylines_out.size(); + if (params.dont_connect()) + append(polylines_out, chain_polylines(polylines)); else this->connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params); - // new paths must be rotated back + + // new paths must be rotated back if (std::abs(infill_angle) >= EPSILON) { - for (auto it = polylines_out.begin() + polylines_out_first_idx; it != polylines_out.end(); ++it) - it->rotate(infill_angle); - } + for (auto it = polylines_out.begin() + polylines_out_first_idx; it != polylines_out.end(); ++ it) + it->rotate(infill_angle); + } } } diff --git a/src/libslic3r/Fill/FillTpmsD.hpp b/src/libslic3r/Fill/FillTpmsD.hpp index cf5d5f69fa..73b55e1e1c 100644 --- a/src/libslic3r/Fill/FillTpmsD.hpp +++ b/src/libslic3r/Fill/FillTpmsD.hpp @@ -1,31 +1,46 @@ #ifndef slic3r_FillTpmsD_hpp_ #define slic3r_FillTpmsD_hpp_ -#include "../libslic3r.h" +#include + +#include "libslic3r/libslic3r.h" #include "FillBase.hpp" +#include "libslic3r/ExPolygon.hpp" +#include "libslic3r/Polyline.hpp" namespace Slic3r { +class Point; class FillTpmsD : public Fill { public: - FillTpmsD(); + FillTpmsD() {} Fill* clone() const override { return new FillTpmsD(*this); } // require bridge flow since most of this pattern hangs in air bool use_bridge_flow() const override { return false; } + // Correction applied to regular infill angle to maximize printing // speed in default configuration (degrees) static constexpr float CorrectionAngle = -45.; - void _fill_surface_single(const FillParams& params, - unsigned int thickness_layers, - const std::pair& direction, - ExPolygon expolygon, - Polylines& polylines_out) override; + // Density adjustment to have a good %of weight. + static constexpr double DensityAdjust = 2.1; + + // Gyroid upper resolution tolerance (mm^-2) + static constexpr double PatternTolerance = 0.1; + + +protected: + void _fill_surface_single( + const FillParams ¶ms, + unsigned int thickness_layers, + const std::pair &direction, + ExPolygon expolygon, + Polylines &polylines_out) override; }; } // namespace Slic3r -#endif // slic3r_FillTpmsD_hpp_ +#endif // slic3r_FillTpmsD_hpp_ \ No newline at end of file From fa70582ed164b0f8bb507a861a0a58c51cafec16 Mon Sep 17 00:00:00 2001 From: Alexandre Folle de Menezes Date: Sun, 22 Jun 2025 04:10:40 -0300 Subject: [PATCH 03/13] Standard units don't need translation (#9965) --- localization/i18n/OrcaSlicer.pot | 12 +- localization/i18n/ca/OrcaSlicer_ca.po | 19 +- localization/i18n/cs/OrcaSlicer_cs.po | 18 +- localization/i18n/de/OrcaSlicer_de.po | 16 +- localization/i18n/en/OrcaSlicer_en.po | 10 +- localization/i18n/es/OrcaSlicer_es.po | 22 +- localization/i18n/fr/OrcaSlicer_fr.po | 27 +- localization/i18n/hu/OrcaSlicer_hu.po | 12 +- localization/i18n/it/OrcaSlicer_it.po | 28 +- localization/i18n/ja/OrcaSlicer_ja.po | 12 +- localization/i18n/ko/OrcaSlicer_ko.po | 16 +- localization/i18n/lt/OrcaSlicer_lt.po | 16 +- localization/i18n/nl/OrcaSlicer_nl.po | 12 +- localization/i18n/pl/OrcaSlicer_pl.po | 20 +- localization/i18n/pt_BR/OrcaSlicer_pt_BR.po | 24 +- localization/i18n/ru/OrcaSlicer_ru.po | 12 +- localization/i18n/sv/OrcaSlicer_sv.po | 12 +- localization/i18n/tr/OrcaSlicer_tr.po | 18 +- localization/i18n/uk/OrcaSlicer_uk.po | 12 +- localization/i18n/zh_CN/OrcaSlicer_zh_CN.po | 15 +- localization/i18n/zh_TW/OrcaSlicer_zh_TW.po | 16 +- src/libslic3r/PrintConfig.cpp | 414 +++++++++--------- src/slic3r/GUI/BedShapeDialog.cpp | 6 +- .../GUI/CalibrationWizardPresetPage.cpp | 6 +- src/slic3r/GUI/ConfigWizard.cpp | 10 +- src/slic3r/GUI/CreatePresetsDialog.cpp | 10 +- src/slic3r/GUI/DeviceManager.cpp | 6 +- src/slic3r/GUI/ExtrusionCalibration.cpp | 6 +- src/slic3r/GUI/GCodeViewer.cpp | 6 +- src/slic3r/GUI/GUI_ObjectLayers.cpp | 4 +- src/slic3r/GUI/ObjectDataViewModel.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/RammingChart.cpp | 4 +- src/slic3r/GUI/WipeTowerDialog.cpp | 8 +- src/slic3r/GUI/calib_dlg.cpp | 30 +- 35 files changed, 434 insertions(+), 429 deletions(-) diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot index 2a82a9b6b9..c894f59848 100644 --- a/localization/i18n/OrcaSlicer.pot +++ b/localization/i18n/OrcaSlicer.pot @@ -11517,7 +11517,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -11527,13 +11527,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -12952,7 +12952,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/ca/OrcaSlicer_ca.po b/localization/i18n/ca/OrcaSlicer_ca.po index 370383e1eb..32c8f173e2 100644 --- a/localization/i18n/ca/OrcaSlicer_ca.po +++ b/localization/i18n/ca/OrcaSlicer_ca.po @@ -13264,7 +13264,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13274,13 +13274,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13303,13 +13303,13 @@ msgstr "" "això, pot proporcionar algun benefici marginal en certs casos en què les " "velocitats de les característiques varien molt. Per exemple, quan hi ha " "desacceleracions agressives a causa dels voladissos. En aquests casos es " -"recomana un valor elevat d'uns 300-350mm3/s2, ja que això permet un " +"recomana un valor elevat d'uns 300-350 mm³/s², ja que això permet un " "suavitzat suficient per ajudar a avançar la pressió a aconseguir una " "transició de flux més suau.\n" "\n" "Per a impressores més lentes sense Avanç de Pressió, el valor s'ha " -"d'establir molt més baix. Un valor de 10-15mm3/s2 és un bon punt de partida " -"per als extrusors d'extrusió directa i 5-10mm3/s2 per al tipus Bowden.\n" +"d'establir molt més baix. Un valor de 10-15 mm³/s² és un bon punt de partida " +"per als extrusors d'extrusió directa i 5-10 mm³/s² per al tipus Bowden.\n" "\n" "Aquesta característica es coneix com a Equalitzador de Pressió a Prusa " "slicer.\n" @@ -15126,6 +15126,7 @@ msgstr "" msgid "Maximum wipe tower print speed" msgstr "Velocitat màxima d'impressió de la torre de purga" +#, fuzzy msgid "" "The maximum print speed when purging in the wipe tower and printing the wipe " "tower sparse layers. When purging, if the sparse infill speed or calculated " @@ -15140,7 +15141,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/cs/OrcaSlicer_cs.po b/localization/i18n/cs/OrcaSlicer_cs.po index e280ce94ba..036cc163bf 100644 --- a/localization/i18n/cs/OrcaSlicer_cs.po +++ b/localization/i18n/cs/OrcaSlicer_cs.po @@ -12375,7 +12375,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -12385,13 +12385,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -12411,13 +12411,13 @@ msgstr "" "lab nebo Voron) tato hodnota obvykle není potřebná. Nicméně v některých " "případech, kde se rychlosti funkcí výrazně liší, může poskytnout marginální " "přínos. Například při agresivních zpomaleních způsobených přesahy. V těchto " -"případech se doporučuje vysoká hodnota kolem 300-350 mm3/s2, protože to " +"případech se doporučuje vysoká hodnota kolem 300-350 mm³/s², protože to " "umožňuje dostatečné vyhlazení pro pomoc při dosažení plynulejšího přechodu " "tlaku při extruzi.\n" "\n" "Pro pomalejší tiskárny bez tlakového předstihu by měla být hodnota nastavena " -"mnohem nižší. Pro přímé pohony je hodnota 10-15 mm3/s2 dobrým výchozím " -"bodem, a pro styl Bowden 5-10 mm3/s2.\n" +"mnohem nižší. Pro přímé pohony je hodnota 10-15 mm³/s² dobrým výchozím " +"bodem, a pro styl Bowden 5-10 mm³/s².\n" "\n" "Tato funkce je známa jako Pressure Equalizer v programu Prusa Slicer.\n" "\n" @@ -14031,7 +14031,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/de/OrcaSlicer_de.po b/localization/i18n/de/OrcaSlicer_de.po index 31d843f404..bc2750f932 100644 --- a/localization/i18n/de/OrcaSlicer_de.po +++ b/localization/i18n/de/OrcaSlicer_de.po @@ -13372,7 +13372,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13382,13 +13382,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13411,7 +13411,7 @@ msgstr "" "erforderlich. Er kann jedoch in bestimmten Fällen einen geringfügigen " "Vorteil bieten, in denen sich die Funktionen stark unterscheiden. Zum " "Beispiel, wenn es aggressive Verlangsamungen aufgrund von Überhängen gibt. " -"In diesen Fällen wird ein hoher Wert von ca. 300-350mm3/s2 empfohlen, da " +"In diesen Fällen wird ein hoher Wert von ca. 300-350 mm³/s² empfohlen, da " msgid "mm³/s²" msgstr "" @@ -15244,7 +15244,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" @@ -19600,7 +19600,7 @@ msgstr "" #~ "is lower, the lowest speed will be used instead.\n" #~ "Increasing this speed may affect the tower's stability, as purging can be " #~ "performed over sparse layers. Before increasing this parameter beyond the " -#~ "default of 90mm/sec, make sure your printer can reliably bridge at the " +#~ "default of 90 mm/s, make sure your printer can reliably bridge at the " #~ "increased speeds." #~ msgstr "" #~ "Die maximale Druckgeschwindigkeit beim Reinigen im Reinigungsturm. Wenn " diff --git a/localization/i18n/en/OrcaSlicer_en.po b/localization/i18n/en/OrcaSlicer_en.po index 43828620d7..c8f9554a4d 100644 --- a/localization/i18n/en/OrcaSlicer_en.po +++ b/localization/i18n/en/OrcaSlicer_en.po @@ -11851,7 +11851,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -11861,13 +11861,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " "for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13356,7 +13356,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/es/OrcaSlicer_es.po b/localization/i18n/es/OrcaSlicer_es.po index 6242ca4af7..018f5738f1 100644 --- a/localization/i18n/es/OrcaSlicer_es.po +++ b/localization/i18n/es/OrcaSlicer_es.po @@ -13141,7 +13141,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13151,13 +13151,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13168,7 +13168,7 @@ msgstr "" "(alta velocidad/ancho mayor) a una extrusión de menor flujo (menor velocidad/" "ancho menor) y viceversa.\n" "\n" -"Define la velocidad máxima a la que el flujo volumétrico extruido en mm3/seg " +"Define la velocidad máxima a la que el flujo volumétrico extruido en mm³/s² " "puede cambiar con el tiempo. Valores más altos significan que se permiten " "cambios de velocidad de extrusión más altos, lo que resulta en transiciones " "de velocidad más rápidas.\n" @@ -13180,13 +13180,13 @@ msgstr "" "embargo, puede proporcionar algún beneficio marginal en ciertos casos en los " "que las velocidades de las características varían mucho. Por ejemplo, cuando " "hay ralentizaciones agresivas debidas a voladizos. En estos casos, se " -"recomienda un valor alto de alrededor de 300-350 mm3/s2, ya que esto permite " +"recomienda un valor alto de alrededor de 300-350 mm³/s², ya que esto permite " "el suavizado suficiente para ayudar al avance de presión a lograr una " "transición de flujo más suave.\n" "\n" "Para impresoras más lentas sin avance de presión, el valor debe fijarse " -"mucho más bajo. Un valor de 10-15mm3/s2 es un buen punto de partida para " -"extrusoras de accionamiento directo y de 5-10mm3/s2 para las de estilo " +"mucho más bajo. Un valor de 10-15 mm³/s² es un buen punto de partida para " +"extrusoras de accionamiento directo y de 5-10 mm³/s² para las de estilo " "Bowden.\n" "\n" "Esta característica es conocida como Pressure Equalizer en Prusa slicer.\n" @@ -14995,7 +14995,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" @@ -15016,7 +15016,7 @@ msgstr "" "aumentar la fuerza con la que la boquilla colisiona con las acummulaciones " "que se hayan podido formar en la torre de purga.\n" "\n" -"Antes de aumentar este parámetro más allá del valor por defecto de 90mm/seg, " +"Antes de aumentar este parámetro más allá del valor por defecto de 90mm/s, " "asegúrese de que su impresora puede puentear de forma fiable a las " "velocidades aumentadas y que el rezume al cambiar de cabezal está bien " "controlado.\n" diff --git a/localization/i18n/fr/OrcaSlicer_fr.po b/localization/i18n/fr/OrcaSlicer_fr.po index 51d8bc425e..5a02f47028 100644 --- a/localization/i18n/fr/OrcaSlicer_fr.po +++ b/localization/i18n/fr/OrcaSlicer_fr.po @@ -13441,7 +13441,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13451,13 +13451,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13468,7 +13468,7 @@ msgstr "" "élevée / largeur de ligne plus grande) à une extrusion à débit plus faible " "(vitesse plus faible / largeur de ligne plus petite) et vice versa.\n" "\n" -"Il définit le taux maximum auquel le débit volumétrique extrudé en mm3/sec " +"Il définit le taux maximum auquel le débit volumétrique extrudé en mm³/s² " "peut varier dans le temps. Des valeurs plus élevées signifient que des " "changements du taux d’extrusion plus élevés sont autorisés, ce qui entraîne " "des transitions de vitesse plus rapides.\n" @@ -13480,13 +13480,13 @@ msgstr "" "Cependant, cela peut apporter un avantage marginal dans certains cas où les " "vitesses varient considérablement. Par exemple, en cas de ralentissements " "agressifs dus à des surplombs. Dans ces cas, une valeur élevée d’environ " -"300-350 mm3/s2 est recommandée car elle permet un lissage juste suffisant " +"300-350 mm³/s² est recommandée car elle permet un lissage juste suffisant " "pour aider l’augmentation de la pression pour obtenir une transition de " "débit plus douce.\n" "\n" "Pour les imprimantes plus lentes sans fonction de pressure advance, la " -"valeur doit être réglée beaucoup plus bas. Une valeur de 10-15 mm3/s2 est un " -"bon point de départ en direct drive et de 5-10 mm3/s2 en Bowden.\n" +"valeur doit être réglée beaucoup plus bas. Une valeur de 10-15 mm³/s² est un " +"bon point de départ en direct drive et de 5-10 mm³/s² en Bowden.\n" "\n" "Cette fonctionnalité est connue sous le nom de Pressure Equalizer dans Prusa " "Slicer.\n" @@ -15323,6 +15323,7 @@ msgstr "" msgid "Maximum wipe tower print speed" msgstr "Vitesse maximale d’impression de la tour d’essuyage" +#, fuzzy msgid "" "The maximum print speed when purging in the wipe tower and printing the wipe " "tower sparse layers. When purging, if the sparse infill speed or calculated " @@ -15337,7 +15338,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" @@ -15358,7 +15359,7 @@ msgstr "" "augmenter la force avec laquelle la buse entre en collision avec les blobs " "qui peuvent s’être formés sur la tour d’essuyage.\n" "\n" -"Avant d’augmenter ce paramètre au-delà de la valeur par défaut de 90 mm/sec, " +"Avant d’augmenter ce paramètre au-delà de la valeur par défaut de 90 mm/s, " "assurez-vous que votre imprimante peut effectuer un pontage fiable à des " "vitesses élevées et que le suintement lors du changement d’outil est bien " "contrôlé.\n" @@ -19841,7 +19842,7 @@ msgstr "" #~ "is lower, the lowest speed will be used instead.\n" #~ "Increasing this speed may affect the tower's stability, as purging can be " #~ "performed over sparse layers. Before increasing this parameter beyond the " -#~ "default of 90mm/sec, make sure your printer can reliably bridge at the " +#~ "default of 90 mm/s, make sure your printer can reliably bridge at the " #~ "increased speeds." #~ msgstr "" #~ "Vitesse d’impression maximale lors de la purge dans la tour d’essuyage. " @@ -19850,7 +19851,7 @@ msgstr "" #~ "vitesse la plus basse qui sera utilisée.\n" #~ "L’augmentation de cette vitesse peut affecter la stabilité de la tour, " #~ "car la purge peut être effectuée sur des couches peu épaisses. Avant " -#~ "d’augmenter ce paramètre au-delà de la valeur par défaut de 90 mm/sec, " +#~ "d’augmenter ce paramètre au-delà de la valeur par défaut de 90 mm/s, " #~ "assurez-vous que votre imprimante peut effectuer un pontage fiable aux " #~ "vitesses accrues." diff --git a/localization/i18n/hu/OrcaSlicer_hu.po b/localization/i18n/hu/OrcaSlicer_hu.po index d787017ca4..77f50f0f84 100644 --- a/localization/i18n/hu/OrcaSlicer_hu.po +++ b/localization/i18n/hu/OrcaSlicer_hu.po @@ -12170,7 +12170,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -12180,13 +12180,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13760,7 +13760,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index 2387d447cd..b305c28c4d 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -13355,7 +13355,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13365,13 +13365,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13383,8 +13383,8 @@ msgstr "" "un'estrusione a basso flusso (bassa velocità/larghezza inferiore) e " "viceversa.\n" "\n" -"Definisce la velocità massima con cui la portata volumetrica estrusa in mm3/" -"sec può variare nel tempo. Valori più alti significano che sono consentite " +"Definisce la velocità massima con cui la portata volumetrica estrusa in mm³/" +"s² può variare nel tempo. Valori più alti significano che sono consentite " "variazioni più elevate della velocità di estrusione, con conseguenti " "transizioni di velocità più rapide.\n" "\n" @@ -13395,14 +13395,14 @@ msgstr "" "può fornire alcuni vantaggi marginali in alcuni casi in cui le velocità di " "stampa di alcuni elementi variano notevolmente, ad esempio quando ci sono " "rallentamenti aggressivi dovuti a sporgenze. In questi casi si consiglia un " -"valore elevato di circa 300-350 mm3/s2 in quanto ciò consente un " +"valore elevato di circa 300-350 mm³/s² in quanto ciò consente un " "livellamento sufficiente per aiutare l'anticipo di pressione a ottenere una " "transizione di flusso più graduale.\n" "\n" "Per le stampanti più lente senza anticipo di pressione, l'opzione deve " -"essere impostata su un valore molto più basso. Un valore di 10-15 mm3/s2 è " +"essere impostata su un valore molto più basso. Un valore di 10-15 mm³/s² è " "un buon punto di partenza per gli estrusori a trasmissione diretta e di 5-10 " -"mm3/s2 per quelli Bowden.\n" +"mm³/s² per quelli Bowden.\n" "\n" "Questa funzione è nota come Equalizzatore di Pressione in Prusa slicer.\n" "\n" @@ -15256,7 +15256,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" @@ -15276,9 +15276,9 @@ msgstr "" "aumentare la forza con cui l'ugello entra in collisione con eventuali grumi " "che si sono formati sulla torre di spurgo.\n" "\n" -"Prima di aumentare questo parametro oltre il valore predefinito di 90 mm/" -"sec, accertati che la stampante sia in grado di gestire in modo affidabile " -"le maggiori velocità, e che il trasudo del materiale durante il cambio di " +"Prima di aumentare questo parametro oltre il valore predefinito di 90 mm/s, " +"accertati che la stampante sia in grado di gestire in modo affidabile le " +"maggiori velocità, e che il trasudo del materiale durante il cambio di " "testina sia ben controllato.\n" "\n" "Per i perimetri esterni della torre di spurgo viene utilizzata la velocità " diff --git a/localization/i18n/ja/OrcaSlicer_ja.po b/localization/i18n/ja/OrcaSlicer_ja.po index 1015f67fff..9df1755cc8 100644 --- a/localization/i18n/ja/OrcaSlicer_ja.po +++ b/localization/i18n/ja/OrcaSlicer_ja.po @@ -11895,7 +11895,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -11905,13 +11905,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13427,7 +13427,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/ko/OrcaSlicer_ko.po b/localization/i18n/ko/OrcaSlicer_ko.po index 9a2ebe6a87..ed8dc910bd 100644 --- a/localization/i18n/ko/OrcaSlicer_ko.po +++ b/localization/i18n/ko/OrcaSlicer_ko.po @@ -12686,7 +12686,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -12696,12 +12696,12 @@ msgid "" "Voron) this value is usually not needed. However it can provide some marginal " "benefit in certain cases where feature speeds vary greatly. For example, when " "there are aggressive slowdowns due to overhangs. In these cases a high value " -"of around 300-350mm3/s2 is recommended as this allows for just enough " +"of around 300-350 mm³/s² is recommended as this allows for just enough " "smoothing to assist pressure advance achieve a smoother flow transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -12720,13 +12720,13 @@ msgstr "" "고속, 고압출량 직접 구동 프린터(예: 뱀부랩 또는 보론)의 경우 일반적으로 이 값" "이 필요하지 않습니다. 그러나 기능 속도가 크게 달라지는 특정 경우에는 약간의 이" "점을 제공할 수 있습니다. 예를 들어 오버행로 인해 급격하게 감속이 발생하는 경우" -"입니다. 이러한 경우 약 300-350mm3/s2의 높은 값이 권장됩니다. 이렇게 하면 프레" +"입니다. 이러한 경우 약 300-350 mm³/s²의 높은 값이 권장됩니다. 이렇게 하면 프레" "셔 어드밴스가 더 부드러운 압출량 전환을 달성하는 데 도움이 될 만큼 충분히 매끄" "러워질 수 있기 때문입니다.\n" "\n" "프레셔 어드밴스 기능이 없는 느린 프린터의 경우 값을 훨씬 낮게 설정해야 합니" -"다. 10-15mm3/s2 값은 직접 구동 압출기의 좋은 시작점이고 보우덴 스타일의 경우 " -"5-10mm3/s2입니다.\n" +"다. 10-15 mm³/s² 값은 직접 구동 압출기의 좋은 시작점이고 보우덴 스타일의 경우 " +"5-10 mm³/s²입니다.\n" "\n" "이 기능은 Prusa 슬라이서에서는 프레셔 이퀄라이저(Pressure Equalizer)로 알려져 " "있습니다.\n" @@ -14419,7 +14419,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/lt/OrcaSlicer_lt.po b/localization/i18n/lt/OrcaSlicer_lt.po index d892883656..0a3c917ebb 100644 --- a/localization/i18n/lt/OrcaSlicer_lt.po +++ b/localization/i18n/lt/OrcaSlicer_lt.po @@ -13160,7 +13160,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13170,13 +13170,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13197,13 +13197,13 @@ msgstr "" "\"Bambu lab\" arba \"Voron\") ši vertė paprastai nereikalinga. Tačiau tam " "tikrais atvejais, kai funkcijos greičiai labai skiriasi, ji gali duoti " "nedidelę naudą. Pavyzdžiui, kai yra agresyvių sulėtėjimų dėl iškyšų. Tokiais " -"atvejais rekomenduojama didelė vertė, maždaug 300-350 mm3/s2 , nes tai " +"atvejais rekomenduojama didelė vertė, maždaug 300-350 mm³/s² , nes tai " "leidžia pakankamai išlyginti, kad padedant slėgio avansui būtų pasiektas " "sklandesnis srauto perėjimas.\n" "\n" "Lėtesniems spausdintuvams, kuriuose nėra slėgio didinimo, vertė turėtų būti " "nustatyta daug mažesnė. Tiesioginės pavaros ekstruderiams gera pradinė vertė " -"yra 10-15 mm3/s2, o Bowdeno tipo ekstruderiams - 5-10 mm3/s2.\n" +"yra 10-15 mm³/s², o Bowdeno tipo ekstruderiams - 5-10 mm³/s².\n" "\n" "Ši funkcija \"Prusa\" programoje \"Prusa slicer\" vadinama slėgio išlyginimo " "funkcija.\n" @@ -14997,7 +14997,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/nl/OrcaSlicer_nl.po b/localization/i18n/nl/OrcaSlicer_nl.po index 1d0b11e891..60891c7b7b 100644 --- a/localization/i18n/nl/OrcaSlicer_nl.po +++ b/localization/i18n/nl/OrcaSlicer_nl.po @@ -12362,7 +12362,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -12372,13 +12372,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13974,7 +13974,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/pl/OrcaSlicer_pl.po b/localization/i18n/pl/OrcaSlicer_pl.po index cb29061de1..747dd49871 100644 --- a/localization/i18n/pl/OrcaSlicer_pl.po +++ b/localization/i18n/pl/OrcaSlicer_pl.po @@ -13193,7 +13193,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13203,13 +13203,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13232,13 +13232,13 @@ msgstr "" "potrzebna. Może ona jednak zapewnić pewne marginalne korzyści w niektórych " "przypadkach, gdy prędkości funkcji znacznie się różnią. Na przykład, gdy " "występują agresywne spowolnienia spowodowane nawisami. W takich przypadkach " -"zalecana jest wysoka wartość około 300-350 mm3/s2, ponieważ pozwala to na " +"zalecana jest wysoka wartość około 300-350 mm³/s², ponieważ pozwala to na " "wystarczające wygładzenie, aby wspomóc wzrost ciśnienia w celu uzyskania " "płynniejszego przejścia przepływu.\n" "\n" "W przypadku wolniejszych drukarek bez przyspieszenia ciśnienia wartość ta " -"powinna być znacznie niższa. Wartość 10-15 mm3/s2 jest dobrym punktem " -"wyjścia dla extruderów z napędem bezpośrednim i 5-10 mm3/s2 dla extruderów " +"powinna być znacznie niższa. Wartość 10-15 mm³/s² jest dobrym punktem " +"wyjścia dla extruderów z napędem bezpośrednim i 5-10 mm³/s² dla extruderów " "typu Bowden.\n" "\n" "Ta funkcja jest znana jako Pressure Equalizer w Prusa slicer.\n" @@ -15055,7 +15055,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" @@ -19260,7 +19260,7 @@ msgstr "" #~ "is lower, the lowest speed will be used instead.\n" #~ "Increasing this speed may affect the tower's stability, as purging can be " #~ "performed over sparse layers. Before increasing this parameter beyond the " -#~ "default of 90mm/sec, make sure your printer can reliably bridge at the " +#~ "default of 90 mm/s, make sure your printer can reliably bridge at the " #~ "increased speeds." #~ msgstr "" #~ "Maksymalna prędkość drukowania podczas oczyszczania w wieży czyszczącej. " diff --git a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po index 5f467865af..2ea8c9c909 100644 --- a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po +++ b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po @@ -13226,7 +13226,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13236,13 +13236,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13253,7 +13253,7 @@ msgstr "" "velocidade/maior largura) para uma extrusão de baixo fluxo (baixa velocidade/" "menor largura) e vice-versa.\n" "\n" -"Define a taxa máxima pela qual o fluxo volumétrico extrudado em mm3/seg pode " +"Define a taxa máxima pela qual o fluxo volumétrico extrudado em mm³/s² pode " "mudar ao longo do tempo. Valores mais altos significam que mudanças de taxa " "de extrusão mais altas são permitidas, resultando em transições de " "velocidade mais rápidas.\n" @@ -13265,20 +13265,20 @@ msgstr "" "entanto, pode fornecer alguns benefícios marginais em certos casos em que as " "velocidades das características variam muito. Por exemplo, quando há " "desacelerações agressivas devido a saliências. Nesses casos, um valor alto " -"de cerca de 300-350mm3/s2 é recomendado, pois isso permite apenas suavização " +"de cerca de 300-350 mm³/s² é recomendado, pois isso permite apenas suavização " "suficiente para ajudar o avanço de pressão a alcançar uma transição de fluxo " "mais suave.\n" "\n" "Para impressoras mais lentas sem avanço de pressão, o valor deve ser " -"definido muito mais baixo. Um valor de 10-15mm3/s2 é um bom ponto de partida " -"para extrusoras de acionamento direto e 5-10mm3/s2 para estilo Bowden.\n" +"definido muito mais baixo. Um valor de 10-15 mm³/s² é um bom ponto de partida " +"para extrusoras de acionamento direto e 5-10 mm³/s² para estilo Bowden.\n" "\n" "Este recurso é conhecido como Equalizador de Pressão no slicer Prusa.\n" "\n" "Nota: este parâmetro desativa o ajuste de arco." msgid "mm³/s²" -msgstr "mm3/s2" +msgstr "" msgid "Smoothing segment length" msgstr "Comprimento do segmento de suavização" @@ -15085,7 +15085,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" @@ -15105,7 +15105,7 @@ msgstr "" "aumentar a força com que o bico colide com quaisquer bolhas que possam ter " "se formado na torre de limpeza.\n" "\n" -"Antes de aumentar esse parâmetro além do padrão de 90mm/s, certifique-se de " +"Antes de aumentar esse parâmetro além do padrão de 90 mm/s, certifique-se de " "que sua impressora pode realizar pontes de forma confiável nas velocidades " "aumentadas e que o vazamento ao trocar a ferramenta está bem controlado.\n" "\n" diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po index 66eb450532..f7fadcd9ce 100644 --- a/localization/i18n/ru/OrcaSlicer_ru.po +++ b/localization/i18n/ru/OrcaSlicer_ru.po @@ -13420,7 +13420,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13430,13 +13430,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -15353,7 +15353,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/sv/OrcaSlicer_sv.po b/localization/i18n/sv/OrcaSlicer_sv.po index f41eee1b56..5e594f4298 100644 --- a/localization/i18n/sv/OrcaSlicer_sv.po +++ b/localization/i18n/sv/OrcaSlicer_sv.po @@ -12113,7 +12113,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -12123,13 +12123,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13660,7 +13660,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/tr/OrcaSlicer_tr.po b/localization/i18n/tr/OrcaSlicer_tr.po index 1cf6de1cb9..7978a3662f 100644 --- a/localization/i18n/tr/OrcaSlicer_tr.po +++ b/localization/i18n/tr/OrcaSlicer_tr.po @@ -13061,7 +13061,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13071,13 +13071,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13099,13 +13099,13 @@ msgstr "" "veya Voron gibi) bu değer genellikle gerekli değildir. Ancak özellik " "hızlarının büyük ölçüde değiştiği bazı durumlarda marjinal bir fayda " "sağlayabilir. Örneğin, çıkıntılar nedeniyle agresif yavaşlamalar olduğunda. " -"Bu durumlarda 300-350mm3/s2 civarında yüksek bir değer önerilir çünkü bu, " +"Bu durumlarda 300-350 mm³/s² civarında yüksek bir değer önerilir çünkü bu, " "basınç ilerlemesinin daha yumuşak bir akış geçişi elde etmesine yardımcı " "olmak için yeterli yumuşatmaya izin verir.\n" "\n" "Basınç avansı olmayan daha yavaş yazıcılar için değer çok daha düşük " -"ayarlanmalıdır. Doğrudan tahrikli ekstruderler için 10-15mm3/s2 ve Bowden " -"tarzı için 5-10mm3/s2 değeri iyi bir başlangıç noktasıdır.\n" +"ayarlanmalıdır. Doğrudan tahrikli ekstruderler için 10-15 mm³/s² ve Bowden " +"tarzı için 5-10 mm³/s² değeri iyi bir başlangıç noktasıdır.\n" "\n" "Bu özellik Prusa slicer'da Basınç Dengeleyici olarak bilinir.\n" "\n" @@ -14898,7 +14898,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/uk/OrcaSlicer_uk.po b/localization/i18n/uk/OrcaSlicer_uk.po index 5f92c7e356..131ed159eb 100644 --- a/localization/i18n/uk/OrcaSlicer_uk.po +++ b/localization/i18n/uk/OrcaSlicer_uk.po @@ -13192,7 +13192,7 @@ msgid "" "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -13202,13 +13202,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -15024,7 +15024,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po index 1a81e41dda..686cf9ad63 100644 --- a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po +++ b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po @@ -12033,13 +12033,14 @@ msgstr "挤出头最大可打印的层高。用于限制开启自适应层高时 msgid "Extrusion rate smoothing" msgstr "平滑挤出率" +#, fuzzy msgid "" "This parameter smooths out sudden extrusion rate changes that happen when " "the printer transitions from printing a high flow (high speed/larger width) " "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -12049,13 +12050,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -12074,7 +12075,7 @@ msgstr "" "够的平滑,以帮助压力提前实现更平滑的流量过渡。\n" "\n" "对于没有压力提前的较慢打印机,该值应该设置得非常低。对于近程挤出机来说10-15 " -"mm3/s2是一个很好值的起点,而对于远程挤出机来说是5-10 mm3/s2。\n" +"mm³/s²是一个很好值的起点,而对于远程挤出机来说是5-10 mm³/s²。\n" "\n" "这个功能在Prusa切片机中被称为压力均衡器。\n" "\n" @@ -13624,7 +13625,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" diff --git a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po index ac89ddae6f..73062ca190 100644 --- a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po +++ b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po @@ -12272,13 +12272,14 @@ msgstr "擠出頭最大可列印的層高。用於限制開啟自適應層高時 msgid "Extrusion rate smoothing" msgstr "平滑擠出率" +#, fuzzy msgid "" "This parameter smooths out sudden extrusion rate changes that happen when " "the printer transitions from printing a high flow (high speed/larger width) " "extrusion to a lower flow (lower speed/smaller width) extrusion and vice " "versa.\n" "\n" -"It defines the maximum rate by which the extruded volumetric flow in mm3/sec " +"It defines the maximum rate by which the extruded volumetric flow in mm³/s² " "can change over time. Higher values mean higher extrusion rate changes are " "allowed, resulting in faster speed transitions.\n" "\n" @@ -12288,13 +12289,13 @@ msgid "" "Voron) this value is usually not needed. However it can provide some " "marginal benefit in certain cases where feature speeds vary greatly. For " "example, when there are aggressive slowdowns due to overhangs. In these " -"cases a high value of around 300-350mm3/s2 is recommended as this allows for " -"just enough smoothing to assist pressure advance achieve a smoother flow " +"cases a high value of around 300-350 mm³/s² is recommended as this allows " +"for just enough smoothing to assist pressure advance achieve a smoother flow " "transition.\n" "\n" "For slower printers without pressure advance, the value should be set much " -"lower. A value of 10-15mm3/s2 is a good starting point for direct drive " -"extruders and 5-10mm3/s2 for Bowden style.\n" +"lower. A value of 10-15 mm³/s² is a good starting point for direct drive " +"extruders and 5-10 mm³/s² for Bowden style.\n" "\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n" "\n" @@ -13880,6 +13881,7 @@ msgstr "圓錐體頂點處的角度,用於穩定換料塔。 更大的角度 msgid "Maximum wipe tower print speed" msgstr "換料塔最快列印速度" +#, fuzzy msgid "" "The maximum print speed when purging in the wipe tower and printing the wipe " "tower sparse layers. When purging, if the sparse infill speed or calculated " @@ -13894,7 +13896,7 @@ msgid "" "the force with which the nozzle collides with any blobs that may have formed " "on the wipe tower.\n" "\n" -"Before increasing this parameter beyond the default of 90mm/sec, make sure " +"Before increasing this parameter beyond the default of 90 mm/s, make sure " "your printer can reliably bridge at the increased speeds and that ooze when " "tool changing is well controlled.\n" "\n" @@ -13909,7 +13911,7 @@ msgstr "" "\n" "提高此速度可能會影響塔的穩定性,並增加噴嘴與換料塔上斑點的碰撞力。\n" "\n" -"在將此參數提高於預設值 90mm/sec 以上之前,請確保您的印表設備能夠可靠地在更高" +"在將此參數提高於預設值 90mm/s 以上之前,請確保您的印表設備能夠可靠地在更高" "的速度下橋接,並且工具更換時的溢出能良好的被控制。\n" "\n" "對於換料塔外部周邊,無論此設定如何,都使用內部周邊速度。" diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 945ee4ab35..f0b82cbe36 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -515,7 +515,7 @@ void PrintConfigDef::init_common_params() def->label = L("Elephant foot compensation"); def->category = L("Quality"); def->tooltip = L("Shrinks the initial layer on build plate to compensate for elephant foot effect."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.)); @@ -535,14 +535,14 @@ void PrintConfigDef::init_common_params() def->label = L("Layer height"); def->category = L("Quality"); def->tooltip = L("Slicing height for each layer. Smaller layer height means more accurate and more printing time."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->set_default_value(new ConfigOptionFloat(0.2)); def = this->add("printable_height", coFloat); def->label = L("Printable height"); def->tooltip = L("Maximum printable height which is limited by mechanism of printer."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 214700; def->mode = comSimple; @@ -551,7 +551,7 @@ void PrintConfigDef::init_common_params() def = this->add("preferred_orientation", coFloat); def->label = L("Preferred orientation"); def->tooltip = L("Automatically orient stls on the Z-axis upon initial import."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->max = 360; def->min = -360; def->mode = comAdvanced; @@ -694,7 +694,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Other layers"); def->tooltip = L("Bed temperature for layers except the initial one. " "A value of 0 means the filament does not support printing on the Cool Plate SuperTack."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Bed temperature"); def->min = 0; def->max = 120; @@ -704,7 +704,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Other layers"); def->tooltip = L("Bed temperature for layers except the initial one. " "A value of 0 means the filament does not support printing on the Cool Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Bed temperature"); def->min = 0; def->max = 300; @@ -714,7 +714,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Other layers"); def->tooltip = L("Bed temperature for layers except the initial one. " "A value of 0 means the filament does not support printing on the Textured Cool Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Bed temperature"); def->min = 0; def->max = 300; @@ -724,7 +724,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Other layers"); def->tooltip = L("Bed temperature for layers except the initial one. " "A value of 0 means the filament does not support printing on the Engineering Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Bed temperature"); def->min = 0; def->max = 300; @@ -734,7 +734,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Other layers"); def->tooltip = L("Bed temperature for layers except the initial one. " "A value of 0 means the filament does not support printing on the High Temp Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Bed temperature"); def->min = 0; def->max = 300; @@ -744,7 +744,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Other layers"); def->tooltip = L("Bed temperature for layers except the initial one. " "A value of 0 means the filament does not support printing on the Textured PEI Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Bed temperature"); def->min = 0; def->max = 300; @@ -755,7 +755,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Initial layer bed temperature"); def->tooltip = L("Bed temperature of the initial layer. " "A value of 0 means the filament does not support printing on the Cool Plate SuperTack."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = 120; def->set_default_value(new ConfigOptionInts{ 35 }); @@ -765,7 +765,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Initial layer bed temperature"); def->tooltip = L("Bed temperature of the initial layer. " "A value of 0 means the filament does not support printing on the Cool Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = 120; def->set_default_value(new ConfigOptionInts{ 35 }); @@ -775,7 +775,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Initial layer bed temperature"); def->tooltip = L("Bed temperature of the initial layer. " "A value of 0 means the filament does not support printing on the Textured Cool Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = 120; def->set_default_value(new ConfigOptionInts{ 40 }); @@ -785,7 +785,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Initial layer bed temperature"); def->tooltip = L("Bed temperature of the initial layer. " "A value of 0 means the filament does not support printing on the Engineering Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = 300; def->set_default_value(new ConfigOptionInts{ 45 }); @@ -795,7 +795,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Initial layer bed temperature"); def->tooltip = L("Bed temperature of the initial layer. " "A value of 0 means the filament does not support printing on the High Temp Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->max = 300; def->set_default_value(new ConfigOptionInts{ 45 }); @@ -804,7 +804,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Initial layer bed temperature"); def->tooltip = L("Bed temperature of the initial layer. " "A value of 0 means the filament does not support printing on the Textured PEI Plate."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = 300; def->set_default_value(new ConfigOptionInts{45}); @@ -895,7 +895,7 @@ void PrintConfigDef::init_fff_params() "thinner than this value. This can avoid having too thin shell when layer height is small. 0 means that " "this setting is disabled and thickness of bottom shell is absolutely determined by bottom shell layers."); def->full_label = L("Bottom shell thickness"); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->set_default_value(new ConfigOptionFloat(0.)); @@ -954,7 +954,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("When the overhang exceeds this specified threshold, force the cooling fan to run at the 'Overhang Fan Speed' set below. " "This threshold is expressed as a percentage, indicating the portion of each line's width that is unsupported by the layer " "beneath it. Setting this value to 0% forces the cooling fan to run for all outer walls, regardless of the overhang degree."); - def->sidetext = ""; + //def->sidetext = ""; def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->mode = comAdvanced; def->enum_values.emplace_back("0%"); @@ -978,7 +978,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Bridging angle override. If left to zero, the bridging angle will be calculated " "automatically. Otherwise the provided angle will be used for external bridges. " "Use 180°for zero angle."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.)); @@ -990,7 +990,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Internal bridging angle override. If left to zero, the bridging angle will be calculated " "automatically. Otherwise the provided angle will be used for internal bridges. " "Use 180°for zero angle.\n\nIt is recommended to leave it at 0 unless there is a specific model need not to."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.)); @@ -1237,7 +1237,7 @@ void PrintConfigDef::init_fff_params() "In addition, if Slow down for curled perimeters is disabled or Classic overhang mode is enabled, " "it will be the print speed of overhang walls that are supported by less than 13%, " "whether they are part of a bridge or an overhang."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(25)); @@ -1256,7 +1256,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Brim width"); def->category = L("Support"); def->tooltip = L("Distance from model to the outermost brim line."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 100; def->mode = comSimple; @@ -1289,7 +1289,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Brim-object gap"); def->category = L("Support"); def->tooltip = L("A gap between innermost brim line and object can make brim be removed more easily."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 2; def->mode = comAdvanced; @@ -1308,7 +1308,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Maximum angle to let a brim ear appear.\n" "If set to 0, no brim will be created.\n" "If set to ~180, brim will be created on everything but straight sections."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 180; def->mode = comAdvanced; @@ -1320,7 +1320,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("The geometry will be decimated before detecting sharp angles. This parameter indicates the " "minimum length of the deviation for the decimation. " "\n0 to deactivate."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(1)); @@ -1412,7 +1412,7 @@ void PrintConfigDef::init_fff_params() def = this->add("default_acceleration", coFloat); def->label = L("Normal printing"); def->tooltip = L("The default acceleration of both normal printing and travel except initial layer."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(500.0)); @@ -1551,7 +1551,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Max bridge length"); def->category = L("Support"); def->tooltip = L("Max length of bridges that don't need support. Set it to 0 if you want all bridges to be supported, and set it to a very large value if you don't want any bridges to be supported."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(10)); @@ -1660,7 +1660,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Speed"); def->tooltip = L("Speed of outer wall which is outermost and visible. " "It's used to be slower than inner wall speed to get better quality."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(60)); @@ -1681,7 +1681,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Small perimeters threshold"); def->category = L("Speed"); def->tooltip = L("This sets the threshold for small perimeter length. Default threshold is 0mm."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -1749,7 +1749,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Height to rod"); def->tooltip = L("Distance of the nozzle tip to the lower rod. " "Used for collision avoidance in by-object printing."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(40)); @@ -1759,7 +1759,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Height to lid"); def->tooltip = L("Distance of the nozzle tip to the lid. " "Used for collision avoidance in by-object printing."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(120)); @@ -1767,7 +1767,7 @@ void PrintConfigDef::init_fff_params() def = this->add("extruder_clearance_radius", coFloat); def->label = L("Radius"); def->tooltip = L("Clearance radius around extruder. Used for collision avoidance in by-object printing."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(40)); @@ -1775,7 +1775,7 @@ void PrintConfigDef::init_fff_params() def = this->add("nozzle_height", coFloat); def->label = L("Nozzle height"); def->tooltip = L("The height of nozzle tip."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comDevelop; def->set_default_value(new ConfigOptionFloat(2.5)); @@ -1788,7 +1788,7 @@ void PrintConfigDef::init_fff_params() "set appropriately. OrcaSlicer ensures that adaptive_bed_mesh_min/adaptive_bed_mesh_max values do not exceed these min/max " "points. This information can usually be obtained from your printer manufacturer. The default setting is (-99999, -99999), which " "means there are no limits, thus allowing probing across the entire bed."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionPoint(Vec2d(-99999, -99999))); @@ -1800,7 +1800,7 @@ void PrintConfigDef::init_fff_params() "set appropriately. OrcaSlicer ensures that adaptive_bed_mesh_min/adaptive_bed_mesh_max values do not exceed these min/max " "points. This information can usually be obtained from your printer manufacturer. The default setting is (99999, 99999), which " "means there are no limits, thus allowing probing across the entire bed."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionPoint(Vec2d(99999, 99999))); @@ -1809,14 +1809,14 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This option sets the preferred distance between probe points (grid size) for the X and Y directions, with the " "default being 50mm for both X and Y."); def->min = 0; - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionPoint(Vec2d(50, 50))); def = this->add("adaptive_bed_mesh_margin", coFloat); def->label = L("Mesh margin"); def->tooltip = L("This option determines the additional distance by which the adaptive bed mesh area should be expanded in the XY directions."); - def->sidetext = L("mm"); // ORCA add side text + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -1834,7 +1834,7 @@ void PrintConfigDef::init_fff_params() // "to take it into account. This option lets you specify the displacement of each extruder " // "with respect to the first one. It expects positive coordinates (they will be subtracted " // "from the XY coordinate)."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionPoints { Vec2d(0,0) }); @@ -1961,7 +1961,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Layer time"); def->tooltip = L("Part cooling fan will be enabled for layers of which estimated time is shorter than this value. " "Fan speed is interpolated between the minimum and maximum fan speeds according to layer printing time."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->max = 1000; def->mode = comSimple; @@ -2006,7 +2006,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This setting stands for how much volume of filament can be melted and extruded per second. " "Printing speed is limited by max volumetric speed, in case of too high and unreasonable speed setting. " "Can't be zero."); - def->sidetext = L("mm³/s"); + def->sidetext = "mm³/s"; // cubic milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 2. }); @@ -2015,7 +2015,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Filament load time"); def->tooltip = L("Time to load new filament when switch filament. It's usually applicable for single-extruder multi-material machines. " "For tool changers or multi-tool machines, it's typically 0. For statistics only."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.0)); @@ -2024,7 +2024,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Filament unload time"); def->tooltip = L("Time to unload old filament when switch filament. It's usually applicable for single-extruder multi-material machines. " "For tool changers or multi-tool machines, it's typically 0. For statistics only."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.0)); @@ -2033,7 +2033,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Tool change time"); def->tooltip = L("Time taken to switch tools. It's usually applicable for tool changers or multi-tool machines. " "For single-extruder multi-material machines, it's typically 0. For statistics only."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat { 0. }); @@ -2042,7 +2042,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_diameter", coFloats); def->label = L("Diameter"); def->tooltip = L("Filament diameter is used to calculate extrusion in G-code, so it is important and should be accurate."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->set_default_value(new ConfigOptionFloats { 1.75 }); @@ -2105,7 +2105,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_loading_speed", coFloats); def->label = L("Loading speed"); def->tooltip = L("Speed used for loading the filament on the wipe tower."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 28. }); @@ -2113,7 +2113,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_loading_speed_start", coFloats); def->label = L("Loading speed at the start"); def->tooltip = L("Speed used at the very beginning of loading phase."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 3. }); @@ -2122,7 +2122,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Unloading speed"); def->tooltip = L("Speed used for unloading the filament on the wipe tower (does not affect " "initial part of unloading just after ramming)."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 90. }); @@ -2130,7 +2130,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_unloading_speed_start", coFloats); def->label = L("Unloading speed at the start"); def->tooltip = L("Speed used for unloading the tip of the filament immediately after ramming."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 100. }); @@ -2140,7 +2140,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Time to wait after the filament is unloaded. " "May help to get reliable tool changes with flexible materials " "that may need more time to shrink to original dimensions."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); @@ -2172,7 +2172,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_cooling_initial_speed", coFloats); def->label = L("Speed of the first cooling move"); def->tooltip = L("Cooling moves are gradually accelerating beginning at this speed."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 2.2 }); @@ -2183,7 +2183,7 @@ void PrintConfigDef::init_fff_params() "the nozzle may not be known, and the filament pressure is likely not yet stable. " "Before purging the print head into an infill or a sacrificial object, Orca Slicer will always prime " "this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably."); - def->sidetext = L("mm³"); + def->sidetext = "mm³"; // cubic milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 15. }); @@ -2191,7 +2191,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_cooling_final_speed", coFloats); def->label = L("Speed of the last cooling move"); def->tooltip = L("Cooling moves are gradually accelerating towards this speed."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 3.4 }); @@ -2214,7 +2214,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_multitool_ramming_volume", coFloats); def->label = L("Multi-tool ramming volume"); def->tooltip = L("The volume to be rammed before the tool change."); - def->sidetext = L("mm³"); + def->sidetext = "mm³"; // cubic milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 10. }); @@ -2222,7 +2222,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_multitool_ramming_flow", coFloats); def->label = L("Multi-tool ramming flow"); def->tooltip = L("Flow used for ramming the filament before the tool change."); - def->sidetext = L("mm³/s"); + def->sidetext = "mm³/s"; // cubic milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 10. }); @@ -2230,7 +2230,7 @@ void PrintConfigDef::init_fff_params() def = this->add("filament_density", coFloats); def->label = L("Density"); def->tooltip = L("Filament density. For statistics only."); - def->sidetext = L("g/cm³"); + def->sidetext = "g/cm³"; // grams per cubic milimeter, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); @@ -2300,7 +2300,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Softening temperature"); def->tooltip = L("The material softens at this temperature, so when the bed temperature is equal to or greater than this, " "it's highly recommended to open the front door and/or remove the upper glass to avoid clogging."); - def->sidetext = "°C"; // ORCA add side text + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->mode = comSimple; def->set_default_value(new ConfigOptionInts{ 100 }); @@ -2332,7 +2332,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Sparse infill direction"); def->category = L("Strength"); def->tooltip = L("Angle for sparse infill pattern, which controls the start or main direction of line."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 360; def->mode = comAdvanced; @@ -2342,7 +2342,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Solid infill direction"); def->category = L("Strength"); def->tooltip = L("Angle for solid infill pattern, which controls the start or main direction of line."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 360; def->mode = comAdvanced; @@ -2420,7 +2420,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Lattice angle 1"); def->category = L("Strength"); def->tooltip = L("The angle of the first set of 2D lattice elements in the Z direction. Zero is vertical."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = -75; def->max = 75; def->mode = comAdvanced; @@ -2430,7 +2430,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Lattice angle 2"); def->category = L("Strength"); def->tooltip = L("The angle of the second set of 2D lattice elements in the Z direction. Zero is vertical."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = -75; def->max = 75; def->mode = comAdvanced; @@ -2440,7 +2440,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Infill overhang angle"); def->category = L("Strength"); def->tooltip = L("The angle of the infill angled lines. 60° will result in a pure honeycomb."); - def->sidetext = L("°"); + def->sidetext = "°"; // degrees, don't need translation def->min = 15; def->max = 75; def->mode = comAdvanced; @@ -2500,7 +2500,7 @@ void PrintConfigDef::init_fff_params() def = this->add("outer_wall_acceleration", coFloat); def->label = L("Outer wall"); def->tooltip = L("Acceleration of outer walls."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(10000)); @@ -2508,7 +2508,7 @@ void PrintConfigDef::init_fff_params() def = this->add("inner_wall_acceleration", coFloat); def->label = L("Inner wall"); def->tooltip = L("Acceleration of inner walls."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(10000)); @@ -2516,7 +2516,7 @@ void PrintConfigDef::init_fff_params() def = this->add("travel_acceleration", coFloat); def->label = L("Travel"); def->tooltip = L("Acceleration of travel moves."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(10000)); @@ -2524,7 +2524,7 @@ void PrintConfigDef::init_fff_params() def = this->add("top_surface_acceleration", coFloat); def->label = L("Top surface"); def->tooltip = L("Acceleration of top surface infill. Using a lower value may improve top surface quality."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(500)); @@ -2532,7 +2532,7 @@ void PrintConfigDef::init_fff_params() def = this->add("outer_wall_acceleration", coFloat); def->label = L("Outer wall"); def->tooltip = L("Acceleration of outer wall. Using a lower value can improve quality."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(500)); @@ -2567,7 +2567,7 @@ void PrintConfigDef::init_fff_params() def = this->add("initial_layer_acceleration", coFloat); def->label = L("Initial layer"); def->tooltip = L("Acceleration of initial layer. Using a lower value can improve build plate adhesion."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(300)); @@ -2590,7 +2590,7 @@ void PrintConfigDef::init_fff_params() def = this->add("default_jerk", coFloat); def->label = L("Default"); def->tooltip = L("Default jerk."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -2598,7 +2598,7 @@ void PrintConfigDef::init_fff_params() def = this->add("default_junction_deviation", coFloat); def->label = L("Junction Deviation"); def->tooltip = L("Marlin Firmware Junction Deviation (replaces the traditional XY Jerk setting)"); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -2606,7 +2606,7 @@ void PrintConfigDef::init_fff_params() def = this->add("outer_wall_jerk", coFloat); def->label = L("Outer wall"); def->tooltip = L("Jerk of outer walls."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(9)); @@ -2614,7 +2614,7 @@ void PrintConfigDef::init_fff_params() def = this->add("inner_wall_jerk", coFloat); def->label = L("Inner wall"); def->tooltip = L("Jerk of inner walls."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(9)); @@ -2622,7 +2622,7 @@ void PrintConfigDef::init_fff_params() def = this->add("top_surface_jerk", coFloat); def->label = L("Top surface"); def->tooltip = L("Jerk for top surface."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(9)); @@ -2630,7 +2630,7 @@ void PrintConfigDef::init_fff_params() def = this->add("infill_jerk", coFloat); def->label = L("Infill"); def->tooltip = L("Jerk for infill."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(9)); @@ -2638,7 +2638,7 @@ void PrintConfigDef::init_fff_params() def = this->add("initial_layer_jerk", coFloat); def->label = L("Initial layer"); def->tooltip = L("Jerk for initial layer."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(9)); @@ -2646,7 +2646,7 @@ void PrintConfigDef::init_fff_params() def = this->add("travel_jerk", coFloat); def->label = L("Travel"); def->tooltip = L("Jerk for travel."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(12)); @@ -2668,7 +2668,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Initial layer height"); def->category = L("Quality"); def->tooltip = L("Height of initial layer. Making initial layer height to be thick slightly can improve build plate adhesion."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->set_default_value(new ConfigOptionFloat(0.2)); @@ -2683,7 +2683,7 @@ void PrintConfigDef::init_fff_params() def = this->add("initial_layer_speed", coFloat); def->label = L("Initial layer"); def->tooltip = L("Speed of initial layer except the solid infill part."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(30)); @@ -2691,7 +2691,7 @@ void PrintConfigDef::init_fff_params() def = this->add("initial_layer_infill_speed", coFloat); def->label = L("Initial layer infill"); def->tooltip = L("Speed of solid infill part of initial layer."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(60.0)); @@ -2720,7 +2720,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Initial layer"); def->full_label = L("Initial layer nozzle temperature"); def->tooltip = L("Nozzle temperature for printing initial layer when using this filament."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = max_temp; def->set_default_value(new ConfigOptionInts { 200 }); @@ -2782,7 +2782,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Fuzzy skin thickness"); def->category = L("Others"); def->tooltip = L("The width within which to jitter. It's advised to be below outer wall line width."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 1; def->mode = comSimple; @@ -2792,7 +2792,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Fuzzy skin point distance"); def->category = L("Others"); def->tooltip = L("The average distance between the random points introduced on each line segment."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 5; def->mode = comSimple; @@ -2832,7 +2832,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Fuzzy skin feature size"); def->category = L("Others"); def->tooltip = L("The base size of the coherent noise features, in mm. Higher values will result in larger features."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0.1; def->max = 500; def->mode = comAdvanced; @@ -2861,7 +2861,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Layers and Perimeters"); def->tooltip = L("Don't print gap fill with a length is smaller than the threshold specified (in mm). This setting applies to top, " "bottom and solid infill and, if using the classic perimeter generator, to wall gap fill."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -2869,7 +2869,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Gap infill"); def->category = L("Speed"); def->tooltip = L("Speed of gap infill. Gap usually has irregular line width and should be printed more slowly."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(30)); @@ -2980,7 +2980,7 @@ void PrintConfigDef::init_fff_params() "\nIt won't move fan commands from custom G-code (they act as a sort of 'barrier')." "\nIt won't move fan commands into the start G-code if the 'only custom start G-code' is activated." "\nUse 0 to deactivate."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -2996,7 +2996,7 @@ void PrintConfigDef::init_fff_params() "\nThis is useful for fans where a low PWM/power may be insufficient to get the fan started spinning from a stop, or to " "get the fan up to speed faster." "\nSet to 0 to deactivate."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -3165,7 +3165,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Sparse infill"); def->category = L("Speed"); def->tooltip = L("Speed of internal sparse infill."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(100)); @@ -3196,7 +3196,7 @@ void PrintConfigDef::init_fff_params() def = this->add("mmu_segmented_region_max_width", coFloat); def->label = L("Maximum width of a segmented region"); def->tooltip = L("Maximum width of a segmented region. Zero disables this feature."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->category = L("Advanced"); def->mode = comAdvanced; @@ -3207,7 +3207,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Interlocking depth of a segmented region. It will be ignored if " "\"mmu_segmented_region_max_width\" is zero or if \"mmu_segmented_region_interlocking_depth\" " "is bigger than \"mmu_segmented_region_max_width\". Zero disables this feature."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->category = L("Advanced"); def->mode = comAdvanced; @@ -3223,7 +3223,7 @@ void PrintConfigDef::init_fff_params() def = this->add("interlocking_beam_width", coFloat); def->label = L("Interlocking beam width"); def->tooltip = L("The width of the interlocking structure beams."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0.01; def->category = L("Advanced"); def->mode = comAdvanced; @@ -3232,7 +3232,7 @@ void PrintConfigDef::init_fff_params() def = this->add("interlocking_orientation", coFloat); def->label = L("Interlocking direction"); def->tooltip = L("Orientation of interlock beams."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 360; def->category = L("Advanced"); @@ -3313,7 +3313,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Ironing line spacing"); def->category = L("Quality"); def->tooltip = L("The distance between the lines of ironing."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 1; def->mode = comAdvanced; @@ -3323,7 +3323,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Ironing inset"); def->category = L("Quality"); def->tooltip = L("The distance to keep from the edges. A value of 0 sets this to half of the nozzle diameter."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 100; def->mode = comAdvanced; @@ -3333,7 +3333,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Ironing speed"); def->category = L("Quality"); def->tooltip = L("Print speed of ironing lines"); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(20)); @@ -3342,7 +3342,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Ironing angle"); def->category = L("Quality"); def->tooltip = L("The angle ironing is done at. A negative number disables this function and uses the default method."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = -1; def->max = 359; def->mode = comAdvanced; @@ -3451,7 +3451,7 @@ void PrintConfigDef::init_fff_params() (void)L("Maximum Y speed"); (void)L("Maximum Z speed"); (void)L("Maximum E speed"); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comSimple; def->set_default_value(new ConfigOptionFloats(axis.max_feedrate)); @@ -3469,7 +3469,7 @@ void PrintConfigDef::init_fff_params() (void)L("Maximum acceleration of the Y axis"); (void)L("Maximum acceleration of the Z axis"); (void)L("Maximum acceleration of the E axis"); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->mode = comSimple; def->set_default_value(new ConfigOptionFloats(axis.max_acceleration)); @@ -3487,7 +3487,7 @@ void PrintConfigDef::init_fff_params() (void)L("Maximum jerk of the Y axis"); (void)L("Maximum jerk of the Z axis"); (void)L("Maximum jerk of the E axis"); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comSimple; def->set_default_value(new ConfigOptionFloats(axis.max_jerk)); @@ -3498,7 +3498,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Maximum Junction Deviation"); def->category = L("Machine limits"); def->tooltip = L("Maximum junction deviation (M205 J, only apply if JD > 0 for Marlin Firmware)"); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats{0. ,0. }); @@ -3508,7 +3508,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Minimum speed for extruding"); def->category = L("Machine limits"); def->tooltip = L("Minimum speed for extruding (M205 S)"); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comDevelop; def->set_default_value(new ConfigOptionFloats{ 0., 0. }); @@ -3518,7 +3518,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Minimum travel speed"); def->category = L("Machine limits"); def->tooltip = L("Minimum travel speed (M205 T)"); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comDevelop; def->set_default_value(new ConfigOptionFloats{ 0., 0. }); @@ -3530,7 +3530,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Maximum acceleration for extruding (M204 P)"); // "Marlin (legacy) firmware flavor will use this also " // "as travel acceleration (M204 T)."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->readonly = false; def->mode = comSimple; @@ -3542,7 +3542,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Maximum acceleration for retracting"); def->category = L("Machine limits"); def->tooltip = L("Maximum acceleration for retracting (M204 R)"); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->readonly = false; def->mode = comSimple; @@ -3553,7 +3553,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Maximum acceleration for travel"); def->category = L("Machine limits"); def->tooltip = L("Maximum acceleration for travel (M204 T), it only applies to Marlin 2."); - def->sidetext = L("mm/s²"); + def->sidetext = "mm/s²"; // milimeters per second per second, don't need translation def->min = 0; def->readonly = false; def->mode = comAdvanced; @@ -3571,7 +3571,7 @@ void PrintConfigDef::init_fff_params() def = this->add("min_resonance_avoidance_speed", coFloat); def->label = L("Min"); def->tooltip = L("Minimum speed of resonance avoidance."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(70)); @@ -3579,7 +3579,7 @@ void PrintConfigDef::init_fff_params() def = this->add("max_resonance_avoidance_speed", coFloat); def->label = L("Max"); def->tooltip = L("Maximum speed of resonance avoidance."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(120)); @@ -3598,7 +3598,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Max"); def->tooltip = L("The highest printable layer height for the extruder. " "Used to limit the maximum layer height when enable adaptive layer height."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); @@ -3608,18 +3608,18 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This parameter smooths out sudden extrusion rate changes that happen when " "the printer transitions from printing a high flow (high speed/larger width) " "extrusion to a lower flow (lower speed/smaller width) extrusion and vice versa.\n\n" - "It defines the maximum rate by which the extruded volumetric flow in mm3/sec can change over time. " + "It defines the maximum rate by which the extruded volumetric flow in mm³/s² can change over time. " "Higher values mean higher extrusion rate changes are allowed, resulting in faster speed transitions.\n\n" "A value of 0 disables the feature.\n\n" "For a high speed, high flow direct drive printer (like the Bambu lab or Voron) this value is usually not needed. " "However it can provide some marginal benefit in certain cases where feature speeds vary greatly. For example, " - "when there are aggressive slowdowns due to overhangs. In these cases a high value of around 300-350mm3/s2 is " + "when there are aggressive slowdowns due to overhangs. In these cases a high value of around 300-350 mm³/s² is " "recommended as this allows for just enough smoothing to assist pressure advance achieve a smoother flow transition.\n\n" "For slower printers without pressure advance, the value should be set much lower. " - "A value of 10-15mm3/s2 is a good starting point for direct drive extruders and 5-10mm3/s2 for Bowden style.\n\n" + "A value of 10-15 mm³/s² is a good starting point for direct drive extruders and 5-10 mm³/s² for Bowden style.\n\n" "This feature is known as Pressure Equalizer in Prusa slicer.\n\n" "Note: this parameter disables arc fitting."); - def->sidetext = L("mm³/s²"); + def->sidetext = "mm³/s²"; // cubic milimeters per second per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -3632,7 +3632,7 @@ void PrintConfigDef::init_fff_params() "Allowed values: 0.5-5"); def->min = 0.5; def->max = 5; - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(3.0)); @@ -3667,7 +3667,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Min"); def->tooltip = L("The lowest printable layer height for the extruder. " "Used to limit the minimum layer height when enable adaptive layer height."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0.07 }); @@ -3676,7 +3676,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Min print speed"); def->tooltip = L("The minimum print speed to which the printer slows down to maintain the minimum layer time defined above " "when the slowdown for better layer cooling is enabled."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 10. }); @@ -3684,7 +3684,7 @@ void PrintConfigDef::init_fff_params() def = this->add("nozzle_diameter", coFloats); def->label = L("Nozzle diameter"); def->tooltip = L("Diameter of nozzle"); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->max = 100; def->set_default_value(new ConfigOptionFloats { 0.4 }); @@ -3740,7 +3740,7 @@ void PrintConfigDef::init_fff_params() def = this->add("nozzle_volume", coFloat); def->label = L("Nozzle volume"); def->tooltip = L("Volume of nozzle between the cutter and the end of nozzle."); - def->sidetext = L("mm³"); + def->sidetext = "mm³"; // cubic milimeters, don't need translation def->mode = comAdvanced; def->readonly = false; def->set_default_value(new ConfigOptionFloat { 0.0 }); @@ -3748,7 +3748,7 @@ void PrintConfigDef::init_fff_params() def = this->add("cooling_tube_retraction", coFloat); def->label = L("Cooling tube position"); def->tooltip = L("Distance of the center-point of the cooling tube from the extruder tip."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(91.5)); @@ -3756,7 +3756,7 @@ void PrintConfigDef::init_fff_params() def = this->add("cooling_tube_length", coFloat); def->label = L("Cooling tube length"); def->tooltip = L("Length of the cooling tube to limit space for cooling moves inside it."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(5.)); @@ -3773,7 +3773,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Filament parking position"); def->tooltip = L("Distance of the extruder tip from the position where the filament is parked " "when unloaded. This should match the value in printer firmware."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(92.)); @@ -3783,7 +3783,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("When set to zero, the distance the filament is moved from parking position during load " "is exactly the same as it was moved back during unload. When positive, it is loaded further, " "if negative, the loading move is shorter than unloading."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(-2.)); @@ -3829,7 +3829,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Maximum angle of overhangs to allow after making more steep overhangs printable." "90° will not change the model at all and allow any overhang, while 0 will " "replace all overhangs with conical material."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->mode = comAdvanced; def->min = 0.; def->max = 90.; @@ -3840,7 +3840,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Quality"); def->tooltip = L("Maximum area of a hole in the base of the model before it's filled by conical material. " "A value of 0 will fill all the holes in the model base."); - def->sidetext = L("mm²"); + def->sidetext = "mm²"; // square milimeters, don't need translation def->mode = comAdvanced; def->min = 0.; def->set_default_value(new ConfigOptionFloat(0.)); @@ -3878,7 +3878,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Inner wall"); def->category = L("Speed"); def->tooltip = L("Speed of inner wall."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->aliases = { "perimeter_feed_rate" }; def->min = 1; def->mode = comAdvanced; @@ -3949,7 +3949,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Raft contact Z distance"); def->category = L("Support"); def->tooltip = L("Z gap between object and raft. Ignored for soluble interface."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.1)); @@ -3958,7 +3958,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Raft expansion"); def->category = L("Support"); def->tooltip = L("Expand all raft layers in XY plane."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(1.5)); @@ -3977,7 +3977,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Initial layer expansion"); def->category = L("Support"); def->tooltip = L("Expand the first raft or support layer to improve bed plate adhesion."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; //BBS: change from 3.0 to 2.0 @@ -3998,7 +3998,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Resolution"); def->tooltip = L("The G-code path is generated after simplifying the contour of models to avoid too many points and G-code lines. " "Smaller value means higher resolution and more time to slice."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.01)); @@ -4006,7 +4006,7 @@ void PrintConfigDef::init_fff_params() def = this->add("retraction_minimum_travel", coFloats); def->label = L("Travel distance threshold"); def->tooltip = L("Only trigger retraction when the travel distance is longer than this threshold."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 2. }); @@ -4028,7 +4028,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Retraction Length"); def->tooltip = L("Some amount of material in extruder is pulled back to avoid ooze during long travel. " "Set zero to disable retraction."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comSimple; def->set_default_value(new ConfigOptionFloats { 0.8 }); @@ -4058,7 +4058,7 @@ void PrintConfigDef::init_fff_params() //def->tooltip = L("When retraction is triggered before changing tool, filament is pulled back " // "by the specified amount (the length is measured on raw filament, before it enters " // "the extruder)."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 10. }); @@ -4067,7 +4067,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Whenever the retraction is done, the nozzle is lifted a little to create clearance between nozzle and the print. " "It prevents nozzle from hitting the print when travel move. " "Using spiral lines to lift Z can prevent stringing."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comSimple; def->min = 0; def->max = 5; @@ -4076,7 +4076,7 @@ void PrintConfigDef::init_fff_params() def = this->add("retract_lift_above", coFloats); def->label = L("Z-hop lower boundary"); def->tooltip = L("Z-hop will only come into effect when Z is above this value and is below the parameter: \"Z-hop upper boundary\"."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->min = 0; def->set_default_value(new ConfigOptionFloats{0.}); @@ -4084,7 +4084,7 @@ void PrintConfigDef::init_fff_params() def = this->add("retract_lift_below", coFloats); def->label = L("Z-hop upper boundary"); def->tooltip = L("If this value is positive, Z-hop will only come into effect when Z is above the parameter: \"Z-hop lower boundary\" and is below this value."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->min = 0; def->set_default_value(new ConfigOptionFloats{0.}); @@ -4107,7 +4107,7 @@ void PrintConfigDef::init_fff_params() def = this->add("travel_slope", coFloats); def->label = L("Traveling angle"); def->tooltip = L("Traveling angle for Slope and Spiral Z-hop type. Setting it to 90° results in Normal Lift."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->mode = comAdvanced; def->min = 1; def->max = 90; @@ -4116,14 +4116,14 @@ void PrintConfigDef::init_fff_params() def = this->add("retract_lift_above", coFloats); def->label = L("Only lift Z above"); def->tooltip = L("If you set this to a positive value, Z lift will only take place above the specified absolute Z."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats{0.}); def = this->add("retract_lift_below", coFloats); def->label = L("Only lift Z below"); def->tooltip = L("If you set this to a positive value, Z lift will only take place below the specified absolute Z."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats{0.}); @@ -4146,7 +4146,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Extra length on restart"); def->tooltip = L("When the retraction is compensated after the travel move, the extruder will push " "this additional amount of filament. This setting is rarely needed."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); @@ -4154,7 +4154,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Extra length on restart"); def->tooltip = L("When the retraction is compensated after changing tool, the extruder will push " "this additional amount of filament."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); @@ -4162,7 +4162,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Retraction Speed"); def->full_label = L("Retraction Speed"); def->tooltip = L("Speed for retracting filament from the nozzle."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 30. }); @@ -4170,7 +4170,7 @@ void PrintConfigDef::init_fff_params() def->label = L("De-retraction Speed"); def->full_label = L("De-retraction Speed"); def->tooltip = L("Speed for reloading filament into the nozzle. Zero means same speed of retraction."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); @@ -4249,7 +4249,7 @@ void PrintConfigDef::init_fff_params() "This option sets the threshold angle for applying a conditional scarf joint seam.\nIf the maximum angle within the perimeter loop " "exceeds this value (indicating the absence of sharp corners), a scarf joint seam will be used. The default value is 155°."); def->mode = comAdvanced; - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 180; def->set_default_value(new ConfigOptionInt(155)); @@ -4306,7 +4306,7 @@ void PrintConfigDef::init_fff_params() def = this->add("seam_slope_min_length", coFloat); def->label = L("Scarf length"); def->tooltip = L("Length of the scarf. Setting this parameter to zero effectively disables the scarf."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(20)); @@ -4361,7 +4361,7 @@ void PrintConfigDef::init_fff_params() def = this->add("skirt_distance", coFloat); def->label = L("Skirt distance"); def->tooltip = L("Distance from skirt to brim or object"); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 60; def->mode = comAdvanced; @@ -4370,7 +4370,7 @@ void PrintConfigDef::init_fff_params() def = this->add("skirt_start_angle", coFloat); def->label = L("Skirt start point"); def->tooltip = L("Angle from the object center to skirt start point. Zero is the most right position, counter clockwise is positive angle."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = -180; def->max = 180; def->mode = comAdvanced; @@ -4431,7 +4431,7 @@ void PrintConfigDef::init_fff_params() def->full_label = L("Skirt speed"); def->tooltip = L("Speed of skirt, in mm/s. Zero means use default layer extrusion speed."); def->min = 0; - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(50.0)); @@ -4442,7 +4442,7 @@ void PrintConfigDef::init_fff_params() "Using a non-zero value is useful if the printer is set up to print without a prime line.\n" "Final number of loops is not taking into account while arranging or validating objects distance. Increase loop number in such case."); def->min = 0; - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.0)); @@ -4450,7 +4450,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Layer time"); def->tooltip = L("The printing speed in exported G-code will be slowed down when the estimated layer time is " "shorter than this value in order to get better cooling for these layers."); - def->sidetext = L("s"); + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->max = 1000; def->mode = comSimple; @@ -4460,7 +4460,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Minimum sparse infill threshold"); def->category = L("Strength"); def->tooltip = L("Sparse infill area which is smaller than threshold value is replaced by internal solid infill."); - def->sidetext = L("mm²"); + def->sidetext = "mm²"; // square milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(15)); @@ -4490,7 +4490,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Internal solid infill"); def->category = L("Speed"); def->tooltip = L("Speed of internal solid infill, not the top and bottom surface."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(100)); @@ -4568,7 +4568,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Temperature difference to be applied when an extruder is not active. " "The value is not used when 'idle_temperature' in filament settings " "is set to non-zero value."); - def->sidetext = "∆°C"; + def->sidetext = "∆\u2103"; // delta degrees Celsius, don't need translation def->min = -max_temp; def->max = max_temp; def->mode = comAdvanced; @@ -4578,7 +4578,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Preheat time"); def->tooltip = L("To reduce the waiting time after tool change, Orca can preheat the next tool while the current tool is still in use. " "This setting specifies the time in seconds to preheat the next tool. Orca will insert a M104 command to preheat the tool in advance."); - def->sidetext = "s"; + def->sidetext = "s"; // seconds, don't need translation def->min = 0; def->max = 120; def->mode = comAdvanced; @@ -4658,7 +4658,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Quality"); def->tooltip = L("Cracks smaller than 2x gap closing radius are being filled during the triangle mesh slicing. " "The gap closing operation may reduce the final print resolution, therefore it is advisable to keep the value reasonably low."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.049)); @@ -4683,7 +4683,7 @@ void PrintConfigDef::init_fff_params() "in the output G-code. It is used to compensate for bad Z endstop position: " "for example, if your endstop zero actually leaves the nozzle 0.3mm far " "from the print bed, set this to -0.3 (or fix your endstop)."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -4715,7 +4715,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Support/object xy distance"); def->category = L("Support"); def->tooltip = L("XY separation between an object and its support."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 10; def->mode = comAdvanced; @@ -4726,7 +4726,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Support/object first layer gap"); def->category = L("Support"); def->tooltip = L("XY separation between an object and its support at the first layer."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 10; def->mode = comAdvanced; @@ -4737,7 +4737,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Pattern angle"); def->category = L("Support"); def->tooltip = L("Use this setting to rotate the support pattern on the horizontal plane."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 359; def->mode = comAdvanced; @@ -4773,7 +4773,7 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->category = L("Support"); def->tooltip = L("The Z gap between the top support interface and object."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation // def->min = 0; #if 0 //def->enum_values.push_back("0"); @@ -4790,7 +4790,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Bottom Z distance"); def->category = L("Support"); def->tooltip = L("The Z gap between the bottom support interface and object."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.2)); @@ -4891,7 +4891,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Support"); def->tooltip = L("Spacing of interface lines. Zero means solid interface.\n" "Force using solid interface when support ironing is enabled."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.5)); @@ -4901,7 +4901,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Bottom interface spacing"); def->category = L("Support"); def->tooltip = L("Spacing of bottom interface lines. Zero means solid interface."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.5)); @@ -4910,7 +4910,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Support interface"); def->category = L("Speed"); def->tooltip = L("Speed of support interface."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(80)); @@ -4959,7 +4959,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Base pattern spacing"); def->category = L("Support"); def->tooltip = L("Spacing between support lines."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(2.5)); @@ -4968,7 +4968,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Normal Support expansion"); def->category = L("Support"); def->tooltip = L("Expand (+) or shrink (-) the horizontal span of normal support."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -4976,7 +4976,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Support"); def->category = L("Speed"); def->tooltip = L("Speed of support."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(80)); @@ -5021,7 +5021,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Threshold angle"); def->category = L("Support"); def->tooltip = L("Support will be generated for overhangs whose slope angle is below the threshold."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 90; def->mode = comSimple; @@ -5043,7 +5043,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Support"); def->tooltip = L("This setting determines the maximum overhang angle that the branches of tree support are allowed to make. " "If the angle is increased, the branches can be printed more horizontally, allowing them to reach farther."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 60; def->mode = comAdvanced; @@ -5054,7 +5054,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Support"); def->tooltip = L("This setting determines the maximum overhang angle that the branches of tree support are allowed to make. " "If the angle is increased, the branches can be printed more horizontally, allowing them to reach farther."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 60; def->mode = comAdvanced; @@ -5066,7 +5066,7 @@ void PrintConfigDef::init_fff_params() // TRN PrintSettings: "Organic supports" > "Preferred Branch Angle" def->tooltip = L("The preferred angle of the branches, when they do not have to avoid the model. " "Use a lower angle to make them more vertical and more stable. Use a higher angle for branches to merge faster."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 10; def->max = 85; def->mode = comAdvanced; @@ -5076,7 +5076,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Tree support branch distance"); def->category = L("Support"); def->tooltip = L("This setting determines the distance between neighboring tree support nodes."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 1.0; def->max = 10; def->mode = comAdvanced; @@ -5086,7 +5086,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Tree support branch distance"); def->category = L("Support"); def->tooltip = L("This setting determines the distance between neighboring tree support nodes."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 1.0; def->max = 10; def->mode = comAdvanced; @@ -5130,7 +5130,7 @@ void PrintConfigDef::init_fff_params() def->category = L("Support"); // TRN PrintSettings: "Organic supports" > "Tip Diameter" def->tooltip = L("Branch tip diameter for organic supports."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0.1f; def->max = 100.f; def->mode = comAdvanced; @@ -5140,7 +5140,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Tree support branch diameter"); def->category = L("Support"); def->tooltip = L("This setting determines the initial diameter of support nodes."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 1.0; def->max = 10; def->mode = comAdvanced; @@ -5154,7 +5154,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("The angle of the branches' diameter as they gradually become thicker towards the bottom. " "An angle of 0 will cause the branches to have uniform thickness over their length. " "A bit of an angle can increase stability of the organic support."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->min = 0; def->max = 15; def->mode = comAdvanced; @@ -5164,7 +5164,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Tree support branch diameter"); def->category = L("Support"); def->tooltip = L("This setting determines the initial diameter of support nodes."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 1.0; def->max = 10; def->mode = comAdvanced; @@ -5222,7 +5222,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Support Ironing line spacing"); def->category = L("Support"); def->tooltip = L("The distance between the lines of ironing."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 1; def->mode = comAdvanced; @@ -5252,7 +5252,7 @@ void PrintConfigDef::init_fff_params() "This may be useful if your printer does not support M141/M191 commands, or if you desire " "to handle heat soaking in the print start macro if no active chamber heater is installed." ); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Chamber temperature"); def->min = 0; def->max = max_temp; @@ -5261,7 +5261,7 @@ void PrintConfigDef::init_fff_params() def = this->add("nozzle_temperature", coInts); def->label = L("Other layers"); def->tooltip = L("Nozzle temperature for layers after the initial one."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->full_label = L("Nozzle temperature"); def->min = 0; def->max = max_temp; @@ -5270,7 +5270,7 @@ void PrintConfigDef::init_fff_params() def = this->add("nozzle_temperature_range_low", coInts); def->label = L("Min"); //def->tooltip = L(""); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = max_temp; def->set_default_value(new ConfigOptionInts { 190 }); @@ -5278,7 +5278,7 @@ void PrintConfigDef::init_fff_params() def = this->add("nozzle_temperature_range_high", coInts); def->label = L("Max"); //def->tooltip = L(""); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = max_temp; def->set_default_value(new ConfigOptionInts { 240 }); @@ -5330,7 +5330,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Top surface"); def->category = L("Speed"); def->tooltip = L("Speed of top surface infill which is solid."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(100)); @@ -5353,14 +5353,14 @@ void PrintConfigDef::init_fff_params() "thinner than this value. This can avoid having too thin shell when layer height is small. 0 means that " "this setting is disabled and thickness of top shell is absolutely determined by top shell layers."); def->full_label = L("Top shell thickness"); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->set_default_value(new ConfigOptionFloat(0.6)); def = this->add("travel_speed", coFloat); def->label = L("Travel"); def->tooltip = L("Speed of travel which is faster and without extrusion."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(120)); @@ -5370,7 +5370,7 @@ void PrintConfigDef::init_fff_params() //def->tooltip = L("Speed of vertical travel along z axis. " // "This is typically lower because build plate or gantry is hard to be moved. " // "Zero means using travel speed directly in G-code, but will be limited by printer's ability when run G-code."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->min = 0; def->mode = comDevelop; def->set_default_value(new ConfigOptionFloat(0.)); @@ -5388,7 +5388,7 @@ void PrintConfigDef::init_fff_params() "Depending on how long the wipe operation lasts, how fast and long the extruder/filament retraction settings are, " "a retraction move may be needed to retract the remaining filament.\n\n" "Setting a value in the retract amount before wipe setting below will perform any excess retraction before the wipe, else it will be performed after."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 1. }); @@ -5423,14 +5423,14 @@ void PrintConfigDef::init_fff_params() def = this->add("flush_multiplier", coFloat); def->label = L("Flush multiplier"); def->tooltip = L("The actual flushing volumes is equal to the flush multiplier multiplied by the flushing volumes in the table."); - def->sidetext = ""; + //def->sidetext = ""; def->set_default_value(new ConfigOptionFloat(0.3)); // BBS def = this->add("prime_volume", coFloat); def->label = L("Prime volume"); def->tooltip = L("The volume of material to prime extruder on tower."); - def->sidetext = L("mm³"); + def->sidetext = "mm³"; // cubic milimeters, don't need translation def->min = 1.0; def->mode = comSimple; def->set_default_value(new ConfigOptionFloat(45.)); @@ -5438,7 +5438,7 @@ void PrintConfigDef::init_fff_params() def = this->add("wipe_tower_x", coFloats); //def->label = L("Position X"); //def->tooltip = L("X coordinate of the left front corner of a wipe tower."); - //def->sidetext = L("mm"); + //def->sidetext = "mm"; // milimeters, don't need translation def->mode = comDevelop; // BBS: change data type to floats to add partplate logic def->set_default_value(new ConfigOptionFloats{ 15. }); @@ -5446,7 +5446,7 @@ void PrintConfigDef::init_fff_params() def = this->add("wipe_tower_y", coFloats); //def->label = L("Position Y"); //def->tooltip = L("Y coordinate of the left front corner of a wipe tower."); - //def->sidetext = L("mm"); + //def->sidetext = "mm"; // milimeters, don't need translation def->mode = comDevelop; // BBS: change data type to floats to add partplate logic def->set_default_value(new ConfigOptionFloats{ 220. }); @@ -5454,7 +5454,7 @@ void PrintConfigDef::init_fff_params() def = this->add("prime_tower_width", coFloat); def->label = L("Width"); def->tooltip = L("Width of the prime tower."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 2.0; def->mode = comSimple; def->set_default_value(new ConfigOptionFloat(60.)); @@ -5462,14 +5462,14 @@ void PrintConfigDef::init_fff_params() def = this->add("wipe_tower_rotation_angle", coFloat); def->label = L("Wipe tower rotation angle"); def->tooltip = L("Wipe tower rotation angle with respect to x-axis."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.)); def = this->add("prime_tower_brim_width", coFloat); def->label = L("Brim width"); def->tooltip = L("Width of the brim."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->min = 0.; def->set_default_value(new ConfigOptionFloat(3.)); @@ -5478,7 +5478,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Stabilization cone apex angle"); def->tooltip = L("Angle at the apex of the cone that is used to stabilize the wipe tower. " "Larger angle means wider base."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->mode = comAdvanced; def->min = 0.; def->max = 90.; @@ -5490,9 +5490,9 @@ void PrintConfigDef::init_fff_params() "When purging, if the sparse infill speed or calculated speed from the filament max volumetric speed is lower, the lowest will be used instead.\n\n" "When printing the sparse layers, if the internal perimeter speed or calculated speed from the filament max volumetric speed is lower, the lowest will be used instead.\n\n" "Increasing this speed may affect the tower's stability as well as increase the force with which the nozzle collides with any blobs that may have formed on the wipe tower.\n\n" - "Before increasing this parameter beyond the default of 90mm/sec, make sure your printer can reliably bridge at the increased speeds and that ooze when tool changing is well controlled.\n\n" + "Before increasing this parameter beyond the default of 90 mm/s, make sure your printer can reliably bridge at the increased speeds and that ooze when tool changing is well controlled.\n\n" "For the wipe tower external perimeters the internal perimeter speed is used regardless of this setting."); - def->sidetext = L("mm/s"); + def->sidetext = "mm/s"; // milimeters per second, don't need translation def->mode = comAdvanced; def->min = 10; def->set_default_value(new ConfigOptionFloat(90.)); @@ -5517,7 +5517,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Extra rib length"); def->tooltip = L("Positive values can increase the size of the rib wall, while negative values can reduce the size." "However, the size of the rib wall can not be smaller than that determined by the cleaning volume."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->max = 300; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -5525,7 +5525,7 @@ void PrintConfigDef::init_fff_params() def = this->add("wipe_tower_rib_width", coFloat); def->label = L("Rib width"); def->tooltip = L("Rib width"); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->min = 0; def->set_default_value(new ConfigOptionFloat(8)); @@ -5582,7 +5582,7 @@ void PrintConfigDef::init_fff_params() def = this->add("wipe_tower_bridging", coFloat); def->label = L("Maximal bridging distance"); def->tooltip = L("Maximal distance between supports on sparse infill sections."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(10.)); @@ -5609,7 +5609,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Idle temperature"); def->tooltip = L("Nozzle temperature when the tool is currently not used in multi-tool setups. " "This is only used when 'Ooze prevention' is active in Print Settings. Set to 0 to disable."); - def->sidetext = "°C"; + def->sidetext = "\u2103" /* °C */; // degrees Celsius, don't need translation def->min = 0; def->max = max_temp; def->set_default_value(new ConfigOptionInts{0}); @@ -5620,7 +5620,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Holes in objects will expand or contract in the XY plane by the configured value. " "Positive values make holes bigger, negative values make holes smaller. " "This function is used to adjust sizes slightly when the objects have assembling issues."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -5630,7 +5630,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Contours of objects will expand or contract in the XY plane by the configured value. " "Positive values make contours bigger, negative values make contours smaller. " "This function is used to adjust sizes slightly when the objects have assembling issues."); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); @@ -5743,7 +5743,7 @@ void PrintConfigDef::init_fff_params() " an angle greater than this setting will not have transitions and no walls will be " "printed in the center to fill the remaining space. Reducing this setting reduces " "the number and length of these center walls, but may leave gaps or overextrude."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->mode = comAdvanced; def->min = 1.; def->max = 59.; @@ -5777,7 +5777,7 @@ void PrintConfigDef::init_fff_params() "NOTE: Bottom and top surfaces will not be affected by this value to prevent visual gaps on the outside of the model. " "Adjust 'One wall threshold' in the Advanced settings below to adjust the sensitivity of what is considered a top-surface. " "'One wall threshold' is only visible if this setting is set above the default value of 0.5, or if single-wall top surfaces is enabled."); - def->sidetext = L("mm"); // ORCA add side text + def->sidetext = "mm"; // milimeters, don't need translation def->mode = comAdvanced; def->min = 0.0; def->max = 25.0; @@ -6400,7 +6400,7 @@ void PrintConfigDef::init_sla_params() //def->label = L(""); //def->category = L(""); //def->tooltip = L(""); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->set_default_value(new ConfigOptionFloat(1.)); @@ -6541,7 +6541,7 @@ void PrintConfigDef::init_sla_params() //def->label = L(""); //def->category = L(""); //def->tooltip = L(""); - def->sidetext = L("mm"); + def->sidetext = "mm"; // milimeters, don't need translation def->min = 0; def->max = 10; def->mode = comAdvanced; @@ -7632,19 +7632,19 @@ CLITransformConfigDef::CLITransformConfigDef() def = this->add("rotate", coFloat); def->label = L("Rotate"); def->tooltip = L("Rotation angle around the Z axis in degrees."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->set_default_value(new ConfigOptionFloat(0)); def = this->add("rotate_x", coFloat); def->label = L("Rotate around X"); def->tooltip = L("Rotation angle around the X axis in degrees."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->set_default_value(new ConfigOptionFloat(0)); def = this->add("rotate_y", coFloat); def->label = L("Rotate around Y"); def->tooltip = L("Rotation angle around the Y axis in degrees."); - def->sidetext = "°"; + def->sidetext = "°"; // degrees, don't need translation def->set_default_value(new ConfigOptionFloat(0)); def = this->add("scale", coFloat); diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 3ee1930d27..1aed26e661 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -49,7 +49,7 @@ void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter para def.min = 0; def.max = 214700; def.width = 10; // increase width for large scale printers with 4 digit values - def.sidetext = L("mm"); + def.sidetext = "mm"; // milimeters, don't need translation def.label = get_option_label(param); def.tooltip = L("Size in X and Y of the rectangular plate."); key = "rect_size"; @@ -60,7 +60,7 @@ void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter para def.min = -107350; def.max = 107350; def.width = 10; // increase width for large scale printers with 4 digit values - def.sidetext = L("mm"); + def.sidetext = "mm"; // milimeters, don't need translation def.label = get_option_label(param); def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle."); key = "rect_origin"; @@ -69,7 +69,7 @@ void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter para def.type = coFloat; def.set_default_value(new ConfigOptionFloat(200)); def.width = 10; // match size - def.sidetext = L("mm"); + def.sidetext = "mm"; // milimeters, don't need translation def.label = get_option_label(param); def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center."); key = "diameter"; diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp index 17aca8df5c..12cb6e233e 100644 --- a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp @@ -313,7 +313,7 @@ void CaliPresetCustomRangePanel::create_panel(wxWindow* parent) m_title_texts[i]->Wrap(-1); m_title_texts[i]->SetFont(::Label::Body_14); item_sizer->Add(m_title_texts[i], 0, wxALL, 0); - m_value_inputs[i] = new TextInput(parent, wxEmptyString, wxString::FromUTF8("°C"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, 0); + m_value_inputs[i] = new TextInput(parent, wxEmptyString, wxString::FromUTF8("\u2103" /* °C */), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, 0); m_value_inputs[i]->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); m_value_inputs[i]->GetTextCtrl()->Bind(wxEVT_TEXT, [this, i](wxCommandEvent& event) { std::string number = m_value_inputs[i]->GetTextCtrl()->GetValue().ToStdString(); @@ -392,7 +392,7 @@ void CaliPresetTipsPanel::create_panel(wxWindow* parent) auto nozzle_temp_sizer = new wxBoxSizer(wxVERTICAL); auto nozzle_temp_text = new Label(parent, _L("Nozzle temperature")); nozzle_temp_text->SetFont(Label::Body_12); - m_nozzle_temp = new TextInput(parent, wxEmptyString, wxString::FromUTF8("°C"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, wxTE_READONLY); + m_nozzle_temp = new TextInput(parent, wxEmptyString, wxString::FromUTF8("\u2103" /* °C */), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, wxTE_READONLY); m_nozzle_temp->SetBorderWidth(0); nozzle_temp_sizer->Add(nozzle_temp_text, 0, wxALIGN_LEFT); nozzle_temp_sizer->Add(m_nozzle_temp, 0, wxEXPAND); @@ -439,7 +439,7 @@ void CaliPresetTipsPanel::set_params(int nozzle_temp, int bed_temp, float max_vo m_nozzle_temp->GetTextCtrl()->SetValue(text_nozzle_temp); std::string bed_temp_text = bed_temp==0 ? "-": std::to_string(bed_temp); - m_bed_temp->SetLabel(wxString::FromUTF8(bed_temp_text + "°C")); + m_bed_temp->SetLabel(wxString::FromUTF8(bed_temp_text + "\u2103" /* °C */)); wxString flow_val_text = wxString::Format("%0.2f", max_volumetric); m_max_volumetric_speed->GetTextCtrl()->SetValue(flow_val_text); diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index f9a06a02e1..a58186a3f9 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -278,7 +278,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt const auto &variant = model.variants[i]; const auto label = model.technology == ptFFF - ? from_u8((boost::format("%1% %2% %3%") % variant.name % _utf8(L("mm")) % _utf8(L("nozzle"))).str()) + ? from_u8((boost::format("%1% %2% %3%") % variant.name % _utf8("mm") % _utf8(L("nozzle"))).str()) : from_u8(model.name); if (i == 1) { @@ -1353,7 +1353,7 @@ PageDiameters::PageDiameters(ConfigWizard *parent) auto *sizer_nozzle = new wxFlexGridSizer(3, 5, 5); auto *text_nozzle = new wxStaticText(this, wxID_ANY, _L("Nozzle Diameter:")); - auto *unit_nozzle = new wxStaticText(this, wxID_ANY, _L("mm")); + auto *unit_nozzle = new wxStaticText(this, wxID_ANY, "mm"); sizer_nozzle->AddGrowableCol(0, 1); sizer_nozzle->Add(text_nozzle, 0, wxALIGN_CENTRE_VERTICAL); sizer_nozzle->Add(diam_nozzle); @@ -1367,7 +1367,7 @@ PageDiameters::PageDiameters(ConfigWizard *parent) auto *sizer_filam = new wxFlexGridSizer(3, 5, 5); auto *text_filam = new wxStaticText(this, wxID_ANY, _L("Filament Diameter:")); - auto *unit_filam = new wxStaticText(this, wxID_ANY, _L("mm")); + auto *unit_filam = new wxStaticText(this, wxID_ANY, "mm"); sizer_filam->AddGrowableCol(0, 1); sizer_filam->Add(text_filam, 0, wxALIGN_CENTRE_VERTICAL); sizer_filam->Add(diam_filam); @@ -1448,7 +1448,7 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent) auto *sizer_extr = new wxFlexGridSizer(3, 5, 5); auto *text_extr = new wxStaticText(this, wxID_ANY, _L("Extrusion Temperature:")); - auto *unit_extr = new wxStaticText(this, wxID_ANY, "°C"); + auto *unit_extr = new wxStaticText(this, wxID_ANY, "\u2103" /* °C */); sizer_extr->AddGrowableCol(0, 1); sizer_extr->Add(text_extr, 0, wxALIGN_CENTRE_VERTICAL); sizer_extr->Add(spin_extr); @@ -1462,7 +1462,7 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent) auto *sizer_bed = new wxFlexGridSizer(3, 5, 5); auto *text_bed = new wxStaticText(this, wxID_ANY, _L("Bed Temperature:")); - auto *unit_bed = new wxStaticText(this, wxID_ANY, "°C"); + auto *unit_bed = new wxStaticText(this, wxID_ANY, "\u2103" /* °C */); sizer_bed->AddGrowableCol(0, 1); sizer_bed->Add(text_bed, 0, wxALIGN_CENTRE_VERTICAL); sizer_bed->Add(spin_bed); diff --git a/src/slic3r/GUI/CreatePresetsDialog.cpp b/src/slic3r/GUI/CreatePresetsDialog.cpp index d2dfcd054e..ca8bb0c9de 100644 --- a/src/slic3r/GUI/CreatePresetsDialog.cpp +++ b/src/slic3r/GUI/CreatePresetsDialog.cpp @@ -1870,7 +1870,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_bed_size_item(wxWindow *parent) // ORCA use icon on input box to match style with other Point fields horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10)); wxBoxSizer *length_input_sizer = new wxBoxSizer(wxVERTICAL); - m_bed_size_x_input = new TextInput(parent, "200", _L("mm"), "inputbox_x", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); + m_bed_size_x_input = new TextInput(parent, "200", "mm", "inputbox_x", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); wxTextValidator validator(wxFILTER_DIGITS); m_bed_size_x_input->GetTextCtrl()->SetValidator(validator); length_input_sizer->Add(m_bed_size_x_input, 0, wxEXPAND | wxLEFT, FromDIP(5)); @@ -1880,7 +1880,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_bed_size_item(wxWindow *parent) // ORCA use icon on input box to match style with other Point fields horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10)); wxBoxSizer *width_input_sizer = new wxBoxSizer(wxVERTICAL); - m_bed_size_y_input = new TextInput(parent, "200", _L("mm"), "inputbox_y", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); + m_bed_size_y_input = new TextInput(parent, "200", "mm", "inputbox_y", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); m_bed_size_y_input->GetTextCtrl()->SetValidator(validator); width_input_sizer->Add(m_bed_size_y_input, 0, wxEXPAND | wxALL, 0); horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); @@ -1903,7 +1903,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_origin_item(wxWindow *parent) // ORCA use icon on input box to match style with other Point fields horizontal_sizer->Add(length_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10)); wxBoxSizer *length_input_sizer = new wxBoxSizer(wxVERTICAL); - m_bed_origin_x_input = new TextInput(parent, "0", _L("mm"), "inputbox_x", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); + m_bed_origin_x_input = new TextInput(parent, "0", "mm", "inputbox_x", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); wxTextValidator validator(wxFILTER_DIGITS); m_bed_origin_x_input->GetTextCtrl()->SetValidator(validator); length_input_sizer->Add(m_bed_origin_x_input, 0, wxEXPAND | wxLEFT, FromDIP(5)); // Align with other @@ -1913,7 +1913,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_origin_item(wxWindow *parent) // ORCA use icon on input box to match style with other Point fields horizontal_sizer->Add(width_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxALIGN_CENTER_VERTICAL, FromDIP(10)); wxBoxSizer *width_input_sizer = new wxBoxSizer(wxVERTICAL); - m_bed_origin_y_input = new TextInput(parent, "0", _L("mm"), "inputbox_y", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); + m_bed_origin_y_input = new TextInput(parent, "0", "mm", "inputbox_y", wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); m_bed_origin_y_input->GetTextCtrl()->SetValidator(validator); width_input_sizer->Add(m_bed_origin_y_input, 0, wxEXPAND | wxALL, 0); horizontal_sizer->Add(width_input_sizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); @@ -2006,7 +2006,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_max_print_height_item(wxWindow *pa horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(10)); wxBoxSizer *hight_input_sizer = new wxBoxSizer(wxVERTICAL); - m_print_height_input = new TextInput(parent, "200", _L("mm"), wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); // Use same alignment with all other input boxes + m_print_height_input = new TextInput(parent, "200", "mm", wxEmptyString, wxDefaultPosition, PRINTER_SPACE_SIZE, wxTE_PROCESS_ENTER); // Use same alignment with all other input boxes wxTextValidator validator(wxFILTER_DIGITS); m_print_height_input->GetTextCtrl()->SetValidator(validator); hight_input_sizer->Add(m_print_height_input, 0, wxEXPAND | wxLEFT, FromDIP(5)); diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index cd94ab183a..a42af2664c 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -3088,7 +3088,7 @@ int MachineObject::parse_json(std::string payload, bool key_field_only) if (jj.contains("errno")) { if (jj["errno"].is_number()) { if (jj["errno"].get() == -2) { - wxString text = _L("The current chamber temperature or the target chamber temperature exceeds 45\u2103. " + wxString text = _L("The current chamber temperature or the target chamber temperature exceeds 45\u2103. " /* 45°C */ "In order to avoid extruder clogging, low temperature filament (PLA/PETG/TPU) is not allowed to be loaded."); GUI::wxGetApp().push_notification(text); } @@ -3102,11 +3102,11 @@ int MachineObject::parse_json(std::string payload, bool key_field_only) wxString text; if (jj["errno"].get() == -2) { text = _L("Low temperature filament (PLA/PETG/TPU) is loaded in the extruder. " - "In order to avoid extruder clogging, it is not allowed to set the chamber temperature above 45\u2103."); + "In order to avoid extruder clogging, it is not allowed to set the chamber temperature above 45\u2103." /* 45°C */); } else if (jj["errno"].get() == -4) { text = _L("When you set the chamber temperature below 40\u2103, the chamber temperature control will not be activated, " - "and the target chamber temperature will automatically be set to 0\u2103."); + "and the target chamber temperature will automatically be set to 0\u2103." /* 0°C */); } if(!text.empty()){ #if __WXOSX__ diff --git a/src/slic3r/GUI/ExtrusionCalibration.cpp b/src/slic3r/GUI/ExtrusionCalibration.cpp index 26216edc93..677fff64fe 100644 --- a/src/slic3r/GUI/ExtrusionCalibration.cpp +++ b/src/slic3r/GUI/ExtrusionCalibration.cpp @@ -127,21 +127,21 @@ void ExtrusionCalibration::create() wxWindow::GetTextExtent(_L("Bed Temperature")).x), wxWindow::GetTextExtent(_L("Max volumetric speed")).x), EXTRUSION_CALIBRATION_INPUT_SIZE.x); - m_nozzle_temp = new TextInput(m_step_1_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); + m_nozzle_temp = new TextInput(m_step_1_panel, wxEmptyString, "\u2103" /* °C */, "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); nozzle_temp_sizer->Add(nozzle_temp_text, 0, wxALIGN_LEFT); nozzle_temp_sizer->AddSpacer(FromDIP(4)); nozzle_temp_sizer->Add(m_nozzle_temp, 0, wxEXPAND); auto bed_temp_sizer = new wxBoxSizer(wxVERTICAL); auto bed_temp_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Bed temperature")); - m_bed_temp = new TextInput(m_step_1_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); + m_bed_temp = new TextInput(m_step_1_panel, wxEmptyString, "\u2103" /* °C */, "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); bed_temp_sizer->Add(bed_temp_text, 0, wxALIGN_LEFT); bed_temp_sizer->AddSpacer(FromDIP(4)); bed_temp_sizer->Add(m_bed_temp, 0, wxEXPAND); auto max_flow_sizer = new wxBoxSizer(wxVERTICAL); auto max_flow_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Max volumetric speed")); - m_max_flow_ratio = new TextInput(m_step_1_panel, wxEmptyString, _L("mm\u00B3"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); + m_max_flow_ratio = new TextInput(m_step_1_panel, wxEmptyString, "mm³", "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY); max_flow_sizer->Add(max_flow_text, 0, wxALIGN_LEFT); max_flow_sizer->AddSpacer(FromDIP(4)); max_flow_sizer->Add(m_max_flow_ratio, 0, wxEXPAND); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 172a9959d7..fe3660baa9 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4606,13 +4606,13 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv auto upto_label = [](double z) { char buf[64]; ::sprintf(buf, "%.2f", z); - return _u8L("up to") + " " + std::string(buf) + " " + _u8L("mm"); + return _u8L("up to") + " " + std::string(buf) + " " + "mm"; }; auto above_label = [](double z) { char buf[64]; ::sprintf(buf, "%.2f", z); - return _u8L("above") + " " + std::string(buf) + " " + _u8L("mm"); + return _u8L("above") + " " + std::string(buf) + " " + "mm"; }; auto fromto_label = [](double z1, double z2) { @@ -4620,7 +4620,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv ::sprintf(buf1, "%.2f", z1); char buf2[64]; ::sprintf(buf2, "%.2f", z2); - return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm"); + return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + "mm"; }; auto role_time_and_percent = [time_mode](ExtrusionRole role) { diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index 9b36885e56..a0e19983ce 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -135,7 +135,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus m_grid_sizer->Add(editor, 1, wxEXPAND); auto sizer2 = new wxBoxSizer(wxHORIZONTAL); - auto unit_text = new wxStaticText(m_parent, wxID_ANY, _L("mm"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + auto unit_text = new wxStaticText(m_parent, wxID_ANY, "mm", wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); unit_text->SetBackgroundStyle(wxBG_STYLE_PAINT); unit_text->SetFont(wxGetApp().normal_font()); sizer2->Add(unit_text, 0, wxALIGN_CENTER_VERTICAL); @@ -156,7 +156,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus //auto sizer = new wxBoxSizer(wxHORIZONTAL); //sizer->Add(editor); - //auto temp = new wxStaticText(m_parent, wxID_ANY, _L("mm")); + //auto temp = new wxStaticText(m_parent, wxID_ANY, "mm"); //temp->SetBackgroundStyle(wxBG_STYLE_PAINT); //temp->SetFont(wxGetApp().normal_font()); //sizer->Add(temp, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit()); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index cc28670443..89bf458b30 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -157,7 +157,7 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent parent->GetNthChild(i)->SetIdx(i + 1); } const std::string label_range = (boost::format(" %.2f-%.2f ") % layer_range.first % layer_range.second).str(); - m_name = _(L("Range")) + label_range + "(" + _(L("mm")) + ")"; + m_name = _(L("Range")) + label_range + "(" + _("mm") + ")"; m_bmp = create_scaled_bitmap(LayerIcon); set_icons(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 08881caa6f..fc7f6c7305 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -9618,7 +9618,7 @@ void Plater::_calib_pa_pattern(const Calib_Params& params) speeds.assign({speed}); const auto msg{_L("INFO:") + "\n" + - _L("No speeds provided for calibration. Use default optimal speed ") + std::to_string(long(speed)) + _L("mm/s")}; + _L("No speeds provided for calibration. Use default optimal speed ") + std::to_string(long(speed)) + "mm/s"}; get_notification_manager()->push_notification(msg.ToStdString()); } else if (speeds.size() == 1) { // If we have single value provided, set speed using global configuration. diff --git a/src/slic3r/GUI/RammingChart.cpp b/src/slic3r/GUI/RammingChart.cpp index 265c4aa4e0..4d4bcc5082 100644 --- a/src/slic3r/GUI/RammingChart.cpp +++ b/src/slic3r/GUI/RammingChart.cpp @@ -89,10 +89,10 @@ void Chart::draw() { } // axis labels: - wxString label = _(L("Time")) + " ("+_(L("s"))+")"; + wxString label = _(L("Time")) + " ("+_("s")+")"; dc.GetTextExtent(label,&text_width,&text_height); dc.DrawText(label,wxPoint(0.5*(m_rect.GetRight()+m_rect.GetLeft())-text_width/2.f, m_rect.GetBottom()+0.6*legend_side)); - label = _(L("Volumetric speed")) + " (" + _(L("mm³/s")) + ")"; + label = _(L("Volumetric speed")) + " (" + _("mm³/s") + ")"; dc.GetTextExtent(label,&text_width,&text_height); dc.DrawRotatedText(label,wxPoint(0,0.5*(m_rect.GetBottom()+m_rect.GetTop())+text_width/2.f),90); } diff --git a/src/slic3r/GUI/WipeTowerDialog.cpp b/src/slic3r/GUI/WipeTowerDialog.cpp index 20532464ee..58045c57b5 100644 --- a/src/slic3r/GUI/WipeTowerDialog.cpp +++ b/src/slic3r/GUI/WipeTowerDialog.cpp @@ -115,10 +115,10 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters) update_ui(m_chart); sizer_chart->Add(m_chart, 0, wxALL, 5); - m_widget_time = new SpinInput(this, wxEmptyString, _L("ms") , wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 0 , 5000 , 3000, 500); - m_widget_volume = new SpinInput(this, wxEmptyString, _L("mm³"), wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 0 , 10000, 0 ); - m_widget_ramming_line_width_multiplicator = new SpinInput(this, wxEmptyString, _L("%") , wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 10, 200 , 100 ); - m_widget_ramming_step_multiplicator = new SpinInput(this, wxEmptyString, _L("%") , wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 10, 200 , 100 ); + m_widget_time = new SpinInput(this, wxEmptyString, "ms" , wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 0 , 5000 , 3000, 500); + m_widget_volume = new SpinInput(this, wxEmptyString, "mm³", wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 0 , 10000, 0 ); + m_widget_ramming_line_width_multiplicator = new SpinInput(this, wxEmptyString, "%" , wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 10, 200 , 100 ); + m_widget_ramming_step_multiplicator = new SpinInput(this, wxEmptyString, "%" , wxDefaultPosition, wxSize(scale(120), -1), wxSP_ARROW_KEYS, 10, 200 , 100 ); auto add_title = [this, sizer_param](wxString label){ auto title = new StaticLine(this, 0, label); diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 92455ec5de..cfe8035844 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -306,7 +306,7 @@ Temp_Calibration_Dlg::Temp_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plat // start temp auto start_temp_sizer = new wxBoxSizer(wxHORIZONTAL); auto start_temp_text = new wxStaticText(this, wxID_ANY, start_temp_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStart = new TextInput(this, std::to_string(230), _L("\u2103"), "", wxDefaultPosition, ti_size); + m_tiStart = new TextInput(this, std::to_string(230), "\u2103" /* °C */, "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); start_temp_sizer->Add(start_temp_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); start_temp_sizer->Add(m_tiStart , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -315,7 +315,7 @@ Temp_Calibration_Dlg::Temp_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plat // end temp auto end_temp_sizer = new wxBoxSizer(wxHORIZONTAL); auto end_temp_text = new wxStaticText(this, wxID_ANY, end_temp_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiEnd = new TextInput(this, std::to_string(190), _L("\u2103"), "", wxDefaultPosition, ti_size); + m_tiEnd = new TextInput(this, std::to_string(190), "\u2103" /* °C */, "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); end_temp_sizer->Add(end_temp_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); end_temp_sizer->Add(m_tiEnd , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -324,7 +324,7 @@ Temp_Calibration_Dlg::Temp_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plat // temp step auto temp_step_sizer = new wxBoxSizer(wxHORIZONTAL); auto temp_step_text = new wxStaticText(this, wxID_ANY, temp_step_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStep = new TextInput(this, wxString::FromDouble(5),_L("\u2103"), "", wxDefaultPosition, ti_size); + m_tiStep = new TextInput(this, wxString::FromDouble(5),"\u2103" /* °C */, "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); m_tiStep->Enable(false); temp_step_sizer->Add(temp_step_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -353,7 +353,7 @@ Temp_Calibration_Dlg::Temp_Calibration_Dlg(wxWindow* parent, wxWindowID id, Plat if(!ti->GetTextCtrl()->GetValue().ToULong(&t)) return; if(t> 350 || t < 170){ - MessageDialog msg_dlg(nullptr, wxString::Format(L"Supported range: 170%s - 350%s",_L("\u2103"),_L("\u2103")), wxEmptyString, wxICON_WARNING | wxOK); + MessageDialog msg_dlg(nullptr, wxString::Format(L"Supported range: 170%s - 350%s","\u2103" /* °C */,"\u2103" /* °C */), wxEmptyString, wxICON_WARNING | wxOK); msg_dlg.ShowModal(); if(t > 350) t = 350; @@ -479,7 +479,7 @@ MaxVolumetricSpeed_Test_Dlg::MaxVolumetricSpeed_Test_Dlg(wxWindow* parent, wxWin // start vol auto start_vol_sizer = new wxBoxSizer(wxHORIZONTAL); auto start_vol_text = new wxStaticText(this, wxID_ANY, start_vol_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStart = new TextInput(this, std::to_string(5), _L("mm³/s"), "", wxDefaultPosition, ti_size); + m_tiStart = new TextInput(this, std::to_string(5), "mm³/s", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); start_vol_sizer->Add(start_vol_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -489,7 +489,7 @@ MaxVolumetricSpeed_Test_Dlg::MaxVolumetricSpeed_Test_Dlg(wxWindow* parent, wxWin // end vol auto end_vol_sizer = new wxBoxSizer(wxHORIZONTAL); auto end_vol_text = new wxStaticText(this, wxID_ANY, end_vol_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiEnd = new TextInput(this, std::to_string(20), _L("mm³/s"), "", wxDefaultPosition, ti_size); + m_tiEnd = new TextInput(this, std::to_string(20), "mm³/s", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); end_vol_sizer->Add(end_vol_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); end_vol_sizer->Add(m_tiEnd , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -498,7 +498,7 @@ MaxVolumetricSpeed_Test_Dlg::MaxVolumetricSpeed_Test_Dlg(wxWindow* parent, wxWin // vol step auto vol_step_sizer = new wxBoxSizer(wxHORIZONTAL); auto vol_step_text = new wxStaticText(this, wxID_ANY, vol_step_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStep = new TextInput(this, wxString::FromDouble(0.5), _L("mm³/s"), "", wxDefaultPosition, ti_size); + m_tiStep = new TextInput(this, wxString::FromDouble(0.5), "mm³/s", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); vol_step_sizer->Add(vol_step_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); vol_step_sizer->Add(m_tiStep , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -578,7 +578,7 @@ VFA_Test_Dlg::VFA_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) // start vol auto start_vol_sizer = new wxBoxSizer(wxHORIZONTAL); auto start_vol_text = new wxStaticText(this, wxID_ANY, start_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStart = new TextInput(this, std::to_string(40), _L("mm/s"), "", wxDefaultPosition, ti_size); + m_tiStart = new TextInput(this, std::to_string(40), "mm/s", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); start_vol_sizer->Add(start_vol_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -588,7 +588,7 @@ VFA_Test_Dlg::VFA_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) // end vol auto end_vol_sizer = new wxBoxSizer(wxHORIZONTAL); auto end_vol_text = new wxStaticText(this, wxID_ANY, end_vol_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiEnd = new TextInput(this, std::to_string(200), _L("mm/s"), "", wxDefaultPosition, ti_size); + m_tiEnd = new TextInput(this, std::to_string(200), "mm/s", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); end_vol_sizer->Add(end_vol_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); end_vol_sizer->Add(m_tiEnd , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -597,7 +597,7 @@ VFA_Test_Dlg::VFA_Test_Dlg(wxWindow* parent, wxWindowID id, Plater* plater) // vol step auto vol_step_sizer = new wxBoxSizer(wxHORIZONTAL); auto vol_step_text = new wxStaticText(this, wxID_ANY, vol_step_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStep = new TextInput(this, wxString::FromDouble(10), _L("mm/s"), "", wxDefaultPosition, ti_size); + m_tiStep = new TextInput(this, wxString::FromDouble(10), "mm/s", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); vol_step_sizer->Add(vol_step_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); vol_step_sizer->Add(m_tiStep , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -680,7 +680,7 @@ Retraction_Test_Dlg::Retraction_Test_Dlg(wxWindow* parent, wxWindowID id, Plater // start length auto start_length_sizer = new wxBoxSizer(wxHORIZONTAL); auto start_length_text = new wxStaticText(this, wxID_ANY, start_length_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStart = new TextInput(this, std::to_string(0), _L("mm"), "", wxDefaultPosition, ti_size); + m_tiStart = new TextInput(this, std::to_string(0), "mm", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); start_length_sizer->Add(start_length_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -690,7 +690,7 @@ Retraction_Test_Dlg::Retraction_Test_Dlg(wxWindow* parent, wxWindowID id, Plater // end length auto end_length_sizer = new wxBoxSizer(wxHORIZONTAL); auto end_length_text = new wxStaticText(this, wxID_ANY, end_length_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiEnd = new TextInput(this, std::to_string(2), _L("mm"), "", wxDefaultPosition, ti_size); + m_tiEnd = new TextInput(this, std::to_string(2), "mm", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); end_length_sizer->Add(end_length_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); end_length_sizer->Add(m_tiEnd , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -699,7 +699,7 @@ Retraction_Test_Dlg::Retraction_Test_Dlg(wxWindow* parent, wxWindowID id, Plater // length step auto length_step_sizer = new wxBoxSizer(wxHORIZONTAL); auto length_step_text = new wxStaticText(this, wxID_ANY, length_step_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiStep = new TextInput(this, wxString::FromDouble(0.1), _L("mm"), "", wxDefaultPosition, ti_size); + m_tiStep = new TextInput(this, wxString::FromDouble(0.1), "mm", "", wxDefaultPosition, ti_size); m_tiStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); length_step_sizer->Add(length_step_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); length_step_sizer->Add(m_tiStep , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -1043,7 +1043,7 @@ Junction_Deviation_Test_Dlg::Junction_Deviation_Test_Dlg(wxWindow* parent, wxWin // Start junction deviation auto start_jd_sizer = new wxBoxSizer(wxHORIZONTAL); auto start_jd_text = new wxStaticText(this, wxID_ANY, start_jd_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiJDStart = new TextInput(this, wxString::Format("%.3f", 0.000), _L("mm"), "", wxDefaultPosition, ti_size); + m_tiJDStart = new TextInput(this, wxString::Format("%.3f", 0.000), "mm", "", wxDefaultPosition, ti_size); m_tiJDStart->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); start_jd_sizer->Add(start_jd_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); start_jd_sizer->Add(m_tiJDStart , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); @@ -1052,7 +1052,7 @@ Junction_Deviation_Test_Dlg::Junction_Deviation_Test_Dlg(wxWindow* parent, wxWin // End junction deviation auto end_jd_sizer = new wxBoxSizer(wxHORIZONTAL); auto end_jd_text = new wxStaticText(this, wxID_ANY, end_jd_str, wxDefaultPosition, st_size, wxALIGN_LEFT); - m_tiJDEnd = new TextInput(this, wxString::Format("%.3f", 0.250), _L("mm"), "", wxDefaultPosition, ti_size); + m_tiJDEnd = new TextInput(this, wxString::Format("%.3f", 0.250), "mm", "", wxDefaultPosition, ti_size); m_tiJDEnd->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); end_jd_sizer->Add(end_jd_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); end_jd_sizer->Add(m_tiJDEnd , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); From 88fb8187d9816b5c30a58953bdfc173a8038aaed Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 22 Jun 2025 23:10:35 +0800 Subject: [PATCH 04/13] Allow specifying rotation patterns for Sparse and Solid infill (#9924) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SPE-2405: Add Zig Zag infill that is rectilinear infill but with a consistent pattern between layers. This Zig Zag infill is inspired by the Zig Zag infill in Cura. Change-Id: I798affa99f4b5c3bd67f47643e67530fb7c3e0cb (cherry picked from commit 2808d04d5deef6f99f9618648e46f11de03efc98) * Add Cross zag and locked-zag for shoes Ported from BambuStudio * wip * sparse infill roratation template * solid_infill_rotate_template * remove rotate_solid_infill_direction * hide sparse infill rotation template for non applicable infill pattern * hide solid_infill_rotate_template for non supported solid infill patterns * update icon * support empty string for ConfigOptionFloats deserialize * fix build errors --------- Co-authored-by: Lukáš Hejl --- resources/images/param_crosszag.svg | 44 + resources/images/param_lockedzag.svg | 29 + resources/images/param_zigzag.svg | 158 +++ resources/profiles/BBL.json | 2 +- .../BBL/process/fdm_process_common.json | 5 +- src/libslic3r/BoundingBox.cpp | 7 + src/libslic3r/BoundingBox.hpp | 4 +- src/libslic3r/Config.hpp | 12 + src/libslic3r/ExPolygon.cpp | 1095 +++++++++-------- src/libslic3r/ExPolygon.hpp | 2 +- src/libslic3r/Fill/Fill.cpp | 179 ++- src/libslic3r/Fill/Fill3DHoneycomb.hpp | 4 + src/libslic3r/Fill/FillAdaptive.hpp | 1 + src/libslic3r/Fill/FillBase.cpp | 71 +- src/libslic3r/Fill/FillBase.hpp | 40 +- src/libslic3r/Fill/FillConcentric.hpp | 1 + src/libslic3r/Fill/FillConcentricInternal.hpp | 1 + src/libslic3r/Fill/FillCrossHatch.hpp | 1 + src/libslic3r/Fill/FillGyroid.hpp | 1 + src/libslic3r/Fill/FillHoneycomb.hpp | 1 + src/libslic3r/Fill/FillLightning.hpp | 1 + src/libslic3r/Fill/FillLine.hpp | 1 + src/libslic3r/Fill/FillPlanePath.hpp | 1 + src/libslic3r/Fill/FillRectilinear.cpp | 209 +++- src/libslic3r/Fill/FillRectilinear.hpp | 49 +- src/libslic3r/Fill/FillTpmsD.hpp | 16 +- src/libslic3r/Flow.hpp | 7 + src/libslic3r/MultiPoint.cpp | 7 + src/libslic3r/MultiPoint.hpp | 2 +- src/libslic3r/Preset.cpp | 7 +- src/libslic3r/Print.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 161 ++- src/libslic3r/PrintConfig.hpp | 14 +- src/libslic3r/PrintObject.cpp | 13 +- src/slic3r/GUI/ConfigManipulation.cpp | 47 +- src/slic3r/GUI/Field.cpp | 10 + src/slic3r/GUI/GUI_Factories.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 1 - src/slic3r/GUI/Tab.cpp | 57 +- 39 files changed, 1551 insertions(+), 714 deletions(-) create mode 100644 resources/images/param_crosszag.svg create mode 100644 resources/images/param_lockedzag.svg create mode 100644 resources/images/param_zigzag.svg diff --git a/resources/images/param_crosszag.svg b/resources/images/param_crosszag.svg new file mode 100644 index 0000000000..0a21257317 --- /dev/null +++ b/resources/images/param_crosszag.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/param_lockedzag.svg b/resources/images/param_lockedzag.svg new file mode 100644 index 0000000000..55e87074ff --- /dev/null +++ b/resources/images/param_lockedzag.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/param_zigzag.svg b/resources/images/param_zigzag.svg new file mode 100644 index 0000000000..f762e99c9a --- /dev/null +++ b/resources/images/param_zigzag.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index 10383cb01e..9ac95694b3 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.10.00.36", + "version": "02.00.00.53", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/process/fdm_process_common.json b/resources/profiles/BBL/process/fdm_process_common.json index 9b99ec1b28..8a9c65ad17 100644 --- a/resources/profiles/BBL/process/fdm_process_common.json +++ b/resources/profiles/BBL/process/fdm_process_common.json @@ -71,5 +71,8 @@ "compatible_printers": [], "smooth_coefficient": "80", "overhang_totally_speed": "19", - "scarf_angle_threshold": "155" + "scarf_angle_threshold": "155", + "infill_shift_step": "0.4", + "infill_rotate_step": "0", + "symmetric_infill_y_axis": "false" } \ No newline at end of file diff --git a/src/libslic3r/BoundingBox.cpp b/src/libslic3r/BoundingBox.cpp index f2a258797b..a2a510b64c 100644 --- a/src/libslic3r/BoundingBox.cpp +++ b/src/libslic3r/BoundingBox.cpp @@ -49,6 +49,13 @@ BoundingBox BoundingBox::rotated(double angle, const Point ¢er) const return out; } +BoundingBox BoundingBox::scaled(double factor) const +{ + BoundingBox out(*this); + out.scale(factor); + return out; +} + template void BoundingBoxBase::scale(double factor) { diff --git a/src/libslic3r/BoundingBox.hpp b/src/libslic3r/BoundingBox.hpp index 9c305bd9ad..d6baa27012 100644 --- a/src/libslic3r/BoundingBox.hpp +++ b/src/libslic3r/BoundingBox.hpp @@ -222,7 +222,9 @@ public: BoundingBox(const Point &pmin, const Point &pmax) : BoundingBoxBase(pmin, pmax) {} BoundingBox(const Points &points) : BoundingBoxBase(points) {} - BoundingBox inflated(coordf_t delta) const throw() { BoundingBox out(*this); out.offset(delta); return out; } + BoundingBox inflated(coordf_t delta) const noexcept { BoundingBox out(*this); out.offset(delta); return out; } + + BoundingBox scaled(double factor) const; friend BoundingBox get_extents_rotated(const Points &points, double angle); }; diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 3ce062ac39..d5332688ab 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -657,6 +657,11 @@ public: { if (! append) this->values.clear(); + + if (str.empty()) { + this->values.push_back(0); + return true; + } std::istringstream is(str); std::string item_str; while (std::getline(is, item_str, ',')) { @@ -675,6 +680,13 @@ public: } return true; } + static bool validate_string(const std::string &str) + { + // should only have number and commas + return std::all_of(str.begin(), str.end(), [](char c) { + return std::isdigit(c) || c == ','|| std::isspace(c); + }); + } ConfigOptionFloatsTempl& operator=(const ConfigOption *opt) { diff --git a/src/libslic3r/ExPolygon.cpp b/src/libslic3r/ExPolygon.cpp index f2dbf7389a..185e925084 100644 --- a/src/libslic3r/ExPolygon.cpp +++ b/src/libslic3r/ExPolygon.cpp @@ -1,544 +1,551 @@ -#include "BoundingBox.hpp" -#include "ExPolygon.hpp" -#include "Exception.hpp" -#include "Geometry/MedialAxis.hpp" -#include "Polygon.hpp" -#include "Line.hpp" -#include "ClipperUtils.hpp" -#include "SVG.hpp" -#include -#include -#include - -namespace Slic3r { - -void ExPolygon::scale(double factor) -{ - contour.scale(factor); - for (Polygon &hole : holes) - hole.scale(factor); -} - -void ExPolygon::scale(double factor_x, double factor_y) -{ - contour.scale(factor_x, factor_y); - for (Polygon &hole : holes) - hole.scale(factor_x, factor_y); -} - -void ExPolygon::translate(const Point &p) -{ - contour.translate(p); - for (Polygon &hole : holes) - hole.translate(p); -} - -void ExPolygon::rotate(double angle) -{ - contour.rotate(angle); - for (Polygon &hole : holes) - hole.rotate(angle); -} - -void ExPolygon::rotate(double angle, const Point ¢er) -{ - contour.rotate(angle, center); - for (Polygon &hole : holes) - hole.rotate(angle, center); -} - -double ExPolygon::area() const -{ - double a = this->contour.area(); - for (const Polygon &hole : holes) - a -= - hole.area(); // holes have negative area - return a; -} - -bool ExPolygon::is_valid() const -{ - if (!this->contour.is_valid() || !this->contour.is_counter_clockwise()) return false; - for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) { - if (!(*it).is_valid() || (*it).is_counter_clockwise()) return false; - } - return true; -} - -void ExPolygon::douglas_peucker(double tolerance) -{ - this->contour.douglas_peucker(tolerance); - for (Polygon &poly : this->holes) - poly.douglas_peucker(tolerance); -} - -bool ExPolygon::contains(const Line &line) const -{ - return this->contains(Polyline(line.a, line.b)); -} - -bool ExPolygon::contains(const Polyline &polyline) const -{ - BoundingBox bbox1 = get_extents(*this); - BoundingBox bbox2 = get_extents(polyline); - bbox2.inflated(1); - if (!bbox1.overlap(bbox2)) - return false; - - return diff_pl(polyline, *this).empty(); -} - -bool ExPolygon::contains(const Polylines &polylines) const -{ - #if 0 - BoundingBox bbox = get_extents(polylines); - bbox.merge(get_extents(*this)); - SVG svg(debug_out_path("ExPolygon_contains.svg"), bbox); - svg.draw(*this); - svg.draw_outline(*this); - svg.draw(polylines, "blue"); - #endif - Polylines pl_out = diff_pl(polylines, *this); - #if 0 - svg.draw(pl_out, "red"); - #endif - return pl_out.empty(); -} - -bool ExPolygon::contains(const Point &point, bool border_result /* = true */) const -{ - if (! Slic3r::contains(contour, point, border_result)) - // Outside the outer contour, not on the contour boundary. - return false; - for (const Polygon &hole : this->holes) - if (Slic3r::contains(hole, point, ! border_result)) - // Inside a hole, not on the hole boundary. - return false; - return true; -} - -bool ExPolygon::on_boundary(const Point &point, double eps) const -{ - if (this->contour.on_boundary(point, eps)) - return true; - for (const Polygon &hole : this->holes) - if (hole.on_boundary(point, eps)) - return true; - return false; -} - -// Projection of a point onto the polygon. -Point ExPolygon::point_projection(const Point &point) const -{ - if (this->holes.empty()) { - return this->contour.point_projection(point); - } else { - double dist_min2 = std::numeric_limits::max(); - Point closest_pt_min; - for (size_t i = 0; i < this->num_contours(); ++ i) { - Point closest_pt = this->contour_or_hole(i).point_projection(point); - double d2 = (closest_pt - point).cast().squaredNorm(); - if (d2 < dist_min2) { - dist_min2 = d2; - closest_pt_min = closest_pt; - } - } - return closest_pt_min; - } -} - -bool ExPolygon::overlaps(const ExPolygon &other) const -{ - if (this->empty() || other.empty()) - return false; - - #if 0 - BoundingBox bbox = get_extents(other); - bbox.merge(get_extents(*this)); - static int iRun = 0; - SVG svg(debug_out_path("ExPolygon_overlaps-%d.svg", iRun ++), bbox); - svg.draw(*this); - svg.draw_outline(*this); - svg.draw_outline(other, "blue"); - #endif - - Polylines pl_out = intersection_pl(to_polylines(other), *this); - - #if 0 - svg.draw(pl_out, "red"); - #endif - - // See unit test SCENARIO("Clipper diff with polyline", "[Clipper]") - // for in which case the intersection_pl produces any intersection. - return ! pl_out.empty() || - // If *this is completely inside other, then pl_out is empty, but the expolygons overlap. Test for that situation. - other.contains(this->contour.points.front()); -} - -bool overlaps(const ExPolygons& expolys1, const ExPolygons& expolys2) -{ - for (const ExPolygon& expoly1 : expolys1) { - for (const ExPolygon& expoly2 : expolys2) { - if (expoly1.overlaps(expoly2)) - return true; - } - } - return false; -} - -bool overlaps(const ExPolygons& expolys, const ExPolygon& expoly) -{ - for (const ExPolygon& el : expolys) { - if (el.overlaps(expoly)) - return true; - } - return false; -} - -Point projection_onto(const ExPolygons& polygons, const Point& from) -{ - Point projected_pt; - double min_dist = std::numeric_limits::max(); - - for (const auto& poly : polygons) { - for (int i = 0; i < poly.num_contours(); i++) { - Point p = from.projection_onto(poly.contour_or_hole(i)); - double dist = (from - p).cast().squaredNorm(); - if (dist < min_dist) { - projected_pt = p; - min_dist = dist; - } - } - } - - return projected_pt; -} - -void ExPolygon::simplify_p(double tolerance, Polygons* polygons) const -{ - Polygons pp = this->simplify_p(tolerance); - polygons->insert(polygons->end(), pp.begin(), pp.end()); -} - -Polygons ExPolygon::simplify_p(double tolerance) const -{ - Polygons pp; - pp.reserve(this->holes.size() + 1); - // contour - { - Polygon p = this->contour; - p.points.push_back(p.points.front()); - p.points = MultiPoint::_douglas_peucker(p.points, tolerance); - p.points.pop_back(); - pp.emplace_back(std::move(p)); - } - // holes - for (Polygon p : this->holes) { - p.points.push_back(p.points.front()); - p.points = MultiPoint::_douglas_peucker(p.points, tolerance); - p.points.pop_back(); - pp.emplace_back(std::move(p)); - } - return simplify_polygons(pp); -} - -ExPolygons ExPolygon::simplify(double tolerance) const -{ - return union_ex(this->simplify_p(tolerance)); -} - -void ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const -{ - append(*expolygons, this->simplify(tolerance)); -} - -void ExPolygon::medial_axis(double min_width, double max_width, ThickPolylines* polylines) const -{ - // init helper object - Slic3r::Geometry::MedialAxis ma(min_width, max_width, *this); - - // compute the Voronoi diagram and extract medial axis polylines - ThickPolylines pp; - ma.build(&pp); - - /* - SVG svg("medial_axis.svg"); - svg.draw(*this); - svg.draw(pp); - svg.Close(); - */ - - /* Find the maximum width returned; we're going to use this for validating and - filtering the output segments. */ - double max_w = 0; - for (ThickPolylines::const_iterator it = pp.begin(); it != pp.end(); ++it) - max_w = fmaxf(max_w, *std::max_element(it->width.begin(), it->width.end())); - - /* Loop through all returned polylines in order to extend their endpoints to the - expolygon boundaries */ - bool removed = false; - for (size_t i = 0; i < pp.size(); ++i) { - ThickPolyline& polyline = pp[i]; - - // extend initial and final segments of each polyline if they're actual endpoints - /* We assign new endpoints to temporary variables because in case of a single-line - polyline, after we extend the start point it will be caught by the intersection() - call, so we keep the inner point until we perform the second intersection() as well */ - Point new_front = polyline.points.front(); - Point new_back = polyline.points.back(); - if (polyline.endpoints.first && !this->on_boundary(new_front, SCALED_EPSILON)) { - Vec2d p1 = polyline.points.front().cast(); - Vec2d p2 = polyline.points[1].cast(); - // prevent the line from touching on the other side, otherwise intersection() might return that solution - if (polyline.points.size() == 2) - p2 = (p1 + p2) * 0.5; - // Extend the start of the segment. - p1 -= (p2 - p1).normalized() * max_width; - this->contour.intersection(Line(p1.cast(), p2.cast()), &new_front); - } - if (polyline.endpoints.second && !this->on_boundary(new_back, SCALED_EPSILON)) { - Vec2d p1 = (polyline.points.end() - 2)->cast(); - Vec2d p2 = polyline.points.back().cast(); - // prevent the line from touching on the other side, otherwise intersection() might return that solution - if (polyline.points.size() == 2) - p1 = (p1 + p2) * 0.5; - // Extend the start of the segment. - p2 += (p2 - p1).normalized() * max_width; - this->contour.intersection(Line(p1.cast(), p2.cast()), &new_back); - } - polyline.points.front() = new_front; - polyline.points.back() = new_back; - - /* remove too short polylines - (we can't do this check before endpoints extension and clipping because we don't - know how long will the endpoints be extended since it depends on polygon thickness - which is variable - extension will be <= max_width/2 on each side) */ - if ((polyline.endpoints.first || polyline.endpoints.second) - && polyline.length() < max_w*2) { - pp.erase(pp.begin() + i); - --i; - removed = true; - continue; - } - } - - /* If we removed any short polylines we now try to connect consecutive polylines - in order to allow loop detection. Note that this algorithm is greedier than - MedialAxis::process_edge_neighbors() as it will connect random pairs of - polylines even when more than two start from the same point. This has no - drawbacks since we optimize later using nearest-neighbor which would do the - same, but should we use a more sophisticated optimization algorithm we should - not connect polylines when more than two meet. */ - if (removed) { - for (size_t i = 0; i < pp.size(); ++i) { - ThickPolyline& polyline = pp[i]; - if (polyline.endpoints.first && polyline.endpoints.second) continue; // optimization - - // find another polyline starting here - for (size_t j = i+1; j < pp.size(); ++j) { - ThickPolyline& other = pp[j]; - if (polyline.last_point() == other.last_point()) { - other.reverse(); - } else if (polyline.first_point() == other.last_point()) { - polyline.reverse(); - other.reverse(); - } else if (polyline.first_point() == other.first_point()) { - polyline.reverse(); - } else if (polyline.last_point() != other.first_point()) { - continue; - } - - polyline.points.insert(polyline.points.end(), other.points.begin() + 1, other.points.end()); - polyline.width.insert(polyline.width.end(), other.width.begin(), other.width.end()); - polyline.endpoints.second = other.endpoints.second; - assert(polyline.width.size() == polyline.points.size()*2 - 2); - - pp.erase(pp.begin() + j); - j = i; // restart search from i+1 - } - } - } - - polylines->insert(polylines->end(), pp.begin(), pp.end()); -} - -void ExPolygon::medial_axis(double min_width, double max_width, Polylines* polylines) const -{ - ThickPolylines tp; - this->medial_axis(min_width, max_width, &tp); - polylines->reserve(polylines->size() + tp.size()); - for (auto &pl : tp) - polylines->emplace_back(pl.points); -} - -Lines ExPolygon::lines() const -{ - Lines lines = this->contour.lines(); - for (Polygons::const_iterator h = this->holes.begin(); h != this->holes.end(); ++h) { - Lines hole_lines = h->lines(); - lines.insert(lines.end(), hole_lines.begin(), hole_lines.end()); - } - return lines; -} - -// Do expolygons match? If they match, they must have the same topology, -// however their contours may be rotated. -bool expolygons_match(const ExPolygon &l, const ExPolygon &r) -{ - if (l.holes.size() != r.holes.size() || ! polygons_match(l.contour, r.contour)) - return false; - for (size_t hole_idx = 0; hole_idx < l.holes.size(); ++ hole_idx) - if (! polygons_match(l.holes[hole_idx], r.holes[hole_idx])) - return false; - return true; -} - -BoundingBox get_extents(const ExPolygon &expolygon) -{ - return get_extents(expolygon.contour); -} - -BoundingBox get_extents(const ExPolygons &expolygons) -{ - BoundingBox bbox; - if (! expolygons.empty()) { - for (size_t i = 0; i < expolygons.size(); ++ i) - if (! expolygons[i].contour.points.empty()) - bbox.merge(get_extents(expolygons[i])); - } - return bbox; -} - -BoundingBox get_extents_rotated(const ExPolygon &expolygon, double angle) -{ - return get_extents_rotated(expolygon.contour, angle); -} - -BoundingBox get_extents_rotated(const ExPolygons &expolygons, double angle) -{ - BoundingBox bbox; - if (! expolygons.empty()) { - bbox = get_extents_rotated(expolygons.front().contour, angle); - for (size_t i = 1; i < expolygons.size(); ++ i) - bbox.merge(get_extents_rotated(expolygons[i].contour, angle)); - } - return bbox; -} - -extern std::vector get_extents_vector(const ExPolygons &polygons) -{ - std::vector out; - out.reserve(polygons.size()); - for (ExPolygons::const_iterator it = polygons.begin(); it != polygons.end(); ++ it) - out.push_back(get_extents(*it)); - return out; -} - -bool has_duplicate_points(const ExPolygon &expoly) -{ -#if 1 - // Check globally. - size_t cnt = expoly.contour.points.size(); - for (const Polygon &hole : expoly.holes) - cnt += hole.points.size(); - Points allpts; - allpts.reserve(cnt); - allpts.insert(allpts.begin(), expoly.contour.points.begin(), expoly.contour.points.end()); - for (const Polygon &hole : expoly.holes) - allpts.insert(allpts.end(), hole.points.begin(), hole.points.end()); - return has_duplicate_points(std::move(allpts)); -#else - // Check per contour. - if (has_duplicate_points(expoly.contour)) - return true; - for (const Polygon &hole : expoly.holes) - if (has_duplicate_points(hole)) - return true; - return false; -#endif -} - -bool has_duplicate_points(const ExPolygons &expolys) -{ -#if 1 - // Check globally. - Points allpts; - allpts.reserve(count_points(expolys)); - for (const ExPolygon &expoly : expolys) { - allpts.insert(allpts.begin(), expoly.contour.points.begin(), expoly.contour.points.end()); - for (const Polygon &hole : expoly.holes) - allpts.insert(allpts.end(), hole.points.begin(), hole.points.end()); - } - return has_duplicate_points(std::move(allpts)); -#else - // Check per contour. - for (const ExPolygon &expoly : expolys) - if (has_duplicate_points(expoly)) - return true; - return false; -#endif -} - -bool remove_same_neighbor(ExPolygons &expolygons) -{ - if (expolygons.empty()) - return false; - bool remove_from_holes = false; - bool remove_from_contour = false; - for (ExPolygon &expoly : expolygons) { - remove_from_contour |= remove_same_neighbor(expoly.contour); - remove_from_holes |= remove_same_neighbor(expoly.holes); - } - // Removing of expolygons without contour - if (remove_from_contour) - expolygons.erase(std::remove_if(expolygons.begin(), expolygons.end(), - [](const ExPolygon &p) { return p.contour.points.size() <= 2; }), - expolygons.end()); - return remove_from_holes || remove_from_contour; -} - -bool remove_sticks(ExPolygon &poly) -{ - return remove_sticks(poly.contour) || remove_sticks(poly.holes); -} - -bool remove_small_and_small_holes(ExPolygons &expolygons, double min_area) -{ - bool modified = false; - size_t free_idx = 0; - for (size_t expoly_idx = 0; expoly_idx < expolygons.size(); ++expoly_idx) { - if (std::abs(expolygons[expoly_idx].area()) >= min_area) { - // Expolygon is big enough, so also check all its holes - modified |= remove_small(expolygons[expoly_idx].holes, min_area); - if (free_idx < expoly_idx) { - std::swap(expolygons[expoly_idx].contour, expolygons[free_idx].contour); - std::swap(expolygons[expoly_idx].holes, expolygons[free_idx].holes); - } - ++free_idx; - } else - modified = true; - } - if (free_idx < expolygons.size()) - expolygons.erase(expolygons.begin() + free_idx, expolygons.end()); - return modified; -} - -void keep_largest_contour_only(ExPolygons &polygons) -{ - if (polygons.size() > 1) { - double max_area = 0.; - ExPolygon* max_area_polygon = nullptr; - for (ExPolygon& p : polygons) { - double a = p.contour.area(); - if (a > max_area) { - max_area = a; - max_area_polygon = &p; - } - } - assert(max_area_polygon != nullptr); - ExPolygon p(std::move(*max_area_polygon)); - polygons.clear(); - polygons.emplace_back(std::move(p)); - } -} - -} // namespace Slic3r +#include "BoundingBox.hpp" +#include "ExPolygon.hpp" +#include "Exception.hpp" +#include "Geometry/MedialAxis.hpp" +#include "Polygon.hpp" +#include "Line.hpp" +#include "ClipperUtils.hpp" +#include "SVG.hpp" +#include +#include +#include + +namespace Slic3r { + +void ExPolygon::scale(double factor) +{ + contour.scale(factor); + for (Polygon &hole : holes) + hole.scale(factor); +} + +void ExPolygon::scale(double factor_x, double factor_y) +{ + contour.scale(factor_x, factor_y); + for (Polygon &hole : holes) + hole.scale(factor_x, factor_y); +} + +void ExPolygon::translate(const Point &p) +{ + contour.translate(p); + for (Polygon &hole : holes) + hole.translate(p); +} + +void ExPolygon::rotate(double angle) +{ + contour.rotate(angle); + for (Polygon &hole : holes) + hole.rotate(angle); +} + +void ExPolygon::rotate(double angle, const Point ¢er) +{ + contour.rotate(angle, center); + for (Polygon &hole : holes) + hole.rotate(angle, center); +} + +double ExPolygon::area() const +{ + double a = this->contour.area(); + for (const Polygon &hole : holes) + a -= - hole.area(); // holes have negative area + return a; +} + +bool ExPolygon::is_valid() const +{ + if (!this->contour.is_valid() || !this->contour.is_counter_clockwise()) return false; + for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) { + if (!(*it).is_valid() || (*it).is_counter_clockwise()) return false; + } + return true; +} + +void ExPolygon::douglas_peucker(double tolerance) +{ + this->contour.douglas_peucker(tolerance); + for (Polygon &poly : this->holes) + poly.douglas_peucker(tolerance); +} + +bool ExPolygon::contains(const Line &line) const +{ + return this->contains(Polyline(line.a, line.b)); +} + +bool ExPolygon::contains(const Polyline &polyline) const +{ + BoundingBox bbox1 = get_extents(*this); + BoundingBox bbox2 = get_extents(polyline); + bbox2.inflated(1); + if (!bbox1.overlap(bbox2)) + return false; + + return diff_pl(polyline, *this).empty(); +} + +bool ExPolygon::contains(const Polylines &polylines) const +{ + #if 0 + BoundingBox bbox = get_extents(polylines); + bbox.merge(get_extents(*this)); + SVG svg(debug_out_path("ExPolygon_contains.svg"), bbox); + svg.draw(*this); + svg.draw_outline(*this); + svg.draw(polylines, "blue"); + #endif + Polylines pl_out = diff_pl(polylines, *this); + #if 0 + svg.draw(pl_out, "red"); + #endif + return pl_out.empty(); +} + +bool ExPolygon::contains(const Point &point, bool border_result /* = true */) const +{ + if (! Slic3r::contains(contour, point, border_result)) + // Outside the outer contour, not on the contour boundary. + return false; + for (const Polygon &hole : this->holes) + if (Slic3r::contains(hole, point, ! border_result)) + // Inside a hole, not on the hole boundary. + return false; + return true; +} + +bool ExPolygon::on_boundary(const Point &point, double eps) const +{ + if (this->contour.on_boundary(point, eps)) + return true; + for (const Polygon &hole : this->holes) + if (hole.on_boundary(point, eps)) + return true; + return false; +} + +// Projection of a point onto the polygon. +Point ExPolygon::point_projection(const Point &point) const +{ + if (this->holes.empty()) { + return this->contour.point_projection(point); + } else { + double dist_min2 = std::numeric_limits::max(); + Point closest_pt_min; + for (size_t i = 0; i < this->num_contours(); ++ i) { + Point closest_pt = this->contour_or_hole(i).point_projection(point); + double d2 = (closest_pt - point).cast().squaredNorm(); + if (d2 < dist_min2) { + dist_min2 = d2; + closest_pt_min = closest_pt; + } + } + return closest_pt_min; + } +} + +void ExPolygon::symmetric_y(const coord_t &y_axis) +{ + this->contour.symmetric_y(y_axis); + for (Polygon &hole : holes) + hole.symmetric_y(y_axis); +} + +bool ExPolygon::overlaps(const ExPolygon &other) const +{ + if (this->empty() || other.empty()) + return false; + + #if 0 + BoundingBox bbox = get_extents(other); + bbox.merge(get_extents(*this)); + static int iRun = 0; + SVG svg(debug_out_path("ExPolygon_overlaps-%d.svg", iRun ++), bbox); + svg.draw(*this); + svg.draw_outline(*this); + svg.draw_outline(other, "blue"); + #endif + + Polylines pl_out = intersection_pl(to_polylines(other), *this); + + #if 0 + svg.draw(pl_out, "red"); + #endif + + // See unit test SCENARIO("Clipper diff with polyline", "[Clipper]") + // for in which case the intersection_pl produces any intersection. + return ! pl_out.empty() || + // If *this is completely inside other, then pl_out is empty, but the expolygons overlap. Test for that situation. + other.contains(this->contour.points.front()); +} + +bool overlaps(const ExPolygons& expolys1, const ExPolygons& expolys2) +{ + for (const ExPolygon& expoly1 : expolys1) { + for (const ExPolygon& expoly2 : expolys2) { + if (expoly1.overlaps(expoly2)) + return true; + } + } + return false; +} + +bool overlaps(const ExPolygons& expolys, const ExPolygon& expoly) +{ + for (const ExPolygon& el : expolys) { + if (el.overlaps(expoly)) + return true; + } + return false; +} + +Point projection_onto(const ExPolygons& polygons, const Point& from) +{ + Point projected_pt; + double min_dist = std::numeric_limits::max(); + + for (const auto& poly : polygons) { + for (int i = 0; i < poly.num_contours(); i++) { + Point p = from.projection_onto(poly.contour_or_hole(i)); + double dist = (from - p).cast().squaredNorm(); + if (dist < min_dist) { + projected_pt = p; + min_dist = dist; + } + } + } + + return projected_pt; +} + +void ExPolygon::simplify_p(double tolerance, Polygons* polygons) const +{ + Polygons pp = this->simplify_p(tolerance); + polygons->insert(polygons->end(), pp.begin(), pp.end()); +} + +Polygons ExPolygon::simplify_p(double tolerance) const +{ + Polygons pp; + pp.reserve(this->holes.size() + 1); + // contour + { + Polygon p = this->contour; + p.points.push_back(p.points.front()); + p.points = MultiPoint::_douglas_peucker(p.points, tolerance); + p.points.pop_back(); + pp.emplace_back(std::move(p)); + } + // holes + for (Polygon p : this->holes) { + p.points.push_back(p.points.front()); + p.points = MultiPoint::_douglas_peucker(p.points, tolerance); + p.points.pop_back(); + pp.emplace_back(std::move(p)); + } + return simplify_polygons(pp); +} + +ExPolygons ExPolygon::simplify(double tolerance) const +{ + return union_ex(this->simplify_p(tolerance)); +} + +void ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const +{ + append(*expolygons, this->simplify(tolerance)); +} + +void ExPolygon::medial_axis(double min_width, double max_width, ThickPolylines* polylines) const +{ + // init helper object + Slic3r::Geometry::MedialAxis ma(min_width, max_width, *this); + + // compute the Voronoi diagram and extract medial axis polylines + ThickPolylines pp; + ma.build(&pp); + + /* + SVG svg("medial_axis.svg"); + svg.draw(*this); + svg.draw(pp); + svg.Close(); + */ + + /* Find the maximum width returned; we're going to use this for validating and + filtering the output segments. */ + double max_w = 0; + for (ThickPolylines::const_iterator it = pp.begin(); it != pp.end(); ++it) + max_w = fmaxf(max_w, *std::max_element(it->width.begin(), it->width.end())); + + /* Loop through all returned polylines in order to extend their endpoints to the + expolygon boundaries */ + bool removed = false; + for (size_t i = 0; i < pp.size(); ++i) { + ThickPolyline& polyline = pp[i]; + + // extend initial and final segments of each polyline if they're actual endpoints + /* We assign new endpoints to temporary variables because in case of a single-line + polyline, after we extend the start point it will be caught by the intersection() + call, so we keep the inner point until we perform the second intersection() as well */ + Point new_front = polyline.points.front(); + Point new_back = polyline.points.back(); + if (polyline.endpoints.first && !this->on_boundary(new_front, SCALED_EPSILON)) { + Vec2d p1 = polyline.points.front().cast(); + Vec2d p2 = polyline.points[1].cast(); + // prevent the line from touching on the other side, otherwise intersection() might return that solution + if (polyline.points.size() == 2) + p2 = (p1 + p2) * 0.5; + // Extend the start of the segment. + p1 -= (p2 - p1).normalized() * max_width; + this->contour.intersection(Line(p1.cast(), p2.cast()), &new_front); + } + if (polyline.endpoints.second && !this->on_boundary(new_back, SCALED_EPSILON)) { + Vec2d p1 = (polyline.points.end() - 2)->cast(); + Vec2d p2 = polyline.points.back().cast(); + // prevent the line from touching on the other side, otherwise intersection() might return that solution + if (polyline.points.size() == 2) + p1 = (p1 + p2) * 0.5; + // Extend the start of the segment. + p2 += (p2 - p1).normalized() * max_width; + this->contour.intersection(Line(p1.cast(), p2.cast()), &new_back); + } + polyline.points.front() = new_front; + polyline.points.back() = new_back; + + /* remove too short polylines + (we can't do this check before endpoints extension and clipping because we don't + know how long will the endpoints be extended since it depends on polygon thickness + which is variable - extension will be <= max_width/2 on each side) */ + if ((polyline.endpoints.first || polyline.endpoints.second) + && polyline.length() < max_w*2) { + pp.erase(pp.begin() + i); + --i; + removed = true; + continue; + } + } + + /* If we removed any short polylines we now try to connect consecutive polylines + in order to allow loop detection. Note that this algorithm is greedier than + MedialAxis::process_edge_neighbors() as it will connect random pairs of + polylines even when more than two start from the same point. This has no + drawbacks since we optimize later using nearest-neighbor which would do the + same, but should we use a more sophisticated optimization algorithm we should + not connect polylines when more than two meet. */ + if (removed) { + for (size_t i = 0; i < pp.size(); ++i) { + ThickPolyline& polyline = pp[i]; + if (polyline.endpoints.first && polyline.endpoints.second) continue; // optimization + + // find another polyline starting here + for (size_t j = i+1; j < pp.size(); ++j) { + ThickPolyline& other = pp[j]; + if (polyline.last_point() == other.last_point()) { + other.reverse(); + } else if (polyline.first_point() == other.last_point()) { + polyline.reverse(); + other.reverse(); + } else if (polyline.first_point() == other.first_point()) { + polyline.reverse(); + } else if (polyline.last_point() != other.first_point()) { + continue; + } + + polyline.points.insert(polyline.points.end(), other.points.begin() + 1, other.points.end()); + polyline.width.insert(polyline.width.end(), other.width.begin(), other.width.end()); + polyline.endpoints.second = other.endpoints.second; + assert(polyline.width.size() == polyline.points.size()*2 - 2); + + pp.erase(pp.begin() + j); + j = i; // restart search from i+1 + } + } + } + + polylines->insert(polylines->end(), pp.begin(), pp.end()); +} + +void ExPolygon::medial_axis(double min_width, double max_width, Polylines* polylines) const +{ + ThickPolylines tp; + this->medial_axis(min_width, max_width, &tp); + polylines->reserve(polylines->size() + tp.size()); + for (auto &pl : tp) + polylines->emplace_back(pl.points); +} + +Lines ExPolygon::lines() const +{ + Lines lines = this->contour.lines(); + for (Polygons::const_iterator h = this->holes.begin(); h != this->holes.end(); ++h) { + Lines hole_lines = h->lines(); + lines.insert(lines.end(), hole_lines.begin(), hole_lines.end()); + } + return lines; +} + +// Do expolygons match? If they match, they must have the same topology, +// however their contours may be rotated. +bool expolygons_match(const ExPolygon &l, const ExPolygon &r) +{ + if (l.holes.size() != r.holes.size() || ! polygons_match(l.contour, r.contour)) + return false; + for (size_t hole_idx = 0; hole_idx < l.holes.size(); ++ hole_idx) + if (! polygons_match(l.holes[hole_idx], r.holes[hole_idx])) + return false; + return true; +} + +BoundingBox get_extents(const ExPolygon &expolygon) +{ + return get_extents(expolygon.contour); +} + +BoundingBox get_extents(const ExPolygons &expolygons) +{ + BoundingBox bbox; + if (! expolygons.empty()) { + for (size_t i = 0; i < expolygons.size(); ++ i) + if (! expolygons[i].contour.points.empty()) + bbox.merge(get_extents(expolygons[i])); + } + return bbox; +} + +BoundingBox get_extents_rotated(const ExPolygon &expolygon, double angle) +{ + return get_extents_rotated(expolygon.contour, angle); +} + +BoundingBox get_extents_rotated(const ExPolygons &expolygons, double angle) +{ + BoundingBox bbox; + if (! expolygons.empty()) { + bbox = get_extents_rotated(expolygons.front().contour, angle); + for (size_t i = 1; i < expolygons.size(); ++ i) + bbox.merge(get_extents_rotated(expolygons[i].contour, angle)); + } + return bbox; +} + +extern std::vector get_extents_vector(const ExPolygons &polygons) +{ + std::vector out; + out.reserve(polygons.size()); + for (ExPolygons::const_iterator it = polygons.begin(); it != polygons.end(); ++ it) + out.push_back(get_extents(*it)); + return out; +} + +bool has_duplicate_points(const ExPolygon &expoly) +{ +#if 1 + // Check globally. + size_t cnt = expoly.contour.points.size(); + for (const Polygon &hole : expoly.holes) + cnt += hole.points.size(); + Points allpts; + allpts.reserve(cnt); + allpts.insert(allpts.begin(), expoly.contour.points.begin(), expoly.contour.points.end()); + for (const Polygon &hole : expoly.holes) + allpts.insert(allpts.end(), hole.points.begin(), hole.points.end()); + return has_duplicate_points(std::move(allpts)); +#else + // Check per contour. + if (has_duplicate_points(expoly.contour)) + return true; + for (const Polygon &hole : expoly.holes) + if (has_duplicate_points(hole)) + return true; + return false; +#endif +} + +bool has_duplicate_points(const ExPolygons &expolys) +{ +#if 1 + // Check globally. + Points allpts; + allpts.reserve(count_points(expolys)); + for (const ExPolygon &expoly : expolys) { + allpts.insert(allpts.begin(), expoly.contour.points.begin(), expoly.contour.points.end()); + for (const Polygon &hole : expoly.holes) + allpts.insert(allpts.end(), hole.points.begin(), hole.points.end()); + } + return has_duplicate_points(std::move(allpts)); +#else + // Check per contour. + for (const ExPolygon &expoly : expolys) + if (has_duplicate_points(expoly)) + return true; + return false; +#endif +} + +bool remove_same_neighbor(ExPolygons &expolygons) +{ + if (expolygons.empty()) + return false; + bool remove_from_holes = false; + bool remove_from_contour = false; + for (ExPolygon &expoly : expolygons) { + remove_from_contour |= remove_same_neighbor(expoly.contour); + remove_from_holes |= remove_same_neighbor(expoly.holes); + } + // Removing of expolygons without contour + if (remove_from_contour) + expolygons.erase(std::remove_if(expolygons.begin(), expolygons.end(), + [](const ExPolygon &p) { return p.contour.points.size() <= 2; }), + expolygons.end()); + return remove_from_holes || remove_from_contour; +} + +bool remove_sticks(ExPolygon &poly) +{ + return remove_sticks(poly.contour) || remove_sticks(poly.holes); +} + +bool remove_small_and_small_holes(ExPolygons &expolygons, double min_area) +{ + bool modified = false; + size_t free_idx = 0; + for (size_t expoly_idx = 0; expoly_idx < expolygons.size(); ++expoly_idx) { + if (std::abs(expolygons[expoly_idx].area()) >= min_area) { + // Expolygon is big enough, so also check all its holes + modified |= remove_small(expolygons[expoly_idx].holes, min_area); + if (free_idx < expoly_idx) { + std::swap(expolygons[expoly_idx].contour, expolygons[free_idx].contour); + std::swap(expolygons[expoly_idx].holes, expolygons[free_idx].holes); + } + ++free_idx; + } else + modified = true; + } + if (free_idx < expolygons.size()) + expolygons.erase(expolygons.begin() + free_idx, expolygons.end()); + return modified; +} + +void keep_largest_contour_only(ExPolygons &polygons) +{ + if (polygons.size() > 1) { + double max_area = 0.; + ExPolygon* max_area_polygon = nullptr; + for (ExPolygon& p : polygons) { + double a = p.contour.area(); + if (a > max_area) { + max_area = a; + max_area_polygon = &p; + } + } + assert(max_area_polygon != nullptr); + ExPolygon p(std::move(*max_area_polygon)); + polygons.clear(); + polygons.emplace_back(std::move(p)); + } +} + +} // namespace Slic3r diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index 187ef27a11..87a1146d41 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -56,7 +56,7 @@ public: bool on_boundary(const Point &point, double eps) const; // Projection of a point onto the polygon. Point point_projection(const Point &point) const; - + void symmetric_y(const coord_t &y_axis); // Does this expolygon overlap another expolygon? // Either the ExPolygons intersect, or one is fully inside the other, // and it is not inside a hole of the other expolygon. diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index a3d8b45323..47726328c4 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -34,7 +34,6 @@ struct SurfaceFillParams coordf_t overlap = 0.; // Angle as provided by the region config, in radians. float angle = 0.f; - bool rotate_angle = true; // Is bridging used for this fill? Bridging parameters may be used even if this->flow.bridge() is not set. bool bridge; // Non-negative for a bridge. @@ -68,6 +67,9 @@ struct SurfaceFillParams // Params for lattice infill angles float lattice_angle_1 = 0.f; float lattice_angle_2 = 0.f; + float infill_lock_depth = 0; + float skin_infill_depth = 0; + bool symmetric_infill_y_axis = false; // Params for 2D honeycomb float infill_overhang_angle = 60.f; @@ -85,7 +87,6 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(spacing); RETURN_COMPARE_NON_EQUAL(overlap); RETURN_COMPARE_NON_EQUAL(angle); - RETURN_COMPARE_NON_EQUAL(rotate_angle); RETURN_COMPARE_NON_EQUAL(density); // RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust); RETURN_COMPARE_NON_EQUAL(anchor_length); @@ -100,33 +101,36 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(solid_infill_speed); RETURN_COMPARE_NON_EQUAL(lattice_angle_1); RETURN_COMPARE_NON_EQUAL(lattice_angle_2); - RETURN_COMPARE_NON_EQUAL(infill_overhang_angle); + RETURN_COMPARE_NON_EQUAL(symmetric_infill_y_axis); + RETURN_COMPARE_NON_EQUAL(infill_lock_depth); + RETURN_COMPARE_NON_EQUAL(skin_infill_depth); RETURN_COMPARE_NON_EQUAL(infill_overhang_angle); return false; } - bool operator==(const SurfaceFillParams &rhs) const { - return this->extruder == rhs.extruder && - this->pattern == rhs.pattern && - this->spacing == rhs.spacing && - this->overlap == rhs.overlap && - this->angle == rhs.angle && - this->rotate_angle == rhs.rotate_angle && - this->bridge == rhs.bridge && - this->bridge_angle == rhs.bridge_angle && - this->density == rhs.density && -// this->dont_adjust == rhs.dont_adjust && - this->anchor_length == rhs.anchor_length && - this->anchor_length_max == rhs.anchor_length_max && - this->flow == rhs.flow && - this->extrusion_role == rhs.extrusion_role && - this->sparse_infill_speed == rhs.sparse_infill_speed && - this->top_surface_speed == rhs.top_surface_speed && - this->solid_infill_speed == rhs.solid_infill_speed && - this->lattice_angle_1 == rhs.lattice_angle_1 && - this->lattice_angle_2 == rhs.lattice_angle_2 && + bool operator==(const SurfaceFillParams &rhs) const { + return this->extruder == rhs.extruder && + this->pattern == rhs.pattern && + this->spacing == rhs.spacing && + this->overlap == rhs.overlap && + this->angle == rhs.angle && + this->bridge == rhs.bridge && + this->bridge_angle == rhs.bridge_angle && + this->density == rhs.density && +// this->dont_adjust == rhs.dont_adjust && + this->anchor_length == rhs.anchor_length && + this->anchor_length_max == rhs.anchor_length_max && + this->flow == rhs.flow && + this->extrusion_role == rhs.extrusion_role && + this->sparse_infill_speed == rhs.sparse_infill_speed && + this->top_surface_speed == rhs.top_surface_speed && + this->solid_infill_speed == rhs.solid_infill_speed && + this->lattice_angle_1 == rhs.lattice_angle_1 && + this->lattice_angle_2 == rhs.lattice_angle_2 && + this->infill_lock_depth == rhs.infill_lock_depth && + this->skin_infill_depth == rhs.skin_infill_depth && this->infill_overhang_angle == rhs.infill_overhang_angle; - } + } }; struct SurfaceFill { @@ -602,16 +606,34 @@ void split_solid_surface(size_t layer_id, const SurfaceFill &fill, ExPolygons &n #endif } -std::vector group_fills(const Layer &layer) +std::vector group_fills(const Layer &layer, LockRegionParam &lock_param) { std::vector surface_fills; - // Fill in a map of a region & surface to SurfaceFillParams. std::set set_surface_params; std::vector> region_to_surface_params(layer.regions().size(), std::vector()); SurfaceFillParams params; bool has_internal_voids = false; const PrintObjectConfig& object_config = layer.object()->config(); + + auto append_flow_param = [](std::map &flow_params, Flow flow, const ExPolygon &exp) { + auto it = flow_params.find(flow); + if (it == flow_params.end()) + flow_params.insert({flow, {exp}}); + else + it->second.push_back(exp); + it++; + }; + + auto append_density_param = [](std::map &density_params, float density, const ExPolygon &exp) { + auto it = density_params.find(density); + if (it == density_params.end()) + density_params.insert({density, {exp}}); + else + it->second.push_back(exp); + it++; + }; + for (size_t region_id = 0; region_id < layer.regions().size(); ++ region_id) { const LayerRegion &layerm = *layer.regions()[region_id]; region_to_surface_params[region_id].assign(layerm.fill_surfaces.size(), nullptr); @@ -628,8 +650,19 @@ std::vector group_fills(const Layer &layer) params.lattice_angle_1 = region_config.lattice_angle_1; params.lattice_angle_2 = region_config.lattice_angle_2; params.infill_overhang_angle = region_config.infill_overhang_angle; + if (params.pattern == ipLockedZag) { + params.infill_lock_depth = scale_(region_config.infill_lock_depth); + params.skin_infill_depth = scale_(region_config.skin_infill_depth); + } + if (params.pattern == ipCrossZag || params.pattern == ipLockedZag) { + params.symmetric_infill_y_axis = region_config.symmetric_infill_y_axis; + } else if (params.pattern == ipZigZag) { - if (surface.is_solid()) { + + params.symmetric_infill_y_axis = region_config.symmetric_infill_y_axis; + } + + if (surface.is_solid()) { params.density = 100.f; //FIXME for non-thick bridges, shall we allow a bottom surface pattern? if (surface.is_solid_infill()) @@ -667,10 +700,8 @@ std::vector group_fills(const Layer &layer) params.bridge_angle = float(surface.bridge_angle); if (params.extrusion_role == erInternalInfill) { params.angle = float(Geometry::deg2rad(region_config.infill_direction.value)); - params.rotate_angle = (params.pattern == ipRectilinear || params.pattern == ipLine); } else { params.angle = float(Geometry::deg2rad(region_config.solid_infill_direction.value)); - params.rotate_angle = region_config.rotate_solid_infill_direction; } // Calculate the actual flow we'll be using for this infill. @@ -709,7 +740,28 @@ std::vector group_fills(const Layer &layer) params.anchor_length = std::min(params.anchor_length, params.anchor_length_max); } - auto it_params = set_surface_params.find(params); + //get locked region param + if (params.pattern == ipLockedZag){ + const PrintObject *object = layerm.layer()->object(); + auto nozzle_diameter = float(object->print()->config().nozzle_diameter.get_at(layerm.region().extruder(extrusion_role) - 1)); + Flow skin_flow = params.bridge ? params.flow : Flow::new_from_config_width(extrusion_role, region_config.skin_infill_line_width, nozzle_diameter, float((surface.thickness == -1) ? layer.height : surface.thickness)); + //add skin flow + append_flow_param(lock_param.skin_flow_params, skin_flow, surface.expolygon); + + Flow skeleton_flow = params.bridge ? params.flow : Flow::new_from_config_width(extrusion_role, region_config.skeleton_infill_line_width, nozzle_diameter, float((surface.thickness == -1) ? layer.height : surface.thickness)) ; + // add skeleton flow + append_flow_param(lock_param.skeleton_flow_params, skeleton_flow, surface.expolygon); + + // add skin density + append_density_param(lock_param.skin_density_params, float(0.01 * region_config.skin_infill_density), surface.expolygon); + + // add skin density + append_density_param(lock_param.skeleton_density_params, float(0.01 * region_config.skeleton_infill_density), surface.expolygon); + + } + + auto it_params = set_surface_params.find(params); + if (it_params == set_surface_params.end()) it_params = set_surface_params.insert(it_params, params); region_to_surface_params[region_id][&surface - &layerm.fill_surfaces.surfaces.front()] = &(*it_params); @@ -829,7 +881,6 @@ std::vector group_fills(const Layer &layer) params.density = 100.f; params.extrusion_role = erSolidInfill; params.angle = float(Geometry::deg2rad(layerm.region().config().solid_infill_direction.value)); - params.rotate_angle = layerm.region().config().rotate_solid_infill_direction; // calculate the actual flow we'll be using for this infill params.flow = layerm.flow(frSolidInfill); params.spacing = params.flow.spacing(); @@ -914,8 +965,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: #ifdef SLIC3R_DEBUG_SLICE_PROCESSING // this->export_region_fill_surfaces_to_svg_debug("10_fill-initial"); #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ - - std::vector surface_fills = group_fills(*this); + LockRegionParam lock_param; + std::vector surface_fills = group_fills(*this, lock_param); const Slic3r::BoundingBox bbox = this->object()->bounding_box(); const auto resolution = this->object()->print()->config().resolution.value; @@ -933,14 +984,22 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: f->layer_id = this->id(); f->z = this->print_z; f->angle = surface_fill.params.angle; - f->rotate_angle = surface_fill.params.rotate_angle; f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree; f->print_config = &this->object()->print()->config(); f->print_object_config = &this->object()->config(); - - if (surface_fill.params.pattern == ipLightning) + f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree; + if (surface_fill.params.pattern == ipConcentricInternal) { + FillConcentricInternal *fill_concentric = dynamic_cast(f.get()); + assert(fill_concentric != nullptr); + fill_concentric->print_config = &this->object()->print()->config(); + fill_concentric->print_object_config = &this->object()->config(); + } else if (surface_fill.params.pattern == ipConcentric) { + FillConcentric *fill_concentric = dynamic_cast(f.get()); + assert(fill_concentric != nullptr); + fill_concentric->print_config = &this->object()->print()->config(); + fill_concentric->print_object_config = &this->object()->config(); + } else if (surface_fill.params.pattern == ipLightning) dynamic_cast(f.get())->generator = lightning_generator; - // calculate flow spacing for infill pattern generation bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.bridge; double link_max_length = 0.; @@ -979,11 +1038,41 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: params.extrusion_role = surface_fill.params.extrusion_role; params.using_internal_flow = using_internal_flow; params.no_extrusion_overlap = surface_fill.params.overlap; - params.config = &layerm->region().config(); + auto ®ion_config = layerm->region().config(); + + ConfigOptionFloats rotate_angles; + rotate_angles.deserialize( surface_fill.params.extrusion_role == erInternalInfill ? region_config.sparse_infill_rotate_template.value : region_config.solid_infill_rotate_template.value); + auto rotate_angle_idx = f->layer_id % rotate_angles.size(); + f->rotate_angle = Geometry::deg2rad(rotate_angles.values[rotate_angle_idx]); + + params.config = ®ion_config; + params.pattern = surface_fill.params.pattern; + if( surface_fill.params.pattern == ipLockedZag ) { + params.locked_zag = true; + params.infill_lock_depth = surface_fill.params.infill_lock_depth; + params.skin_infill_depth = surface_fill.params.skin_infill_depth; + f->set_lock_region_param(lock_param); + } + if (surface_fill.params.pattern == ipCrossZag || surface_fill.params.pattern == ipLockedZag) { + if (f->layer_id % 2 == 0) { + params.horiz_move -= scale_(region_config.infill_shift_step) * (f->layer_id / 2); + } else { + params.horiz_move += scale_(region_config.infill_shift_step) * (f->layer_id / 2); + } + + params.symmetric_infill_y_axis = surface_fill.params.symmetric_infill_y_axis; + + } if (surface_fill.params.pattern == ipGrid) params.can_reverse = false; for (ExPolygon& expoly : surface_fill.expolygons) { - f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes); + + f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes); + if (params.symmetric_infill_y_axis) { + params.symmetric_y_axis = f->extended_object_bounding_box().center().x(); + expoly.symmetric_y(params.symmetric_y_axis); + } + // Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon. f->spacing = surface_fill.params.spacing; surface_fill.surface.expolygon = std::move(expoly); @@ -1023,9 +1112,10 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator) const { - std::vector surface_fills = group_fills(*this); - const Slic3r::BoundingBox bbox = this->object()->bounding_box(); - const auto resolution = this->object()->print()->config().resolution.value; + LockRegionParam skin_inner_param; + std::vector surface_fills = group_fills(*this, skin_inner_param); + const Slic3r::BoundingBox bbox = this->object()->bounding_box(); + const auto resolution = this->object()->print()->config().resolution.value; Polylines sparse_infill_polylines{}; @@ -1059,7 +1149,10 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc case ipTpmsD: case ipHilbertCurve: case ipArchimedeanChords: - case ipOctagramSpiral: break; + case ipOctagramSpiral: + case ipZigZag: + case ipCrossZag: + case ipLockedZag: break; } // Create the filler object. diff --git a/src/libslic3r/Fill/Fill3DHoneycomb.hpp b/src/libslic3r/Fill/Fill3DHoneycomb.hpp index f7a27cf4f9..ccb37a36a0 100644 --- a/src/libslic3r/Fill/Fill3DHoneycomb.hpp +++ b/src/libslic3r/Fill/Fill3DHoneycomb.hpp @@ -15,6 +15,10 @@ public: Fill* clone() const override { return new Fill3DHoneycomb(*this); }; ~Fill3DHoneycomb() override {} + // require bridge flow since most of this pattern hangs in air + bool use_bridge_flow() const override { return true; } + bool is_self_crossing() override { return false; } + protected: void _fill_surface_single( const FillParams ¶ms, diff --git a/src/libslic3r/Fill/FillAdaptive.hpp b/src/libslic3r/Fill/FillAdaptive.hpp index 0578cc3e1b..0132ffaa6c 100644 --- a/src/libslic3r/Fill/FillAdaptive.hpp +++ b/src/libslic3r/Fill/FillAdaptive.hpp @@ -71,6 +71,7 @@ protected: // may not be optimal as the internal infill lines may get extruded before the long infill // lines to which the short infill lines are supposed to anchor. bool no_sort() const override { return false; } + bool is_self_crossing() override { return true; } }; } // namespace FillAdaptive diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 3b2f5bcc5c..9f5a54a0d9 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -67,6 +67,9 @@ Fill* Fill::new_from_type(const InfillPattern type) // BBS: for bottom and top surface only // Orca: Replace BBS implementation with Prusa implementation case ipMonotonicLine: return new FillMonotonicLines(); + case ipZigZag: return new FillZigZag(); + case ipCrossZag: return new FillCrossZag(); + case ipLockedZag: return new FillLockedZag(); default: throw Slic3r::InvalidArgument("unknown type"); } } @@ -243,7 +246,7 @@ void Fill::_create_gap_fill(const Surface* surface, const FillParams& params, Ex // Calculate a new spacing to fill width with possibly integer number of lines, // the first and last line being centered at the interval ends. -// This function possibly increases the spacing, never decreases, +// This function possibly increases the spacing, never decreases, // and for a narrow width the increase in spacing may become severe, // therefore the adjustment is limited to 20% increase. coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance) @@ -252,8 +255,8 @@ coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance) assert(distance > 0); // floor(width / distance) const auto number_of_intervals = coord_t((width - EPSILON) / distance); - coord_t distance_new = (number_of_intervals == 0) ? - distance : + coord_t distance_new = (number_of_intervals == 0) ? + distance : coord_t((width - EPSILON) / number_of_intervals); const coordf_t factor = coordf_t(distance_new) / coordf_t(distance); assert(factor > 1. - 1e-5); @@ -279,8 +282,8 @@ std::pair Fill::_infill_direction(const Surface *surface) const // Bounding box is the bounding box of a perl object Slic3r::Print::Object (c++ object Slic3r::PrintObject) // The bounding box is only undefined in unit tests. - Point out_shift = empty(this->bounding_box) ? - surface->expolygon.contour.bounding_box().center() : + Point out_shift = empty(this->bounding_box) ? + surface->expolygon.contour.bounding_box().center() : this->bounding_box.center(); #if 0 @@ -354,10 +357,10 @@ struct ContourIntersectionPoint { bool could_take_next() const throw() { return ! this->consumed && this->contour_not_taken_length_next > SCALED_EPSILON; } // Could extrude a complete segment from this to this->prev_on_contour. - bool could_connect_prev() const throw() + bool could_connect_prev() const throw() { return ! this->consumed && this->prev_on_contour != this && ! this->prev_on_contour->consumed && ! this->prev_trimmed && ! this->prev_on_contour->next_trimmed; } // Could extrude a complete segment from this to this->next_on_contour. - bool could_connect_next() const throw() + bool could_connect_next() const throw() { return ! this->consumed && this->next_on_contour != this && ! this->next_on_contour->consumed && ! this->next_trimmed && ! this->next_on_contour->prev_trimmed; } }; @@ -566,7 +569,7 @@ static void take(Polyline &pl1, const Polyline &pl2, const Points &contour, Cont } static void take_limited( - Polyline &pl1, const Points &contour, const std::vector ¶ms, + Polyline &pl1, const Points &contour, const std::vector ¶ms, ContourIntersectionPoint *cp_start, ContourIntersectionPoint *cp_end, bool clockwise, double take_max_length, double line_half_width) { #ifndef NDEBUG @@ -730,8 +733,8 @@ static inline SegmentPoint clip_end_segment_and_point(const Points &polyline, do // Calculate intersection of a line with a thick segment. // Returns Eucledian parameters of the line / thick segment overlap. static inline bool line_rounded_thick_segment_collision( - const Vec2d &line_a, const Vec2d &line_b, - const Vec2d &segment_a, const Vec2d &segment_b, const double offset, + const Vec2d &line_a, const Vec2d &line_b, + const Vec2d &segment_a, const Vec2d &segment_b, const double offset, std::pair &out_interval) { const Vec2d line_v0 = line_b - line_a; @@ -794,8 +797,8 @@ static inline bool line_rounded_thick_segment_collision( std::pair interval; if (Geometry::liang_barsky_line_clipping_interval( Vec2d(line_p0.dot(dir_x), line_p0.dot(dir_y)), - Vec2d(line_v0.dot(dir_x), line_v0.dot(dir_y)), - BoundingBoxf(Vec2d(0., - offset), Vec2d(segment_l, offset)), + Vec2d(line_v0.dot(dir_x), line_v0.dot(dir_y)), + BoundingBoxf(Vec2d(0., - offset), Vec2d(segment_l, offset)), interval)) extend_interval(interval.first, interval.second); } else @@ -1155,7 +1158,7 @@ void mark_boundary_segments_touching_infill( // Clip the infill polyline by the Eucledian distance along the polyline. SegmentPoint start_point = clip_start_segment_and_point(polyline.points, clip_distance); SegmentPoint end_point = clip_end_segment_and_point(polyline.points, clip_distance); - if (start_point.valid() && end_point.valid() && + if (start_point.valid() && end_point.valid() && (start_point.idx_segment < end_point.idx_segment || (start_point.idx_segment == end_point.idx_segment && start_point.t < end_point.t))) { // The clipped polyline is non-empty. #ifdef INFILL_DEBUG_OUTPUT @@ -1295,21 +1298,21 @@ struct BoundaryInfillGraph }; static Direction dir(const Point &p1, const Point &p2) { - return p1.x() == p2.x() ? + return p1.x() == p2.x() ? (p1.y() < p2.y() ? Up : Down) : (p1.x() < p2.x() ? Right : Left); } const Direction dir_prev(const ContourIntersectionPoint &cp) const { assert(cp.prev_on_contour); - return cp.could_take_prev() ? + return cp.could_take_prev() ? dir(this->point(cp), this->point(*cp.prev_on_contour)) : Taken; } const Direction dir_next(const ContourIntersectionPoint &cp) const { assert(cp.next_on_contour); - return cp.could_take_next() ? + return cp.could_take_next() ? dir(this->point(cp), this->point(*cp.next_on_contour)) : Taken; } @@ -1367,7 +1370,7 @@ static inline void mark_boundary_segments_overlapping_infill( assert(interval.first == 0.); double len_out = closed_contour_distance_ccw(contour_params[cp.point_idx], contour_params[i], contour_params.back()) + interval.second; if (len_out < cp.contour_not_taken_length_next) { - // Leaving the infill line region before exiting cp.contour_not_taken_length_next, + // Leaving the infill line region before exiting cp.contour_not_taken_length_next, // thus at least some of the contour is outside and we will extrude this segment. inside = false; break; @@ -1399,7 +1402,7 @@ static inline void mark_boundary_segments_overlapping_infill( assert(interval.first == 0.); double len_out = closed_contour_distance_cw(contour_params[cp.point_idx], contour_params[i], contour_params.back()) + interval.second; if (len_out < cp.contour_not_taken_length_prev) { - // Leaving the infill line region before exiting cp.contour_not_taken_length_next, + // Leaving the infill line region before exiting cp.contour_not_taken_length_next, // thus at least some of the contour is outside and we will extrude this segment. inside = false; break; @@ -1496,7 +1499,7 @@ BoundaryInfillGraph create_boundary_infill_graph(const Polylines &infill_ordered ContourIntersectionPoint *pthis = &out.map_infill_end_point_to_boundary[it->second]; if (pprev) { pprev->next_on_contour = pthis; - pthis->prev_on_contour = pprev; + pthis->prev_on_contour = pprev; } else pfirst = pthis; contour_intersection_points.emplace_back(pthis); @@ -1521,7 +1524,7 @@ BoundaryInfillGraph create_boundary_infill_graph(const Polylines &infill_ordered ip->param = contour_params[ip->point_idx]; // and measure distance to the previous and next intersection point. const double contour_length = contour_params.back(); - for (ContourIntersectionPoint *ip : contour_intersection_points) + for (ContourIntersectionPoint *ip : contour_intersection_points) if (ip->next_on_contour == ip) { assert(ip->prev_on_contour == ip); ip->contour_not_taken_length_prev = ip->contour_not_taken_length_next = contour_length; @@ -1556,6 +1559,18 @@ BoundaryInfillGraph create_boundary_infill_graph(const Polylines &infill_ordered return out; } +// The extended bounding box of the whole object that covers any rotation of every layer. +BoundingBox Fill::extended_object_bounding_box() const +{ + BoundingBox out = bounding_box; + out.merge(Point(out.min.y(), out.min.x())); + out.merge(Point(out.max.y(), out.max.x())); + + // The bounding box is scaled by sqrt(2.) to ensure that the bounding box + // covers any possible rotations. + return out.scaled(sqrt(2.)); +} + void Fill::connect_infill(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms) { assert(! infill_ordered.empty()); @@ -1927,14 +1942,14 @@ static inline void base_support_extend_infill_lines(Polylines &infill, BoundaryI // The contour is supposed to enter the "forbidden" zone outside of the (left, right) band at tbegin and also at tend. static inline void emit_loops_in_band( // Vertical band, which will trim the contour between tbegin and tend. - coord_t left, + coord_t left, coord_t right, // Contour and its parametrization. const Points &contour, const std::vector &contour_params, // Span of the parameters of an arch to trim with the vertical band. double tbegin, - double tend, + double tend, // Minimum arch length to put into polylines_out. Shorter arches are not necessary to support a dense support infill. double min_length, Polylines &polylines_out) @@ -1990,13 +2005,13 @@ static inline void emit_loops_in_band( }; enum InOutBand { - Entering, + Entering, Leaving, }; class State { public: - State(coord_t left, coord_t right, double min_length, Polylines &polylines_out) : + State(coord_t left, coord_t right, double min_length, Polylines &polylines_out) : m_left(left), m_right(right), m_min_length(min_length), m_polylines_out(polylines_out) {} void add_inner_point(const Point* p) @@ -2297,7 +2312,7 @@ void Fill::connect_base_support(Polylines &&infill_ordered, const std::vector SCALED_EPSILON && + if (cp.contour_not_taken_length_prev > SCALED_EPSILON && (cost_prev.self_loop ? cost_prev.cost > cap_cost : cost_prev.cost > cost_veryhigh)) { @@ -2643,7 +2658,7 @@ void Fill::connect_base_support(Polylines &&infill_ordered, const std::vector SCALED_EPSILON && + if (cp.contour_not_taken_length_next > SCALED_EPSILON && (cost_next.self_loop ? cost_next.cost > cap_cost : cost_next.cost > cost_veryhigh)) { diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 62eeb9000e..4348ba5127 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -36,6 +36,15 @@ public: InfillFailedException() : Slic3r::RuntimeError("Infill failed") {} }; +struct LockRegionParam +{ + LockRegionParam() {} + std::map skin_density_params; + std::map skeleton_density_params; + std::map skin_flow_params; + std::map skeleton_flow_params; +}; + struct FillParams { bool full_infill() const { return density > 0.9999f; } @@ -72,6 +81,7 @@ struct FillParams // For 2D lattice coordf_t lattice_angle_1 { 0.f }; coordf_t lattice_angle_2 { 0.f }; + InfillPattern pattern{ ipRectilinear }; // For 2D Honeycomb float infill_overhang_angle { 60 }; @@ -85,6 +95,13 @@ struct FillParams const PrintRegionConfig* config{ nullptr }; bool dont_sort{ false }; // do not sort the lines, just simply connect them bool can_reverse{true}; + + float horiz_move{0.0}; //move infill to get cross zag pattern + bool symmetric_infill_y_axis{false}; + coord_t symmetric_y_axis{0}; + bool locked_zag{false}; + float infill_lock_depth{0.0}; + float skin_infill_depth{0.0}; }; static_assert(IsTriviallyCopyable::value, "FillParams class is not POD (and it should be - see constructor)."); @@ -102,7 +119,7 @@ public: // in radians, ccw, 0 = East float angle; // Orca: enable angle shifting for layer change - bool rotate_angle{ true }; + float rotate_angle{ M_PI/180.0 }; // In scaled coordinates. Maximum lenght of a perimeter segment connecting two infill lines. // Used by the FillRectilinear2, FillGrid2, FillTriangles, FillStars and FillCubic. // If left to zero, the links will not be limited. @@ -135,20 +152,25 @@ public: static bool use_bridge_flow(const InfillPattern type); void set_bounding_box(const Slic3r::BoundingBox &bbox) { bounding_box = bbox; } - + BoundingBox extended_object_bounding_box() const; // Use bridge flow for the fill? virtual bool use_bridge_flow() const { return false; } // Do not sort the fill lines to optimize the print head path? virtual bool no_sort() const { return false; } + virtual bool is_self_crossing() = 0; + + // Return true if infill has a consistent pattern between layers. + virtual bool has_consistent_pattern() const { return false; } + // Perform the fill. virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms); virtual ThickPolylines fill_surface_arachne(const Surface* surface, const FillParams& params); - + virtual void set_lock_region_param(const LockRegionParam &lock_param){}; // BBS: this method is used to fill the ExtrusionEntityCollection. // It call fill_surface by default - virtual void fill_surface_extrusion(const Surface* surface, const FillParams& params, ExtrusionEntitiesPtr& out); + virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out); protected: Fill() : @@ -159,7 +181,7 @@ protected: overlap(0.), // Initial angle is undefined. angle(FLT_MAX), - rotate_angle(true), + rotate_angle(M_PI/180.0), link_max_length(0), loop_clipping(0), // The initial bounding box is empty, therefore undefined. @@ -168,11 +190,11 @@ protected: // The expolygon may be modified by the method to avoid a copy. virtual void _fill_surface_single( - const FillParams & /* params */, + const FillParams & /* params */, unsigned int /* thickness_layers */, - const std::pair & /* direction */, + const std::pair & /* direction */, ExPolygon /* expolygon */, - Polylines & /* polylines_out */) {}; + Polylines & /* polylines_out */) {} // Used for concentric infill to generate ThickPolylines using Arachne. virtual void _fill_surface_single(const FillParams& params, @@ -181,7 +203,7 @@ protected: ExPolygon expolygon, ThickPolylines& thick_polylines_out) {} - virtual float _layer_angle(size_t idx) const { return (rotate_angle && (idx & 1)) ? float(M_PI/2.) : 0; } + virtual float _layer_angle(size_t idx) const { return rotate_angle; } virtual std::pair _infill_direction(const Surface *surface) const; diff --git a/src/libslic3r/Fill/FillConcentric.hpp b/src/libslic3r/Fill/FillConcentric.hpp index 476c9b8757..56040d848d 100644 --- a/src/libslic3r/Fill/FillConcentric.hpp +++ b/src/libslic3r/Fill/FillConcentric.hpp @@ -9,6 +9,7 @@ class FillConcentric : public Fill { public: ~FillConcentric() override = default; + bool is_self_crossing() override { return false; } protected: Fill* clone() const override { return new FillConcentric(*this); }; diff --git a/src/libslic3r/Fill/FillConcentricInternal.hpp b/src/libslic3r/Fill/FillConcentricInternal.hpp index e362d72b81..2c93eb5ee9 100644 --- a/src/libslic3r/Fill/FillConcentricInternal.hpp +++ b/src/libslic3r/Fill/FillConcentricInternal.hpp @@ -10,6 +10,7 @@ class FillConcentricInternal : public Fill public: ~FillConcentricInternal() override = default; void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) override; + bool is_self_crossing() override { return false; } protected: Fill* clone() const override { return new FillConcentricInternal(*this); }; diff --git a/src/libslic3r/Fill/FillCrossHatch.hpp b/src/libslic3r/Fill/FillCrossHatch.hpp index 859d5bd8b5..34c46116eb 100644 --- a/src/libslic3r/Fill/FillCrossHatch.hpp +++ b/src/libslic3r/Fill/FillCrossHatch.hpp @@ -14,6 +14,7 @@ class FillCrossHatch : public Fill public: Fill *clone() const override { return new FillCrossHatch(*this); }; ~FillCrossHatch() override {} + bool is_self_crossing() override { return false; } protected: void _fill_surface_single( diff --git a/src/libslic3r/Fill/FillGyroid.hpp b/src/libslic3r/Fill/FillGyroid.hpp index ac66dfca98..751a7c2570 100644 --- a/src/libslic3r/Fill/FillGyroid.hpp +++ b/src/libslic3r/Fill/FillGyroid.hpp @@ -15,6 +15,7 @@ public: // require bridge flow since most of this pattern hangs in air bool use_bridge_flow() const override { return false; } + bool is_self_crossing() override { return false; } // Correction applied to regular infill angle to maximize printing // speed in default configuration (degrees) diff --git a/src/libslic3r/Fill/FillHoneycomb.hpp b/src/libslic3r/Fill/FillHoneycomb.hpp index 707e976fd9..55be423854 100644 --- a/src/libslic3r/Fill/FillHoneycomb.hpp +++ b/src/libslic3r/Fill/FillHoneycomb.hpp @@ -13,6 +13,7 @@ class FillHoneycomb : public Fill { public: ~FillHoneycomb() override {} + bool is_self_crossing() override { return false; } protected: Fill* clone() const override { return new FillHoneycomb(*this); }; diff --git a/src/libslic3r/Fill/FillLightning.hpp b/src/libslic3r/Fill/FillLightning.hpp index 6e672783a1..74aa159b0b 100644 --- a/src/libslic3r/Fill/FillLightning.hpp +++ b/src/libslic3r/Fill/FillLightning.hpp @@ -20,6 +20,7 @@ class Filler : public Slic3r::Fill { public: ~Filler() override = default; + bool is_self_crossing() override { return false; } Generator *generator { nullptr }; protected: diff --git a/src/libslic3r/Fill/FillLine.hpp b/src/libslic3r/Fill/FillLine.hpp index 9bf2b97e09..4ad9ca49a4 100644 --- a/src/libslic3r/Fill/FillLine.hpp +++ b/src/libslic3r/Fill/FillLine.hpp @@ -14,6 +14,7 @@ class FillLine : public Fill public: Fill* clone() const override { return new FillLine(*this); }; ~FillLine() override = default; + bool is_self_crossing() override { return false; } protected: void _fill_surface_single( diff --git a/src/libslic3r/Fill/FillPlanePath.hpp b/src/libslic3r/Fill/FillPlanePath.hpp index f05f3209aa..1371e8506a 100644 --- a/src/libslic3r/Fill/FillPlanePath.hpp +++ b/src/libslic3r/Fill/FillPlanePath.hpp @@ -37,6 +37,7 @@ class FillPlanePath : public Fill { public: ~FillPlanePath() override = default; + bool is_self_crossing() override { return false; } protected: void _fill_surface_single( diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 6948cfd799..261ae3c046 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -987,7 +987,6 @@ static std::vector slice_region_by_vertical_lines(con throw; } #endif //INFILL_DEBUG_OUTPUT - return segs; } @@ -1352,8 +1351,11 @@ static SegmentIntersection& end_of_vertical_run(SegmentedIntersectionLine &il, S return const_cast(end_of_vertical_run(std::as_const(il), std::as_const(start))); } -static void traverse_graph_generate_polylines( - const ExPolygonWithOffset& poly_with_offset, const FillParams& params, const coord_t link_max_length, std::vector& segs, Polylines& polylines_out) +static void traverse_graph_generate_polylines(const ExPolygonWithOffset &poly_with_offset, + const FillParams ¶ms, + std::vector &segs, + const bool consistent_pattern, + Polylines &polylines_out) { // For each outer only chords, measure their maximum distance to the bow of the outer contour. // Mark an outer only chord as consumed, if the distance is low. @@ -1387,34 +1389,28 @@ static void traverse_graph_generate_polylines( pointLast = polylines_out.back().points.back(); for (;;) { if (i_intersection == -1) { - // The path has been interrupted. Find a next starting point, closest to the previous extruder position. - coordf_t dist2min = std::numeric_limits().max(); - for (int i_vline2 = 0; i_vline2 < int(segs.size()); ++ i_vline2) { + // The path has been interrupted. Find a next starting point. + for (int i_vline2 = 0; i_vline2 < int(segs.size()); ++i_vline2) { const SegmentedIntersectionLine &vline = segs[i_vline2]; - if (! vline.intersections.empty()) { + if (!vline.intersections.empty()) { assert(vline.intersections.size() > 1); // Even number of intersections with the loops. assert((vline.intersections.size() & 1) == 0); assert(vline.intersections.front().type == SegmentIntersection::OUTER_LOW); - for (int i = 0; i < int(vline.intersections.size()); ++ i) { - const SegmentIntersection& intrsctn = vline.intersections[i]; + + // For infill that needs to be consistent between layers (like Zig Zag), + // we are switching between forward and backward passes based on the line index. + const bool forward_pass = !consistent_pattern || (i_vline2 % 2 == 0); + for (int i = 0; i < int(vline.intersections.size()); ++i) { + const int intrsctn_idx = forward_pass ? i : int(vline.intersections.size()) - i - 1; + const SegmentIntersection &intrsctn = vline.intersections[intrsctn_idx]; if (intrsctn.is_outer()) { - assert(intrsctn.is_low() || i > 0); - bool consumed = intrsctn.is_low() ? - intrsctn.consumed_vertical_up : - vline.intersections[i - 1].consumed_vertical_up; - if (! consumed) { - coordf_t dist2 = sqr(coordf_t(pointLast(0) - vline.pos)) + sqr(coordf_t(pointLast(1) - intrsctn.pos())); - if (dist2 < dist2min) { - dist2min = dist2; - i_vline = i_vline2; - i_intersection = i; - //FIXME We are taking the first left point always. Verify, that the caller chains the paths - // by a shortest distance, while reversing the paths if needed. - //if (polylines_out.empty()) - // Initial state, take the first line, which is the first from the left. - goto found; - } + assert(intrsctn.is_low() || intrsctn_idx > 0); + const bool consumed = intrsctn.is_low() ? intrsctn.consumed_vertical_up : vline.intersections[intrsctn_idx - 1].consumed_vertical_up; + if (!consumed) { + i_vline = i_vline2; + i_intersection = intrsctn_idx; + goto found; } } } @@ -1487,9 +1483,13 @@ static void traverse_graph_generate_polylines( // 1) Find possible connection points on the previous / next vertical line. int i_prev = it->left_horizontal(); int i_next = it->right_horizontal(); - bool intersection_prev_valid = intersection_on_prev_vertical_line_valid(segs, i_vline, i_intersection); + + // To ensure pattern consistency between layers for Zig Zag infill, we always + // try to connect to the next vertical line and never to the previous vertical line. + bool intersection_prev_valid = intersection_on_prev_vertical_line_valid(segs, i_vline, i_intersection) && !consistent_pattern; bool intersection_next_valid = intersection_on_next_vertical_line_valid(segs, i_vline, i_intersection); bool intersection_horizontal_valid = intersection_prev_valid || intersection_next_valid; + // Mark both the left and right connecting segment as consumed, because one cannot go to this intersection point as it has been consumed. if (i_prev != -1) segs[i_vline - 1].intersections[i_prev].consumed_perimeter_right = true; @@ -2737,6 +2737,17 @@ static void polylines_from_paths(const std::vector &path, c } } +// The extended bounding box of the whole object that covers any rotation of every layer. +BoundingBox FillRectilinear::extended_object_bounding_box() const { + BoundingBox out = this->bounding_box; + out.merge(Point(out.min.y(), out.min.x())); + out.merge(Point(out.max.y(), out.max.x())); + + // The bounding box is scaled by sqrt(2.) to ensure that the bounding box + // covers any possible rotations. + return out.scaled(sqrt(2.)); +} + bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillParams ¶ms, float angleBase, float pattern_shift, Polylines &polylines_out) { // At the end, only the new polylines will be rotated back. @@ -2749,6 +2760,8 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa // Rotate polygons so that we can work with vertical lines here std::pair rotate_vector = this->_infill_direction(surface); + if (params.locked_zag) + rotate_vector.first += float(M_PI/2.); rotate_vector.first += angleBase; assert(params.density > 0.0001f && params.density <= 1.f); @@ -2766,11 +2779,14 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa return true; } - BoundingBox bounding_box = poly_with_offset.bounding_box_src(); + // For infill that needs to be consistent between layers (like Zig Zag), + // we use bounding box of whole object to match vertical lines between layers. + BoundingBox bounding_box_src = poly_with_offset.bounding_box_src(); + BoundingBox bounding_box = this->has_consistent_pattern() ? this->extended_object_bounding_box() : bounding_box_src; // define flow spacing according to requested density if (params.full_infill() && !params.dont_adjust) { - line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing); + line_spacing = this->_adjust_solid_spacing(bounding_box_src.size().x(), line_spacing); this->spacing = unscale(line_spacing); } else { // extend bounding box so that our pattern will be aligned with other layers @@ -2792,6 +2808,13 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa if (params.full_infill()) x0 += (line_spacing + coord_t(SCALED_EPSILON)) / 2; + int gap_line = params.horiz_move / line_spacing; + if (gap_line % 2 == 0) { + x0 += params.horiz_move - gap_line * line_spacing; + } else { + x0 += params.horiz_move - (gap_line - 1) * line_spacing; + n_vlines += 1; + } #ifdef SLIC3R_DEBUG static int iRun = 0; BoundingBox bbox_svg = poly_with_offset.bounding_box_outer(); @@ -2803,7 +2826,6 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa } iRun ++; #endif /* SLIC3R_DEBUG */ - std::vector segs = slice_region_by_vertical_lines(poly_with_offset, n_vlines, x0, line_spacing); // Connect by horizontal / vertical links, classify the links based on link_max_length as too long. connect_segment_intersections_by_contours(poly_with_offset, segs, params, link_max_length); @@ -2848,8 +2870,9 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa std::vector path = chain_monotonic_regions(regions, poly_with_offset, segs, rng); polylines_from_paths(path, poly_with_offset, segs, polylines_out); } - } else - traverse_graph_generate_polylines(poly_with_offset, params, this->link_max_length, segs, polylines_out); + } else { + traverse_graph_generate_polylines(poly_with_offset, params, segs, this->has_consistent_pattern(), polylines_out); + } #ifdef SLIC3R_DEBUG { @@ -2876,6 +2899,11 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa //FIXME rather simplify the paths to avoid very short edges? //assert(! it->has_duplicate_points()); it->remove_duplicate_points(); + + //get origin direction infill + if (params.symmetric_infill_y_axis) { + it->symmetric_y(params.symmetric_y_axis); + } } #ifdef SLIC3R_DEBUG @@ -2884,6 +2912,8 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa assert(! polyline.has_duplicate_points()); #endif /* SLIC3R_DEBUG */ + + return true; } @@ -2963,7 +2993,8 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar Polylines FillRectilinear::fill_surface(const Surface *surface, const FillParams ¶ms) { Polylines polylines_out; - if (params.full_infill()) { + // Orca Todo: fow now don't use fill_surface_by_multilines for zipzag infill + if (params.full_infill() || params.pattern == ipCrossZag || params.pattern == ipZigZag || params.pattern == ipLockedZag) { if (!fill_surface_by_lines(surface, params, 0.f, 0.f, polylines_out)) BOOST_LOG_TRIVIAL(error) << "FillRectilinear::fill_surface() fill_surface_by_lines() failed to fill a region."; } else { @@ -3409,5 +3440,119 @@ void FillMonotonicLineWGapFill::fill_surface_by_lines(const Surface* surface, co } }*/ +void FillLockedZag::fill_surface_locked_zag (const Surface * surface, + const FillParams & params, + std::vector> &multi_width_polyline) +{ + // merge different part exps + // diff skin flow + Polylines skin_lines; + Polylines skeloton_lines; + double offset_threshold = params.skin_infill_depth; + double overlap_threshold = params.infill_lock_depth; + Surface cross_surface = *surface; + Surface zig_surface = *surface; + // inner exps + // inner union exps + ExPolygons zig_expas = offset_ex({surface->expolygon}, -offset_threshold); + ExPolygons cross_expas = diff_ex(surface->expolygon, zig_expas); + + bool zig_get = false; + FillParams zig_params = params; + zig_params.horiz_move = 0; + // generate skeleton for diff density + auto generate_for_different_flow = [&multi_width_polyline](const std::map &flow_params, const Polylines &polylines) { + auto it = flow_params.begin(); + while (it != flow_params.end()) { + ExPolygons region_exp = union_safety_offset_ex(it->second); + + Polylines polys = intersection_pl(polylines, region_exp); + multi_width_polyline.emplace_back(polys, it->first); + it++; + } + }; + + auto it = this->lock_param.skeleton_density_params.begin(); + while (it != this->lock_param.skeleton_density_params.end()) { + ExPolygons region_exp = union_safety_offset_ex(it->second); + ExPolygons exps = intersection_ex(region_exp, zig_expas); + zig_params.density = it->first; + exps = intersection_ex(offset_ex(exps, overlap_threshold), surface->expolygon); + for (ExPolygon &exp : exps) { + zig_surface.expolygon = exp; + + Polylines zig_polylines_out = this->fill_surface(&zig_surface, zig_params); + skeloton_lines.insert(skeloton_lines.end(), zig_polylines_out.begin(), zig_polylines_out.end()); + } + it++; + } + + // set skeleton flow + generate_for_different_flow(this->lock_param.skeleton_flow_params, skeloton_lines); + + // skin exps + bool cross_get = false; + FillParams cross_params = params; + cross_params.locked_zag = false; + auto skin_density = this->lock_param.skin_density_params.begin(); + while (skin_density != this->lock_param.skin_density_params.end()) { + ExPolygons region_exp = union_safety_offset_ex(skin_density->second); + ExPolygons exps = intersection_ex(region_exp, cross_expas); + cross_params.density = skin_density->first; + for (ExPolygon &exp : exps) { + cross_surface.expolygon = exp; + Polylines cross_polylines_out = this->fill_surface(&cross_surface, cross_params); + skin_lines.insert(skin_lines.end(), cross_polylines_out.begin(), cross_polylines_out.end()); + } + skin_density++; + } + + generate_for_different_flow(this->lock_param.skin_flow_params, skin_lines); +} + +void FillLockedZag::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) +{ + Polylines polylines; + ThickPolylines thick_polylines; + std::vector> multi_width_polyline; + try { + this->fill_surface_locked_zag(surface, params, multi_width_polyline); + } + catch (InfillFailedException&) {} + + if (!thick_polylines.empty() || !multi_width_polyline.empty()) { + // Save into layer. + ExtrusionEntityCollection* eec = nullptr; + out.push_back(eec = new ExtrusionEntityCollection()); + // Only concentric fills are not sorted. + eec->no_sort = this->no_sort(); + size_t idx = eec->entities.size(); + { + for (std::pair &poly_with_flow: multi_width_polyline) { + // calculate actual flow from spacing (which might have been adjusted by the infill + // pattern generator) + double flow_mm3_per_mm = poly_with_flow.second.mm3_per_mm(); + double flow_width = poly_with_flow.second.width(); + if (params.using_internal_flow) { + // if we used the internal flow we're not doing a solid infill + // so we can safely ignore the slight variation that might have + // been applied to f->spacing + } else { + Flow new_flow = poly_with_flow.second.with_spacing(this->spacing); + flow_mm3_per_mm = new_flow.mm3_per_mm(); + flow_width = new_flow.width(); + } + extrusion_entities_append_paths( + eec->entities, std::move(poly_with_flow.first), + params.extrusion_role, + flow_mm3_per_mm, float(flow_width), poly_with_flow.second.height()); + } + } + if (!params.can_reverse) { + for (size_t i = idx; i < eec->entities.size(); i++) + eec->entities[i]->set_reverse(); + } + } +} } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillRectilinear.hpp b/src/libslic3r/Fill/FillRectilinear.hpp index 2dbcad3e90..28b20ef1f2 100644 --- a/src/libslic3r/Fill/FillRectilinear.hpp +++ b/src/libslic3r/Fill/FillRectilinear.hpp @@ -16,6 +16,7 @@ public: Fill* clone() const override { return new FillRectilinear(*this); } ~FillRectilinear() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; + bool is_self_crossing() override { return false; } protected: // Fill by single directional lines, interconnect the lines along perimeters. @@ -28,6 +29,9 @@ protected: float pattern_shift; }; bool fill_surface_by_multilines(const Surface *surface, FillParams params, const std::initializer_list &sweep_params, Polylines &polylines_out); + + // The extended bounding box of the whole object that covers any rotation of every layer. + BoundingBox extended_object_bounding_box() const; }; class FillAlignedRectilinear : public FillRectilinear @@ -65,6 +69,7 @@ public: Fill* clone() const override { return new FillGrid(*this); } ~FillGrid() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; + bool is_self_crossing() override { return true; } protected: // The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill. @@ -89,6 +94,7 @@ public: Fill* clone() const override { return new FillTriangles(*this); } ~FillTriangles() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; + bool is_self_crossing() override { return true; } protected: // The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill. @@ -101,6 +107,7 @@ public: Fill* clone() const override { return new FillStars(*this); } ~FillStars() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; + bool is_self_crossing() override { return true; } protected: // The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill. @@ -113,6 +120,7 @@ public: Fill* clone() const override { return new FillCubic(*this); } ~FillCubic() override = default; Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override; + bool is_self_crossing() override { return true; } protected: // The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill. @@ -170,6 +178,7 @@ public: public: ~FillMonotonicLineWGapFill() override = default; void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) override; + bool is_self_crossing() override { return false; } protected: Fill* clone() const override { return new FillMonotonicLineWGapFill(*this); }; @@ -179,9 +188,43 @@ private: void fill_surface_by_lines(const Surface* surface, const FillParams& params, Polylines& polylines_out); };*/ -Points sample_grid_pattern(const ExPolygon& expolygon, coord_t spacing, const BoundingBox& global_bounding_box); -Points sample_grid_pattern(const ExPolygons& expolygons, coord_t spacing, const BoundingBox& global_bounding_box); -Points sample_grid_pattern(const Polygons& polygons, coord_t spacing, const BoundingBox& global_bounding_box); +class FillZigZag : public FillRectilinear +{ +public: + Fill* clone() const override { return new FillZigZag(*this); } + ~FillZigZag() override = default; + + bool has_consistent_pattern() const override { return true; } +}; + +class FillCrossZag : public FillRectilinear +{ +public: + Fill *clone() const override { return new FillCrossZag(*this); } + ~FillCrossZag() override = default; + + bool has_consistent_pattern() const override { return true; } +}; + +class FillLockedZag : public FillRectilinear +{ +public: + Fill *clone() const override { return new FillLockedZag(*this); } + ~FillLockedZag() override = default; + LockRegionParam lock_param; + + void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) override; + + bool has_consistent_pattern() const override { return true; } + void set_lock_region_param(const LockRegionParam &lock_param) override { this->lock_param = lock_param;}; + void fill_surface_locked_zag(const Surface * surface, + const FillParams & params, + std::vector> &multi_width_polyline); +}; + +Points sample_grid_pattern(const ExPolygon &expolygon, coord_t spacing, const BoundingBox &global_bounding_box); +Points sample_grid_pattern(const ExPolygons &expolygons, coord_t spacing, const BoundingBox &global_bounding_box); +Points sample_grid_pattern(const Polygons &polygons, coord_t spacing, const BoundingBox &global_bounding_box); } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillTpmsD.hpp b/src/libslic3r/Fill/FillTpmsD.hpp index 73b55e1e1c..5e8accc19c 100644 --- a/src/libslic3r/Fill/FillTpmsD.hpp +++ b/src/libslic3r/Fill/FillTpmsD.hpp @@ -25,20 +25,20 @@ public: // speed in default configuration (degrees) static constexpr float CorrectionAngle = -45.; + void _fill_surface_single(const FillParams& params, + unsigned int thickness_layers, + const std::pair& direction, + ExPolygon expolygon, + Polylines& polylines_out) override; + + bool is_self_crossing() override { return false; } + // Density adjustment to have a good %of weight. static constexpr double DensityAdjust = 2.1; // Gyroid upper resolution tolerance (mm^-2) static constexpr double PatternTolerance = 0.1; - -protected: - void _fill_surface_single( - const FillParams ¶ms, - unsigned int thickness_layers, - const std::pair &direction, - ExPolygon expolygon, - Polylines &polylines_out) override; }; } // namespace Slic3r diff --git a/src/libslic3r/Flow.hpp b/src/libslic3r/Flow.hpp index c7954158f5..79cb1b324d 100644 --- a/src/libslic3r/Flow.hpp +++ b/src/libslic3r/Flow.hpp @@ -82,6 +82,13 @@ public: bool operator==(const Flow &rhs) const { return m_width == rhs.m_width && m_height == rhs.m_height && m_nozzle_diameter == rhs.m_nozzle_diameter && m_bridge == rhs.m_bridge; } + bool operator!=(const Flow &rhs) const{ + return m_width != rhs.m_width || m_height != rhs.m_height || m_nozzle_diameter != rhs.m_nozzle_diameter || m_bridge != rhs.m_bridge; + } + + bool operator <(const Flow &rhs) const { + return this->mm3_per_mm() < rhs.mm3_per_mm(); + } Flow with_width (float width) const { assert(! m_bridge); return Flow(width, m_height, rounded_rectangle_extrusion_spacing(width, m_height), m_nozzle_diameter, m_bridge); diff --git a/src/libslic3r/MultiPoint.cpp b/src/libslic3r/MultiPoint.cpp index f027e93a07..fbf898234e 100644 --- a/src/libslic3r/MultiPoint.cpp +++ b/src/libslic3r/MultiPoint.cpp @@ -507,4 +507,11 @@ BoundingBox get_extents_rotated(const MultiPoint &mp, double angle) return get_extents_rotated(mp.points, angle); } +void MultiPoint::symmetric_y(const coord_t &x_axis) +{ + for (Point &pt : points) { + pt(0) = 2 * x_axis - pt(0); + } +} + } diff --git a/src/libslic3r/MultiPoint.hpp b/src/libslic3r/MultiPoint.hpp index db51a6a87a..0dfb98f4b4 100644 --- a/src/libslic3r/MultiPoint.hpp +++ b/src/libslic3r/MultiPoint.hpp @@ -94,7 +94,7 @@ public: bool intersection(const Line& line, Point* intersection) const; bool first_intersection(const Line& line, Point* intersection) const; bool intersections(const Line &line, Points *intersections) const; - + void symmetric_y(const coord_t &y_axis); static Points _douglas_peucker(const Points &points, const double tolerance); static Points visivalingam(const Points& pts, const double tolerance); static Points concave_hull_2d(const Points& pts, const double tolerence); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index b640815ec7..3812601bb5 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -786,7 +786,7 @@ static std::vector s_Preset_print_options { "top_shell_layers", "top_shell_thickness", "bottom_shell_layers", "bottom_shell_thickness", "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold","overhang_reverse_internal_only", "wall_direction", "seam_position", "staggered_inner_seams", "wall_sequence", "is_infill_first", "sparse_infill_density", "sparse_infill_pattern", "lattice_angle_1", "lattice_angle_2", "infill_overhang_angle", "top_surface_pattern", "bottom_surface_pattern", - "infill_direction", "solid_infill_direction", "rotate_solid_infill_direction", "counterbore_hole_bridging", + "infill_direction", "solid_infill_direction", "counterbore_hole_bridging","infill_shift_step", "sparse_infill_rotate_template", "solid_infill_rotate_template", "symmetric_infill_y_axis","skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density", "minimum_sparse_infill_area", "reduce_infill_retraction","internal_solid_infill_pattern","gap_fill_target", "ironing_type", "ironing_pattern", "ironing_flow", "ironing_speed", "ironing_spacing", "ironing_angle", "ironing_inset", "support_ironing", "support_ironing_pattern", "support_ironing_flow", "support_ironing_spacing", @@ -806,8 +806,9 @@ static std::vector s_Preset_print_options { "support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "thick_internal_bridges","dont_filter_internal_bridges","enable_extra_bridge_layer", "max_bridge_length", "print_sequence", "print_order", "support_remove_small_overhang", "filename_format", "wall_filament", "support_bottom_z_distance", "sparse_infill_filament", "solid_infill_filament", "support_filament", "support_interface_filament","support_interface_not_for_body", - "ooze_prevention", "standby_temperature_delta", "preheat_time","preheat_steps", "interface_shells", "line_width", "initial_layer_line_width", - "inner_wall_line_width", "outer_wall_line_width", "sparse_infill_line_width", "internal_solid_infill_line_width", + "ooze_prevention", "standby_temperature_delta", "preheat_time","preheat_steps", "interface_shells", "line_width", "initial_layer_line_width", "inner_wall_line_width", + "outer_wall_line_width", "sparse_infill_line_width", "internal_solid_infill_line_width", + "skin_infill_line_width","skeleton_infill_line_width", "top_surface_line_width", "support_line_width", "infill_wall_overlap","top_bottom_infill_wall_overlap", "bridge_flow", "internal_bridge_flow", "elefant_foot_compensation", "elefant_foot_compensation_layers", "xy_contour_compensation", "xy_hole_compensation", "resolution", "enable_prime_tower", "prime_tower_width", "prime_tower_brim_width", "prime_volume", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1bb7834927..ae2b420049 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1387,7 +1387,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* if (!validate_extrusion_width(object->config(), "support_line_width", layer_height, err_msg)) return {err_msg, object, "support_line_width"}; } - for (const char *opt_key : { "inner_wall_line_width", "outer_wall_line_width", "sparse_infill_line_width", "internal_solid_infill_line_width", "top_surface_line_width" }) + for (const char *opt_key : { "inner_wall_line_width", "outer_wall_line_width", "sparse_infill_line_width", "internal_solid_infill_line_width", "top_surface_line_width","skin_infill_line_width" ,"skeleton_infill_line_width"}) for (const PrintRegion ®ion : object->all_regions()) if (!validate_extrusion_width(region.config(), opt_key, layer_height, err_msg)) return {err_msg, object, opt_key}; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index f0b82cbe36..d3eb2174e0 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -161,6 +161,9 @@ static t_config_enum_values s_keys_map_InfillPattern { { "lightning", ipLightning }, { "crosshatch", ipCrossHatch}, { "quartercubic", ipQuarterCubic}, + { "zigzag", ipZigZag }, + { "crosszag", ipCrossZag }, + { "lockedzag", ipLockedZag } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(InfillPattern) @@ -2348,13 +2351,6 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(45)); - def = this->add("rotate_solid_infill_direction", coBool); - def->label = L("Rotate solid infill direction"); - def->category = L("Strength"); - def->tooltip = L("Rotate the solid infill direction by 90° for each layer."); - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionBool(true)); - def = this->add("sparse_infill_density", coPercent); def->label = L("Sparse infill density"); def->category = L("Strength"); @@ -2392,6 +2388,9 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("lightning"); def->enum_values.push_back("crosshatch"); def->enum_values.push_back("quartercubic"); + def->enum_values.push_back("zigzag"); + def->enum_values.push_back("crosszag"); + def->enum_values.push_back("lockedzag"); def->enum_labels.push_back(L("Concentric")); def->enum_labels.push_back(L("Rectilinear")); def->enum_labels.push_back(L("Grid")); @@ -2414,6 +2413,9 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Lightning")); def->enum_labels.push_back(L("Cross Hatch")); def->enum_labels.push_back(L("Quarter Cubic")); + def->enum_labels.push_back(L("Zig Zag")); + def->enum_labels.push_back(L("Cross Zag")); + def->enum_labels.push_back(L("Locked Zag")); def->set_default_value(new ConfigOptionEnum(ipCrossHatch)); def = this->add("lattice_angle_1", coFloat); @@ -3100,6 +3102,113 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("infill_shift_step", coFloat); + def->label = L("Infill shift step"); + def->category = L("Strength"); + def->tooltip = L("This parameter adds a slight displacement to each layer of infill to create a cross texture."); + def->sidetext = L("mm"); + def->min = 0; + def->max = 10; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.4)); + + //Orca + def = this->add("sparse_infill_rotate_template", coString); + def->label = L("Sparse infill rotatation template"); + def->category = L("Strength"); + def->tooltip = L("This parameter adds a rotation of sparse infill direction to each layer according to the specified template. " + "The template is a comma-separated list of angles in degrees, e.g. '0,90'. " + "The first angle is applied to the first layer, the second angle to the second layer, and so on. " + "If there are more layers than angles, the angles will be repeated. Note that not all all sparse infill patterns support rotation."); + def->sidetext = L("°"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionString("0,90")); + + //Orca + def = this->add("solid_infill_rotate_template", coString); + def->label = L("Solid infill rotatation template"); + def->category = L("Strength"); + def->tooltip = L("This parameter adds a rotation of solid infill direction to each layer according to the specified template. " + "The template is a comma-separated list of angles in degrees, e.g. '0,90'. " + "The first angle is applied to the first layer, the second angle to the second layer, and so on. " + "If there are more layers than angles, the angles will be repeated. Note that not all all solid infill patterns support rotation."); + def->sidetext = L("°"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionString("0,90")); + + + def = this->add("skeleton_infill_density", coPercent); + def->label = L("Skeleton infill density"); + def->category = L("Strength"); + def->tooltip = L("The remaining part of the model contour after removing a certain depth from the surface is called the skeleton. This parameter is used to adjust the density of this section." + "When two regions have the same sparse infill settings but different skeleton densities, their skeleton areas will develop overlapping sections." + "default is as same as infill density."); + def->sidetext = "%"; + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionPercent(25)); + + def = this->add("skin_infill_density", coPercent); + def->label = L("Skin infill density"); + def->category = L("Strength"); + def->tooltip = L("The portion of the model's outer surface within a certain depth range is called the skin. This parameter is used to adjust the density of this section." + "When two regions have the same sparse infill settings but different skin densities, This area will not be split into two separate regions." + "default is as same as infill density."); + def->sidetext = "%"; + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionPercent(25)); + + def = this->add("skin_infill_depth", coFloat); + def->label = L("Skin infill depth"); + def->category = L("Strength"); + def->tooltip = L("The parameter sets the depth of skin."); + def->sidetext = L("mm"); + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(2.0)); + + def = this->add("infill_lock_depth", coFloat); + def->label = L("Infill lock depth"); + def->category = L("Strength"); + def->tooltip = L("The parameter sets the overlapping depth between the interior and skin."); + def->sidetext = L("mm"); + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1.0)); + + def = this->add("skin_infill_line_width", coFloatOrPercent); + def->label = L("Skin line width"); + def->category = L("Strength"); + def->tooltip = L("Adjust the line width of the selected skin paths."); + def->sidetext = L("mm"); + def->ratio_over = "nozzle_diameter"; + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloatOrPercent(0.4, false)); + + def = this->add("skeleton_infill_line_width", coFloatOrPercent); + def->label = L("Skeleton line width"); + def->category = L("Strength"); + def->tooltip = L("Adjust the line width of the selected skeleton paths."); + def->sidetext = L("mm"); + def->ratio_over = "nozzle_diameter"; + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloatOrPercent(0.4, false)); + + def = this->add("symmetric_infill_y_axis", coBool); + def->label = L("Symmetric infill y axis"); + def->category = L("Strength"); + def->tooltip = L("If the model has two parts that are symmetric about the y-axis," + " and you want these parts to have symmetric textures, please click this option on one of the parts."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + // Orca: max layer height for combined infill def = this->add("infill_combination_max_layer_height", coFloatOrPercent); def->label = L("Infill combination - Max layer height"); @@ -6657,33 +6766,31 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va else if (value == "0"){ value = "ensure_moderate"; } - } - else if (opt_key == "sparse_infill_anchor") { + } else if (opt_key == "rotate_solid_infill_direction") { + opt_key = "solid_infill_rotate_template"; + if (value == "1") { + value = "0,90"; + } else if (value == "0") { + value = "0"; + } + } else if (opt_key == "sparse_infill_anchor") { opt_key = "infill_anchor"; - } - else if (opt_key == "sparse_infill_anchor_max") { + } else if (opt_key == "sparse_infill_anchor_max") { opt_key = "infill_anchor_max"; - } - else if (opt_key == "chamber_temperatures") { + } else if (opt_key == "chamber_temperatures") { opt_key = "chamber_temperature"; - } - else if (opt_key == "thumbnail_size") { + } else if (opt_key == "thumbnail_size") { opt_key = "thumbnails"; - } - else if (opt_key == "top_one_wall_type" && value != "none") { + } else if (opt_key == "top_one_wall_type" && value != "none") { opt_key = "only_one_wall_top"; value = "1"; - } - else if (opt_key == "initial_layer_flow_ratio") { + } else if (opt_key == "initial_layer_flow_ratio") { opt_key = "bottom_solid_infill_flow_ratio"; - } - else if(opt_key == "ironing_direction") { + } else if (opt_key == "ironing_direction") { opt_key = "ironing_angle"; - } - else if(opt_key == "counterbole_hole_bridging") { + } else if (opt_key == "counterbole_hole_bridging") { opt_key = "counterbore_hole_bridging"; - } - else if (opt_key == "draft_shield" && value == "limited") { + } else if (opt_key == "draft_shield" && value == "limited") { value = "disabled"; } @@ -7304,7 +7411,9 @@ std::map validate(const FullPrintConfig &cfg, bool und "internal_solid_infill_line_width", "top_surface_line_width", "support_line_width", - "initial_layer_line_width" }; + "initial_layer_line_width", + "skin_infill_line_width", + "skeleton_infill_line_width"}; for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++ i) { std::string key(widths[i]); if (cfg.get_abs_value(key, max_nozzle_diameter) > 2.5 * max_nozzle_diameter) { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ffd97c0ac9..b4ce02309b 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -60,7 +60,7 @@ enum AuthorizationType { enum InfillPattern : int { ipConcentric, ipRectilinear, ipGrid, ip2DLattice, ipLine, ipCubic, ipTriangles, ipStars, ipGyroid, ipTpmsD, ipHoneycomb, ipAdaptiveCubic, ipMonotonic, ipMonotonicLine, ipAlignedRectilinear, ip2DHoneycomb, ip3DHoneycomb, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSupportCubic, ipSupportBase, ipConcentricInternal, - ipLightning, ipCrossHatch, ipQuarterCubic, + ipLightning, ipCrossHatch, ipQuarterCubic, ipZigZag, ipCrossZag, ipLockedZag, ipCount, }; @@ -946,7 +946,10 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, outer_wall_speed)) ((ConfigOptionFloat, infill_direction)) ((ConfigOptionFloat, solid_infill_direction)) - ((ConfigOptionBool, rotate_solid_infill_direction)) + ((ConfigOptionString, solid_infill_rotate_template)) + ((ConfigOptionBool, symmetric_infill_y_axis)) + ((ConfigOptionFloat, infill_shift_step)) + ((ConfigOptionString, sparse_infill_rotate_template)) ((ConfigOptionPercent, sparse_infill_density)) ((ConfigOptionEnum, sparse_infill_pattern)) ((ConfigOptionFloat, lattice_angle_1)) @@ -966,7 +969,12 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionPercent, infill_wall_overlap)) ((ConfigOptionPercent, top_bottom_infill_wall_overlap)) ((ConfigOptionFloat, sparse_infill_speed)) - //BBS + ((ConfigOptionPercent, skeleton_infill_density)) + ((ConfigOptionPercent, skin_infill_density)) + ((ConfigOptionFloat, infill_lock_depth)) + ((ConfigOptionFloat, skin_infill_depth)) + ((ConfigOptionFloatOrPercent, skin_infill_line_width)) + ((ConfigOptionFloatOrPercent, skeleton_infill_line_width)) ((ConfigOptionBool, infill_combination)) // Orca: ((ConfigOptionFloatOrPercent, infill_combination_max_layer_height)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 5db480347e..8b121f0bd9 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1073,9 +1073,10 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "sparse_infill_filament" || opt_key == "solid_infill_filament" || opt_key == "sparse_infill_line_width" + || opt_key == "skin_infill_line_width" + || opt_key == "skeleton_infill_line_width" || opt_key == "infill_direction" || opt_key == "solid_infill_direction" - || opt_key == "rotate_solid_infill_direction" || opt_key == "ensure_vertical_shell_thickness" || opt_key == "bridge_angle" || opt_key == "internal_bridge_angle" // ORCA: Internal bridge angle override @@ -1097,7 +1098,15 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "lattice_angle_2" || opt_key == "infill_overhang_angle") { steps.emplace_back(posInfill); - } else if (opt_key == "sparse_infill_pattern") { + } else if (opt_key == "sparse_infill_pattern" + || opt_key == "symmetric_infill_y_axis" + || opt_key == "infill_shift_step" + || opt_key == "sparse_infill_rotate_template" + || opt_key == "solid_infill_rotate_template" + || opt_key == "skeleton_infill_density" + || opt_key == "skin_infill_density" + || opt_key == "infill_lock_depth" + || opt_key == "skin_infill_depth") { steps.emplace_back(posPrepareInfill); } else if (opt_key == "sparse_infill_density") { // One likely wants to reslice only when switching between zero infill to simulate boolean difference (subtracting volumes), diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index dc73eb9454..134538137d 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -472,6 +472,20 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con apply(config, &new_conf); is_msg_dlg_already_exist = false; } + + // layer_height shouldn't be equal to zero + float skin_depth = config->opt_float("skin_infill_depth"); + if (config->opt_float("infill_lock_depth") > skin_depth) { + const wxString msg_text = _(L("lock depth should smaller than skin depth.\nReset to 50% of skin depth")); + MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK); + DynamicPrintConfig new_conf = *config; + is_msg_dlg_already_exist = true; + dialog.ShowModal(); + new_conf.set_key_value("infill_lock_depth", new ConfigOptionFloat(skin_depth / 2)); + apply(config, &new_conf); + is_msg_dlg_already_exist = false; + } + } void ConfigManipulation::apply_null_fff_config(DynamicPrintConfig *config, std::vector const &keys, std::map const &configs) @@ -526,7 +540,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co bool have_infill = config->option("sparse_infill_density")->value > 0; // sparse_infill_filament uses the same logic as in Print::extruders() for (auto el : { "sparse_infill_pattern", "infill_combination", - "minimum_sparse_infill_area", "sparse_infill_filament", "infill_anchor_max"}) + "minimum_sparse_infill_area", "sparse_infill_filament", "infill_anchor_max","infill_shift_step","sparse_infill_rotate_template","symmetric_infill_y_axis"}) toggle_line(el, have_infill); bool have_combined_infill = config->opt_bool("infill_combination") && have_infill; @@ -539,6 +553,19 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co bool has_infill_anchors = have_infill && config->option("infill_anchor_max")->value > 0 && infill_anchor; toggle_field("infill_anchor", has_infill_anchors); + //cross zag + bool is_cross_zag = config->option>("sparse_infill_pattern")->value == InfillPattern::ipCrossZag; + bool is_locked_zig = config->option>("sparse_infill_pattern")->value == InfillPattern::ipLockedZag; + + toggle_line("infill_shift_step", is_cross_zag || is_locked_zig); + + for (auto el : { "skeleton_infill_density", "skin_infill_density", "infill_lock_depth", "skin_infill_depth","skin_infill_line_width", "skeleton_infill_line_width" }) + toggle_line(el, is_locked_zig); + + bool is_zig_zag = config->option>("sparse_infill_pattern")->value == InfillPattern::ipZigZag; + + toggle_line("symmetric_infill_y_axis", is_zig_zag || is_cross_zag || is_locked_zig); + bool has_spiral_vase = config->opt_bool("spiral_mode"); toggle_line("spiral_mode_smooth", has_spiral_vase); toggle_line("spiral_mode_max_xy_smoothing", has_spiral_vase && config->opt_bool("spiral_mode_smooth")); @@ -552,7 +579,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co for (auto el : { "infill_direction", "sparse_infill_line_width", "sparse_infill_speed", "bridge_speed", "internal_bridge_speed", "bridge_angle", "internal_bridge_angle", - "solid_infill_direction", "rotate_solid_infill_direction", "internal_solid_infill_pattern", "solid_infill_filament", + "solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "solid_infill_filament", }) toggle_field(el, have_infill || has_solid_infill); @@ -823,6 +850,22 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co for (auto el : { "lattice_angle_1", "lattice_angle_2"}) toggle_line(el, lattice_options); + //Orca: hide rotate template for solid infill if not support + const auto _sparse_infill_pattern = config->option>("sparse_infill_pattern")->value; + bool show_sparse_infill_rotate_template = _sparse_infill_pattern == ipRectilinear || _sparse_infill_pattern == ipLine || + _sparse_infill_pattern == ipZigZag || _sparse_infill_pattern == ipCrossZag || + _sparse_infill_pattern == ipLockedZag; + + toggle_line("sparse_infill_rotate_template", show_sparse_infill_rotate_template); + + //Orca: hide rotate template for solid infill if not support + const auto _solid_infill_pattern = config->option>("internal_solid_infill_pattern")->value; + bool show_solid_infill_rotate_template = _solid_infill_pattern == ipRectilinear || _solid_infill_pattern == ipMonotonic || + _solid_infill_pattern == ipMonotonicLine || _solid_infill_pattern == ipAlignedRectilinear; + + toggle_line("solid_infill_rotate_template", show_solid_infill_rotate_template); + + toggle_line("infill_overhang_angle", config->opt_enum("sparse_infill_pattern") == InfillPattern::ip2DHoneycomb); } diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 7e5f229f1a..d7c9408103 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -430,6 +430,16 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true str = str_out; set_value(str, true); } + } else if (m_opt.opt_key == "sparse_infill_rotate_template" || m_opt.opt_key == "solid_infill_rotate_template") { + if (!ConfigOptionFloats::validate_string(str.utf8_string())) { + show_error(m_parent, format_wxstr(_L("This parameter expects a comma-delimited list of numbers. E.g, \"0,90\"."))); + wxString old_value(boost::any_cast(m_value)); + this->set_value(old_value, true); // Revert to previous value + } else { + // Valid string, so update m_value with the new string from the control. + m_value = into_u8(str); + } + break; } m_value = into_u8(str); diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 237c8c9604..d5d5de76a9 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -107,7 +107,7 @@ std::map> SettingsFactory::PART_CAT { L("Strength"), {{"wall_loops", "",1},{"top_shell_layers", L("Top Solid Layers"),1},{"top_shell_thickness", L("Top Minimum Shell Thickness"),1}, {"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1}, {"sparse_infill_density", "",1},{"sparse_infill_pattern", "",1},{"lattice_angle_1", "",1},{"lattice_angle_2", "",1},{"infill_overhang_angle", "",1},{"infill_anchor", "",1},{"infill_anchor_max", "",1},{"top_surface_pattern", "",1},{"bottom_surface_pattern", "",1}, {"internal_solid_infill_pattern", "",1}, - {"infill_combination", "",1}, {"infill_combination_max_layer_height", "",1}, {"infill_wall_overlap", "",1},{"top_bottom_infill_wall_overlap", "",1}, {"solid_infill_direction", "",1}, {"rotate_solid_infill_direction", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1}, {"internal_bridge_angle", "",1}, {"minimum_sparse_infill_area", "",1} + {"infill_combination", "",1}, {"infill_combination_max_layer_height", "",1}, {"infill_wall_overlap", "",1},{"top_bottom_infill_wall_overlap", "",1}, {"solid_infill_direction", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1}, {"internal_bridge_angle", "",1}, {"minimum_sparse_infill_area", "",1} }}, { L("Speed"), {{"outer_wall_speed", "",1},{"inner_wall_speed", "",2},{"sparse_infill_speed", "",3},{"top_surface_speed", "",4}, {"internal_solid_infill_speed", "",5}, {"enable_overhang_speed", "",6}, {"overhang_1_4_speed", "",7}, {"overhang_2_4_speed", "",8}, {"overhang_3_4_speed", "",9}, {"overhang_4_4_speed", "",10}, diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index fc7f6c7305..30e1f48d3c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -9920,7 +9920,6 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i _obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); _obj->config.set_key_value("infill_direction", new ConfigOptionFloat(45)); _obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(135)); - _obj->config.set_key_value("rotate_solid_infill_direction", new ConfigOptionBool(true)); _obj->config.set_key_value("ironing_type", new ConfigOptionEnum(IroningType::NoIroning)); _obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(internal_solid_speed)); _obj->config.set_key_value("top_surface_speed", new ConfigOptionFloat(top_surface_speed)); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 7b645a891f..730a3fda96 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1470,6 +1470,9 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } } + if (opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" ) + update_wiping_button_visibility(); + if (opt_key == "pellet_flow_coefficient") { @@ -1483,6 +1486,44 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } + if (opt_key == "single_extruder_multi_material" ){ + const auto bSEMM = m_config->opt_bool("single_extruder_multi_material"); + wxGetApp().sidebar().show_SEMM_buttons(bSEMM); + wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); + } + + if(opt_key == "purge_in_prime_tower") + wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); + + + if (opt_key == "enable_prime_tower") { + auto timelapse_type = m_config->option>("timelapse_type"); + bool timelapse_enabled = timelapse_type->value == TimelapseType::tlSmooth; + if (!boost::any_cast(value) && timelapse_enabled) { + MessageDialog dlg(wxGetApp().plater(), _L("A prime tower is required for smooth timelapse. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"), + _L("Warning"), wxICON_WARNING | wxYES | wxNO); + if (dlg.ShowModal() == wxID_NO) { + DynamicPrintConfig new_conf = *m_config; + new_conf.set_key_value("enable_prime_tower", new ConfigOptionBool(true)); + m_config_manipulation.apply(m_config, &new_conf); + } + wxGetApp().plater()->update(); + } + bool is_precise_z_height = m_config->option("precise_z_height")->value; + if (boost::any_cast(value) && is_precise_z_height) { + MessageDialog dlg(wxGetApp().plater(), _L("Enabling both precise Z height and the prime tower may cause the size of prime tower to increase. Do you still want to enable?"), + _L("Warning"), wxICON_WARNING | wxYES | wxNO); + if (dlg.ShowModal() == wxID_NO) { + DynamicPrintConfig new_conf = *m_config; + new_conf.set_key_value("enable_prime_tower", new ConfigOptionBool(false)); + m_config_manipulation.apply(m_config, &new_conf); + } + wxGetApp().plater()->update(); + } + update_wiping_button_visibility(); + } + + if (opt_key == "single_extruder_multi_material" ){ const auto bSEMM = m_config->opt_bool("single_extruder_multi_material"); wxGetApp().sidebar().show_SEMM_buttons(bSEMM); @@ -2165,20 +2206,30 @@ void TabPrint::build() optgroup = page->new_optgroup(L("Infill"), L"param_infill"); optgroup->append_single_option_line("sparse_infill_density", "strength_settings_infill#sparse-infill-density"); optgroup->append_single_option_line("sparse_infill_pattern", "strength_settings_infill#sparse-infill-pattern"); + optgroup->append_single_option_line("infill_direction"); + optgroup->append_single_option_line("sparse_infill_rotate_template"); + optgroup->append_single_option_line("skin_infill_density"); + optgroup->append_single_option_line("skeleton_infill_density"); + optgroup->append_single_option_line("infill_lock_depth"); + optgroup->append_single_option_line("skin_infill_depth"); + optgroup->append_single_option_line("skin_infill_line_width", "parameter/line-width"); + optgroup->append_single_option_line("skeleton_infill_line_width", "parameter/line-width"); + optgroup->append_single_option_line("symmetric_infill_y_axis"); + optgroup->append_single_option_line("infill_shift_step"); + optgroup->append_single_option_line("lattice_angle_1"); optgroup->append_single_option_line("lattice_angle_2"); optgroup->append_single_option_line("infill_overhang_angle"); optgroup->append_single_option_line("infill_anchor_max"); optgroup->append_single_option_line("infill_anchor"); optgroup->append_single_option_line("internal_solid_infill_pattern"); + optgroup->append_single_option_line("solid_infill_direction"); + optgroup->append_single_option_line("solid_infill_rotate_template"); optgroup->append_single_option_line("gap_fill_target"); optgroup->append_single_option_line("filter_out_gap_fill"); optgroup->append_single_option_line("infill_wall_overlap"); optgroup = page->new_optgroup(L("Advanced"), L"param_advanced"); - optgroup->append_single_option_line("infill_direction"); - optgroup->append_single_option_line("solid_infill_direction"); - optgroup->append_single_option_line("rotate_solid_infill_direction"); optgroup->append_single_option_line("bridge_angle"); optgroup->append_single_option_line("internal_bridge_angle"); // ORCA: Internal bridge angle override optgroup->append_single_option_line("minimum_sparse_infill_area"); From 51d844af2c5ecfc0c54f5d08c7a5ec6c08d3d1b1 Mon Sep 17 00:00:00 2001 From: Jonathan Dyrekilde Sommerlund <79661189+Buildasaurus@users.noreply.github.com> Date: Mon, 23 Jun 2025 04:28:21 +0200 Subject: [PATCH 05/13] Top/bottom surface pattern density (#9783) * Create top surface density option * Update tooltip * Specify what 0% top infill means * Add density for bottom layers * Discourage users from using top/bottom density incorrectly * Fix percent don't need translation * Fix incorrect indentation --------- Co-authored-by: Noisyfox --- src/libslic3r/Fill/Fill.cpp | 38 ++++++++--------- src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 24 +++++++++++ src/libslic3r/PrintConfig.hpp | 2 + src/libslic3r/PrintObject.cpp | 2 + src/slic3r/GUI/GUI_Factories.cpp | 16 +++---- src/slic3r/GUI/Tab.cpp | 72 ++++++++++++++++---------------- 7 files changed, 93 insertions(+), 63 deletions(-) diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 47726328c4..e56d4b2ec7 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -657,30 +657,30 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p if (params.pattern == ipCrossZag || params.pattern == ipLockedZag) { params.symmetric_infill_y_axis = region_config.symmetric_infill_y_axis; } else if (params.pattern == ipZigZag) { - - params.symmetric_infill_y_axis = region_config.symmetric_infill_y_axis; } if (surface.is_solid()) { - params.density = 100.f; - //FIXME for non-thick bridges, shall we allow a bottom surface pattern? - if (surface.is_solid_infill()) - params.pattern = region_config.internal_solid_infill_pattern.value; - else if (surface.is_external() && ! is_bridge) { - if(surface.is_top()) + if (surface.is_external() && !is_bridge) { + if (surface.is_top()) { params.pattern = region_config.top_surface_pattern.value; - else + params.density = float(region_config.top_surface_density); + } else { // Surface is bottom params.pattern = region_config.bottom_surface_pattern.value; - } - else { - if(region_config.top_surface_pattern == ipMonotonic || region_config.top_surface_pattern == ipMonotonicLine) + params.density = float(region_config.bottom_surface_density); + } + } else if (surface.is_solid_infill()) { + params.pattern = region_config.internal_solid_infill_pattern.value; + params.density = 100.f; + } else { + if (region_config.top_surface_pattern == ipMonotonic || region_config.top_surface_pattern == ipMonotonicLine) params.pattern = ipMonotonic; else params.pattern = ipRectilinear; + params.density = 100.f; } - } else if (params.density <= 0) - continue; + } else if (params.density <= 0) + continue; params.extrusion_role = erInternalInfill; if (is_bridge) { @@ -1029,7 +1029,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: params.resolution = resolution; params.use_arachne = surface_fill.params.pattern == ipConcentric || surface_fill.params.pattern == ipConcentricInternal; params.layer_height = layerm->layer()->height; - params.lattice_angle_1 = surface_fill.params.lattice_angle_1; + params.lattice_angle_1 = surface_fill.params.lattice_angle_1; params.lattice_angle_2 = surface_fill.params.lattice_angle_2; params.infill_overhang_angle = surface_fill.params.infill_overhang_angle; @@ -1041,7 +1041,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: auto ®ion_config = layerm->region().config(); ConfigOptionFloats rotate_angles; - rotate_angles.deserialize( surface_fill.params.extrusion_role == erInternalInfill ? region_config.sparse_infill_rotate_template.value : region_config.solid_infill_rotate_template.value); + rotate_angles.deserialize( surface_fill.params.extrusion_role == erInternalInfill ? region_config.sparse_infill_rotate_template.value : region_config.solid_infill_rotate_template.value); auto rotate_angle_idx = f->layer_id % rotate_angles.size(); f->rotate_angle = Geometry::deg2rad(rotate_angles.values[rotate_angle_idx]); @@ -1149,7 +1149,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc case ipTpmsD: case ipHilbertCurve: case ipArchimedeanChords: - case ipOctagramSpiral: + case ipOctagramSpiral: case ipZigZag: case ipCrossZag: case ipLockedZag: break; @@ -1196,8 +1196,8 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc params.resolution = resolution; params.use_arachne = false; params.layer_height = layerm.layer()->height; - params.lattice_angle_1 = surface_fill.params.lattice_angle_1; - params.lattice_angle_2 = surface_fill.params.lattice_angle_2; + params.lattice_angle_1 = surface_fill.params.lattice_angle_1; + params.lattice_angle_2 = surface_fill.params.lattice_angle_2; params.infill_overhang_angle = surface_fill.params.infill_overhang_angle; for (ExPolygon &expoly : surface_fill.expolygons) { diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 3812601bb5..255270421a 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -783,7 +783,7 @@ bool Preset::has_cali_lines(PresetBundle* preset_bundle) static std::vector s_Preset_print_options { "layer_height", "initial_layer_print_height", "wall_loops", "alternate_extra_wall", "slice_closing_radius", "spiral_mode", "spiral_mode_smooth", "spiral_mode_max_xy_smoothing", "spiral_starting_flow_ratio", "spiral_finishing_flow_ratio", "slicing_mode", - "top_shell_layers", "top_shell_thickness", "bottom_shell_layers", "bottom_shell_thickness", + "top_shell_layers", "top_shell_thickness", "top_surface_density", "bottom_surface_density", "bottom_shell_layers", "bottom_shell_thickness", "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold","overhang_reverse_internal_only", "wall_direction", "seam_position", "staggered_inner_seams", "wall_sequence", "is_infill_first", "sparse_infill_density", "sparse_infill_pattern", "lattice_angle_1", "lattice_angle_2", "infill_overhang_angle", "top_surface_pattern", "bottom_surface_pattern", "infill_direction", "solid_infill_direction", "counterbore_hole_bridging","infill_shift_step", "sparse_infill_rotate_template", "solid_infill_rotate_template", "symmetric_infill_y_axis","skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d3eb2174e0..42de0f68cc 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5466,6 +5466,30 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->set_default_value(new ConfigOptionFloat(0.6)); + def = this->add("top_surface_density", coPercent); + def->label = L("Top surface density"); + def->category = L("Strength"); + def->tooltip = L("Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. " + "Reducing this value results in a textured top surface, according to the chosen top surface pattern. " + "A value of 0% will result in only the walls on the top layer being created. " + "Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion."); + def->sidetext = ("%"); + def->min = 0; + def->max = 100; + def->set_default_value(new ConfigOptionPercent(100)); + + def = this->add("bottom_surface_density", coPercent); + def->label = L("Bottom surface density"); + def->category = L("Strength"); + def->tooltip = L("Density of the bottom surface layer. " + "Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion.\n" + "WARNING: Lowering this value may negatively affect bed adhesion."); + def->sidetext = ("%"); + def->min = 10; + def->max = 100; + def->set_default_value(new ConfigOptionPercent(100)); + + def = this->add("travel_speed", coFloat); def->label = L("Travel"); def->tooltip = L("Speed of travel which is faster and without extrusion."); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index b4ce02309b..a71adcab88 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -939,6 +939,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, bridge_speed)) ((ConfigOptionFloatOrPercent, internal_bridge_speed)) ((ConfigOptionEnum, ensure_vertical_shell_thickness)) + ((ConfigOptionPercent, top_surface_density)) + ((ConfigOptionPercent, bottom_surface_density)) ((ConfigOptionEnum, top_surface_pattern)) ((ConfigOptionEnum, bottom_surface_pattern)) ((ConfigOptionEnum, internal_solid_infill_pattern)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 8b121f0bd9..8c13c43cc2 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1092,6 +1092,8 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "infill_anchor" || opt_key == "infill_anchor_max" || opt_key == "top_surface_line_width" + || opt_key == "top_surface_density" + || opt_key == "bottom_surface_density" || opt_key == "initial_layer_line_width" || opt_key == "small_area_infill_flow_compensation" || opt_key == "lattice_angle_1" diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index d5d5de76a9..e0be119d7f 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -104,8 +104,8 @@ std::map> SettingsFactory::PART_CAT { { L("Quality"), {{"ironing_type", "",8},{"ironing_flow", "",9},{"ironing_spacing", "",10},{"ironing_inset", "", 11},{"bridge_flow", "",11},{"make_overhang_printable", "",11},{"bridge_density", "", 1} }}, - { L("Strength"), {{"wall_loops", "",1},{"top_shell_layers", L("Top Solid Layers"),1},{"top_shell_thickness", L("Top Minimum Shell Thickness"),1}, - {"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1}, + { L("Strength"), {{"wall_loops", "",1},{"top_shell_layers", L("Top Solid Layers"),1},{"top_shell_thickness", L("Top Minimum Shell Thickness"),1},{"top_surface_density", L("Top Surface Density"),1}, + {"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1},{"bottom_surface_density", L("Bottom Surface Density"),1}, {"sparse_infill_density", "",1},{"sparse_infill_pattern", "",1},{"lattice_angle_1", "",1},{"lattice_angle_2", "",1},{"infill_overhang_angle", "",1},{"infill_anchor", "",1},{"infill_anchor_max", "",1},{"top_surface_pattern", "",1},{"bottom_surface_pattern", "",1}, {"internal_solid_infill_pattern", "",1}, {"infill_combination", "",1}, {"infill_combination_max_layer_height", "",1}, {"infill_wall_overlap", "",1},{"top_bottom_infill_wall_overlap", "",1}, {"solid_infill_direction", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1}, {"internal_bridge_angle", "",1}, {"minimum_sparse_infill_area", "",1} }}, @@ -523,7 +523,7 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty append_menu_item_add_text(sub_menu, type); append_menu_item_add_svg(sub_menu, type); - + return sub_menu; } @@ -619,7 +619,7 @@ static void append_menu_itemm_add_(const wxString& name, GLGizmosManager::EType } else { svg->create_volume(volume_type); } - } + } }; if (type == ModelVolumeType::MODEL_PART || type == ModelVolumeType::NEGATIVE_VOLUME || type == ModelVolumeType::PARAMETER_MODIFIER || @@ -1131,7 +1131,7 @@ void MenuFactory::append_menu_item_edit_text(wxMenu *menu) auto can_edit_text = []() { if (plater() == nullptr) - return false; + return false; const Selection& selection = plater()->get_selection(); if (selection.volumes_count() != 1) return false; @@ -1141,7 +1141,7 @@ void MenuFactory::append_menu_item_edit_text(wxMenu *menu) const ModelVolume *volume = get_model_volume(*gl_volume, selection.get_model()->objects); if (volume == nullptr) return false; - return volume->is_text(); + return volume->is_text(); }; if (menu != &m_text_part_menu) { @@ -1168,7 +1168,7 @@ void MenuFactory::append_menu_item_edit_svg(wxMenu *menu) wxString name = _L("Edit SVG"); auto can_edit_svg = []() { if (plater() == nullptr) - return false; + return false; const Selection& selection = plater()->get_selection(); if (selection.volumes_count() != 1) return false; @@ -1178,7 +1178,7 @@ void MenuFactory::append_menu_item_edit_svg(wxMenu *menu) const ModelVolume *volume = get_model_volume(*gl_volume, selection.get_model()->objects); if (volume == nullptr) return false; - return volume->is_svg(); + return volume->is_svg(); }; if (menu != &m_svg_part_menu) { diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 730a3fda96..e7f4a4fc18 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -811,18 +811,18 @@ void Tab::decorate() } } } - if (!sys_page) { + if (!sys_page) { is_nonsys_value = true; sys_icon = m_bmp_non_system; sys_tt = m_tt_non_system; - if (!modified_page) + if (!modified_page) color = &m_default_text_clr; - else + else color = &m_modified_label_clr; } - if (!modified_page) { + if (!modified_page) { is_modified_value = false; icon = &m_bmp_white_bullet; tt = &m_tt_white_bullet; @@ -1474,7 +1474,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) update_wiping_button_visibility(); - if (opt_key == "pellet_flow_coefficient") + if (opt_key == "pellet_flow_coefficient") { double double_value = Preset::convert_pellet_flow_to_filament_diameter(boost::any_cast(value)); m_config->set_key_value("filament_diameter", new ConfigOptionFloats{double_value}); @@ -1484,7 +1484,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) double double_value = Preset::convert_filament_diameter_to_pellet_flow(boost::any_cast(value)); m_config->set_key_value("pellet_flow_coefficient", new ConfigOptionFloats{double_value}); } - + if (opt_key == "single_extruder_multi_material" ){ const auto bSEMM = m_config->opt_bool("single_extruder_multi_material"); @@ -1632,7 +1632,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } } } - + if(opt_key=="layer_height"){ auto min_layer_height_from_nozzle=wxGetApp().preset_bundle->full_config().option("min_layer_height")->values; auto max_layer_height_from_nozzle=wxGetApp().preset_bundle->full_config().option("max_layer_height")->values; @@ -1700,7 +1700,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (opt_key == "filament_long_retractions_when_cut"){ unsigned char activate = boost::any_cast(value); if (activate == 1) { - MessageDialog dialog(wxGetApp().plater(), + MessageDialog dialog(wxGetApp().plater(), _L("Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. " "Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications. " "Please use with the latest printer firmware."), "", wxICON_WARNING | wxOK); @@ -2197,9 +2197,11 @@ void TabPrint::build() optgroup = page->new_optgroup(L("Top/bottom shells"), L"param_shell"); optgroup->append_single_option_line("top_shell_layers"); optgroup->append_single_option_line("top_shell_thickness"); + optgroup->append_single_option_line("top_surface_density"); optgroup->append_single_option_line("top_surface_pattern"); optgroup->append_single_option_line("bottom_shell_layers"); optgroup->append_single_option_line("bottom_shell_thickness"); + optgroup->append_single_option_line("bottom_surface_density"); optgroup->append_single_option_line("bottom_surface_pattern"); optgroup->append_single_option_line("top_bottom_infill_wall_overlap"); @@ -2335,7 +2337,7 @@ void TabPrint::build() //optgroup = page->new_optgroup(L("Options for support material and raft")); - // Support + // Support optgroup = page->new_optgroup(L("Advanced"), L"param_advanced"); optgroup->append_single_option_line("support_top_z_distance", "support#top-z-distance"); optgroup->append_single_option_line("support_bottom_z_distance", "support#bottom-z-distance"); @@ -2371,7 +2373,7 @@ void TabPrint::build() optgroup->append_single_option_line("tree_support_adaptive_layer_height"); optgroup->append_single_option_line("tree_support_auto_brim"); optgroup->append_single_option_line("tree_support_brim_width"); - + page = add_options_page(L("Multimaterial"), "custom-gcode_multi_material"); // ORCA: icon only visible on placeholders optgroup = page->new_optgroup(L("Prime tower"), L"param_tower"); optgroup->append_single_option_line("enable_prime_tower"); @@ -2470,7 +2472,7 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v option.opt.multiline = true; // option.opt.height = 5; optgroup->append_single_option_line(option); - + optgroup = page->new_optgroup(L("Post-processing Scripts"), L"param_gcode", 0); option = optgroup->get_option("post_process"); option.opt.full_width = true; @@ -2491,7 +2493,7 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v // create_line_with_widget(optgroup.get(), "compatible_printers", "", [this](wxWindow* parent) { // return compatible_widget_create(parent, m_compatible_printers); // }); - + // option = optgroup->get_option("compatible_printers_condition"); // option.opt.full_width = true; // optgroup->append_single_option_line(option); @@ -2900,7 +2902,7 @@ void TabPrintPlate::build() auto page = add_options_page(L("Plate Settings"), "empty"); auto optgroup = page->new_optgroup(""); optgroup->append_single_option_line("curr_bed_type"); - optgroup->append_single_option_line("skirt_start_angle"); + optgroup->append_single_option_line("skirt_start_angle"); optgroup->append_single_option_line("print_sequence"); optgroup->append_single_option_line("spiral_mode"); optgroup->append_single_option_line("first_layer_sequence_choice"); @@ -3051,7 +3053,7 @@ void TabPrintPlate::notify_changed(ObjectBase* object) for (auto item : items) { if (objects_list->GetModel()->GetItemType(item) == itPlate) { ObjectDataViewModelNode* node = static_cast(item.GetID()); - if (node) + if (node) node->set_action_icon(!m_all_keys.empty()); } } @@ -3059,7 +3061,7 @@ void TabPrintPlate::notify_changed(ObjectBase* object) void TabPrintPlate::update_custom_dirty() { - for (auto k : m_null_keys) + for (auto k : m_null_keys) m_options_list[k] = 0; for (auto k : m_all_keys) { if (k == "first_layer_sequence_choice" || k == "other_layers_sequence_choice") { @@ -3301,9 +3303,9 @@ void TabFilament::update_filament_overrides_page(const DynamicPrintConfig* print std::vector opt_keys = { "filament_retraction_length", "filament_z_hop", - "filament_z_hop_types", + "filament_z_hop_types", "filament_retract_lift_above", - "filament_retract_lift_below", + "filament_retract_lift_below", "filament_retract_lift_enforce", "filament_retraction_speed", "filament_deretraction_speed", @@ -3414,7 +3416,7 @@ void TabFilament::build() optgroup->append_single_option_line("adaptive_pressure_advance"); optgroup->append_single_option_line("adaptive_pressure_advance_overhangs"); optgroup->append_single_option_line("adaptive_pressure_advance_bridges"); - + Option option = optgroup->get_option("adaptive_pressure_advance_model"); option.opt.full_width = true; option.opt.is_code = true; @@ -3726,7 +3728,7 @@ void TabFilament::toggle_options() toggle_option(el, has_enable_overhang_bridge_fan); toggle_option("additional_cooling_fan_speed", cfg.opt_bool("auxiliary_fan")); - + // Orca: toggle dont slow down for external perimeters if bool has_slow_down_for_layer_cooling = m_config->opt_bool("slow_down_for_layer_cooling", 0); toggle_option("dont_slow_down_outer_wall", has_slow_down_for_layer_cooling); @@ -3739,7 +3741,7 @@ void TabFilament::toggle_options() //Orca: Enable the plates that should be visible when multi bed support is enabled or a BBL printer is selected; otherwise, enable only the plate visible for the selected bed type. DynamicConfig& proj_cfg = m_preset_bundle->project_config; std::string bed_temp_1st_layer_key = ""; - if (proj_cfg.has("curr_bed_type")) + if (proj_cfg.has("curr_bed_type")) { bed_temp_1st_layer_key = get_bed_temp_1st_layer_key(proj_cfg.opt_enum("curr_bed_type")); } @@ -3752,13 +3754,13 @@ void TabFilament::toggle_options() bed_temp_keys.end() || is_BBL_printer || cfg.opt_bool("support_multi_bed_types"); - for (const auto& key : bed_temp_keys) + for (const auto& key : bed_temp_keys) { toggle_line(key, support_multi_bed_types || bed_temp_1st_layer_key == key); } - - + + // Orca: adaptive pressure advance and calibration model // If PA is not enabled, disable adaptive pressure advance and hide the model section // If adaptive PA is not enabled, hide the adaptive PA model section @@ -3942,7 +3944,7 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("use_firmware_retraction"); // optgroup->append_single_option_line("spaghetti_detector"); optgroup->append_single_option_line("time_cost"); - + optgroup = page->new_optgroup(L("Cooling Fan"), "param_cooling_fan"); Line line = Line{ L("Fan speed-up time"), optgroup->get_option("fan_speedup_time").opt.tooltip }; line.append_option(optgroup->get_option("fan_speedup_time")); @@ -4005,8 +4007,8 @@ void TabPrinter::build_fff() option.opt.is_code = true; option.opt.height = gcode_field_height; // 150; optgroup->append_single_option_line(option); - - + + optgroup = page->new_optgroup(L("Before layer change G-code"),"param_gcode", 0); optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { validate_custom_gcode_cb(this, optgroup_title, opt_key, value); @@ -4028,7 +4030,7 @@ void TabPrinter::build_fff() option.opt.is_code = true; option.opt.height = gcode_field_height;//150; optgroup->append_single_option_line(option); - + optgroup = page->new_optgroup(L("Timelapse G-code"), L"param_gcode", 0); optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { validate_custom_gcode_cb(this, optgroup_title, opt_key, value); @@ -4223,7 +4225,7 @@ PageShp TabPrinter::build_kinematics_page() } auto optgroup = page->new_optgroup(L("Advanced"), "param_advanced"); optgroup->append_single_option_line("emit_machine_limits_to_gcode"); - + // resonance avoidance ported over from qidi slicer optgroup = page->new_optgroup(L("Resonance Avoidance")); optgroup->append_single_option_line("resonance_avoidance"); @@ -4762,7 +4764,7 @@ void TabPrinter::toggle_options() toggle_option("long_retractions_when_cut", !use_firmware_retraction && m_config->opt_int("enable_long_retraction_when_cut"),i); toggle_line("retraction_distances_when_cut#0", m_config->opt_bool("long_retractions_when_cut", i)); //toggle_option("retraction_distances_when_cut", m_config->opt_bool("long_retractions_when_cut",i),i); - + toggle_option("travel_slope", m_config->opt_enum("z_hop_types", i) != ZHopType::zhtNormal, i); } @@ -5174,13 +5176,13 @@ bool Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, try { //BBS delete preset Preset ¤t_preset = m_presets->get_selected_preset(); - + // Obtain compatible filament and process presets for printers if (m_preset_bundle && m_presets->get_preset_base(current_preset) == ¤t_preset && printer_tab && !current_preset.is_system) { delete_third_printer = true; for (const Preset &preset : m_preset_bundle->filaments.get_presets()) { if (preset.is_compatible && !preset.is_default) { - if (preset.inherits() != "") + if (preset.inherits() != "") filament_presets.push_front(preset); else filament_presets.push_back(preset); @@ -5311,7 +5313,7 @@ bool Tab::select_preset(std::string preset_name, bool delete_current /*=false*/, }); } - + } if (technology_changed) @@ -5913,7 +5915,7 @@ void Tab::delete_preset() //wxID_YES != wxMessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal()) wxID_YES == MessageDialog(parent(), msg, title, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION).ShowModal())) return; - + // if we just delete preset from the physical printer if (m_presets_choice->is_selected_physical_printer()) { PhysicalPrinter& printer = physical_printers.get_selected_printer(); @@ -6037,7 +6039,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep deps.checkbox->SetValue(state); deps.btn->Enable(!state); // All printers have been made compatible with this preset. - if (state) + if (state) this->load_key_value(deps.key_list, std::vector {}); this->get_field(deps.key_condition)->toggle(state); this->update_changed_ui(); @@ -6196,7 +6198,7 @@ void TabPrinter::cache_extruder_cnt(const DynamicPrintConfig* config/* = nullptr if (Preset::printer_technology(cached_config) == ptSLA) return; - // get extruders count + // get extruders count auto* nozzle_diameter = dynamic_cast(cached_config.option("nozzle_diameter")); m_cache_extruder_count = nozzle_diameter->values.size(); //m_extruders_count; } From 3696d43590984752ad5c0162bdbf95db701e4cb0 Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Mon, 23 Jun 2025 16:53:35 +0800 Subject: [PATCH 06/13] Fix invalid value for `symmetric_infill_y_axis` (#9983) --- resources/profiles/BBL/process/fdm_process_common.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/profiles/BBL/process/fdm_process_common.json b/resources/profiles/BBL/process/fdm_process_common.json index 8a9c65ad17..f4c9efb184 100644 --- a/resources/profiles/BBL/process/fdm_process_common.json +++ b/resources/profiles/BBL/process/fdm_process_common.json @@ -74,5 +74,5 @@ "scarf_angle_threshold": "155", "infill_shift_step": "0.4", "infill_rotate_step": "0", - "symmetric_infill_y_axis": "false" + "symmetric_infill_y_axis": "0" } \ No newline at end of file From 661d7b88da6c0095e805a0a48ce3876759f147c3 Mon Sep 17 00:00:00 2001 From: yw4z Date: Mon, 23 Jun 2025 12:00:42 +0300 Subject: [PATCH 07/13] Fix notification position on scaling (#9982) Update NotificationManager.cpp --- src/slic3r/GUI/NotificationManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 5814e96075..b66777acb3 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -2537,19 +2537,19 @@ void NotificationManager::render_notifications(GLCanvas3D &canvas, float overlay { sort_notifications(); - float bottom_up_last_y = bottom_margin * m_scale; + float bottom_up_last_y = bottom_margin; // ORCA dont scale margins int i = 0; for (const auto& notification : m_pop_notifications) { if (notification->get_data().level == NotificationLevel::ErrorNotificationLevel || notification->get_data().level == NotificationLevel::SeriousWarningNotificationLevel) { - notification->bbl_render_block_notification(canvas, bottom_up_last_y, m_move_from_overlay && !m_in_preview, overlay_width * m_scale, right_margin * m_scale); + notification->bbl_render_block_notification(canvas, bottom_up_last_y, m_move_from_overlay && !m_in_preview, overlay_width * m_scale, right_margin); // ORCA dont scale margins if (notification->get_state() != PopNotification::EState::Finished) bottom_up_last_y = notification->get_top() + GAP_WIDTH; } else { if (notification->get_state() != PopNotification::EState::Hidden && notification->get_state() != PopNotification::EState::Finished) { i++; - notification->render(canvas, bottom_up_last_y, m_move_from_overlay && !m_in_preview, overlay_width * m_scale, right_margin * m_scale); + notification->render(canvas, bottom_up_last_y, m_move_from_overlay && !m_in_preview, overlay_width * m_scale, right_margin); // ORCA dont scale margins if (notification->get_state() != PopNotification::EState::Finished) bottom_up_last_y = notification->get_top() + GAP_WIDTH; } From 392a3dd7abec5dd6214c0578bb42e797e0e79602 Mon Sep 17 00:00:00 2001 From: Rodrigo <162915171+RF47@users.noreply.github.com> Date: Mon, 23 Jun 2025 09:42:12 -0300 Subject: [PATCH 08/13] Fillgyroid Bug Fix (#9975) Bugfix Fillgyroid --- src/libslic3r/Fill/FillGyroid.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp index 9040f740b2..12c9a8cfec 100644 --- a/src/libslic3r/Fill/FillGyroid.cpp +++ b/src/libslic3r/Fill/FillGyroid.cpp @@ -168,6 +168,10 @@ void FillGyroid::_fill_surface_single( // align bounding box to a multiple of our grid module bb.merge(align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance))); + // Expand the bounding box to avoid artifacts at the edges + coord_t expand = 10 * (scale_(this->spacing)); + bb.offset(expand); + // generate pattern Polylines polylines = make_gyroid_waves( scale_(this->z), From 168dd08042c7fbd99b7956d1ca94becf2f8d49d6 Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Mon, 23 Jun 2025 22:28:55 +0800 Subject: [PATCH 09/13] Fix load step as modifier (#9946) Fix load step as modifier (SoftFever/OrcaSlicer#9940) --- src/slic3r/GUI/GUI_ObjectList.cpp | 45 +++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index ab8b3583f5..2be2190577 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -22,6 +22,7 @@ #include "MsgDialog.hpp" #include "Widgets/ProgressDialog.hpp" #include "SingleChoiceDialog.hpp" +#include "StepMeshDialog.hpp" #include #include @@ -2031,15 +2032,49 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo dlg.Update(static_cast(100.0f * static_cast(i) / static_cast(input_files.size())), _L("Loading file") + ": " + from_path(boost::filesystem::path(input_file).filename())); dlg.Fit(); - + + bool is_user_cancel = false; Model model; try { - model = Model::read_from_file(input_file, nullptr, nullptr, LoadStrategy::LoadModel); + if (boost::iends_with(input_file, ".stp") || + boost::iends_with(input_file, ".step")) { + double linear = string_to_double_decimal_point(wxGetApp().app_config->get("linear_defletion")); + if (linear <= 0) linear = 0.003; + double angle = string_to_double_decimal_point(wxGetApp().app_config->get("angle_defletion")); + if (angle <= 0) angle = 0.5; + bool split_compound = wxGetApp().app_config->get_bool("is_split_compound"); + model = Model::read_from_step( + input_file, LoadStrategy::LoadModel, nullptr, nullptr, + [this, &is_user_cancel, &linear, &angle, &split_compound](Slic3r::Step& file, double& linear_value, + double& angle_value, bool& is_split) -> int { + if (wxGetApp().app_config->get_bool("enable_step_mesh_setting")) { + StepMeshDialog mesh_dlg(nullptr, file, linear, angle); + if (mesh_dlg.ShowModal() == wxID_OK) { + linear_value = mesh_dlg.get_linear_defletion(); + angle_value = mesh_dlg.get_angle_defletion(); + is_split = mesh_dlg.get_split_compound_value(); + return 1; + } + } else { + linear_value = linear; + angle_value = angle; + is_split = split_compound; + return 1; + } + is_user_cancel = true; + return -1; + }, + linear, angle, split_compound); + } else { + model = Model::read_from_file(input_file, nullptr, nullptr, LoadStrategy::LoadModel); + } } catch (std::exception&) { - // auto msg = _L("Error!") + " " + input_file + " : " + e.what() + "."; - auto msg = _L("Error!") + " " + _L("Failed to get the model data in the current file."); - show_error(parent, msg); + if (!is_user_cancel) { + // auto msg = _L("Error!") + " " + input_file + " : " + e.what() + "."; + auto msg = _L("Error!") + " " + _L("Failed to get the model data in the current file."); + show_error(parent, msg); + } return; } From 9be13033a01884636ae1b09d6ec2ecbde9797ec8 Mon Sep 17 00:00:00 2001 From: kris buggenhout <30471699+kbuggenhout@users.noreply.github.com> Date: Tue, 24 Jun 2025 03:03:35 +0200 Subject: [PATCH 10/13] fix for printer time estimate on anker/eufy M5 M5C printers (#9990) Update fdm_marlin_common.json fix for time discrepancy, ;LAYER_COUNT was missing which made it impossible for the anker M5/M5C to have a correct predicted time. --- resources/profiles/Anker/machine/fdm_marlin_common.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/profiles/Anker/machine/fdm_marlin_common.json b/resources/profiles/Anker/machine/fdm_marlin_common.json index 0a4782a64d..da182401ac 100644 --- a/resources/profiles/Anker/machine/fdm_marlin_common.json +++ b/resources/profiles/Anker/machine/fdm_marlin_common.json @@ -6,8 +6,8 @@ "instantiation": "false", "gcode_flavor": "marlin2", "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n", - "machine_start_gcode": "M4899 T3 ; Enable v3 jerk and S-curve acceleration \nM104 S150 ; Set hotend temp to 150 degrees to prevent ooze\nM190 S{first_layer_bed_temperature[0]} ; set and wait for bed temp to stabilize\nM109 S{first_layer_temperature[0]} ; set final nozzle temp to stabilize\nG28 ;Home", + "machine_start_gcode": "M4899 T3 ; Enable v3 jerk and S-curve acceleration \nM104 S150 ; Set hotend temp to 150 degrees to prevent ooze\nM190 S{first_layer_bed_temperature[0]} ; set and wait for bed temp to stabilize\nM109 S{first_layer_temperature[0]} ; set final nozzle temp to stabilize\nG28 ;Home\n;LAYER_COUNT:{total_layer_count}", "machine_end_gcode": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM18", "change_filament_gcode": "M600", "machine_pause_gcode": "M601" -} \ No newline at end of file +} From 9d79eefc2855ec909dac562cad4d1ca5f48c1871 Mon Sep 17 00:00:00 2001 From: Eryoneoffical <120717353+Eryoneoffical@users.noreply.github.com> Date: Tue, 24 Jun 2025 10:26:11 +0800 Subject: [PATCH 11/13] Optimize the default settings for the printer Eryone X400 (#9879) * 1) Optimize some default settings for printer Thinker X400, 2) adding eryone filament * fix the file check error * recover and modify the process files( 0.12 0.16 0.24mm layer profile) --- resources/profiles/Eryone.json | 75 +++++- .../Eryone/filament/Eryone ABS-CF.json | 78 ++++++ .../profiles/Eryone/filament/Eryone ABS.json | 111 ++++++++ .../Eryone/filament/Eryone ASA-CF.json | 78 ++++++ .../profiles/Eryone/filament/Eryone ASA.json | 81 ++++++ .../Eryone/filament/Eryone PA-CF.json | 78 ++++++ .../Eryone/filament/Eryone PA-GF.json | 75 ++++++ .../profiles/Eryone/filament/Eryone PA.json | 84 ++++++ .../Eryone/filament/Eryone PETG-CF.json | 82 ++++++ .../profiles/Eryone/filament/Eryone PETG.json | 61 +++++ .../Eryone/filament/Eryone PLA-CF.json | 58 ++++ .../profiles/Eryone/filament/Eryone PLA.json | 39 +++ .../Eryone/filament/Eryone PP-CF.json | 75 ++++++ .../profiles/Eryone/filament/Eryone PP.json | 79 ++++++ .../Eryone/filament/Eryone Silk PLA.json | 39 +++ .../Eryone/filament/Eryone Standard PLA.json | 250 ++++++++++++++++++ .../profiles/Eryone/filament/Eryone TPU.json | 48 ++++ .../Eryone/filament/fdm_filament_common.json | 132 +++++++++ .../Eryone/filament/fdm_filament_pla.json | 91 +++++++ .../machine/Thinker X400 0.4 nozzle.json | 10 +- .../profiles/Eryone/machine/Thinker X400.json | 2 +- .../0.12mm Standard @Thinker X400.json | 12 +- .../0.16mm Standard @Thinker X400.json | 12 +- .../0.20mm Standard @Thinker X400.json | 20 +- .../0.24mm Standard @Thinker X400.json | 12 +- 25 files changed, 1647 insertions(+), 35 deletions(-) create mode 100644 resources/profiles/Eryone/filament/Eryone ABS-CF.json create mode 100644 resources/profiles/Eryone/filament/Eryone ABS.json create mode 100644 resources/profiles/Eryone/filament/Eryone ASA-CF.json create mode 100644 resources/profiles/Eryone/filament/Eryone ASA.json create mode 100644 resources/profiles/Eryone/filament/Eryone PA-CF.json create mode 100644 resources/profiles/Eryone/filament/Eryone PA-GF.json create mode 100644 resources/profiles/Eryone/filament/Eryone PA.json create mode 100644 resources/profiles/Eryone/filament/Eryone PETG-CF.json create mode 100644 resources/profiles/Eryone/filament/Eryone PETG.json create mode 100644 resources/profiles/Eryone/filament/Eryone PLA-CF.json create mode 100644 resources/profiles/Eryone/filament/Eryone PLA.json create mode 100644 resources/profiles/Eryone/filament/Eryone PP-CF.json create mode 100644 resources/profiles/Eryone/filament/Eryone PP.json create mode 100644 resources/profiles/Eryone/filament/Eryone Silk PLA.json create mode 100644 resources/profiles/Eryone/filament/Eryone Standard PLA.json create mode 100644 resources/profiles/Eryone/filament/Eryone TPU.json create mode 100644 resources/profiles/Eryone/filament/fdm_filament_common.json create mode 100644 resources/profiles/Eryone/filament/fdm_filament_pla.json diff --git a/resources/profiles/Eryone.json b/resources/profiles/Eryone.json index f0c69ddda3..462d7049df 100644 --- a/resources/profiles/Eryone.json +++ b/resources/profiles/Eryone.json @@ -31,7 +31,80 @@ "sub_path": "process/0.24mm Standard @Thinker X400.json" } ], - "filament_list": [], + "filament_list": [ + { + "name": "fdm_filament_common", + "sub_path": "filament/fdm_filament_common.json" + }, + { + "name": "fdm_filament_pla", + "sub_path": "filament/fdm_filament_pla.json" + }, + { + "name": "Eryone Standard PLA", + "sub_path": "filament/Eryone Standard PLA.json" + }, + { + "name": "Eryone PLA", + "sub_path": "filament/Eryone PLA.json" + }, + { + "name": "Eryone PLA-CF", + "sub_path": "filament/Eryone PLA-CF.json" + }, + { + "name": "Eryone PA", + "sub_path": "filament/Eryone PA.json" + }, + { + "name": "Eryone PA-CF", + "sub_path": "filament/Eryone PA-CF.json" + }, + { + "name": "Eryone PA-GF", + "sub_path": "filament/Eryone PA-GF.json" + }, + { + "name": "Eryone PP", + "sub_path": "filament/Eryone PP.json" + }, + { + "name": "Eryone PP-CF", + "sub_path": "filament/Eryone PP-CF.json" + }, + { + "name": "Eryone ABS", + "sub_path": "filament/Eryone ABS.json" + }, + { + "name": "Eryone ABS-CF", + "sub_path": "filament/Eryone ABS-CF.json" + }, + { + "name": "Eryone PETG", + "sub_path": "filament/Eryone PETG.json" + }, + { + "name": "Eryone PETG-CF", + "sub_path": "filament/Eryone PETG-CF.json" + }, + { + "name": "Eryone ASA", + "sub_path": "filament/Eryone ASA.json" + }, + { + "name": "Eryone ASA-CF", + "sub_path": "filament/Eryone ASA-CF.json" + }, + { + "name": "Eryone Silk PLA", + "sub_path": "filament/Eryone Silk PLA.json" + }, + { + "name": "Eryone TPU", + "sub_path": "filament/Eryone TPU.json" + } + ], "machine_list": [ { "name": "fdm_machine_common", diff --git a/resources/profiles/Eryone/filament/Eryone ABS-CF.json b/resources/profiles/Eryone/filament/Eryone ABS-CF.json new file mode 100644 index 0000000000..3532ca4445 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone ABS-CF.json @@ -0,0 +1,78 @@ +{ + "type": "filament", + "filament_id": "EFL81", + "setting_id": "EFSA11", + "name": "Eryone ABS-CF", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.92" + ], + "filament_max_volumetric_speed": [ + "10" + ], + "filament_retraction_length": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "30" + ], + "filament_settings_id": [ + "Eryone ABS-CF" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_type": [ + "ABS-CF" + ], + "filament_vendor": [ + "Eryone" + ], + "hot_plate_temp": [ + "100" + ], + "hot_plate_temp_initial_layer": [ + "100" + ], + "nozzle_temperature": [ + "250" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "nozzle_temperature_range_high": [ + "290" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "slow_down_layer_time": [ + "10" + ], + "overhang_fan_threshold": [ + "25%" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "100" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone ABS.json b/resources/profiles/Eryone/filament/Eryone ABS.json new file mode 100644 index 0000000000..b9126190a8 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone ABS.json @@ -0,0 +1,111 @@ +{ + "type": "filament", + "filament_id": "EFL91", + "setting_id": "EFSA01", + "name": "Eryone ABS", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "additional_cooling_fan_speed": [ + "0" + ], + "complete_print_exhaust_fan_speed": [ + "70" + ], + "cool_plate_temp": [ + "0" + ], + "cool_plate_temp_initial_layer": [ + "0" + ], + "during_print_exhaust_fan_speed": [ + "70" + ], + "eng_plate_temp": [ + "100" + ], + "eng_plate_temp_initial_layer": [ + "105" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "70" + ], + "fan_min_speed": [ + "10" + ], + "filament_settings_id": [ + "Eryone ABS" + ], + "filament_density": [ + "1.04" + ], + "filament_end_gcode": [ + "; filament end gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0\n" + ], + "filament_type": [ + "ABS" + ], + "filament_flow_ratio": [ + "0.92" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_vendor": [ + "Eryone" + ], + "hot_plate_temp": [ + "95" + ], + "hot_plate_temp_initial_layer": [ + "95" + ], + "nozzle_temperature": [ + "255" + ], + "nozzle_temperature_initial_layer": [ + "260" + ], + "nozzle_temperature_range_high": [ + "290" + ], + "overhang_fan_speed": [ + "80" + ], + "overhang_fan_threshold": [ + "25%" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "required_nozzle_HRC": [ + "3" + ], + "slow_down_layer_time": [ + "4" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "100" + ], + "textured_plate_temp": [ + "100" + ], + "textured_plate_temp_initial_layer": [ + "105" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone ASA-CF.json b/resources/profiles/Eryone/filament/Eryone ASA-CF.json new file mode 100644 index 0000000000..b00d225183 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone ASA-CF.json @@ -0,0 +1,78 @@ +{ + "type": "filament", + "filament_id": "EFL82", + "setting_id": "EFSA82", + "name": "Eryone ASA-CF", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "20" + ], + "filament_settings_id": [ + "Eryone ASA-CF" + ], + "filament_type": [ + "ASA-CF" + ], + "filament_vendor": [ + "Eryone" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.92" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "filament_retraction_length": [ + "1" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "hot_plate_temp": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "nozzle_temperature": [ + "260" + ], + "nozzle_temperature_initial_layer": [ + "275" + ], + "nozzle_temperature_range_high": [ + "290" + ], + "overhang_fan_threshold": [ + "25%" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "180" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "slow_down_layer_time": [ + "12" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone ASA.json b/resources/profiles/Eryone/filament/Eryone ASA.json new file mode 100644 index 0000000000..af819db70e --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone ASA.json @@ -0,0 +1,81 @@ +{ + "type": "filament", + "filament_id": "EFL92", + "setting_id": "EFSA02", + "name": "Eryone ASA", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "20" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.92" + ], + "filament_max_volumetric_speed": [ + "14" + ], + "filament_retraction_length": [ + "1" + ], + "filament_settings_id": [ + "Eryone ASA" + ], + "filament_type": [ + "ASA" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_vendor": [ + "Eryone" + ], + "hot_plate_temp": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "nozzle_temperature": [ + "265" + ], + "nozzle_temperature_initial_layer": [ + "270" + ], + "nozzle_temperature_range_high": [ + "290" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "slow_down_layer_time": [ + "12" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_min_speed": [ + "20" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "180" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PA-CF.json b/resources/profiles/Eryone/filament/Eryone PA-CF.json new file mode 100644 index 0000000000..ecf2aaeaf3 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PA-CF.json @@ -0,0 +1,78 @@ +{ + "type": "filament", + "filament_id": "EFL72", + "setting_id": "EFSA72", + "name": "Eryone PA-CF", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "20" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "filament_retraction_length": [ + "1" + ], + "filament_settings_id": [ + "Eryone PA-CF" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_type": [ + "PA-CF" + ], + "filament_vendor": [ + "Eryone" + ], + "hot_plate_temp": [ + "115" + ], + "hot_plate_temp_initial_layer": [ + "115" + ], + "nozzle_temperature": [ + "265" + ], + "nozzle_temperature_initial_layer": [ + "275" + ], + "overhang_fan_threshold": [ + "25%" + ], + "nozzle_temperature_range_high": [ + "280" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "200" + ], + "slow_down_layer_time": [ + "10" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PA-GF.json b/resources/profiles/Eryone/filament/Eryone PA-GF.json new file mode 100644 index 0000000000..00b348fef1 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PA-GF.json @@ -0,0 +1,75 @@ +{ + "type": "filament", + "filament_id": "EFL73", + "setting_id": "EFSA73", + "name": "Eryone PA-GF", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "20" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_retraction_length": [ + "1" + ], + "filament_settings_id": [ + "Eryone PA-GF" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_type": [ + "PA-GF" + ], + "filament_vendor": [ + "Eryone" + ], + "hot_plate_temp": [ + "110" + ], + "hot_plate_temp_initial_layer": [ + "110" + ], + "nozzle_temperature": [ + "270" + ], + "nozzle_temperature_initial_layer": [ + "280" + ], + "nozzle_temperature_range_high": [ + "280" + ], + "nozzle_temperature_range_low": [ + "240" + ], + "overhang_fan_threshold": [ + "25%" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "200" + ], + "slow_down_layer_time": [ + "10" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PA.json b/resources/profiles/Eryone/filament/Eryone PA.json new file mode 100644 index 0000000000..0e21bda8b4 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PA.json @@ -0,0 +1,84 @@ +{ + "type": "filament", + "filament_id": "EFL71", + "setting_id": "EFSA71", + "name": "Eryone PA", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "20" + ], + "fan_min_speed": [ + "10" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.92" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "filament_notes": [ + "brim width >= 20;" + ], + "filament_retraction_length": [ + "1" + ], + "filament_settings_id": [ + "Eryone PA" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_type": [ + "PA" + ], + "filament_vendor": [ + "Eryone" + ], + "hot_plate_temp": [ + "115" + ], + "hot_plate_temp_initial_layer": [ + "115" + ], + "nozzle_temperature": [ + "265" + ], + "nozzle_temperature_initial_layer": [ + "270" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "10" + ], + "slow_down_min_speed": [ + "15" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "200" + ], + "nozzle_temperature_range_high": [ + "280" + ], + "nozzle_temperature_range_low": [ + "240" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PETG-CF.json b/resources/profiles/Eryone/filament/Eryone PETG-CF.json new file mode 100644 index 0000000000..44905acb0f --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PETG-CF.json @@ -0,0 +1,82 @@ +{ + "type": "filament", + "filament_id": "EFL43", + "setting_id": "EFSA43", + "name": "Eryone PETG-CF", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "90" + ], + "fan_min_speed": [ + "50" + ], + "filament_vendor": [ + "Eryone" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0\n" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_retraction_length": [ + "1" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1" + ], + "filament_max_volumetric_speed": [ + "14" + ], + "filament_settings_id": [ + "Eryone PETG" + ], + "filament_type": [ + "PETG-CF" + ], + + "hot_plate_temp": [ + "80" + ], + "hot_plate_temp_initial_layer": [ + "80" + ], + "overhang_fan_threshold": [ + "25%" + ], + "nozzle_temperature": [ + "245" + ], + "nozzle_temperature_initial_layer": [ + "250" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "225" + ], + "slow_down_min_speed": [ + "20" + ], + "support_material_interface_fan_speed": [ + "80" + ], + "temperature_vitrification": [ + "80" + ], + "slow_down_layer_time": [ + "7" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PETG.json b/resources/profiles/Eryone/filament/Eryone PETG.json new file mode 100644 index 0000000000..611346990b --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PETG.json @@ -0,0 +1,61 @@ +{ + "type": "filament", + "filament_id": "EFL93", + "setting_id": "EFSA03", + "name": "Eryone PETG", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "fan_min_speed": [ + "90" + ], + "close_fan_the_first_x_layers": [ + "2" + ], + "filament_vendor": [ + "Eryone" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0\n" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1" + ], + "filament_max_volumetric_speed": [ + "14" + ], + "filament_settings_id": [ + "Eryone PETG" + ], + "filament_type": [ + "PETG" + ], + + "hot_plate_temp": [ + "75" + ], + "hot_plate_temp_initial_layer": [ + "75" + ], + "overhang_fan_threshold": [ + "25%" + ], + "nozzle_temperature": [ + "245" + ], + "nozzle_temperature_initial_layer": [ + "245" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "225" + ], + "slow_down_layer_time": [ + "7" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PLA-CF.json b/resources/profiles/Eryone/filament/Eryone PLA-CF.json new file mode 100644 index 0000000000..0fc8c01fbc --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PLA-CF.json @@ -0,0 +1,58 @@ +{ + "type": "filament", + "filament_id": "EFL40", + "setting_id": "EFSA40", + "name": "Eryone PLA-CF", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "fan_min_speed": [ + "100" + ], + + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_retraction_length": [ + "1" + ], + "filament_settings_id": [ + "Eryone PLA-CF" + ], + "filament_type": [ + "PLA-CF" + ], + "hot_plate_temp": [ + "55" + ], + "hot_plate_temp_initial_layer": [ + "55" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "nozzle_temperature": [ + "225" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "slow_down_layer_time": [ + "7" + ], + "support_material_interface_fan_speed": [ + "100" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PLA.json b/resources/profiles/Eryone/filament/Eryone PLA.json new file mode 100644 index 0000000000..5f18fe72fb --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PLA.json @@ -0,0 +1,39 @@ +{ + "type": "filament", + "filament_id": "EFL90", + "setting_id": "EFSA00", + "name": "Eryone PLA", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "fan_min_speed": [ + "90" + ], + "filament_max_volumetric_speed": [ + "20" + ], + "filament_settings_id": [ + "Eryone PLA" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "slow_down_layer_time": [ + "4" + ], + "slow_down_min_speed": [ + "15" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PP-CF.json b/resources/profiles/Eryone/filament/Eryone PP-CF.json new file mode 100644 index 0000000000..5a137f5b6f --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PP-CF.json @@ -0,0 +1,75 @@ +{ + "type": "filament", + "filament_id": "EFL33", + "setting_id": "EFSA33", + "name": "Eryone PP-CF", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "fan_max_speed": [ + "35" + ], + "fan_min_speed": [ + "20" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.92" + ], + "fan_cooling_layer_time": [ + "30" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "filament_notes": [ + "Printing platform glue spraying" + ], + "filament_retraction_length": [ + "1" + ], + "filament_vendor": [ + "Eryone" + ], + "filament_settings_id": [ + "Eryone PP-CF" + ], + "filament_type": [ + "PP-CF" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "hot_plate_temp": [ + "100" + ], + "hot_plate_temp_initial_layer": [ + "100" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "10" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "160" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone PP.json b/resources/profiles/Eryone/filament/Eryone PP.json new file mode 100644 index 0000000000..dec30ad007 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone PP.json @@ -0,0 +1,79 @@ +{ + "type": "filament", + "filament_id": "EFL43", + "setting_id": "EFSA43", + "name": "Eryone PP", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "35" + ], + "fan_min_speed": [ + "20" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "10" + ], + "filament_notes": [ + "Printing platform glue spraying" + ], + + "filament_vendor": [ + "Eryone" + ], + "filament_settings_id": [ + "Eryone PP" + ], + "filament_type": [ + "PP" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "hot_plate_temp": [ + "100" + ], + "hot_plate_temp_initial_layer": [ + "100" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "235" + ], + "overhang_fan_threshold": [ + "25%" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "nozzle_temperature_range_low": [ + "225" + ], + "slow_down_layer_time": [ + "10" + ], + "support_material_interface_fan_speed": [ + "60" + ], + "temperature_vitrification": [ + "160" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone Silk PLA.json b/resources/profiles/Eryone/filament/Eryone Silk PLA.json new file mode 100644 index 0000000000..6803c1dbff --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone Silk PLA.json @@ -0,0 +1,39 @@ +{ + "type": "filament", + "filament_id": "EFL941", + "setting_id": "EFSA041", + "name": "Eryone Silk PLA", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0\n" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_type": [ + "Silk" + ], + "filament_settings_id": [ + "Eryone Silk PLA" + ], + "hot_plate_temp": [ + "60" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "slow_down_layer_time": [ + "7" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone Standard PLA.json b/resources/profiles/Eryone/filament/Eryone Standard PLA.json new file mode 100644 index 0000000000..66299ef95a --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone Standard PLA.json @@ -0,0 +1,250 @@ +{ + "type": "filament", + + "name": "Eryone Standard PLA", + "from": "system", + "instantiation": "false", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "activate_air_filtration": [ + "0" + ], + "activate_chamber_temp_control": [ + "0" + ], + "additional_cooling_fan_speed": [ + "70" + ], + "chamber_temperature": [ + "0" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "compatible_printers_condition": "", + "compatible_prints": [], + "compatible_prints_condition": "", + "complete_print_exhaust_fan_speed": [ + "80" + ], + "cool_plate_temp": [ + "60" + ], + "cool_plate_temp_initial_layer": [ + "60" + ], + "default_filament_colour": [ + "" + ], + "during_print_exhaust_fan_speed": [ + "60" + ], + "enable_overhang_bridge_fan": [ + "1" + ], + "enable_pressure_advance": [ + "0" + ], + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "fan_cooling_layer_time": [ + "100" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "100" + ], + "filament_cooling_final_speed": [ + "3.4" + ], + "filament_cooling_initial_speed": [ + "2.2" + ], + "filament_cooling_moves": [ + "4" + ], + "filament_cost": [ + "20" + ], + "filament_density": [ + "1.24" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_diameter": [ + "1.75" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_is_support": [ + "0" + ], + "filament_load_time": [ + "0" + ], + "filament_loading_speed": [ + "28" + ], + "filament_loading_speed_start": [ + "3" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15" + ], + "filament_multitool_ramming": [ + "0" + ], + "filament_multitool_ramming_flow": [ + "10" + ], + "filament_multitool_ramming_volume": [ + "10" + ], + "filament_notes": [ + "" + ], + "filament_ramming_parameters": [ + "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_lift_above": [ + "nil" + ], + "filament_retract_lift_below": [ + "nil" + ], + "filament_retract_lift_enforce": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_settings_id": [ + "Eryone Standard PLA" + ], + "filament_shrink": [ + "100%" + ], + "filament_soluble": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode" + ], + "filament_toolchange_delay": [ + "0" + ], + "filament_type": [ + "PLA" + ], + "filament_unload_time": [ + "0" + ], + "filament_unloading_speed": [ + "90" + ], + "filament_unloading_speed_start": [ + "100" + ], + "filament_vendor": [ + "Eryone" + ], + "filament_wipe": [ + "nil" + ], + "filament_wipe_distance": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_z_hop_types": [ + "nil" + ], + "full_fan_speed_layer": [ + "0" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "nozzle_temperature_range_high": [ + "260" + ], + "nozzle_temperature_range_low": [ + "180" + ], + "overhang_fan_speed": [ + "100" + ], + "overhang_fan_threshold": [ + "50%" + ], + "pressure_advance": [ + "0.02" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "required_nozzle_HRC": [ + "0" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "slow_down_layer_time": [ + "5" + ], + "slow_down_min_speed": [ + "10" + ], + "support_material_interface_fan_speed": [ + "-1" + ], + "temperature_vitrification": [ + "60" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ] +} diff --git a/resources/profiles/Eryone/filament/Eryone TPU.json b/resources/profiles/Eryone/filament/Eryone TPU.json new file mode 100644 index 0000000000..fa79600381 --- /dev/null +++ b/resources/profiles/Eryone/filament/Eryone TPU.json @@ -0,0 +1,48 @@ +{ + "type": "filament", + "filament_id": "EFL95", + "setting_id": "EFSA05", + "name": "Eryone TPU", + "from": "system", + "instantiation": "true", + "inherits": "Eryone Standard PLA", + "compatible_printers": [ + "Thinker X400 0.4 nozzle" + ], + "filament_end_gcode": [ + "; filament end gcode \nSET_FAN_SPEED FAN=filter_fan SPEED=0" + ], + "filament_start_gcode": [ + "; filament start gcode\nSET_FAN_SPEED FAN=filter_fan SPEED=1" + ], + "fan_min_speed": [ + "90" + ], + "filament_max_volumetric_speed": [ + "5" + ], + "filament_retraction_length": [ + "1.6" + ], + "filament_settings_id": [ + "Eryone TPU" + ], + "filament_type": [ + "TPU" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "hot_plate_temp": [ + "50" + ], + "hot_plate_temp_initial_layer": [ + "50" + ], + "slow_down_layer_time": [ + "8" + ] +} diff --git a/resources/profiles/Eryone/filament/fdm_filament_common.json b/resources/profiles/Eryone/filament/fdm_filament_common.json new file mode 100644 index 0000000000..4851217fe1 --- /dev/null +++ b/resources/profiles/Eryone/filament/fdm_filament_common.json @@ -0,0 +1,132 @@ +{ + "type": "filament", + "name": "fdm_filament_common", + "from": "system", + "instantiation": "false", + "cool_plate_temp": [ + "60" + ], + "eng_plate_temp": [ + "60" + ], + "hot_plate_temp": [ + "60" + ], + "cool_plate_temp_initial_layer": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "overhang_fan_threshold": [ + "95%" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "close_fan_the_first_x_layers": [ + "3" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ], + "filament_flow_ratio": [ + "1" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "fan_cooling_layer_time": [ + "60" + ], + "filament_cost": [ + "0" + ], + "filament_density": [ + "0" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_diameter": [ + "1.75" + ], + "filament_max_volumetric_speed": [ + "0" + ], + "filament_minimal_purge_on_wipe_tower": [ + "15" + ], + "filament_retraction_minimum_travel": [ + "nil" + ], + "filament_retract_before_wipe": [ + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil" + ], + "filament_retraction_length": [ + "nil" + ], + "filament_z_hop": [ + "nil" + ], + "filament_retract_restart_extra": [ + "nil" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_settings_id": [ + "" + ], + "filament_soluble": [ + "0" + ], + "filament_type": [ + "PLA" + ], + "filament_vendor": [ + "Generic" + ], + "filament_wipe": [ + "nil" + ], + "filament_wipe_distance": [ + "nil" + ], + "nozzle_temperature_initial_layer": [ + "200" + ], + "full_fan_speed_layer": [ + "0" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "35" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "5" + ], + "filament_start_gcode": [ + "; Filament gcode\n" + ], + "nozzle_temperature": [ + "200" + ], + "temperature_vitrification": [ + "100" + ] +} diff --git a/resources/profiles/Eryone/filament/fdm_filament_pla.json b/resources/profiles/Eryone/filament/fdm_filament_pla.json new file mode 100644 index 0000000000..324fe07e49 --- /dev/null +++ b/resources/profiles/Eryone/filament/fdm_filament_pla.json @@ -0,0 +1,91 @@ +{ + "type": "filament", + "name": "fdm_filament_pla", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_common", + "fan_cooling_layer_time": [ + "100" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "filament_type": [ + "PLA" + ], + "filament_density": [ + "1.24" + ], + "filament_cost": [ + "20" + ], + "cool_plate_temp": [ + "35" + ], + "eng_plate_temp": [ + "0" + ], + "hot_plate_temp": [ + "60" + ], + "cool_plate_temp_initial_layer": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "0" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_for_layer_cooling": [ + "0" + ], + "fan_max_speed": [ + "100" + ], + "fan_min_speed": [ + "100" + ], + "overhang_fan_speed": [ + "100" + ], + "overhang_fan_threshold": [ + "50%" + ], + "close_fan_the_first_x_layers": [ + "1" + ], + "nozzle_temperature": [ + "220" + ], + "temperature_vitrification": [ + "60" + ], + "nozzle_temperature_range_low": [ + "190" + ], + "nozzle_temperature_range_high": [ + "230" + ], + "slow_down_min_speed": [ + "10" + ], + "slow_down_layer_time": [ + "4" + ], + "additional_cooling_fan_speed": [ + "70" + ], + "enable_overhang_bridge_fan": [ + "0" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ] +} diff --git a/resources/profiles/Eryone/machine/Thinker X400 0.4 nozzle.json b/resources/profiles/Eryone/machine/Thinker X400 0.4 nozzle.json index d5ea9d7bde..7f2b2e5a29 100644 --- a/resources/profiles/Eryone/machine/Thinker X400 0.4 nozzle.json +++ b/resources/profiles/Eryone/machine/Thinker X400 0.4 nozzle.json @@ -6,7 +6,7 @@ "instantiation": "true", "printer_model": "Thinker X400", "default_print_profile": "0.20mm Standard @Thinker X400", - "default_filament_profile":"Generic PLA @System;Generic ABS @System;Generic ASA @System;Generic PETG @System;Generic PLA Silk @System;Generic TPU @System", + "default_filament_profile":"Eryone PLA;Eryone ABS;Eryone ASA;Eryone PETG;Eryone Silk PLA;Eryone TPU;Eryone ABS-CF;Eryone ASA-CF;Eryone PA;Eryone PA-CF;Eryone PA-GF;Eryone PETG-CF;Eryone PLA-CF;Eryone PP;Eryone PP-CF;", "auxiliary_fan": "0", "bed_custom_model": "", "bed_custom_texture": "", @@ -42,11 +42,11 @@ "machine_end_gcode": "PRINT_END", "machine_load_filament_time": "0", "machine_max_acceleration_e": [ - "10000", + "5000", "5000" ], "machine_max_acceleration_extruding": [ - "5000", + "10000", "20000" ], "machine_max_acceleration_retracting": [ @@ -110,7 +110,7 @@ "0" ], "machine_pause_gcode": "PAUSE", - "machine_start_gcode": "M117 Heating\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nPRINT_START \nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\n\nM104 S0\nM140 S[bed_temperature_initial_layer_single] ; set bed temp\nM117 Heating\nM190 S[bed_temperature_initial_layer_single]\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\n\n;QUAD_GANTRY_LEVEL\nCLEAN_N S=[first_layer_temperature] X=240 Y=-3 A=0\nM117 Quad Level\n_QUAD_GANTRY_LEVEL horizontal_move_z=10 retry_tolerance=1 LIFT_SPEED=5\nG28 Z\nM117 Quad Level\n_QUAD_GANTRY_LEVEL horizontal_move_z=5 retry_tolerance=0.05 LIFT_SPEED=5\nHOME_Z X=132.5 Y=197.5\nM117 Bed Mesh Level\nBED_MESH_CALIBRATE\nM117 Heating\nG1 Y0.0 Z0.3 F1500 ; move print head up\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nM117 .\nG92 E0.0\n; intro line\nG1 X175.0 E12 F1000\nG1 Y0.6\nG1 X5.0 E10 F1000\nG92 E0.0\n; intro line\nG1 Y1.0 Z0.2 F1000\nG1 X200.0 E15.0 F1000\nG92 E0.0", + "machine_start_gcode": "M117 Heating\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nPRINT_START \nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting]\nM104 S0\nM140 S[bed_temperature_initial_layer_single] ; set bed temp\nM117 Heating\nM190 S[bed_temperature_initial_layer_single]\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\n;QUAD_GANTRY_LEVEL\nCLEAN_N S=[first_layer_temperature] X=240 Y=-3 A=0 D=0.4\nM117 Quad Level\n_QUAD_GANTRY_LEVEL horizontal_move_z=10 retry_tolerance=1 LIFT_SPEED=5\nG28 Z\nM117 Quad Level\n_QUAD_GANTRY_LEVEL horizontal_move_z=5 retry_tolerance=0.05 LIFT_SPEED=5\nM117 Bed Mesh Level\nG1 X132.5 Y197.5\nG28 N\nBED_MESH_CALIBRATE\nM117 Heating\nG1 X275.0 Y0.0 Z0.3 F1500 ; move print head up\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nM117 .\nINTRO_LINE D=0.4 ;intro line with 0.4 mm nozzle", "machine_unload_filament_time": "0", "manual_filament_change": "0", "max_layer_height": [ @@ -126,7 +126,7 @@ "nozzle_type": "hardened_steel", "nozzle_volume": "0", "parking_pos_retraction": "92", - "print_host": "192.168.2.8", + "print_host": "192.168.2.2", "print_host_webui": "", "printable_area": [ "0x0", diff --git a/resources/profiles/Eryone/machine/Thinker X400.json b/resources/profiles/Eryone/machine/Thinker X400.json index 007bba55d6..c05855878c 100644 --- a/resources/profiles/Eryone/machine/Thinker X400.json +++ b/resources/profiles/Eryone/machine/Thinker X400.json @@ -8,5 +8,5 @@ "bed_model": "X400_bed.stl", "bed_texture": "Thinker_texture.png", "hotend_model": "", - "default_materials": "Generic PLA @System;Generic ABS @System;Generic ASA @System;Generic PETG @System;Generic PLA Silk @System;Generic TPU @System" + "default_materials": "Eryone PLA;Eryone ABS;Eryone ASA;Eryone PETG;Eryone Silk PLA;Eryone TPU;Eryone ABS-CF;Eryone ASA-CF;Eryone PA;Eryone PA-CF;Eryone PA-GF;Eryone PETG-CF;Eryone PLA-CF;Eryone PP;Eryone PP-CF" } diff --git a/resources/profiles/Eryone/process/0.12mm Standard @Thinker X400.json b/resources/profiles/Eryone/process/0.12mm Standard @Thinker X400.json index 3171630d71..84f349de3c 100644 --- a/resources/profiles/Eryone/process/0.12mm Standard @Thinker X400.json +++ b/resources/profiles/Eryone/process/0.12mm Standard @Thinker X400.json @@ -1,13 +1,13 @@ { "brim_object_gap": "0", - "default_acceleration": "8000", + "default_acceleration": "10000", "elefant_foot_compensation": "0.12", "from": "User", - "gap_infill_speed": "300", + "gap_infill_speed": "250", "inherits": "0.20mm Standard @Thinker X400", "inner_wall_acceleration": "8000", - "inner_wall_speed": "300", - "internal_solid_infill_speed": "300", + "inner_wall_speed": "250", + "internal_solid_infill_speed": "250", "is_custom_defined": "0", "layer_height": "0.12", "name": "0.12mm Standard @Thinker X400", @@ -20,9 +20,9 @@ "print_settings_id": "0.12mm Standard @Thinker X400", "raft_first_layer_expansion": "10", "sparse_infill_density": "15%", - "sparse_infill_speed": "300", + "sparse_infill_speed": "250", "top_shell_layers": "5", "top_shell_thickness": "1", - "version": "1.9.0.2", + "version": "2.3.0.3", "wall_generator": "classic" } \ No newline at end of file diff --git a/resources/profiles/Eryone/process/0.16mm Standard @Thinker X400.json b/resources/profiles/Eryone/process/0.16mm Standard @Thinker X400.json index c19eb5d3a4..b86236dec8 100644 --- a/resources/profiles/Eryone/process/0.16mm Standard @Thinker X400.json +++ b/resources/profiles/Eryone/process/0.16mm Standard @Thinker X400.json @@ -1,13 +1,13 @@ { "brim_object_gap": "0", - "default_acceleration": "8000", + "default_acceleration": "10000", "elefant_foot_compensation": "0.12", "from": "User", - "gap_infill_speed": "300", + "gap_infill_speed": "250", "inherits": "0.20mm Standard @Thinker X400", "inner_wall_acceleration": "8000", - "inner_wall_speed": "300", - "internal_solid_infill_speed": "300", + "inner_wall_speed": "250", + "internal_solid_infill_speed": "250", "is_custom_defined": "0", "layer_height": "0.16", "name": "0.16mm Standard @Thinker X400", @@ -20,9 +20,9 @@ "print_settings_id": "0.16mm Standard @Thinker X400", "raft_first_layer_expansion": "10", "sparse_infill_density": "15%", - "sparse_infill_speed": "300", + "sparse_infill_speed": "250", "top_shell_layers": "5", "top_shell_thickness": "1", - "version": "1.9.0.2", + "version": "2.3.0.3", "wall_generator": "classic" } \ No newline at end of file diff --git a/resources/profiles/Eryone/process/0.20mm Standard @Thinker X400.json b/resources/profiles/Eryone/process/0.20mm Standard @Thinker X400.json index 701ac3b4ce..832f669b09 100644 --- a/resources/profiles/Eryone/process/0.20mm Standard @Thinker X400.json +++ b/resources/profiles/Eryone/process/0.20mm Standard @Thinker X400.json @@ -19,14 +19,14 @@ "bridge_density": "100%", "bridge_flow": "0.95", "bridge_no_support": "0", - "bridge_speed": "50", + "bridge_speed": "45", "brim_ears_detection_length": "1", "brim_ears_max_angle": "125", - "brim_object_gap": "0", + "brim_object_gap": "0.1", "brim_type": "auto_brim", "brim_width": "5", "compatible_printers_condition": "", - "default_acceleration": "8000", + "default_acceleration": "10000", "default_jerk": "0", "detect_overhang_wall": "1", "detect_thin_wall": "0", @@ -38,7 +38,7 @@ "enable_prime_tower": "0", "enable_support": "0", "enforce_support_layers": "0", - "exclude_object": "1", + "exclude_object": "0", "extra_perimeters_on_overhangs": "0", "filename_format": "{input_filename_base}_{filament_type[0]}_{print_time}.gcode", "filter_out_gap_fill": "0", @@ -104,12 +104,12 @@ "only_one_wall_first_layer": "0", "only_one_wall_top": "1", "ooze_prevention": "0", - "outer_wall_acceleration": "5000", + "outer_wall_acceleration": "4000", "outer_wall_jerk": "9", "outer_wall_line_width": "0.42", "outer_wall_speed": "200", "overhang_1_4_speed": "0", - "overhang_2_4_speed": "50", + "overhang_2_4_speed": "45", "overhang_3_4_speed": "30", "overhang_4_4_speed": "10", "overhang_reverse": "0", @@ -149,7 +149,7 @@ "sparse_infill_acceleration": "100%", "sparse_infill_density": "15%", "sparse_infill_filament": "1", - "sparse_infill_line_width": "0.45", + "sparse_infill_line_width": "0.54", "sparse_infill_pattern": "crosshatch", "sparse_infill_speed": "250", "spiral_mode": "0", @@ -189,9 +189,9 @@ "top_surface_line_width": "0.42", "top_surface_pattern": "monotonic", "top_surface_speed": "200", - "travel_acceleration": "5000", + "travel_acceleration": "10000", "travel_jerk": "12", - "travel_speed": "350", + "travel_speed": "400", "travel_speed_z": "0", "tree_support_adaptive_layer_height": "1", "tree_support_angle_slow": "25", @@ -208,7 +208,7 @@ "tree_support_tip_diameter": "0.8", "tree_support_top_rate": "30%", "tree_support_wall_count": "2", - "version": "1.9.0.2", + "version": "2.3.0.3", "wall_distribution_count": "1", "wall_filament": "1", "wall_generator": "classic", diff --git a/resources/profiles/Eryone/process/0.24mm Standard @Thinker X400.json b/resources/profiles/Eryone/process/0.24mm Standard @Thinker X400.json index 37169e4326..5e3d8187bb 100644 --- a/resources/profiles/Eryone/process/0.24mm Standard @Thinker X400.json +++ b/resources/profiles/Eryone/process/0.24mm Standard @Thinker X400.json @@ -1,13 +1,13 @@ { "brim_object_gap": "0", - "default_acceleration": "8000", + "default_acceleration": "10000", "elefant_foot_compensation": "0.12", "from": "User", - "gap_infill_speed": "220", + "gap_infill_speed": "250", "inherits": "0.20mm Standard @Thinker X400", "inner_wall_acceleration": "8000", - "inner_wall_speed": "220", - "internal_solid_infill_speed": "220", + "inner_wall_speed": "250", + "internal_solid_infill_speed": "250", "is_custom_defined": "0", "layer_height": "0.24", "name": "0.24mm Standard @Thinker X400", @@ -17,9 +17,9 @@ "print_settings_id": "0.24mm Standard @Thinker X400", "raft_first_layer_expansion": "10", "sparse_infill_density": "15%", - "sparse_infill_speed": "220", + "sparse_infill_speed": "250", "top_shell_layers": "5", "top_shell_thickness": "1", - "version": "1.9.0.2", + "version": "2.3.0.3", "wall_generator": "classic" } \ No newline at end of file From bec5d9ea576b4c6ca242f684a687da9ecd1aba5c Mon Sep 17 00:00:00 2001 From: yw4z Date: Tue, 24 Jun 2025 17:29:30 +0300 Subject: [PATCH 12/13] Fixes for LabeledStaticBox & Height Range UI (#9991) init --- src/slic3r/GUI/GUI_ObjectLayers.cpp | 32 ++++++++++++++------- src/slic3r/GUI/Widgets/LabeledStaticBox.cpp | 21 +++++++------- src/slic3r/GUI/Widgets/LabeledStaticBox.hpp | 3 ++ 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectLayers.cpp b/src/slic3r/GUI/GUI_ObjectLayers.cpp index a0e19983ce..e5c6928fbc 100644 --- a/src/slic3r/GUI/GUI_ObjectLayers.cpp +++ b/src/slic3r/GUI/GUI_ObjectLayers.cpp @@ -8,6 +8,8 @@ #include "GLCanvas3D.hpp" #include "Plater.hpp" +#include "Widgets/LabeledStaticBox.hpp" + #include #include "I18N.hpp" @@ -29,7 +31,9 @@ ObjectLayers::ObjectLayers(wxWindow* parent) : m_og->activate(); m_og->sizer->Clear(true); - m_og->sizer->Add(m_grid_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, wxOSX ? 0 : 5); + m_og->sizer->Add(m_grid_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 5); + if (auto stb = dynamic_cast(m_og->stb)) + stb->SetCornerRadius(0); m_bmp_delete = ScalableBitmap(parent, "delete"); m_bmp_add = ScalableBitmap(parent, "add"); @@ -74,7 +78,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus }; // Add text - auto head_text = new wxStaticText(m_parent, wxID_ANY, _L("Height Range"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + auto head_text = new wxStaticText(m_og->ctrl_parent(), wxID_ANY, _L("Height Range"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); head_text->SetBackgroundStyle(wxBG_STYLE_PAINT); head_text->SetFont(wxGetApp().normal_font()); m_grid_sizer->Add(head_text, 0, wxALIGN_CENTER_VERTICAL); @@ -105,7 +109,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus m_grid_sizer->Add(editor, 1, wxEXPAND); - auto middle_text = new wxStaticText(m_parent, wxID_ANY, _L("to"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + auto middle_text = new wxStaticText(m_og->ctrl_parent(), wxID_ANY, _L("to"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); middle_text->SetBackgroundStyle(wxBG_STYLE_PAINT); middle_text->SetFont(wxGetApp().normal_font()); m_grid_sizer->Add(middle_text, 0, wxALIGN_CENTER_VERTICAL); @@ -135,12 +139,12 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus m_grid_sizer->Add(editor, 1, wxEXPAND); auto sizer2 = new wxBoxSizer(wxHORIZONTAL); - auto unit_text = new wxStaticText(m_parent, wxID_ANY, "mm", wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); + auto unit_text = new wxStaticText(m_og->ctrl_parent(), wxID_ANY, "mm", wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); unit_text->SetBackgroundStyle(wxBG_STYLE_PAINT); unit_text->SetFont(wxGetApp().normal_font()); sizer2->Add(unit_text, 0, wxALIGN_CENTER_VERTICAL); - m_grid_sizer->Add(sizer2); + m_grid_sizer->Add(sizer2, 0, wxALIGN_CENTER_VERTICAL); // BBS // Add control for the "Layer height" @@ -170,12 +174,12 @@ void ObjectLayers::create_layers_list() { for (const auto &layer : m_object->layer_config_ranges) { const t_layer_height_range& range = layer.first; - auto del_btn = new PlusMinusButton(m_parent, m_bmp_delete, range); + auto del_btn = new PlusMinusButton(m_og->ctrl_parent(), m_bmp_delete, range); del_btn->DisableFocusFromKeyboard(); del_btn->SetBackgroundColour(m_parent->GetBackgroundColour()); del_btn->SetToolTip(_L("Remove height range")); - auto add_btn = new PlusMinusButton(m_parent, m_bmp_add, range); + auto add_btn = new PlusMinusButton(m_og->ctrl_parent(), m_bmp_add, range); add_btn->DisableFocusFromKeyboard(); add_btn->SetBackgroundColour(m_parent->GetBackgroundColour()); wxString tooltip = wxGetApp().obj_list()->can_add_new_range_after_current(range); @@ -183,8 +187,10 @@ void ObjectLayers::create_layers_list() add_btn->Enable(tooltip.IsEmpty()); auto sizer = create_layer(range, del_btn, add_btn); - sizer->Add(del_btn, 0, wxRIGHT | wxLEFT, em_unit(m_parent)); - sizer->Add(add_btn); + auto b_sizer = new wxBoxSizer(wxHORIZONTAL); + b_sizer->Add(del_btn, 0, wxRIGHT | wxLEFT, em_unit(m_parent)); + b_sizer->Add(add_btn); + sizer->Add(b_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, m_parent->FromDIP(1)); // aligns +/- buttons vertically since we got 1px gap on bottom of icons del_btn->Bind(wxEVT_BUTTON, [del_btn](wxEvent &) { wxGetApp().obj_list()->del_layer_range(del_btn->range); @@ -218,6 +224,8 @@ void ObjectLayers::update_layers_list() // only call sizer->Clear(true) via CallAfter, otherwise crash happens in Linux when press enter in Height Range // because an element cannot be destroyed while there are pending events for this element.(https://github.com/wxWidgets/Phoenix/issues/1854) wxGetApp().CallAfter([this, type, objects_ctrl, range]() { + m_og->ctrl_parent()->Freeze(); + // Delete all controls from options group m_grid_sizer->Clear(true); @@ -228,8 +236,10 @@ void ObjectLayers::update_layers_list() else create_layer(range, nullptr, nullptr); + m_og->ctrl_parent()->Thaw(); + m_parent->Layout(); - }); + }); } void ObjectLayers::update_scene_from_editor_selection() const @@ -340,7 +350,7 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent, m_valid_value(value), m_type(type), m_set_focus_data(set_focus_data_fn), - wxTextCtrl(parent->m_parent, wxID_ANY, value, wxDefaultPosition, + wxTextCtrl(parent->m_og->ctrl_parent(), wxID_ANY, value, wxDefaultPosition, wxSize(em_unit(parent->m_parent), wxDefaultCoord), wxTE_PROCESS_ENTER #ifdef _WIN32 | wxBORDER_SIMPLE diff --git a/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp b/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp index 702a0dd4be..e87f98a98b 100644 --- a/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp +++ b/src/slic3r/GUI/Widgets/LabeledStaticBox.cpp @@ -4,12 +4,6 @@ #include "../GUI_Utils.hpp" #include "Label.hpp" -/* -Fix label overflowing to inner frame -Fix use elypsis if text too long -setmin size -*/ - LabeledStaticBox::LabeledStaticBox() : state_handler(this) { @@ -28,7 +22,6 @@ LabeledStaticBox::LabeledStaticBox() std::make_pair(0xDBDBDB, (int) StateColor::Normal), std::make_pair(0xDBDBDB, (int) StateColor::Disabled) ); - } LabeledStaticBox::LabeledStaticBox( @@ -63,11 +56,10 @@ bool LabeledStaticBox::Create( m_pos = this->GetPosition(); int tW,tH,descent,externalLeading; - GetTextExtent("Yy", &tW, &tH, &descent, &externalLeading, &m_font); + // empty label sets m_label_height as 0 that causes extra spacing at top + GetTextExtent(m_label.IsEmpty() ? "Orca" : m_label, &tW, &tH, &descent, &externalLeading, &m_font); m_label_height = tH - externalLeading; - - GetTextExtent(m_label, &tW, &tH, &descent, &externalLeading, &m_font); - m_label_width = tW; + m_label_width = tW; Bind(wxEVT_PAINT,([this](wxPaintEvent e) { wxPaintDC dc(this); @@ -178,4 +170,11 @@ void LabeledStaticBox::DrawBorderAndLabel(wxDC& dc) dc.SetTextForeground(text_color.colorForStates(state_handler.states())); dc.DrawText(m_label, wxPoint(10 * m_scale, 0)); } +} + +void LabeledStaticBox::GetBordersForSizer(int* borderTop, int* borderOther) const { + wxStaticBox::GetBordersForSizer(borderTop, borderOther); +#ifdef __WXOSX__ + *borderOther = 5; // Make sure macOS uses the same border padding as other platforms +#endif } \ No newline at end of file diff --git a/src/slic3r/GUI/Widgets/LabeledStaticBox.hpp b/src/slic3r/GUI/Widgets/LabeledStaticBox.hpp index f18e632073..12e06fc24c 100644 --- a/src/slic3r/GUI/Widgets/LabeledStaticBox.hpp +++ b/src/slic3r/GUI/Widgets/LabeledStaticBox.hpp @@ -63,6 +63,9 @@ protected: int m_label_width; float m_scale; wxPoint m_pos; + + void GetBordersForSizer(int *borderTop, int *borderOther) const override; + }; #endif // !slic3r_GUI_LabeledStaticBox_hpp_ \ No newline at end of file From 5707f8f4a5c4b589d9710a627d459cce4fbdf8b2 Mon Sep 17 00:00:00 2001 From: Kiss Lorand <50251547+kisslorand@users.noreply.github.com> Date: Tue, 24 Jun 2025 18:41:41 +0300 Subject: [PATCH 13/13] Swap pan and rotate mouse buttons (#9972) * Swap pan and rotate buttons * Add translation --- localization/i18n/OrcaSlicer.pot | 6 ++++ localization/i18n/ca/OrcaSlicer_ca.po | 6 ++++ localization/i18n/cs/OrcaSlicer_cs.po | 12 +++++-- localization/i18n/de/OrcaSlicer_de.po | 6 ++++ localization/i18n/en/OrcaSlicer_en.po | 6 ++++ localization/i18n/es/OrcaSlicer_es.po | 6 ++++ localization/i18n/fr/OrcaSlicer_fr.po | 6 ++++ localization/i18n/hu/OrcaSlicer_hu.po | 6 ++++ localization/i18n/it/OrcaSlicer_it.po | 10 ++++-- localization/i18n/ja/OrcaSlicer_ja.po | 10 ++++-- localization/i18n/ko/OrcaSlicer_ko.po | 6 ++++ localization/i18n/lt/OrcaSlicer_lt.po | 6 ++++ localization/i18n/nl/OrcaSlicer_nl.po | 6 ++++ localization/i18n/pl/OrcaSlicer_pl.po | 6 ++++ localization/i18n/pt_BR/OrcaSlicer_pt_BR.po | 6 ++++ localization/i18n/ru/OrcaSlicer_ru.po | 38 +++++++++------------ localization/i18n/sv/OrcaSlicer_sv.po | 24 +++++++------ localization/i18n/tr/OrcaSlicer_tr.po | 9 +++-- localization/i18n/uk/OrcaSlicer_uk.po | 6 ++++ localization/i18n/zh_CN/OrcaSlicer_zh_CN.po | 6 ++++ localization/i18n/zh_TW/OrcaSlicer_zh_TW.po | 6 ++++ src/libslic3r/AppConfig.cpp | 3 ++ src/slic3r/GUI/GLCanvas3D.cpp | 31 +++++++++-------- src/slic3r/GUI/GLCanvas3D.hpp | 10 +++--- src/slic3r/GUI/Preferences.cpp | 12 ++++--- 25 files changed, 183 insertions(+), 66 deletions(-) diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot index c894f59848..184f943551 100644 --- a/localization/i18n/OrcaSlicer.pot +++ b/localization/i18n/OrcaSlicer.pot @@ -6342,6 +6342,12 @@ msgstr "" msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "" +msgid "Swap pan and rotate mouse buttons" +msgstr "" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "" + msgid "Reverse mouse zoom" msgstr "" diff --git a/localization/i18n/ca/OrcaSlicer_ca.po b/localization/i18n/ca/OrcaSlicer_ca.po index 32c8f173e2..5556cac3be 100644 --- a/localization/i18n/ca/OrcaSlicer_ca.po +++ b/localization/i18n/ca/OrcaSlicer_ca.po @@ -6872,6 +6872,12 @@ msgstr "" "Si està activat, fa servir la càmera lliure. Si no està activat, fa servir " "la càmera restringida." +msgid "Swap pan and rotate mouse buttons" +msgstr "Intercanviar la panoràmica i girar els botons del ratolí" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Si està activat, intercanvia les funcions de panoràmica i rotació dels botons esquerre i dret del ratolí." + msgid "Reverse mouse zoom" msgstr "Zoom invers del ratolí" diff --git a/localization/i18n/cs/OrcaSlicer_cs.po b/localization/i18n/cs/OrcaSlicer_cs.po index 036cc163bf..684613bbda 100644 --- a/localization/i18n/cs/OrcaSlicer_cs.po +++ b/localization/i18n/cs/OrcaSlicer_cs.po @@ -6698,17 +6698,23 @@ msgstr "" "Pokud je povoleno, použijte volnou kameru. Pokud není povoleno, použijte " "omezenou kameru." +msgid "Swap pan and rotate mouse buttons" +msgstr "Prohodit tlačítka pro posouvání a otáčení myši" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Pokud je tato možnost povolena, prohodí levé a pravé tlačítko myši pro funkce posouvání a otáčení." + msgid "Reverse mouse zoom" -msgstr "" +msgstr "Zvětšení/zmenšení myší v opačném směru" msgid "If enabled, reverses the direction of zoom with mouse wheel." -msgstr "" +msgstr "Pokud je povoleno, obrací směr přiblížení kolečkem myši." msgid "Show splash screen" msgstr "Zobrazovat úvodní obrazovku" msgid "Show the splash screen during startup." -msgstr "" +msgstr "Zobrazit úvodní obrazovku během spuštění." msgid "Show \"Tip of the day\" notification after start" msgstr "Zobrazovat \"Tip dne\" po spuštění" diff --git a/localization/i18n/de/OrcaSlicer_de.po b/localization/i18n/de/OrcaSlicer_de.po index bc2750f932..e9cbfdaab1 100644 --- a/localization/i18n/de/OrcaSlicer_de.po +++ b/localization/i18n/de/OrcaSlicer_de.po @@ -6939,6 +6939,12 @@ msgstr "Freie Kamera verwenden" msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "Wenn aktiviert, wird die freie Kamera verwendet." +msgid "Swap pan and rotate mouse buttons" +msgstr "Schwenk- und Dreh-Maustasten vertauschen" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Wenn aktiviert, werden die Schwenk- und Drehfunktionen der linken und rechten Maustaste vertauscht." + msgid "Reverse mouse zoom" msgstr "Maus-Zoom umkehren" diff --git a/localization/i18n/en/OrcaSlicer_en.po b/localization/i18n/en/OrcaSlicer_en.po index c8f9554a4d..fadcdf48ff 100644 --- a/localization/i18n/en/OrcaSlicer_en.po +++ b/localization/i18n/en/OrcaSlicer_en.po @@ -6454,6 +6454,12 @@ msgstr "" msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "" +msgid "Swap pan and rotate mouse buttons" +msgstr "" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "" + msgid "Reverse mouse zoom" msgstr "" diff --git a/localization/i18n/es/OrcaSlicer_es.po b/localization/i18n/es/OrcaSlicer_es.po index 018f5738f1..321cf83cae 100644 --- a/localization/i18n/es/OrcaSlicer_es.po +++ b/localization/i18n/es/OrcaSlicer_es.po @@ -6893,6 +6893,12 @@ msgstr "" "Si está activada, utiliza la cámara libre. Si no está activada, utiliza la " "cámara restringida." +msgid "Swap pan and rotate mouse buttons" +msgstr "Intercambiar los botones de panorámica y rotación del mouse" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Si está habilitado, intercambia las funciones de panorámica y rotación de los botones izquierdo y derecho del mouse." + msgid "Reverse mouse zoom" msgstr "Invertir el zoom del ratón" diff --git a/localization/i18n/fr/OrcaSlicer_fr.po b/localization/i18n/fr/OrcaSlicer_fr.po index 5a02f47028..2b692617fd 100644 --- a/localization/i18n/fr/OrcaSlicer_fr.po +++ b/localization/i18n/fr/OrcaSlicer_fr.po @@ -6935,6 +6935,12 @@ msgstr "" "Si activée, utilise la caméra libre. Si désactivée, utilise la caméra " "contrainte." +msgid "Swap pan and rotate mouse buttons" +msgstr "Échanger les boutons de panoramique et de rotation de la souris" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Si cette option est activée, les fonctions de panoramique et de rotation des boutons gauche et droit de la souris sont échangées." + msgid "Reverse mouse zoom" msgstr "Inverser le zoom de la souris" diff --git a/localization/i18n/hu/OrcaSlicer_hu.po b/localization/i18n/hu/OrcaSlicer_hu.po index 77f50f0f84..39139e3a59 100644 --- a/localization/i18n/hu/OrcaSlicer_hu.po +++ b/localization/i18n/hu/OrcaSlicer_hu.po @@ -6614,6 +6614,12 @@ msgstr "" "Ha engedélyezve van, szabad kamerát használ. Ha nincs engedélyezve, akkor " "kötött kamerát használ." +msgid "Swap pan and rotate mouse buttons" +msgstr "Felcserélt pásztázás és forgatás egérgombok" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Ha engedélyezve van, felcseréli a bal és jobb egérgomb pásztázási és forgatási funkcióit." + msgid "Reverse mouse zoom" msgstr "" diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index b305c28c4d..c678181da2 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -6894,13 +6894,17 @@ msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "" "Se abilitato, usa la visuale libera. Altrimenti, usa la visuale vincolata." +msgid "Swap pan and rotate mouse buttons" +msgstr "Scambia i pulsanti del mouse per ruotare e spostare" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Se abilitato, inverte le funzioni di panoramica e rotazione dei pulsanti sinistro e destro del mouse." + msgid "Reverse mouse zoom" msgstr "Inverti zoom del mouse" msgid "If enabled, reverses the direction of zoom with mouse wheel." -msgstr "" -"Se abilitato, inverte la direzione dell'ingrandimento con la rotellina del " -"mouse." +msgstr "Se abilitato, inverte la direzione dell'ingrandimento con la rotellina del mouse." msgid "Show splash screen" msgstr "Mostra schermata iniziale" diff --git a/localization/i18n/ja/OrcaSlicer_ja.po b/localization/i18n/ja/OrcaSlicer_ja.po index 9df1755cc8..b391cae343 100644 --- a/localization/i18n/ja/OrcaSlicer_ja.po +++ b/localization/i18n/ja/OrcaSlicer_ja.po @@ -6489,11 +6489,17 @@ msgstr "" "チェックすると、フリーカメラが使用されます。 そうでない場合は、拘束カメラを使" "用します。" +msgid "Swap pan and rotate mouse buttons" +msgstr "パンと回転のマウスボタンを入れ替える" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "有効にすると、マウスの左ボタンと右ボタンのパン機能と回転機能が入れ替わります。" + msgid "Reverse mouse zoom" -msgstr "" +msgstr "マウスの逆ズーム" msgid "If enabled, reverses the direction of zoom with mouse wheel." -msgstr "" +msgstr "有効にすると、マウス ホイールによるズームの方向が反転します。" msgid "Show splash screen" msgstr "スプラッシュ画面を表示する" diff --git a/localization/i18n/ko/OrcaSlicer_ko.po b/localization/i18n/ko/OrcaSlicer_ko.po index ed8dc910bd..db1ed58756 100644 --- a/localization/i18n/ko/OrcaSlicer_ko.po +++ b/localization/i18n/ko/OrcaSlicer_ko.po @@ -6669,6 +6669,12 @@ msgstr "" "활성화된 경우 자유로운 카메라 앵글을 사용합니다. 활성화되지 않은 경우 제한된 " "카메라 앵글을 사용합니다." +msgid "Swap pan and rotate mouse buttons" +msgstr "팬 및 회전 마우스 버튼 바꾸기" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "이 기능을 활성화하면 왼쪽 마우스 버튼과 오른쪽 마우스 버튼의 팬 및 회전 기능이 바뀝니다." + msgid "Reverse mouse zoom" msgstr "역방향 마우스 줌" diff --git a/localization/i18n/lt/OrcaSlicer_lt.po b/localization/i18n/lt/OrcaSlicer_lt.po index 0a3c917ebb..4e69ab84f9 100644 --- a/localization/i18n/lt/OrcaSlicer_lt.po +++ b/localization/i18n/lt/OrcaSlicer_lt.po @@ -6835,6 +6835,12 @@ msgstr "" "Jei įjungta, naudoti laisvą kamerą. Jei neįjungta, naudoti stacionarią " "kamerą." +msgid "Swap pan and rotate mouse buttons" +msgstr "Sukeisti judėjimą ir sukimąsi pelės mygtuko" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Jei įjungta, sukeičia kairiojo ir dešiniojo pelės mygtukų panoraminio ir pasukimo funkcijas." + msgid "Reverse mouse zoom" msgstr "Apversti pelės didinimą" diff --git a/localization/i18n/nl/OrcaSlicer_nl.po b/localization/i18n/nl/OrcaSlicer_nl.po index 60891c7b7b..632d9ebd6b 100644 --- a/localization/i18n/nl/OrcaSlicer_nl.po +++ b/localization/i18n/nl/OrcaSlicer_nl.po @@ -6707,6 +6707,12 @@ msgstr "" "Als dit is ingeschakeld wordt de vrij beweegbare camera gebruikt, anders een " "vaste camera." +msgid "Swap pan and rotate mouse buttons" +msgstr "Wissel de pan- en rotatiemuisknoppen om" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Als deze optie is ingeschakeld, worden de pan- en rotatiefuncties van de linker- en rechtermuisknop omgedraaid." + msgid "Reverse mouse zoom" msgstr "Omgekeerde muiszoom" diff --git a/localization/i18n/pl/OrcaSlicer_pl.po b/localization/i18n/pl/OrcaSlicer_pl.po index 747dd49871..1f26741e65 100644 --- a/localization/i18n/pl/OrcaSlicer_pl.po +++ b/localization/i18n/pl/OrcaSlicer_pl.po @@ -6848,6 +6848,12 @@ msgstr "Używanie wolnego widoku kamery" msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "Przełącza pomiędzy wolnym a ograniczonym widokiem kamery." +msgid "Swap pan and rotate mouse buttons" +msgstr "Zamień przyciski przesuwania i obracania myszy" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Jeśli włączone, zamienia funkcje przesuwania i obracania lewym i prawym przyciskiem myszy." + msgid "Reverse mouse zoom" msgstr "Odwrócone przybliżanie myszką" diff --git a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po index 2ea8c9c909..8abbbcc195 100644 --- a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po +++ b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po @@ -6854,6 +6854,12 @@ msgstr "Usar câmera livre" msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "Se ativado, usa câmera livre. Se não ativado, usa câmera restrita." +msgid "Swap pan and rotate mouse buttons" +msgstr "Alterar a panorâmica e girar os botões do mouse" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Se ativado, troca as funções de panorâmica e rotação dos botões esquerdo e direito do mouse." + msgid "Reverse mouse zoom" msgstr "Inverter zoom do mouse" diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po index f7fadcd9ce..a8178983d2 100644 --- a/localization/i18n/ru/OrcaSlicer_ru.po +++ b/localization/i18n/ru/OrcaSlicer_ru.po @@ -6931,17 +6931,20 @@ msgid "Use free camera" msgstr "Использовать свободную камеру" msgid "If enabled, use free camera. If not enabled, use constrained camera." -msgstr "" -"Если включено, используется свободное вращение камеры. Если выключено, " +msgstr "Если включено, используется свободное вращение камеры. Если выключено, " "используется вращение камера с ограничениями." +msgid "Swap pan and rotate mouse buttons" +msgstr "Поменять местами кнопки панорамирования и вращения мыши" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Если включено, меняет местами функции панорамирования и поворота левой и правой кнопок мыши." + msgid "Reverse mouse zoom" msgstr "Инвертировать управление масштабом" msgid "If enabled, reverses the direction of zoom with mouse wheel." -msgstr "" -"Если включено, направление масштабирования с помощью колесика мыши будет " -"инвертировано." +msgstr "Если включено, направление масштабирования с помощью колесика мыши будет инвертировано." msgid "Show splash screen" msgstr "Показывать заставку при запуске программы" @@ -6953,46 +6956,37 @@ msgid "Show \"Tip of the day\" notification after start" msgstr "Показывать уведомление с полезным советом при запуске приложения" msgid "If enabled, useful hints are displayed at startup." -msgstr "" -"Если включено, будут показываться уведомления с полезном советом при запуске " -"приложения." +msgstr "Если включено, будут показываться уведомления с полезном советом при запуске приложения." msgid "Flushing volumes: Auto-calculate every time the color changed." msgstr "Объём очистки: автопересчёт при каждом изменении цвета" msgid "If enabled, auto-calculate every time the color changed." -msgstr "" -"Если включено, выполняется автоматический перерасчёт объёма очистки при " +msgstr "Если включено, выполняется автоматический перерасчёт объёма очистки при " "каждом изменении цвета." -msgid "" -"Flushing volumes: Auto-calculate every time when the filament is changed." +msgid "Flushing volumes: Auto-calculate every time when the filament is changed." msgstr "Объём очистки: автопересчёт при каждой смене прутка" msgid "If enabled, auto-calculate every time when filament is changed" -msgstr "" -"Если включено, выполняется автоматический перерасчёт объёма очистки при " +msgstr "Если включено, выполняется автоматический перерасчёт объёма очистки при " "каждой смене прутка." msgid "Remember printer configuration" msgstr "Запоминать конфигурацию принтера" -msgid "" -"If enabled, Orca will remember and switch filament/process configuration for " +msgid "If enabled, Orca will remember and switch filament/process configuration for " "each printer automatically." -msgstr "" -"Если включено, программа будет запоминать связь выбранного профиля принтера " +msgstr "Если включено, программа будет запоминать связь выбранного профиля принтера " "с профилем пластиковой нити и процессом печати, выставленными вами в " "последний раз." msgid "Multi-device Management (Take effect after restarting Orca Slicer)." msgstr "Управление несколькими принтерами (требуется перезапуск программы)" -msgid "" -"With this option enabled, you can send a task to multiple devices at the " +msgid "With this option enabled, you can send a task to multiple devices at the " "same time and manage multiple devices." -msgstr "" -"Если включено, вы сможете управлять несколькими устройствами и отправлять " +msgstr "Если включено, вы сможете управлять несколькими устройствами и отправлять " "задания на печать на несколько устройств одновременно." msgid "Auto arrange plate after cloning" diff --git a/localization/i18n/sv/OrcaSlicer_sv.po b/localization/i18n/sv/OrcaSlicer_sv.po index 5e594f4298..7d252ca6fc 100644 --- a/localization/i18n/sv/OrcaSlicer_sv.po +++ b/localization/i18n/sv/OrcaSlicer_sv.po @@ -6598,30 +6598,34 @@ msgstr "" msgid "Zoom to mouse position" msgstr "Zooma till musens position" -msgid "" -"Zoom in towards the mouse pointer's position in the 3D view, rather than the " +msgid "Zoom in towards the mouse pointer's position in the 3D view, rather than the " "2D window center." -msgstr "" -"Zooma in mot muspekarens position i 3D-vyn, istället för mot 2D-fönstrets " +msgstr "Zooma in mot muspekarens position i 3D-vyn, istället för mot 2D-fönstrets " "mitt." msgid "Use free camera" -msgstr "" +msgstr "Använd fri kamera" msgid "If enabled, use free camera. If not enabled, use constrained camera." -msgstr "" +msgstr "Om aktiverat, använd fri kamera. Om inte aktiverat, använd begränsad kamera." + +msgid "Swap pan and rotate mouse buttons" +msgstr "Växla panorerings- och rotationsknapparna på musen" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Om aktiverat växlar vänster och höger musknapps panorerings- och rotationsfunktioner." msgid "Reverse mouse zoom" -msgstr "" +msgstr "Omvänd muszoomning" msgid "If enabled, reverses the direction of zoom with mouse wheel." -msgstr "" +msgstr "Om aktiverad, vänder zoomriktningen med mushjulet." msgid "Show splash screen" -msgstr "" +msgstr "Visa välkomstskärm" msgid "Show the splash screen during startup." -msgstr "" +msgstr "Visa välkomstskärmen under uppstart." msgid "Show \"Tip of the day\" notification after start" msgstr "Visa \"Dagens tips\" efter start" diff --git a/localization/i18n/tr/OrcaSlicer_tr.po b/localization/i18n/tr/OrcaSlicer_tr.po index 7978a3662f..a25bb5dbec 100644 --- a/localization/i18n/tr/OrcaSlicer_tr.po +++ b/localization/i18n/tr/OrcaSlicer_tr.po @@ -6799,12 +6799,17 @@ msgstr "" "Etkinleştirilirse serbest kamerayı kullanın. Etkin değilse kısıtlı kamerayı " "kullanın." +msgid "Swap pan and rotate mouse buttons" +msgstr "Pan ve döndürme işlevlerini fare düğmeleri arasında değiştir" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Etkinleştirildiğinde, sol ve sağ fare düğmelerinin pan ve döndürme işlevlerini yer değiştirir." + msgid "Reverse mouse zoom" msgstr "Mouse yakınlaştırmasını tersine çevir" msgid "If enabled, reverses the direction of zoom with mouse wheel." -msgstr "" -"Etkinleştirilirse, mouse tekerleğiyle yakınlaştırmanın yönü tersine çevrilir." +msgstr "Etkinleştirilirse, mouse tekerleğiyle yakınlaştırmanın yönü tersine çevrilir." msgid "Show splash screen" msgstr "Açılış ekranını göster" diff --git a/localization/i18n/uk/OrcaSlicer_uk.po b/localization/i18n/uk/OrcaSlicer_uk.po index 131ed159eb..75325c195c 100644 --- a/localization/i18n/uk/OrcaSlicer_uk.po +++ b/localization/i18n/uk/OrcaSlicer_uk.po @@ -6860,6 +6860,12 @@ msgstr "" "Якщо увімкнено, використовуватиметься вільна камера. Якщо вимкнено, " "використовуватиметься камера з обмеженими можливостями." +msgid "Swap pan and rotate mouse buttons" +msgstr "Поміняти кнопки миші для панорамування й обертання" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "Якщо ввімкнено, змінює місцями функції панорамування та обертання між лівою та правою кнопками миші." + msgid "Reverse mouse zoom" msgstr "Зворотне масштабування мишкою" diff --git a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po index 686cf9ad63..13d5f78cfe 100644 --- a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po +++ b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po @@ -6519,6 +6519,12 @@ msgstr "使用自由视角" msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "如果启用,使用自由视角。如果未启用,使用约束视角。" +msgid "Swap pan and rotate mouse buttons" +msgstr "交换鼠标按钮的平移与旋转功能" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "启用后,将左键和右键的平移与旋转功能对调" + msgid "Reverse mouse zoom" msgstr "反转鼠标缩放" diff --git a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po index 73062ca190..bd9ee60a19 100644 --- a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po +++ b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po @@ -6540,6 +6540,12 @@ msgstr "使用自由鏡頭" msgid "If enabled, use free camera. If not enabled, use constrained camera." msgstr "如果啟用,則使用自由鏡頭。若未啟用,則使用受限鏡頭。" +msgid "Swap pan and rotate mouse buttons" +msgstr "交换鼠标按钮的平移与旋转功能" + +msgid "If enabled, swaps the left and right mouse buttons pan and rotate functions." +msgstr "启用后,将左键和右键的平移与旋转功能对调" + msgid "Reverse mouse zoom" msgstr "反轉滑鼠滾輪縮放方向" diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 588d1e0c0a..5e21e02d24 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -178,6 +178,9 @@ void AppConfig::set_defaults() if (get("camera_navigation_style").empty()) set("camera_navigation_style", "0"); + if (get("swap_mouse_buttons").empty()) + set_bool("swap_mouse_buttons", false); + if (get("reverse_mouse_wheel_zoom").empty()) set_bool("reverse_mouse_wheel_zoom", false); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e02919d9e0..1e400f6421 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4104,6 +4104,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } bool any_gizmo_active = m_gizmos.get_current() != nullptr; + bool swapMouseButtons = wxGetApp().app_config->get_bool("swap_mouse_buttons"); if (m_mouse.drag.move_requires_threshold && m_mouse.is_move_start_threshold_position_2D_defined() && m_mouse.is_move_threshold_met(pos)) { m_mouse.drag.move_requires_threshold = false; @@ -4305,7 +4306,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_dirty = true; } } - else if (evt.Dragging() || is_camera_rotate(evt) || is_camera_pan(evt)) { + else if (evt.Dragging() || is_camera_rotate(evt, swapMouseButtons) || is_camera_pan(evt, swapMouseButtons)) { m_mouse.dragging = true; if (m_layers_editing.state != LayersEditing::Unknown && layer_editing_object_idx != -1) { @@ -4315,10 +4316,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } // do not process the dragging if the left mouse was set down in another canvas - else if (is_camera_rotate(evt)) { + else if (is_camera_rotate(evt, swapMouseButtons)) { // Orca: Sphere rotation for painting view - // if dragging over blank area with left button, rotate - if ((any_gizmo_active || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) { + // if dragging over blank area with left button or button functions swapped then rotate + if ((any_gizmo_active || swapMouseButtons || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) { Camera& camera = wxGetApp().plater()->get_camera(); auto mult_pref = wxGetApp().app_config->get("camera_orbit_mult"); const double mult = mult_pref.empty() ? 1.0 : std::stod(mult_pref); @@ -4381,15 +4382,17 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } } - camera.auto_type(Camera::EType::Perspective); + camera.auto_type(Camera::EType::Perspective); m_dirty = true; + m_mouse.ignore_right_up = true; // will be reset on button up event even if not right button is pressed } + m_camera_movement = true; m_mouse.drag.start_position_3D = Vec3d((double)pos(0), (double)pos(1), 0.0); } - else if (is_camera_pan(evt)) { - // If dragging over blank area with right button, pan. + else if (is_camera_pan(evt, swapMouseButtons)) { + // if dragging with right button or if button functions swapped and dragging with left button over blank area then pan if (m_mouse.is_start_position_2D_defined()) { // get point in model space at Z = 0 float z = 0.0f; @@ -4407,7 +4410,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) camera.set_target(camera.get_target() + orig - cur_pos); m_dirty = true; - m_mouse.ignore_right_up = true; + m_mouse.ignore_right_up = true; // will be reset on button up event even if not right button is pressed } m_camera_movement = true; @@ -4415,10 +4418,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } else if ((evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) || - (m_camera_movement && !is_camera_rotate(evt) && !is_camera_pan(evt))) { + (m_camera_movement && !is_camera_rotate(evt, swapMouseButtons) && !is_camera_pan(evt, swapMouseButtons))) { m_mouse.position = pos.cast(); - if (evt.LeftUp()) { + if (swapMouseButtons ? evt.RightUp() : evt.LeftUp()) { m_rotation_center(0) = m_rotation_center(1) = m_rotation_center(2) = 0.f; } @@ -4603,21 +4606,21 @@ void GLCanvas3D::on_set_focus(wxFocusEvent& evt) m_is_touchpad_navigation = wxGetApp().app_config->get_bool("camera_navigation_style"); } -bool GLCanvas3D::is_camera_rotate(const wxMouseEvent& evt) const +bool GLCanvas3D::is_camera_rotate(const wxMouseEvent& evt, const bool buttonsSwapped) const { if (m_is_touchpad_navigation) { return evt.Moving() && evt.AltDown() && !evt.ShiftDown(); } else { - return evt.Dragging() && evt.LeftIsDown(); + return evt.Dragging() && (buttonsSwapped ? evt.RightIsDown() : evt.LeftIsDown()); } } -bool GLCanvas3D::is_camera_pan(const wxMouseEvent& evt) const +bool GLCanvas3D::is_camera_pan(const wxMouseEvent& evt, const bool buttonsSwapped) const { if (m_is_touchpad_navigation) { return evt.Moving() && evt.ShiftDown() && !evt.AltDown(); } else { - return evt.Dragging() && (evt.MiddleIsDown() || evt.RightIsDown()); + return evt.Dragging() && (evt.MiddleIsDown() || (buttonsSwapped ? evt.LeftIsDown() : evt.RightIsDown())); } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 26c14fa75e..3845ef462c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -216,7 +216,7 @@ class GLCanvas3D }; static const float THICKNESS_BAR_WIDTH; - + // Orca: Shrinkage compensation void set_shrinkage_compensation(const Vec3d &shrinkage_compensation) { m_shrinkage_compensation = shrinkage_compensation; }; @@ -232,7 +232,7 @@ class GLCanvas3D // Owned by LayersEditing. SlicingParameters* m_slicing_parameters{ nullptr }; std::vector m_layer_height_profile; - + // Orca: Shrinkage compensation to apply when we need to use object_max_z with Z compensation. Vec3d m_shrinkage_compensation{ Vec3d::Ones() }; @@ -968,8 +968,8 @@ public: void on_set_focus(wxFocusEvent& evt); void force_set_focus(); - bool is_camera_rotate(const wxMouseEvent& evt) const; - bool is_camera_pan(const wxMouseEvent& evt) const; + bool is_camera_rotate(const wxMouseEvent& evt, const bool buttonsSwapped) const; + bool is_camera_pan(const wxMouseEvent& evt, const bool buttonsSwapped) const; Size get_canvas_size() const; Vec2d get_local_mouse_position() const; @@ -1063,7 +1063,7 @@ public: bool is_overhang_shown() const { return m_slope.is_GlobalUsed(); } void show_overhang(bool show) { m_slope.globalUse(show); } - + bool is_using_slope() const { return m_slope.is_used(); } void use_slope(bool use) { m_slope.use(use); } void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); } diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index f6255fa368..db52a767e6 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -123,7 +123,7 @@ wxBoxSizer *PreferencesDialog::create_item_combobox(wxString title, wxWindow *pa auto current_setting = app_config->get(param); if (!current_setting.empty()) { auto compare = [current_setting](string possible_setting) { return current_setting == possible_setting; }; - auto iterator = find_if(config_name_index.begin(), config_name_index.end(), compare); + auto iterator = find_if(config_name_index.begin(), config_name_index.end(), compare); current_index = iterator - config_name_index.begin(); } @@ -536,7 +536,7 @@ wxBoxSizer *PreferencesDialog::create_camera_orbit_mult_input(wxString title, wx sizer_input->Add(input_title, 0, wxALIGN_CENTER_VERTICAL | wxALL, 3); sizer_input->Add(input, 0, wxALIGN_CENTER_VERTICAL, 0); sizer_input->Add(0, 0, 0, wxEXPAND | wxLEFT, 3); - + const double min = 0.05; const double max = 2.0; @@ -1200,12 +1200,12 @@ wxWindow* PreferencesDialog::create_general_page() std::vector Units = {_L("Metric") + " (mm, g)", _L("Imperial") + " (in, oz)"}; auto item_currency = create_item_combobox(_L("Units"), page, _L("Units"), "use_inches", Units); - auto item_single_instance = create_item_checkbox(_L("Allow only one OrcaSlicer instance"), page, + auto item_single_instance = create_item_checkbox(_L("Allow only one OrcaSlicer instance"), page, #if __APPLE__ _L("On OSX there is always only one instance of app running by default. However it is allowed to run multiple instances " - "of same app from the command line. In such case this settings will allow only one instance."), + "of same app from the command line. In such case this settings will allow only one instance."), #else - _L("If this is enabled, when starting OrcaSlicer and another instance of the same OrcaSlicer is already running, that instance will be reactivated instead."), + _L("If this is enabled, when starting OrcaSlicer and another instance of the same OrcaSlicer is already running, that instance will be reactivated instead."), #endif 50, "single_instance"); @@ -1217,6 +1217,7 @@ wxWindow* PreferencesDialog::create_general_page() auto item_mouse_zoom_settings = create_item_checkbox(_L("Zoom to mouse position"), page, _L("Zoom in towards the mouse pointer's position in the 3D view, rather than the 2D window center."), 50, "zoom_to_mouse"); auto item_use_free_camera_settings = create_item_checkbox(_L("Use free camera"), page, _L("If enabled, use free camera. If not enabled, use constrained camera."), 50, "use_free_camera"); + auto swap_pan_rotate = create_item_checkbox(_L("Swap pan and rotate mouse buttons"), page, _L("If enabled, swaps the left and right mouse buttons pan and rotate functions."), 50, "swap_mouse_buttons"); auto reverse_mouse_zoom = create_item_checkbox(_L("Reverse mouse zoom"), page, _L("If enabled, reverses the direction of zoom with mouse wheel."), 50, "reverse_mouse_wheel_zoom"); auto camera_orbit_mult = create_camera_orbit_mult_input(_L("Orbit speed multiplier"), page, _L("Multiplies the orbit speed for finer or coarser camera movement.")); @@ -1301,6 +1302,7 @@ wxWindow* PreferencesDialog::create_general_page() sizer_page->Add(item_single_instance, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_use_free_camera_settings, 0, wxTOP, FromDIP(3)); + sizer_page->Add(swap_pan_rotate, 0, wxTOP, FromDIP(3)); sizer_page->Add(reverse_mouse_zoom, 0, wxTOP, FromDIP(3)); sizer_page->Add(camera_orbit_mult, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_show_splash_screen, 0, wxTOP, FromDIP(3));