mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-15 20:01:31 +00:00
Compare commits
102
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0541918592 | ||
|
|
3c8c667dbd | ||
|
|
03568b5200 | ||
|
|
3cf0f4dba5 | ||
|
|
59e655dd1d | ||
|
|
19be9604de | ||
|
|
8e868118d2 | ||
|
|
f13f67959c | ||
|
|
ae2c36f091 | ||
|
|
14e572db5f | ||
|
|
449a4cf9fc | ||
|
|
943a75af0a | ||
|
|
02bc8969a2 | ||
|
|
c2e91cb86c | ||
|
|
a0846ec215 | ||
|
|
0e8288de36 | ||
|
|
0e4928f200 | ||
|
|
8cb2e4e01e | ||
|
|
3b58217b47 | ||
|
|
df95a30a0f | ||
|
|
a1a9a0ce2b | ||
|
|
b7ab7f4225 | ||
|
|
465125167b | ||
|
|
19755451a9 | ||
|
|
5d352294ed | ||
|
|
e3b4c6df84 | ||
|
|
b06305f990 | ||
|
|
dbd9c22d80 | ||
|
|
67645760f2 | ||
|
|
6c7f3629bc | ||
|
|
688127af5b | ||
|
|
0c5d85e516 | ||
|
|
cdc336d80c | ||
|
|
eae002da13 | ||
|
|
b7240ab1c6 | ||
|
|
1ab34a7454 | ||
|
|
da074043f2 | ||
|
|
4e03983426 | ||
|
|
d3ac5ab98e | ||
|
|
0b77321d3a | ||
|
|
7d0fd272b5 | ||
|
|
a6816d8c0d | ||
|
|
045179150f | ||
|
|
4c3e30144d | ||
|
|
ff83aa41ef | ||
|
|
91b712a237 | ||
|
|
8491f87ddb | ||
|
|
d13958ac54 | ||
|
|
99fde4a24e | ||
|
|
599f606f6f | ||
|
|
cc6929e506 | ||
|
|
14ad533d91 | ||
|
|
5538bf6463 | ||
|
|
fdf4a493cb | ||
|
|
932410e06b | ||
|
|
981cd599d5 | ||
|
|
9ec93deeda | ||
|
|
99dea01cc3 | ||
|
|
8522cc5f67 | ||
|
|
b226919217 | ||
|
|
9ee357b77f | ||
|
|
ca388f2d9e | ||
|
|
a409791826 | ||
|
|
ba12608e4a | ||
|
|
b8dd2d3ca8 | ||
|
|
0335d76d30 | ||
|
|
3e56d25f64 | ||
|
|
4c149b69eb | ||
|
|
57cb60e20f | ||
|
|
8ffe84b1dd | ||
|
|
f4268a0eec | ||
|
|
17e2adc283 | ||
|
|
d87f7e462c | ||
|
|
0a6a42ecb5 | ||
|
|
762e474433 | ||
|
|
115d6dde46 | ||
|
|
9da2975424 | ||
|
|
7b3228d10d | ||
|
|
2de58e557b | ||
|
|
514ab02525 | ||
|
|
d7688a27d0 | ||
|
|
c2965a1336 | ||
|
|
a587859e84 | ||
|
|
b142da72d8 | ||
|
|
2ec8aa7b6c | ||
|
|
0b3f5050b0 | ||
|
|
a5453acdc5 | ||
|
|
6690bdf149 | ||
|
|
bb9bc04996 | ||
|
|
246d54a6bf | ||
|
|
15952edf4d | ||
|
|
8a6573db19 | ||
|
|
353e9519f0 | ||
|
|
1c8c7820c8 | ||
|
|
e87b0d57b4 | ||
|
|
7a992b397b | ||
|
|
e785f89833 | ||
|
|
8f2ff7447e | ||
|
|
25c0cf2943 | ||
|
|
59c7809ee1 | ||
|
|
caa5bb38ea | ||
|
|
78daf90c95 |
@@ -17,7 +17,7 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
description: 'Tag of the draft release to upload to (e.g. v2.4.0)'
|
||||
description: 'Tag of the draft release to upload to (e.g. v2.4.0-beta)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
|
||||
Vendored
+1
@@ -25,6 +25,7 @@ if (MSVC AND DEP_DEBUG)
|
||||
endif ()
|
||||
|
||||
orcaslicer_add_cmake_project(Boost
|
||||
${_options}
|
||||
URL "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz"
|
||||
URL_HASH SHA256=4d27e9efed0f6f152dc28db6430b9d3dfb40c0345da7342eaa5a987dde57bd95
|
||||
LIST_SEPARATOR |
|
||||
|
||||
Vendored
+14
-6
@@ -155,17 +155,25 @@ if (NOT _is_multi AND NOT CMAKE_BUILD_TYPE)
|
||||
endif ()
|
||||
|
||||
function(orcaslicer_add_cmake_project projectname)
|
||||
cmake_parse_arguments(P_ARGS "" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN})
|
||||
cmake_parse_arguments(P_ARGS "FORWARD_CONFIG" "INSTALL_DIR;BUILD_COMMAND;INSTALL_COMMAND" "CMAKE_ARGS" ${ARGN})
|
||||
|
||||
set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
|
||||
if (_is_multi OR MSVC)
|
||||
if (ORCA_INCLUDE_DEBUG_INFO AND NOT DEP_DEBUG)
|
||||
if (P_ARGS_FORWARD_CONFIG)
|
||||
set(_configs_line -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
|
||||
elseif (ORCA_INCLUDE_DEBUG_INFO AND NOT DEP_DEBUG)
|
||||
set(_configs_line "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
else ()
|
||||
set(_configs_line "")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (P_ARGS_FORWARD_CONFIG)
|
||||
set(_target_config "$<CONFIG>")
|
||||
else()
|
||||
set(_target_config "Release")
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
set(_gen CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}")
|
||||
else()
|
||||
@@ -208,8 +216,8 @@ if (NOT IS_CROSS_COMPILE OR NOT APPLE)
|
||||
${DEP_CMAKE_OPTS}
|
||||
${P_ARGS_CMAKE_ARGS}
|
||||
${P_ARGS_UNPARSED_ARGUMENTS}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config Release -- ${_build_j}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config Release
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${_target_config} -- ${_build_j}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${_target_config}
|
||||
)
|
||||
|
||||
if (FLATPAK)
|
||||
@@ -251,8 +259,8 @@ else()
|
||||
${DEP_CMAKE_OPTS}
|
||||
${P_ARGS_CMAKE_ARGS}
|
||||
${P_ARGS_UNPARSED_ARGUMENTS}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config Release -- ${_build_j}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config Release
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${_target_config} -- ${_build_j}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${_target_config}
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
Vendored
+6
@@ -1,4 +1,10 @@
|
||||
set(_options "")
|
||||
if (MSVC AND DEP_DEBUG)
|
||||
set(_options "FORWARD_CONFIG")
|
||||
endif ()
|
||||
|
||||
orcaslicer_add_cmake_project(Draco
|
||||
${_options}
|
||||
URL https://github.com/google/draco/archive/refs/tags/1.5.7.zip
|
||||
URL_HASH SHA256=27b72ba2d5ff3d0a9814ad40d4cb88f8dc89a35491c0866d952473f8f9416b77
|
||||
)
|
||||
Vendored
+5
@@ -2,8 +2,12 @@
|
||||
# leaves ~200 unresolved ippicv* externals at link time on Windows ARM64.
|
||||
if (MSVC AND NOT "${DEPS_ARCH}" STREQUAL "arm64")
|
||||
set(_use_IPP "-DWITH_IPP=ON")
|
||||
if (DEP_DEBUG)
|
||||
set(_options "FORWARD_CONFIG")
|
||||
endif ()
|
||||
else ()
|
||||
set(_use_IPP "-DWITH_IPP=OFF")
|
||||
set(_options "")
|
||||
endif ()
|
||||
|
||||
if (IN_GIT_REPO)
|
||||
@@ -11,6 +15,7 @@ if (IN_GIT_REPO)
|
||||
endif ()
|
||||
|
||||
orcaslicer_add_cmake_project(OpenCV
|
||||
${_options}
|
||||
URL https://github.com/opencv/opencv/archive/refs/tags/4.6.0.tar.gz
|
||||
URL_HASH SHA256=1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
|
||||
PATCH_COMMAND git apply ${OpenCV_DIRECTORY_FLAG} --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-vs.patch ${CMAKE_CURRENT_LIST_DIR}/0002-clang19-macos.patch
|
||||
|
||||
@@ -1123,18 +1123,17 @@ private:
|
||||
|
||||
std::vector<RawShape> objs,excludes;
|
||||
for (const Item &item : items_) {
|
||||
if (item.isFixed()) continue;
|
||||
objs.push_back(item.transformedShape());
|
||||
if (item.isFixed())
|
||||
excludes.push_back(item.transformedShape());
|
||||
else
|
||||
objs.push_back(item.transformedShape());
|
||||
}
|
||||
if (objs.empty())
|
||||
return;
|
||||
// Without fixed items this inner-fit NFP can exceed clipper's range and crash MSVC.
|
||||
if (!excludes.empty())
|
||||
{ // find a best position inside NFP of fixed items (excluded regions), so the center of pile is cloest to bed center
|
||||
RawShape objs_convex_hull = sl::convexHull(objs);
|
||||
for (const Item &item : items_) {
|
||||
if (item.isFixed()) {
|
||||
excludes.push_back(item.transformedShape());
|
||||
}
|
||||
}
|
||||
|
||||
auto nfps = calcnfp(objs_convex_hull, excludes, bbin, Lvl<MaxNfpLevel::value>());
|
||||
if (nfps.empty()) {
|
||||
|
||||
+1580
-3933
File diff suppressed because it is too large
Load Diff
+3813
-9104
File diff suppressed because it is too large
Load Diff
+3356
-7406
File diff suppressed because it is too large
Load Diff
+4229
-10545
File diff suppressed because it is too large
Load Diff
+2023
-5116
File diff suppressed because it is too large
Load Diff
+3844
-10776
File diff suppressed because it is too large
Load Diff
+3898
-10840
File diff suppressed because it is too large
Load Diff
+3519
-8363
File diff suppressed because it is too large
Load Diff
+3963
-9861
File diff suppressed because it is too large
Load Diff
+2939
-6287
File diff suppressed because it is too large
Load Diff
+3368
-7456
File diff suppressed because it is too large
Load Diff
+4061
-9144
File diff suppressed because it is too large
Load Diff
+4581
-9987
File diff suppressed because it is too large
Load Diff
+3828
-9077
File diff suppressed because it is too large
Load Diff
+3691
-9153
File diff suppressed because it is too large
Load Diff
+3298
-8587
File diff suppressed because it is too large
Load Diff
+4671
-9843
File diff suppressed because it is too large
Load Diff
+2835
-6531
File diff suppressed because it is too large
Load Diff
+3418
-7897
File diff suppressed because it is too large
Load Diff
+3275
-7400
File diff suppressed because it is too large
Load Diff
+3847
-8214
File diff suppressed because it is too large
Load Diff
+3136
-5375
File diff suppressed because it is too large
Load Diff
+2718
-5683
File diff suppressed because it is too large
Load Diff
@@ -146,16 +146,16 @@ text = Fine-tuning for flow rate\nDid you know that flow rate can be fine-tuned
|
||||
text = Split your prints into plates\nDid you know that you can split a model that has a lot of parts into individual plates ready to print? This will simplify the process of keeping track of all the parts.
|
||||
|
||||
[hint:Speed up your print with Adaptive Layer Height]
|
||||
text = Speed up your print with Adaptive Layer Height\nDid you know that you can print a model even faster, by using the Adaptive Layer Height option? Check it out!
|
||||
text = Speed up your print with Adaptive Layer Height\nDid you know that you can print a model even faster by using the Adaptive Layer Height option? Check it out!
|
||||
|
||||
[hint:Support painting]
|
||||
text = Support painting\nDid you know that you can paint the location of your supports? This feature makes it easy to place the support material only on the sections of the model that actually need it.
|
||||
|
||||
[hint:Different types of supports]
|
||||
text = Different types of supports\nDid you know that you can choose from multiple types of supports? Tree supports work great for organic models, while saving filament and improving print speed. Check them out!
|
||||
text = Different types of supports\nDid you know that you can choose from multiple types of supports? Tree supports work great for organic models while saving filament and improving print speed. Check them out!
|
||||
|
||||
[hint:Printing Silk Filament]
|
||||
text = Printing Silk Filament\nDid you know that Silk filament needs special consideration to print it successfully? Higher temperature and lower speed are always recommended for the best results.
|
||||
text = Printing Silk Filament\nDid you know that Silk filament needs special consideration to print successfully? A higher temperature and lower speed are always recommended for the best results.
|
||||
|
||||
[hint:Brim for better adhesion]
|
||||
text = Brim for better adhesion\nDid you know that when printed models have a small contact interface with the printing surface, it's recommended to use a brim?
|
||||
@@ -167,13 +167,13 @@ text = Set parameters for multiple objects\nDid you know that you can set slicin
|
||||
text = Stack objects\nDid you know that you can stack objects as a whole one?
|
||||
|
||||
[hint:Flush into support/objects/infill]
|
||||
text = Flush into support/objects/infill\nDid you know that you can reduce wasted filament by flushing it into support/objects/infill during filament change?
|
||||
text = Flush into support/objects/infill\nDid you know that you can reduce wasted filament by flushing it into support/objects/infill during filament changes?
|
||||
|
||||
[hint:Improve strength]
|
||||
text = Improve strength\nDid you know that you can use more wall loops and higher sparse infill density to improve the strength of the model?
|
||||
|
||||
[hint:When do you need to print with the printer door opened]
|
||||
text = When do you need to print with the printer door opened?\nDid you know that opening the printer door can reduce the probability of extruder/hotend clogging when printing lower temperature filament with a higher enclosure temperature? More info about this in the Wiki.
|
||||
text = When do you need to print with the printer door opened?\nDid you know that opening the printer door can reduce the probability of extruder/hotend clogging when printing lower temperature filament with a higher enclosure temperature? There is more info about this in the Wiki.
|
||||
|
||||
[hint:Avoid warping]
|
||||
text = Avoid warping\nDid you know that when printing materials that are prone to warping such as ABS, appropriately increasing the heatbed temperature can reduce the probability of warping?
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.2992 1.42627C10.7774 1.42627 8.73315 3.47056 8.73315 5.99231C8.73315 8.51406 10.7774 10.5583 13.2992 10.5583C13.3609 10.5583 13.4223 10.5571 13.4834 10.5547C15.9197 10.4581 17.8652 8.45238 17.8652 5.99231C17.8652 3.47056 15.8209 1.42627 13.2992 1.42627ZM15.6185 11.0536C17.5346 10.1741 18.8652 8.23861 18.8652 5.99231C18.8652 2.91827 16.3732 0.42627 13.2992 0.42627C11.5793 0.42627 10.0417 1.2063 9.02067 2.43188H2.31853C1.93193 2.43188 1.61853 2.74528 1.61853 3.13188V12.4712C1.61853 12.6313 1.6723 12.7789 1.76278 12.8968C1.76671 13.0046 1.79621 13.1144 1.85576 13.2185L3.48408 16.0649C3.60875 16.2829 3.8406 16.4173 4.09168 16.4173H6.75859L7.97903 19.1586C8.22556 19.7123 9.01148 19.7123 9.25801 19.1586L10.4784 16.4173H13.1454C13.3965 16.4173 13.6283 16.2829 13.753 16.0649L15.3813 13.2185C15.4409 13.1144 15.4704 13.0046 15.4743 12.8968C15.5648 12.7789 15.6185 12.6313 15.6185 12.4712V11.0536ZM13.4429 11.5565C13.8469 11.5463 14.2403 11.493 14.6185 11.4011V12.1709H2.61853V3.43188H8.35573C7.95792 4.19837 7.73315 5.06909 7.73315 5.99231C7.73315 9.06635 10.2252 11.5583 13.2992 11.5583C13.3472 11.5583 13.3951 11.5577 13.4429 11.5565ZM2.98076 13.1712H14.2563L12.9714 15.4173H9.85194L9.84578 15.4173H7.39126L7.3851 15.4173H4.26569L2.98076 13.1712ZM9.38381 16.4173L8.61852 18.1363L7.85322 16.4173H9.38381ZM12.2021 3.36422C12.3973 3.55948 12.3973 3.87606 12.2021 4.07133L11.743 4.53041H16.0625C16.3386 4.53041 16.5625 4.75426 16.5625 5.03041C16.5625 5.30655 16.3386 5.53041 16.0625 5.53041H10.7773C10.2428 5.53041 9.97507 4.88412 10.353 4.50614L11.495 3.36422C11.6902 3.16896 12.0068 3.16896 12.2021 3.36422ZM14.3963 7.91305C14.2011 8.10831 14.2011 8.42489 14.3963 8.62015C14.5916 8.81542 14.9082 8.81542 15.1034 8.62015L16.2453 7.47823C16.6233 7.10026 16.3556 6.45397 15.8211 6.45397L10.5359 6.45397C10.2597 6.45397 10.0359 6.67783 10.0359 6.95397C10.0359 7.23011 10.2597 7.45397 10.5359 7.45397L14.8554 7.45397L14.3963 7.91305Z" fill="#262E30"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -2,7 +2,7 @@
|
||||
const bundlesById = new Map(); // bundleId -> bundle object
|
||||
const printersByBundle = new Map(); // bundleId -> Map(index -> printerName)
|
||||
const filamentsByBundle = new Map(); // bundleId -> Map(index -> filamentName)
|
||||
const presetsByBundle = new Map(); // bundleId -> Map(index -> presetName)
|
||||
const processesByBundle = new Map(); // bundleId -> Map(index -> presetName)
|
||||
const UPDATE_TOOLTIP = "Update available";
|
||||
const UNAUTHORIZED_TOOLTIP = "Unauthorized bundle";
|
||||
|
||||
@@ -193,7 +193,7 @@ function unpackPayload(payload) {
|
||||
bundlesById.clear();
|
||||
printersByBundle.clear();
|
||||
filamentsByBundle.clear();
|
||||
presetsByBundle.clear();
|
||||
processesByBundle.clear();
|
||||
|
||||
const list = payload?.data || [];
|
||||
for (const bundle of list) {
|
||||
@@ -212,7 +212,7 @@ function unpackPayload(payload) {
|
||||
|
||||
printersByBundle.set(id, new Map((bundle.printers || []).map((name, i) => [i, name])));
|
||||
filamentsByBundle.set(id, new Map((bundle.filaments || []).map((name, i) => [i, name])));
|
||||
presetsByBundle.set(id, new Map((bundle.presets || []).map((name, i) => [i, name])));
|
||||
processesByBundle.set(id, new Map((bundle.processes || []).map((name, i) => [i, name])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,14 +277,14 @@ function renderBottomForBundle(bundleId) {
|
||||
const key = String(bundleId || "");
|
||||
const printers = printersByBundle.get(key) || new Map();
|
||||
const filaments = filamentsByBundle.get(key) || new Map();
|
||||
const presets = presetsByBundle.get(key) || new Map();
|
||||
const processes = processesByBundle.get(key) || new Map();
|
||||
|
||||
// Convert to a flat list of rows { typeLabel, name }
|
||||
const rows = [];
|
||||
|
||||
for (const [, name] of printers) rows.push({ type: "Printer", name });
|
||||
for (const [, name] of filaments) rows.push({ type: "Filament", name });
|
||||
for (const [, name] of presets) rows.push({ type: "Preset", name });
|
||||
for (const [, name] of processes) rows.push({ type: "Process", name });
|
||||
|
||||
bottomList.innerHTML = rows.map((r, idx) => `
|
||||
<div class="row" data-id="${escapeAttr(bundleId)}" data-idx="${idx}">
|
||||
|
||||
@@ -353,7 +353,7 @@ private:
|
||||
// The basic Display. This is almost just an interface but will do all the
|
||||
// initialization and show the fps values. Overriding the render_scene is
|
||||
// needed to show the scene content. The specific method of displaying the
|
||||
// scene is up the the particular implementation (OpenCSG or other screen space
|
||||
// scene is up the particular implementation (OpenCSG or other screen space
|
||||
// boolean algorithms)
|
||||
class Display : public Scene::Listener
|
||||
{
|
||||
|
||||
@@ -45,16 +45,10 @@
|
||||
<color type="primary" scheme_preference="dark">#00695C</color>
|
||||
</branding>
|
||||
<releases>
|
||||
<release version="2.4.1" date="2026-06-26">
|
||||
<url type="details">https://www.orcaslicer.com/wiki/releases/release_2_4_1</url>
|
||||
<release version="2.5.0-dev" date="2026-06-22" type="development">
|
||||
<url type="details">https://github.com/OrcaSlicer/OrcaSlicer/releases/tag/nightly-builds</url>
|
||||
<description>
|
||||
<p>See the release page for detailed changelog of OrcaSlicer 2.4.1 release.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="2.4.0" date="2026-06-20">
|
||||
<url type="details">https://www.orcaslicer.com/wiki/releases/release_2_4_0</url>
|
||||
<description>
|
||||
<p>See the release page for detailed changelog of OrcaSlicer 2.4.0 release.</p>
|
||||
<p>See the release page for detailed changelog.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="2.3.2" date="2025-03-23">
|
||||
|
||||
@@ -16,7 +16,7 @@ build-options:
|
||||
LDFLAGS: "-fuse-ld=lld"
|
||||
finish-args:
|
||||
- --share=ipc
|
||||
- --socket=fallback-x11
|
||||
- --socket=x11
|
||||
- --socket=wayland
|
||||
- --share=network
|
||||
- --device=all
|
||||
|
||||
@@ -23,7 +23,7 @@ if %FULL_MODE%==1 (
|
||||
call :prepareGettextList "%list_file%" "%filtered_list%" "%missing_list%"
|
||||
if "!has_sources!"=="1" (
|
||||
if not exist "%generated_i18n%" mkdir "%generated_i18n%"
|
||||
.\tools\xgettext.exe --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost -f "%filtered_list%" -o "%generated_pot%"
|
||||
.\tools\xgettext.exe --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost --no-wrap -f "%filtered_list%" -o "%generated_pot%"
|
||||
if errorlevel 1 (
|
||||
set "script_exit_code=1"
|
||||
) else (
|
||||
@@ -122,7 +122,7 @@ exit /b %errorlevel%
|
||||
set "lang=%name:OrcaSlicer_=%"
|
||||
if %FULL_MODE%==1 if exist "%pot_file%" (
|
||||
set "merged_file=%TEMP%\orca_gettext_merged_%RANDOM%_%RANDOM%.po"
|
||||
.\tools\msgmerge.exe -N -o "!merged_file!" "%file%" "%pot_file%"
|
||||
.\tools\msgmerge.exe -N --no-wrap -o "!merged_file!" "%file%" "%pot_file%"
|
||||
if errorlevel 1 (
|
||||
if exist "!merged_file!" del "!merged_file!"
|
||||
echo Error encountered with msgmerge command for language !lang!.
|
||||
|
||||
@@ -85,7 +85,7 @@ if $FULL_MODE; then
|
||||
generated_pot_file="${generated_i18n_dir}/OrcaSlicer.pot"
|
||||
|
||||
mkdir -p "$generated_i18n_dir"
|
||||
xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost -f "$filtered_list" -o "$generated_pot_file"
|
||||
xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost --no-wrap -f "$filtered_list" -o "$generated_pot_file"
|
||||
python3 scripts/HintsToPot.py ./resources "$generated_i18n_dir"
|
||||
|
||||
if [ -f "$pot_file" ] && files_equal_ignoring_pot_date "$pot_file" "$generated_pot_file"; then
|
||||
@@ -108,7 +108,7 @@ do
|
||||
if [ -f "$dir/OrcaSlicer_${lang}.po" ]; then
|
||||
if $FULL_MODE && [ -f "$pot_file" ]; then
|
||||
merged_po=$(mktemp)
|
||||
if ! msgmerge -N -o "$merged_po" "$dir/OrcaSlicer_${lang}.po" "$pot_file"; then
|
||||
if ! msgmerge -N --no-wrap -o "$merged_po" "$dir/OrcaSlicer_${lang}.po" "$pot_file"; then
|
||||
echo "Error encountered with msgmerge command for language ${lang}."
|
||||
rm -f "$merged_po"
|
||||
exit 1
|
||||
|
||||
+26
-19
@@ -1267,15 +1267,15 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
// WebKit2GTK accelerated compositing is unreliable on Wayland: we
|
||||
// observed blank/garbled web views (Home/Device) with both NVIDIA
|
||||
// and AMD drivers. Disable it whenever WAYLAND_DISPLAY is set
|
||||
// (covers native Wayland and XWayland); must happen before the first
|
||||
// web view is created. Pure X11 (DISPLAY only, no WAYLAND_DISPLAY)
|
||||
// and the GDK_BACKEND=x11 opt-in path above keep it enabled.
|
||||
// WebKit2GTK compositing can fail under XWayland on older
|
||||
// WebKit releases. Disable it only when both DISPLAY and
|
||||
// WAYLAND_DISPLAY are set (i.e. an XWayland session is in
|
||||
// use). On pure X11 or native Wayland, compositing is left
|
||||
// enabled so WebKit retains HW acceleration.
|
||||
{
|
||||
const char* display_env_wk = ::getenv("DISPLAY");
|
||||
const char* wayland_env_wk = ::getenv("WAYLAND_DISPLAY");
|
||||
if (wayland_env_wk && *wayland_env_wk) {
|
||||
if (display_env_wk && *display_env_wk && wayland_env_wk && *wayland_env_wk) {
|
||||
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /* replace */ false);
|
||||
}
|
||||
}
|
||||
@@ -3865,13 +3865,13 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
|
||||
//travel_acceleration
|
||||
ConfigOptionFloat *travel_acceleration_option = m_print_config.option<ConfigOptionFloat>("travel_acceleration", true);
|
||||
ConfigOptionFloat *default_acceleration_option = m_print_config.option<ConfigOptionFloat>("default_acceleration");
|
||||
travel_acceleration_option->value = default_acceleration_option->value;
|
||||
ConfigOptionFloatsNullable *travel_acceleration_option = m_print_config.option<ConfigOptionFloatsNullable>("travel_acceleration", true);
|
||||
ConfigOptionFloatsNullable *default_acceleration_option = m_print_config.option<ConfigOptionFloatsNullable>("default_acceleration");
|
||||
travel_acceleration_option->values = default_acceleration_option->values;
|
||||
|
||||
ConfigOptionFloat *initial_layer_travel_acceleration_option = m_print_config.option<ConfigOptionFloat>("initial_layer_travel_acceleration", true);
|
||||
ConfigOptionFloat *initial_layer_acceleration_option = m_print_config.option<ConfigOptionFloat>("initial_layer_acceleration");
|
||||
initial_layer_travel_acceleration_option->value = initial_layer_acceleration_option->value;
|
||||
ConfigOptionFloatsNullable *initial_layer_travel_acceleration_option = m_print_config.option<ConfigOptionFloatsNullable>("initial_layer_travel_acceleration", true);
|
||||
ConfigOptionFloatsNullable *initial_layer_acceleration_option = m_print_config.option<ConfigOptionFloatsNullable>("initial_layer_acceleration");
|
||||
initial_layer_travel_acceleration_option->values = initial_layer_acceleration_option->values;
|
||||
}
|
||||
|
||||
auto get_print_sequence = [](Slic3r::GUI::PartPlate* plate, DynamicPrintConfig& print_config, bool &is_seq_print) {
|
||||
@@ -6058,9 +6058,9 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
(dynamic_cast<Print*>(print))->is_BBL_printer() = is_bbl_vendor_preset;
|
||||
|
||||
StringObjectException warning;
|
||||
std::vector<StringObjectException> warnings;
|
||||
print_fff->set_check_multi_filaments_compatibility(!allow_mix_temp);
|
||||
auto err = print->validate(&warning);
|
||||
auto err = print->validate(&warnings);
|
||||
if (!err.string.empty()) {
|
||||
if ((STRING_EXCEPT_LAYER_HEIGHT_EXCEEDS_LIMIT == err.type) && no_check) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "got warnings: "<< err.string << std::endl;
|
||||
@@ -6094,8 +6094,9 @@ int CLI::run(int argc, char **argv)
|
||||
flush_and_exit(validate_error);
|
||||
}
|
||||
}
|
||||
else if (!warning.string.empty()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "got warnings: "<< warning.string << std::endl;
|
||||
else if (!warnings.empty()) {
|
||||
for (const auto& w : warnings)
|
||||
BOOST_LOG_TRIVIAL(warning) << "got warnings: "<< w.string << std::endl;
|
||||
}
|
||||
|
||||
if (print->empty()) {
|
||||
@@ -6115,8 +6116,14 @@ int CLI::run(int argc, char **argv)
|
||||
BOOST_LOG_TRIVIAL(info) << "set print's callback to cli_status_callback.";
|
||||
print->set_status_callback(cli_status_callback);
|
||||
g_cli_callback_mgr.set_plate_info(index+1, (plate_to_slice== 0)?partplate_list.get_plate_count():1);
|
||||
if (!warning.string.empty()) {
|
||||
PrintBase::SlicingStatus slicing_status{4, warning.string, 0, 0};
|
||||
if (!warnings.empty()) {
|
||||
std::string warning_text;
|
||||
for (const auto& w : warnings) {
|
||||
if (!warning_text.empty())
|
||||
warning_text += "\n";
|
||||
warning_text += w.string;
|
||||
}
|
||||
PrintBase::SlicingStatus slicing_status{4, warning_text, 0, 0};
|
||||
cli_status_callback(slicing_status);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Slic3r::Arachne::LinearAlg2D
|
||||
{
|
||||
|
||||
/*!
|
||||
* Returns the determinant of the 2D matrix defined by the the vectors ab and ap as rows.
|
||||
* Returns the determinant of the 2D matrix defined by the vectors ab and ap as rows.
|
||||
*
|
||||
* The returned value is zero for \p p lying (approximately) on the line going through \p a and \p b
|
||||
* The value is positive for values lying to the left and negative for values lying to the right when looking from \p a to \p b.
|
||||
|
||||
@@ -520,7 +520,7 @@ ClipperLib::Paths expolygon_offset(const Slic3r::ExPolygon &expolygon, const flo
|
||||
|
||||
// This is a safe variant of the polygons offset, tailored for multiple ExPolygons.
|
||||
// It is required, that the input expolygons do not overlap and that the holes of each ExPolygon don't intersect with their respective outer contours.
|
||||
// Each ExPolygon is offsetted separately. For outer offset, the the offsetted ExPolygons shall be united outside of this function.
|
||||
// Each ExPolygon is offsetted separately. For outer offset, the offsetted ExPolygons shall be united outside of this function.
|
||||
template<typename ExPolygonVector>
|
||||
static std::pair<ClipperLib::Paths, size_t> expolygons_offset_raw(const ExPolygonVector &expolygons, const float delta, ClipperLib::JoinType joinType, double miterLimit)
|
||||
{
|
||||
|
||||
@@ -685,6 +685,32 @@ bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, con
|
||||
return success;
|
||||
}
|
||||
|
||||
double ConfigBase::get_abs_value_at(const t_config_option_key &opt_key, size_t index) const
|
||||
{
|
||||
const ConfigOption *raw_opt = this->option(opt_key);
|
||||
assert(raw_opt != nullptr);
|
||||
if (raw_opt->type() == coFloats) {
|
||||
return static_cast<const ConfigOptionFloats*>(raw_opt)->get_at(index);
|
||||
}
|
||||
if (raw_opt->type() == coFloatsOrPercents) {
|
||||
const ConfigDef *def = this->def();
|
||||
if (def == nullptr) throw NoDefinitionException(opt_key);
|
||||
const ConfigOptionDef *opt_def = def->get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
|
||||
if (opt_def->ratio_over.empty()) {
|
||||
return 0;
|
||||
} else {
|
||||
const ConfigOption *ratio_opt = this->option(opt_def->ratio_over);
|
||||
assert(ratio_opt->type() == coFloats);
|
||||
const ConfigOptionFloats *ratio_values = static_cast<const ConfigOptionFloats *>(ratio_opt);
|
||||
return static_cast<const ConfigOptionFloatsOrPercents *>(raw_opt)->get_at(index).get_abs_value(ratio_values->get_at(index));
|
||||
}
|
||||
}
|
||||
|
||||
throw ConfigurationError("ConfigBase::get_abs_value_at(): Not a valid option type for get_abs_value_at()");
|
||||
}
|
||||
|
||||
// Return an absolute value of a possibly relative config variable.
|
||||
// For example, return absolute infill extrusion width, either from an absolute value, or relative to the layer height.
|
||||
double ConfigBase::get_abs_value(const t_config_option_key &opt_key) const
|
||||
@@ -1886,6 +1912,39 @@ t_config_option_keys DynamicConfig::equal(const DynamicConfig &other) const
|
||||
return equal;
|
||||
}
|
||||
|
||||
double& DynamicConfig::opt_float(const t_config_option_key &opt_key, unsigned int idx)
|
||||
{
|
||||
if (ConfigOptionFloats *opt_floats = dynamic_cast<ConfigOptionFloats *>(this->option(opt_key))) {
|
||||
return opt_floats->get_at(idx);
|
||||
} else {
|
||||
ConfigOptionFloatsNullable *opt_floats_nullable = dynamic_cast<ConfigOptionFloatsNullable *>(this->option(opt_key));
|
||||
assert(opt_floats_nullable != nullptr);
|
||||
return opt_floats_nullable->get_at(idx);
|
||||
}
|
||||
}
|
||||
const double& DynamicConfig::opt_float(const t_config_option_key &opt_key, unsigned int idx) const
|
||||
{
|
||||
if (const ConfigOptionFloats *opt_floats = dynamic_cast<const ConfigOptionFloats *>(this->option(opt_key))) {
|
||||
return opt_floats->get_at(idx);
|
||||
} else if (const ConfigOptionFloatsNullable *opt_floats_nullable = dynamic_cast<const ConfigOptionFloatsNullable *>(this->option(opt_key))) {
|
||||
return opt_floats_nullable->get_at(idx);
|
||||
} else {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicConfig::opt_bool(const t_config_option_key &opt_key, unsigned int idx) const {
|
||||
if (const ConfigOptionBools *opts = dynamic_cast<const ConfigOptionBools *>(this->option(opt_key))) {
|
||||
return opts->get_at(idx) != 0;
|
||||
}
|
||||
else {
|
||||
const ConfigOptionBoolsNullable *opt_s = dynamic_cast<const ConfigOptionBoolsNullable *>(this->option(opt_key));
|
||||
assert(opt_s != nullptr);
|
||||
return opt_s->get_at(idx) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <cereal/types/polymorphic.hpp>
|
||||
|
||||
@@ -30,8 +30,14 @@
|
||||
namespace Slic3r {
|
||||
struct FloatOrPercent
|
||||
{
|
||||
double value;
|
||||
bool percent;
|
||||
double value = 0;
|
||||
bool percent = false;
|
||||
|
||||
FloatOrPercent() {}
|
||||
FloatOrPercent(double value_, bool percent_) : value(value_), percent(percent_) { }
|
||||
|
||||
double get_abs_value(double ratio_over) const { return this->percent ? (ratio_over * this->value / 100) : this->value; }
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive& ar) { ar(this->value); ar(this->percent); }
|
||||
@@ -2726,6 +2732,7 @@ public:
|
||||
void set_deserialize_strict(std::initializer_list<SetDeserializeItem> items)
|
||||
{ ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable }; this->set_deserialize(items, ctxt); }
|
||||
|
||||
double get_abs_value_at(const t_config_option_key &opt_key, size_t index) const;
|
||||
double get_abs_value(const t_config_option_key &opt_key) const;
|
||||
double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const;
|
||||
void setenv_() const;
|
||||
@@ -2900,13 +2907,17 @@ public:
|
||||
|
||||
double& opt_float(const t_config_option_key &opt_key) { return this->option<ConfigOptionFloat>(opt_key)->value; }
|
||||
const double& opt_float(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionFloat*>(this->option(opt_key))->value; }
|
||||
double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloats>(opt_key)->get_at(idx); }
|
||||
const double& opt_float(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloats*>(this->option(opt_key))->get_at(idx); }
|
||||
double & opt_float(const t_config_option_key &opt_key, unsigned int idx);
|
||||
const double & opt_float(const t_config_option_key &opt_key, unsigned int idx) const;
|
||||
double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloatsNullable>(opt_key)->get_at(idx); }
|
||||
const double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloatsNullable *>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
int& opt_int(const t_config_option_key &opt_key) { return this->option<ConfigOptionInt>(opt_key)->value; }
|
||||
int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionInt*>(this->option(opt_key))->value; }
|
||||
int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionInts>(opt_key)->get_at(idx); }
|
||||
int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
||||
int& opt_int_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionIntsNullable>(opt_key)->get_at(idx);}
|
||||
const int & opt_int_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionIntsNullable*>(this->option(opt_key))->get_at(idx);}
|
||||
|
||||
// In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*.
|
||||
// Thus the virtual method getInt() is used to retrieve the enum value.
|
||||
@@ -2914,9 +2925,13 @@ public:
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return static_cast<ENUM>(this->option(opt_key)->getInt()); }
|
||||
// BBS
|
||||
int opt_enum(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionEnumsGeneric*>(this->option(opt_key))->get_at(idx); }
|
||||
int opt_enum_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionEnumsGenericNullable*>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
|
||||
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const;
|
||||
bool opt_bool_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionBoolsNullable*>(this->option(opt_key))->get_at(idx);}
|
||||
|
||||
|
||||
// Command line processing
|
||||
bool read_cli(int argc, const char* const argv[], t_config_option_keys* extra, t_config_option_keys* keys = nullptr);
|
||||
|
||||
@@ -960,15 +960,15 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
|
||||
params.role_speed = 0;
|
||||
if (params.extrusion_role == erBridgeInfill)
|
||||
params.role_speed = region_config.bridge_speed;
|
||||
params.role_speed = region_config.bridge_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erInternalBridgeInfill)
|
||||
params.role_speed = region_config.get_abs_value("internal_bridge_speed");
|
||||
params.role_speed = region_config.get_abs_value_at("internal_bridge_speed", layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erInternalInfill)
|
||||
params.role_speed = region_config.sparse_infill_speed;
|
||||
params.role_speed = region_config.sparse_infill_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erTopSolidInfill)
|
||||
params.role_speed = region_config.top_surface_speed;
|
||||
params.role_speed = region_config.top_surface_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erSolidInfill)
|
||||
params.role_speed = region_config.internal_solid_infill_speed;
|
||||
params.role_speed = region_config.internal_solid_infill_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
// Calculate flow spacing for infill pattern generation.
|
||||
if (surface.is_solid() || is_bridge) {
|
||||
params.spacing = params.flow.spacing();
|
||||
|
||||
@@ -1025,7 +1025,7 @@ void mark_boundary_segments_touching_infill(
|
||||
#endif // INFILL_DEBUG_OUTPUT
|
||||
|
||||
EdgeGrid::Grid grid;
|
||||
// Make sure that the the grid is big enough for queries against the thick segment.
|
||||
// Make sure that the grid is big enough for queries against the thick segment.
|
||||
grid.set_bbox(boundary_bbox.inflated(distance_colliding * 1.43));
|
||||
// Inflate the bounding box by a thick line width.
|
||||
grid.create(boundary, coord_t(std::max(clip_distance, distance_colliding) + scale_(10.)));
|
||||
|
||||
@@ -2318,7 +2318,7 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
||||
constexpr float const pheromone_evaporation = 0.1f;
|
||||
// Evaporation rate to diversify paths taken by individual ants.
|
||||
constexpr float const pheromone_diversification = 0.1f;
|
||||
// Probability at which to take the next best path. Otherwise take the the path based on the cost distribution.
|
||||
// Probability at which to take the next best path. Otherwise take the path based on the cost distribution.
|
||||
constexpr float const probability_take_best = 0.9f;
|
||||
// Exponents of the cost function.
|
||||
constexpr float const pheromone_alpha = 1.f; // pheromone exponent
|
||||
|
||||
@@ -61,7 +61,7 @@ static inline FlowRole opt_key_to_flow_role(const std::string &opt_key)
|
||||
|
||||
static inline void throw_on_missing_variable(const std::string &opt_key, const char *dependent_opt_key)
|
||||
{
|
||||
throw FlowErrorMissingVariable((boost::format(L("Failed to calculate line width of %1%. Cannot get value of \"%2%\" ")) % opt_key % dependent_opt_key).str());
|
||||
throw FlowErrorMissingVariable((boost::format(L("Failed to calculate line width of %1%. Cannot get value of \u201c%2%\u201d ")) % opt_key % dependent_opt_key).str());
|
||||
}
|
||||
|
||||
// Used to provide hints to the user on default extrusion width values, and to provide reasonable values to the PlaceholderParser.
|
||||
|
||||
+180
-146
@@ -337,7 +337,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
if(retraction_length_remaining <=EPSILON) return {retractionBeforeWipe,0.f};
|
||||
|
||||
// Calculate wipe speed
|
||||
double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed");
|
||||
double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.cur_extruder_index()));
|
||||
wipe_speed = std::max(wipe_speed, 10.0);
|
||||
|
||||
// Process wipe path & calculate wipe path length
|
||||
@@ -429,7 +429,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
|
||||
/* Reduce feedrate a bit; travel speed is often too high to move on existing material.
|
||||
Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */
|
||||
double _wipe_speed = gcodegen.config().get_abs_value("wipe_speed");// gcodegen.writer().config.travel_speed.value * 0.8;
|
||||
double _wipe_speed = gcodegen.config().get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.cur_extruder_index()));// gcodegen.writer().config.travel_speed.value * 0.8;
|
||||
if(gcodegen.config().role_based_wipe_speed)
|
||||
_wipe_speed = gcodegen.writer().get_current_speed() / 60.0;
|
||||
if(_wipe_speed < 10)
|
||||
@@ -515,7 +515,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
outer_wall_line_width = default_line_width == 0.0 ? filament_diameter : default_line_width;
|
||||
}
|
||||
Flow outer_wall_flow = Flow(outer_wall_line_width, config.layer_height, config.nozzle_diameter.get_at(extruder_id));
|
||||
float outer_wall_speed = print.default_region_config().outer_wall_speed.value;
|
||||
float outer_wall_speed = print.default_region_config().outer_wall_speed.get_at(extruder_id);
|
||||
outer_wall_volumetric_speed = outer_wall_speed * outer_wall_flow.mm3_per_mm();
|
||||
if (outer_wall_volumetric_speed > filament_max_volumetric_speed)
|
||||
outer_wall_volumetric_speed = filament_max_volumetric_speed;
|
||||
@@ -781,6 +781,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
if (gcodegen.writer().filament() != nullptr && !filament_end_gcode.empty()) {
|
||||
DynamicConfig config;
|
||||
config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index));
|
||||
config.set_key_value("layer_z", new ConfigOptionFloat(tcr.print_z));
|
||||
if (!gcodegen.m_filament_instances_code.empty()) {
|
||||
end_filament_gcode_str += ("M624 " + gcodegen.m_filament_instances_code + "\n");
|
||||
gcodegen.m_filament_instances_code = "";
|
||||
@@ -1602,6 +1603,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
|
||||
#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.filament()->extruder_id())
|
||||
#define FILAMENT_CONFIG(OPT) m_config.OPT.get_at(m_writer.filament()->id())
|
||||
#define NOZZLE_CONFIG(OPT) m_config.OPT.get_at(cur_extruder_index())
|
||||
|
||||
void GCode::PlaceholderParserIntegration::reset()
|
||||
{
|
||||
@@ -1816,10 +1818,10 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
|
||||
std::string warning;
|
||||
size_t i = 0;
|
||||
for (i = 0; i < std::min(warning_ranges.size(), size_t(5)); ++i)
|
||||
warning += Slic3r::format(_(L("Object can't be printed for empty layer between %1% and %2%.")),
|
||||
warning += Slic3r::format(_(L("The object has empty layers between %1% and %2% and can\u2019t be printed.")),
|
||||
warning_ranges[i].first, warning_ranges[i].second) + "\n";
|
||||
warning += Slic3r::format(_(L("Object: %1%")), object.model_object()->name) + "\n"
|
||||
+ _(L("Maybe parts of the object at these height are too thin, or the object has faulty mesh"));
|
||||
+ _(L("Parts of the object at these heights may be too thin or the object may have a faulty mesh."));
|
||||
|
||||
const_cast<Print*>(object.print())->active_step_add_warning(
|
||||
PrintStateBase::WarningLevel::CRITICAL, warning, PrintStateBase::SlicingEmptyGcodeLayers);
|
||||
@@ -2753,7 +2755,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
}
|
||||
if (initial_extruder_id == static_cast<unsigned int>(-1))
|
||||
// No object to print was found, cancel the G-code export.
|
||||
throw Slic3r::SlicingError(_(L("No object can be printed. Maybe too small")));
|
||||
throw Slic3r::SlicingError(_(L("No object can be printed. It may be too small.")));
|
||||
// We don't allow switching of extruders per layer by Model::custom_gcode_per_print_z in sequential mode.
|
||||
// Use the extruder IDs collected from Regions.
|
||||
this->set_extruders(print.extruders());
|
||||
@@ -2769,7 +2771,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
max_additional_fan = temp_max_additional_fan;
|
||||
if (tool_ordering.all_extruders().empty())
|
||||
// No object to print was found, cancel the G-code export.
|
||||
throw Slic3r::SlicingError(_(L("No object can be printed. Maybe too small")));
|
||||
throw Slic3r::SlicingError(_(L("No object can be printed. It may be too small.")));
|
||||
has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
|
||||
// Orca: support all extruder priming
|
||||
initial_extruder_id = (wipe_tower_type == WipeTowerType::Type2 && has_wipe_tower && !print.config().single_extruder_multi_material_priming) ?
|
||||
@@ -2806,11 +2808,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
|
||||
print.throw_if_canceled();
|
||||
|
||||
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id);
|
||||
|
||||
int extruder_id = get_extruder_id(initial_extruder_id);
|
||||
|
||||
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id, extruder_id);
|
||||
|
||||
// Orca: Initialise AdaptivePA processor filter
|
||||
m_pa_processor = std::make_unique<AdaptivePAProcessor>(*this, tool_ordering.all_extruders());
|
||||
|
||||
@@ -3245,12 +3247,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
if (print.calib_params().mode == CalibMode::Calib_PA_Line) {
|
||||
std::string gcode;
|
||||
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Layer_Change) + "\n";
|
||||
if ((print.default_object_config().outer_wall_acceleration.value > 0 && print.default_object_config().outer_wall_acceleration.value > 0)) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(print.default_object_config().outer_wall_acceleration.value + 0.5));
|
||||
if ((NOZZLE_CONFIG(outer_wall_acceleration) > 0 && NOZZLE_CONFIG(outer_wall_acceleration) > 0)) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(outer_wall_acceleration) + 0.5));
|
||||
}
|
||||
|
||||
if (print.default_object_config().outer_wall_jerk.value > 0) {
|
||||
double jerk = print.default_object_config().outer_wall_jerk.value;
|
||||
if (NOZZLE_CONFIG(outer_wall_jerk) > 0) {
|
||||
double jerk = NOZZLE_CONFIG(outer_wall_jerk);
|
||||
gcode += m_writer.set_jerk_xy(jerk);
|
||||
}
|
||||
|
||||
@@ -3333,8 +3335,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
file.writeln(printing_by_object_gcode);
|
||||
}
|
||||
// Reset the cooling buffer internal state (the current position, feed rate, accelerations).
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id, get_extruder_id(initial_extruder_id));
|
||||
m_cooling_buffer->reset(this->writer().get_position());
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id);
|
||||
// Process all layers of a single object instance (sequential mode) with a parallel pipeline:
|
||||
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
||||
// and export G-code into file.
|
||||
@@ -3645,6 +3647,13 @@ void GCode::check_placeholder_parser_failed()
|
||||
}
|
||||
}
|
||||
|
||||
size_t GCode::cur_extruder_index() const
|
||||
{
|
||||
//TODO: check if the function is duplicated
|
||||
//just return m_writer.filament()->extruder_id()
|
||||
return get_extruder_id(m_writer.filament()->id());
|
||||
}
|
||||
|
||||
size_t GCode::get_extruder_id(unsigned int filament_id) const
|
||||
{
|
||||
if (m_print) {
|
||||
@@ -3940,51 +3949,75 @@ void GCode::print_machine_envelope(GCodeOutputStream &file, Print &print)
|
||||
const auto flavor = print.config().gcode_flavor.value;
|
||||
if ((flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware || flavor == gcfRepRapFirmware) &&
|
||||
print.config().emit_machine_limits_to_gcode.value == true) {
|
||||
|
||||
// Get all physical tool ids current print will use
|
||||
std::unordered_set<unsigned int> used_extruders;
|
||||
for (const auto& extruder : m_writer.extruders()) {
|
||||
used_extruders.insert(extruder.extruder_id());
|
||||
}
|
||||
|
||||
// Get the max limit value among used extruders
|
||||
auto get_max_value = [&used_extruders](const std::string key, const ConfigOptionFloats& v) {
|
||||
unsigned int stride = 1;
|
||||
if (printer_options_with_variant_2.count(key) > 0) {
|
||||
stride = 2;
|
||||
}
|
||||
|
||||
double value = std::numeric_limits<double>::lowest();
|
||||
for (unsigned int extruder : used_extruders) {
|
||||
value = std::max(value, v.values[extruder * stride]);
|
||||
}
|
||||
|
||||
assert(value > std::numeric_limits<double>::lowest());
|
||||
return value;
|
||||
};
|
||||
#define MAX_LIMIT(OPT) get_max_value(#OPT, print.config().OPT)
|
||||
|
||||
int factor = flavor == gcfRepRapFirmware ? 60 : 1; // RRF M203 and M566 are in mm/min
|
||||
file.write_format("M201 X%d Y%d Z%d E%d\n",
|
||||
int(print.config().machine_max_acceleration_x.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_y.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_z.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_e.values.front() + 0.5));
|
||||
int(MAX_LIMIT(machine_max_acceleration_x) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_y) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_z) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_e) + 0.5));
|
||||
file.write_format("M203 X%d Y%d Z%d E%d\n",
|
||||
int(print.config().machine_max_speed_x.values.front() * factor + 0.5),
|
||||
int(print.config().machine_max_speed_y.values.front() * factor + 0.5),
|
||||
int(print.config().machine_max_speed_z.values.front() * factor + 0.5),
|
||||
int(print.config().machine_max_speed_e.values.front() * factor + 0.5));
|
||||
int(MAX_LIMIT(machine_max_speed_x) * factor + 0.5),
|
||||
int(MAX_LIMIT(machine_max_speed_y) * factor + 0.5),
|
||||
int(MAX_LIMIT(machine_max_speed_z) * factor + 0.5),
|
||||
int(MAX_LIMIT(machine_max_speed_e) * factor + 0.5));
|
||||
|
||||
// Now M204 - acceleration. This one is quite hairy thanks to how Marlin guys care about
|
||||
// Legacy Marlin should export travel acceleration the same as printing acceleration.
|
||||
// MarlinFirmware has the two separated.
|
||||
int travel_acc = flavor == gcfMarlinLegacy
|
||||
? int(print.config().machine_max_acceleration_extruding.values.front() + 0.5)
|
||||
: int(print.config().machine_max_acceleration_travel.values.front() + 0.5);
|
||||
? int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5)
|
||||
: int(MAX_LIMIT(machine_max_acceleration_travel) + 0.5);
|
||||
if (flavor == gcfRepRapFirmware)
|
||||
file.write_format("M204 P%d T%d ; sets acceleration (P, T), mm/sec^2\n",
|
||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5),
|
||||
travel_acc);
|
||||
else if (flavor == gcfMarlinFirmware)
|
||||
// New Marlin uses M204 P[print] R[retract] T[travel]
|
||||
file.write_format("M204 P%d R%d T%d ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2\n",
|
||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_retracting.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_travel.values.front() + 0.5));
|
||||
int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_retracting) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_travel) + 0.5));
|
||||
else
|
||||
file.write_format("M204 P%d R%d T%d\n",
|
||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_retracting.values.front() + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_retracting) + 0.5),
|
||||
travel_acc);
|
||||
|
||||
assert(is_decimal_separator_point());
|
||||
file.write_format(flavor == gcfRepRapFirmware
|
||||
? "M566 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/min\n"
|
||||
: "M205 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/sec\n",
|
||||
print.config().machine_max_jerk_x.values.front() * factor,
|
||||
print.config().machine_max_jerk_y.values.front() * factor,
|
||||
print.config().machine_max_jerk_z.values.front() * factor,
|
||||
print.config().machine_max_jerk_e.values.front() * factor);
|
||||
MAX_LIMIT(machine_max_jerk_x) * factor,
|
||||
MAX_LIMIT(machine_max_jerk_y) * factor,
|
||||
MAX_LIMIT(machine_max_jerk_z) * factor,
|
||||
MAX_LIMIT(machine_max_jerk_e) * factor);
|
||||
|
||||
// New Marlin uses M205 J[mm] for junction deviation (only apply if it is > 0)
|
||||
file.write_format(writer().set_junction_deviation(config().machine_max_junction_deviation.values.front()).c_str());
|
||||
file.write_format(writer().set_junction_deviation(MAX_LIMIT(machine_max_junction_deviation)).c_str());
|
||||
|
||||
// Orca: Override input shaping values
|
||||
if (print.config().input_shaping_emit.value && flavor != gcfMarlinLegacy) {
|
||||
@@ -3997,6 +4030,7 @@ void GCode::print_machine_envelope(GCodeOutputStream &file, Print &print)
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef MAX_LIMIT
|
||||
}
|
||||
|
||||
// BBS
|
||||
@@ -4434,10 +4468,10 @@ std::string GCode::generate_skirt(const Print &print,
|
||||
if (first_layer && i==loops.first) {
|
||||
//set skirt start point location
|
||||
const Point desired_start_point = Skirt::find_start_point(loop, skirt_start_angle);
|
||||
gcode += this->extrude_loop(loop, "skirt", m_config.support_speed.value, {}, &desired_start_point);
|
||||
gcode += this->extrude_loop(loop, "skirt", NOZZLE_CONFIG(support_speed), {}, &desired_start_point);
|
||||
}
|
||||
else
|
||||
gcode += this->extrude_loop(loop, "skirt", m_config.support_speed.value);
|
||||
gcode += this->extrude_loop(loop, "skirt", NOZZLE_CONFIG(support_speed));
|
||||
|
||||
// If we only want a single wall on non-first layers, break now
|
||||
if (!first_layer && print.m_config.single_loop_draft_shield) {
|
||||
@@ -4499,7 +4533,7 @@ std::string GCode::generate_object_brim(const Print &print, const PrintObject &o
|
||||
m_avoid_crossing_perimeters.use_external_mp();
|
||||
for (const ExtrusionEntity* ee : brim.entities)
|
||||
if (ee != nullptr)
|
||||
gcode += this->extrude_entity(*ee, "brim", m_config.support_speed.value);
|
||||
gcode += this->extrude_entity(*ee, "brim", NOZZLE_CONFIG(support_speed));
|
||||
m_avoid_crossing_perimeters.use_external_mp(false);
|
||||
m_avoid_crossing_perimeters.disable_once();
|
||||
for (ObjectID object_id : object_ids)
|
||||
@@ -4698,12 +4732,12 @@ LayerResult GCode::process_layer(
|
||||
}
|
||||
case CalibMode::Calib_VFA_Tower: {
|
||||
auto _speed = print.calib_params().start + std::floor(print_z / 5.0) * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({std::round(_speed)}));
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_Vol_speed_Tower: {
|
||||
auto _speed = print.calib_params().start + print_z * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({std::round(_speed)}));
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_Retraction_tower: {
|
||||
@@ -4760,16 +4794,16 @@ LayerResult GCode::process_layer(
|
||||
//BBS
|
||||
if (first_layer) {
|
||||
// Orca: we don't need to optimize the Klipper as only set once
|
||||
if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.initial_layer_acceleration.value + 0.5));
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0 && NOZZLE_CONFIG(initial_layer_acceleration) > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(initial_layer_acceleration) + 0.5));
|
||||
}
|
||||
|
||||
if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) {
|
||||
gcode += m_writer.set_jerk_xy(m_config.initial_layer_jerk.value);
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0 && NOZZLE_CONFIG(initial_layer_jerk) > 0) {
|
||||
gcode += m_writer.set_jerk_xy(NOZZLE_CONFIG(initial_layer_jerk));
|
||||
}
|
||||
|
||||
if (m_writer.get_gcode_flavor() == gcfMarlinFirmware && m_config.default_junction_deviation.value > 0) {
|
||||
gcode += m_writer.set_junction_deviation(m_config.default_junction_deviation.value);
|
||||
if (m_writer.get_gcode_flavor() == gcfMarlinFirmware && NOZZLE_CONFIG(default_junction_deviation) > 0) {
|
||||
gcode += m_writer.set_junction_deviation(NOZZLE_CONFIG(default_junction_deviation));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4790,12 +4824,12 @@ LayerResult GCode::process_layer(
|
||||
}
|
||||
// Reset acceleration at sencond layer
|
||||
// Orca: only set once, don't need to call set_accel_and_jerk
|
||||
if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int) floor(m_config.default_acceleration.value + 0.5));
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0 && NOZZLE_CONFIG(initial_layer_acceleration) > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int) floor(NOZZLE_CONFIG(default_acceleration) + 0.5));
|
||||
}
|
||||
|
||||
if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) {
|
||||
gcode += m_writer.set_jerk_xy(m_config.default_jerk.value);
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0 && NOZZLE_CONFIG(initial_layer_jerk) > 0) {
|
||||
gcode += m_writer.set_jerk_xy(NOZZLE_CONFIG(default_jerk));
|
||||
}
|
||||
|
||||
// Transition from 1st to 2nd layer. Adjust nozzle temperatures as prescribed by the nozzle dependent
|
||||
@@ -4850,8 +4884,8 @@ LayerResult GCode::process_layer(
|
||||
for (const auto &layer_to_print : layers) {
|
||||
if (layer_to_print.object_layer) {
|
||||
const auto& regions = layer_to_print.object_layer->regions();
|
||||
const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [](const LayerRegion* r) {
|
||||
return r->has_extrusions() && r->region().config().enable_overhang_speed;
|
||||
const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [this](const LayerRegion* r) {
|
||||
return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(cur_extruder_index());
|
||||
});
|
||||
if (enable_overhang_speed) {
|
||||
m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.original_object,
|
||||
@@ -5391,7 +5425,7 @@ LayerResult GCode::process_layer(
|
||||
this->set_origin(0., 0.);
|
||||
m_avoid_crossing_perimeters.use_external_mp();
|
||||
for (const ExtrusionEntity* ee : print.m_supportBrimMap.at(instance_to_print.print_object.id()).entities) {
|
||||
gcode += this->extrude_entity(*ee, "brim", m_config.support_speed.value);
|
||||
gcode += this->extrude_entity(*ee, "brim", NOZZLE_CONFIG(support_speed));
|
||||
}
|
||||
m_avoid_crossing_perimeters.use_external_mp(false);
|
||||
// Allow a straight travel move to the first object point.
|
||||
@@ -5805,11 +5839,11 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
|
||||
|
||||
// SoftFever: check loop lenght for small perimeter.
|
||||
double small_peri_speed = -1;
|
||||
if (speed == -1 && loop.length() <= SMALL_PERIMETER_LENGTH(m_config.small_perimeter_threshold.value)) {
|
||||
if(m_config.small_perimeter_speed == 0)
|
||||
small_peri_speed = m_config.outer_wall_speed * 0.5;
|
||||
if (speed == -1 && loop.length() <= SMALL_PERIMETER_LENGTH(NOZZLE_CONFIG(small_perimeter_threshold))) {
|
||||
if(NOZZLE_CONFIG(small_perimeter_speed).value == 0)
|
||||
small_peri_speed = NOZZLE_CONFIG(outer_wall_speed) * 0.5;
|
||||
else
|
||||
small_peri_speed = m_config.small_perimeter_speed.get_abs_value(m_config.outer_wall_speed);
|
||||
small_peri_speed = NOZZLE_CONFIG(small_perimeter_speed).get_abs_value(NOZZLE_CONFIG(outer_wall_speed));
|
||||
}
|
||||
|
||||
// extrude along the path
|
||||
@@ -6199,8 +6233,8 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
|
||||
if (!support_fills.no_sort)
|
||||
chain_and_reorder_extrusion_entities(extrusions, m_last_pos.to_point());
|
||||
|
||||
const double support_speed = m_config.support_speed.value;
|
||||
const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
//const double support_speed = m_config.support_speed.value;
|
||||
//const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
for (const ExtrusionEntity *ee : extrusions) {
|
||||
ExtrusionRole role = ee->role();
|
||||
assert(role == erSupportMaterial || role == erSupportMaterialInterface || role == erSupportTransition || role == erIroning);
|
||||
@@ -6411,47 +6445,47 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
unsigned int acceleration_i = 0;
|
||||
double jerk = 0;
|
||||
// adjust acceleration
|
||||
if (m_config.default_acceleration.value > 0) {
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0) {
|
||||
double acceleration;
|
||||
if (this->on_first_layer() && m_config.initial_layer_acceleration.value > 0) {
|
||||
acceleration = m_config.initial_layer_acceleration.value;
|
||||
if (this->on_first_layer() && NOZZLE_CONFIG(initial_layer_acceleration) > 0) {
|
||||
acceleration = NOZZLE_CONFIG(initial_layer_acceleration);
|
||||
#if 0
|
||||
} else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) {
|
||||
acceleration = m_config.first_layer_acceleration_over_raft.value;
|
||||
#endif
|
||||
} else if (m_config.get_abs_value("bridge_acceleration") > 0 && is_bridge(path.role())) {
|
||||
acceleration = m_config.get_abs_value("bridge_acceleration");
|
||||
} else if (m_config.get_abs_value("sparse_infill_acceleration") > 0 && (path.role() == erInternalInfill)) {
|
||||
acceleration = m_config.get_abs_value("sparse_infill_acceleration");
|
||||
} else if (m_config.get_abs_value("internal_solid_infill_acceleration") > 0 && (path.role() == erSolidInfill)) {
|
||||
acceleration = m_config.get_abs_value("internal_solid_infill_acceleration");
|
||||
} else if (m_config.outer_wall_acceleration.value > 0 && is_external_perimeter(path.role())) {
|
||||
acceleration = m_config.outer_wall_acceleration.value;
|
||||
} else if (m_config.inner_wall_acceleration.value > 0 && is_internal_perimeter(path.role())) {
|
||||
acceleration = m_config.inner_wall_acceleration.value;
|
||||
} else if (m_config.top_surface_acceleration.value > 0 && is_top_surface(path.role())) {
|
||||
acceleration = m_config.top_surface_acceleration.value;
|
||||
} else if (m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index()) > 0 && is_bridge(path.role())) {
|
||||
acceleration = m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index());
|
||||
} else if (m_config.get_abs_value_at("sparse_infill_acceleration", cur_extruder_index()) > 0 && (path.role() == erInternalInfill)) {
|
||||
acceleration = m_config.get_abs_value_at("sparse_infill_acceleration", cur_extruder_index());
|
||||
} else if (m_config.get_abs_value_at("internal_solid_infill_acceleration", cur_extruder_index()) > 0 && (path.role() == erSolidInfill)) {
|
||||
acceleration = m_config.get_abs_value_at("internal_solid_infill_acceleration", cur_extruder_index());
|
||||
} else if (NOZZLE_CONFIG(outer_wall_acceleration) > 0 && is_external_perimeter(path.role())) {
|
||||
acceleration = NOZZLE_CONFIG(outer_wall_acceleration);
|
||||
} else if (NOZZLE_CONFIG(inner_wall_acceleration) > 0 && is_internal_perimeter(path.role())) {
|
||||
acceleration = NOZZLE_CONFIG(inner_wall_acceleration);
|
||||
} else if (NOZZLE_CONFIG(top_surface_acceleration) > 0 && is_top_surface(path.role())) {
|
||||
acceleration = NOZZLE_CONFIG(top_surface_acceleration);
|
||||
} else {
|
||||
acceleration = m_config.default_acceleration.value;
|
||||
acceleration = NOZZLE_CONFIG(default_acceleration);
|
||||
}
|
||||
acceleration_i = (unsigned int)floor(acceleration + 0.5);
|
||||
}
|
||||
|
||||
// adjust X Y jerk
|
||||
if (m_config.default_jerk.value > 0) {
|
||||
if (this->on_first_layer() && m_config.initial_layer_jerk.value > 0) {
|
||||
jerk = m_config.initial_layer_jerk.value;
|
||||
} else if (m_config.outer_wall_jerk.value > 0 && is_external_perimeter(path.role())) {
|
||||
jerk = m_config.outer_wall_jerk.value;
|
||||
} else if (m_config.inner_wall_jerk.value > 0 && is_internal_perimeter(path.role())) {
|
||||
jerk = m_config.inner_wall_jerk.value;
|
||||
} else if (m_config.top_surface_jerk.value > 0 && is_top_surface(path.role())) {
|
||||
jerk = m_config.top_surface_jerk.value;
|
||||
} else if (m_config.infill_jerk.value > 0 && is_infill(path.role())) {
|
||||
jerk = m_config.infill_jerk.value;
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0) {
|
||||
if (this->on_first_layer() && NOZZLE_CONFIG(initial_layer_jerk) > 0) {
|
||||
jerk = NOZZLE_CONFIG(initial_layer_jerk);
|
||||
} else if (NOZZLE_CONFIG(outer_wall_jerk) > 0 && is_external_perimeter(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(outer_wall_jerk);
|
||||
} else if (NOZZLE_CONFIG(inner_wall_jerk) > 0 && is_internal_perimeter(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(inner_wall_jerk);
|
||||
} else if (NOZZLE_CONFIG(top_surface_jerk) > 0 && is_top_surface(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(top_surface_jerk);
|
||||
} else if (NOZZLE_CONFIG(infill_jerk) > 0 && is_infill(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(infill_jerk);
|
||||
}
|
||||
else {
|
||||
jerk = m_config.default_jerk.value;
|
||||
jerk = NOZZLE_CONFIG(default_jerk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6514,37 +6548,37 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
// set speed
|
||||
if (speed == -1) {
|
||||
if (path.role() == erPerimeter) {
|
||||
speed = m_config.get_abs_value("inner_wall_speed");
|
||||
speed = NOZZLE_CONFIG(inner_wall_speed);
|
||||
if (sloped) {
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("inner_wall_speed")));
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(speed));
|
||||
}
|
||||
} else if (path.role() == erExternalPerimeter) {
|
||||
speed = m_config.get_abs_value("outer_wall_speed");
|
||||
speed = NOZZLE_CONFIG(outer_wall_speed);
|
||||
if (sloped) {
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("outer_wall_speed")));
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(speed));
|
||||
}
|
||||
}
|
||||
else if(path.role() == erInternalBridgeInfill) {
|
||||
speed = m_config.get_abs_value("internal_bridge_speed");
|
||||
speed = m_config.get_abs_value_at("internal_bridge_speed", cur_extruder_index());
|
||||
} else if (path.role() == erOverhangPerimeter || path.role() == erSupportTransition || path.role() == erBridgeInfill) {
|
||||
speed = m_config.get_abs_value("bridge_speed");
|
||||
speed = NOZZLE_CONFIG(bridge_speed);
|
||||
} else if (path.role() == erInternalInfill) {
|
||||
speed = m_config.get_abs_value("sparse_infill_speed");
|
||||
speed = NOZZLE_CONFIG(sparse_infill_speed);
|
||||
} else if (path.role() == erSolidInfill) {
|
||||
speed = m_config.get_abs_value("internal_solid_infill_speed");
|
||||
speed = NOZZLE_CONFIG(internal_solid_infill_speed);
|
||||
} else if (path.role() == erTopSolidInfill) {
|
||||
speed = m_config.get_abs_value("top_surface_speed");
|
||||
speed = NOZZLE_CONFIG(top_surface_speed);
|
||||
} else if (path.role() == erIroning) {
|
||||
speed = m_config.get_abs_value("ironing_speed");
|
||||
} else if (path.role() == erBottomSurface) {
|
||||
speed = m_config.get_abs_value("initial_layer_infill_speed");
|
||||
speed = NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
} else if (path.role() == erGapFill) {
|
||||
speed = m_config.get_abs_value("gap_infill_speed");
|
||||
speed = NOZZLE_CONFIG(gap_infill_speed);
|
||||
}
|
||||
else if (path.role() == erSupportMaterial ||
|
||||
path.role() == erSupportMaterialInterface) {
|
||||
const double support_speed = m_config.support_speed.value;
|
||||
const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
const double support_speed = NOZZLE_CONFIG(support_speed);
|
||||
const double support_interface_speed = NOZZLE_CONFIG(support_interface_speed);
|
||||
speed = (path.role() == erSupportMaterial) ? support_speed : support_interface_speed;
|
||||
} else {
|
||||
throw Slic3r::InvalidArgument("Invalid speed");
|
||||
@@ -6565,16 +6599,16 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
//BBS: for solid infill of first layer, speed can be higher as long as
|
||||
//wall lines have be attached
|
||||
if (path.role() != erBottomSurface) {
|
||||
speed = is_perimeter(path.role()) ? m_config.get_abs_value("initial_layer_speed") :
|
||||
m_config.get_abs_value("initial_layer_infill_speed");
|
||||
speed = is_perimeter(path.role()) ? NOZZLE_CONFIG(initial_layer_speed) :
|
||||
NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
}
|
||||
} else if (m_config.slow_down_layers > 1 && m_config.raft_layers == 0) {
|
||||
|
||||
if (_layer > 0 && _layer < m_config.slow_down_layers) {
|
||||
const auto first_layer_speed =
|
||||
is_perimeter(path.role())
|
||||
? m_config.get_abs_value("initial_layer_speed")
|
||||
: m_config.get_abs_value("initial_layer_infill_speed");
|
||||
? NOZZLE_CONFIG(initial_layer_speed)
|
||||
: NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
if (first_layer_speed < speed) {
|
||||
speed = std::min(
|
||||
speed,
|
||||
@@ -6586,8 +6620,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
|
||||
if (_layer > m_config.raft_layers && (_layer - m_config.raft_layers) < m_config.slow_down_layers) {
|
||||
const auto first_layer_speed
|
||||
= is_perimeter(path.role()) ? m_config.get_abs_value("initial_layer_speed") :
|
||||
m_config.get_abs_value("initial_layer_infill_speed");
|
||||
= is_perimeter(path.role()) ? NOZZLE_CONFIG(initial_layer_speed) :
|
||||
NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
if (first_layer_speed < speed) {
|
||||
speed = std::min(speed, Slic3r::lerp(first_layer_speed, speed,
|
||||
(double) (_layer - m_config.raft_layers) / m_config.slow_down_layers));
|
||||
@@ -6653,10 +6687,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
bool variable_speed = false;
|
||||
std::vector<ProcessedPoint> new_points {};
|
||||
|
||||
if (m_config.enable_overhang_speed && !this->on_first_layer() && !object_layer_over_raft() &&
|
||||
if (NOZZLE_CONFIG(enable_overhang_speed) && !this->on_first_layer() && !object_layer_over_raft() &&
|
||||
(is_bridge(path.role()) || is_perimeter(path.role()))) {
|
||||
bool is_external = is_external_perimeter(path.role());
|
||||
double ref_speed = is_external ? m_config.get_abs_value("outer_wall_speed") : m_config.get_abs_value("inner_wall_speed");
|
||||
double ref_speed = is_external ? NOZZLE_CONFIG(outer_wall_speed) : NOZZLE_CONFIG(inner_wall_speed);
|
||||
if (ref_speed == 0)
|
||||
ref_speed = FILAMENT_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm;
|
||||
|
||||
@@ -6669,46 +6703,46 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
|
||||
ConfigOptionPercents overhang_overlap_levels({90, 75, 50, 25, 13, 0});
|
||||
|
||||
if (m_config.slowdown_for_curled_perimeters){
|
||||
if (NOZZLE_CONFIG(slowdown_for_curled_perimeters)){
|
||||
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
||||
{FloatOrPercent{100, true},
|
||||
(m_config.get_abs_value("overhang_1_4_speed", ref_speed) < 0.5) ?
|
||||
(NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_1_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_2_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_2_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_3_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_3_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_4_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_4_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_4_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_4_4_speed", ref_speed) * 100 / ref_speed, true}});
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true}});
|
||||
|
||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
||||
ref_speed, speed, m_config.slowdown_for_curled_perimeters);
|
||||
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters));
|
||||
}else{
|
||||
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
||||
{FloatOrPercent{100, true},
|
||||
(m_config.get_abs_value("overhang_1_4_speed", ref_speed) < 0.5) ?
|
||||
(NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_1_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_2_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_2_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_3_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_3_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_4_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_4_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
FloatOrPercent{m_config.get_abs_value("bridge_speed") * 100 / ref_speed, true}});
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
FloatOrPercent{NOZZLE_CONFIG(bridge_speed) * 100 / ref_speed, true}});
|
||||
|
||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
||||
ref_speed, speed, m_config.slowdown_for_curled_perimeters);
|
||||
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters));
|
||||
}
|
||||
variable_speed = std::any_of(new_points.begin(), new_points.end(),
|
||||
[speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > 1; }); // Ignore small speed variations (under 1mm/sec)
|
||||
@@ -7367,40 +7401,40 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
|
||||
unsigned int acceleration_to_set = 0;
|
||||
|
||||
if (this->on_first_layer()) {
|
||||
unsigned int initial_layer_travel_acceleration = m_config.get_abs_value("initial_layer_travel_acceleration");
|
||||
double initial_layer_travel_jerk = m_config.get_abs_value("initial_layer_travel_jerk");
|
||||
unsigned int initial_layer_travel_acceleration = m_config.get_abs_value_at("initial_layer_travel_acceleration", cur_extruder_index());
|
||||
double initial_layer_travel_jerk = m_config.get_abs_value_at("initial_layer_travel_jerk", cur_extruder_index());
|
||||
|
||||
if (m_config.default_acceleration.value > 0 && initial_layer_travel_acceleration > 0) {
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0 && initial_layer_travel_acceleration > 0) {
|
||||
acceleration_to_set = (unsigned int) floor(initial_layer_travel_acceleration + 0.5);
|
||||
}
|
||||
if (m_config.default_jerk.value > 0 && initial_layer_travel_jerk > 0) {
|
||||
if (NOZZLE_CONFIG(default_jerk)> 0 && initial_layer_travel_jerk > 0) {
|
||||
jerk_to_set = initial_layer_travel_jerk;
|
||||
}
|
||||
} else { // ORCA: Handle short-travel acceleration and jerk for outer perimeters (if applicable)
|
||||
const bool is_short_travel = travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel));
|
||||
|
||||
if (m_config.default_acceleration.value > 0) {
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0) {
|
||||
if (role == erOverhangPerimeter && is_short_travel) {
|
||||
const double bridge_acceleration = m_config.get_abs_value("bridge_acceleration");
|
||||
const double bridge_acceleration = m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index());
|
||||
|
||||
if (bridge_acceleration > 0)
|
||||
acceleration_to_set = (unsigned int) floor(bridge_acceleration + 0.5);
|
||||
} else if (role == erExternalPerimeter && is_short_travel) {
|
||||
if (m_config.outer_wall_acceleration.value > 0)
|
||||
acceleration_to_set = (unsigned int) floor(m_config.outer_wall_acceleration.value + 0.5);
|
||||
if (NOZZLE_CONFIG(outer_wall_acceleration) > 0)
|
||||
acceleration_to_set = (unsigned int) floor(NOZZLE_CONFIG(outer_wall_acceleration) + 0.5);
|
||||
} else {
|
||||
if (m_config.travel_acceleration.value > 0)
|
||||
acceleration_to_set = (unsigned int) floor(m_config.travel_acceleration.value + 0.5);
|
||||
if (NOZZLE_CONFIG(travel_acceleration) > 0)
|
||||
acceleration_to_set = (unsigned int) floor(NOZZLE_CONFIG(travel_acceleration) + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_config.default_jerk.value > 0) {
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0) {
|
||||
if ((role == erExternalPerimeter || role == erOverhangPerimeter) && is_short_travel) {
|
||||
if (m_config.outer_wall_jerk.value > 0)
|
||||
jerk_to_set = m_config.outer_wall_jerk.value;
|
||||
if (NOZZLE_CONFIG(outer_wall_jerk) > 0)
|
||||
jerk_to_set = NOZZLE_CONFIG(outer_wall_jerk);
|
||||
} else {
|
||||
if (m_config.travel_jerk.value > 0)
|
||||
jerk_to_set = m_config.travel_jerk.value;
|
||||
if (NOZZLE_CONFIG(travel_jerk) > 0)
|
||||
jerk_to_set = NOZZLE_CONFIG(travel_jerk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,6 +392,7 @@ private:
|
||||
|
||||
//BBS
|
||||
void check_placeholder_parser_failed();
|
||||
size_t cur_extruder_index() const;
|
||||
size_t get_extruder_id(unsigned int filament_id) const;
|
||||
|
||||
void set_last_pos(const Point &pos) { m_last_pos = Point3(pos, 0); m_last_pos_defined = true; }
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cctype>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -282,4 +283,81 @@ std::string AdaptivePAProcessor::process_layer(std::string &&gcode) {
|
||||
return output.str();
|
||||
}
|
||||
|
||||
std::string AdaptivePAProcessor::validate_adaptive_pa_model(const std::string& model_str)
|
||||
{
|
||||
if (model_str.empty())
|
||||
return {}; // Empty model is valid
|
||||
|
||||
std::istringstream model_stream(model_str);
|
||||
std::string line;
|
||||
int line_number = 0;
|
||||
|
||||
while (std::getline(model_stream, line)) {
|
||||
++line_number;
|
||||
|
||||
// Trim whitespace
|
||||
const auto first = line.find_first_not_of(" \t\r\n");
|
||||
if (first == std::string::npos)
|
||||
continue; // Skip empty lines
|
||||
|
||||
const auto last = line.find_last_not_of(" \t\r\n");
|
||||
line = line.substr(first, last - first + 1);
|
||||
|
||||
// Only numbers, commas and dots are allowed (no letters or other characters)
|
||||
for (char c : line) {
|
||||
if (!std::isdigit(static_cast<unsigned char>(c)) && c != ',' && c != '.') {
|
||||
return "Line " + std::to_string(line_number) +
|
||||
": only numbers, commas and dots are allowed";
|
||||
}
|
||||
}
|
||||
|
||||
// Count commas to validate format (should be exactly 2 for 3 values)
|
||||
int comma_count = 0;
|
||||
for (char c : line) {
|
||||
if (c == ',') comma_count++;
|
||||
}
|
||||
|
||||
if (comma_count != 2) {
|
||||
return "Line " + std::to_string(line_number) +
|
||||
": must contain exactly 3 comma-separated values (PA, flow, acceleration)";
|
||||
}
|
||||
|
||||
// Parse and validate the values
|
||||
try {
|
||||
std::istringstream line_stream(line);
|
||||
std::string value;
|
||||
|
||||
// Parse PA
|
||||
if (!std::getline(line_stream, value, ','))
|
||||
return "Line " + std::to_string(line_number) + ": missing PA value";
|
||||
double pa = std::stod(value);
|
||||
|
||||
// Parse flow
|
||||
if (!std::getline(line_stream, value, ','))
|
||||
return "Line " + std::to_string(line_number) + ": missing flow value";
|
||||
double flow = std::stod(value);
|
||||
|
||||
// Parse acceleration
|
||||
if (!std::getline(line_stream, value, ','))
|
||||
return "Line " + std::to_string(line_number) + ": missing acceleration value";
|
||||
double accel = std::stod(value);
|
||||
|
||||
// Validate constraints
|
||||
if (pa >= 2.0) {
|
||||
return "Line " + std::to_string(line_number) + ": PA value must be less than 2";
|
||||
}
|
||||
if (flow <= pa) {
|
||||
return "Line " + std::to_string(line_number) + ": flow value must be greater than PA value";
|
||||
}
|
||||
if (accel <= flow) {
|
||||
return "Line " + std::to_string(line_number) + ": acceleration value must be greater than flow value";
|
||||
}
|
||||
} catch (const std::exception&) {
|
||||
return "Line " + std::to_string(line_number) + ": invalid numeric value";
|
||||
}
|
||||
}
|
||||
|
||||
return {}; // All validations passed
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
@@ -54,6 +54,20 @@ public:
|
||||
*/
|
||||
void resetPreviousPA(double PA){ m_last_predicted_pa = PA; };
|
||||
|
||||
/**
|
||||
* @brief Validates an adaptive pressure advance model string.
|
||||
*
|
||||
* Checks that:
|
||||
* - Each non-empty line has exactly 3 comma-separated values (PA, flow, accel)
|
||||
* - PA value is less than 2
|
||||
* - Flow value is greater than PA value
|
||||
* - Accel value is greater than flow value
|
||||
*
|
||||
* @param model_str The model string to validate (typically from config)
|
||||
* @return Empty string if valid, or an error message describing the first issue found
|
||||
*/
|
||||
static std::string validate_adaptive_pa_model(const std::string& model_str);
|
||||
|
||||
private:
|
||||
GCode &m_gcodegen; ///< Reference to the GCode object.
|
||||
std::unordered_map<unsigned int, std::unique_ptr<AdaptivePAInterpolator>> m_AdaptivePAInterpolators; ///< Map between Interpolator objects and tool ID's
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0)
|
||||
CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0), m_current_nozzle(0)
|
||||
{
|
||||
this->reset(gcodegen.writer().get_position());
|
||||
|
||||
@@ -37,7 +37,7 @@ void CoolingBuffer::reset(const Vec3d &position)
|
||||
m_current_pos[0] = float(position.x());
|
||||
m_current_pos[1] = float(position.y());
|
||||
m_current_pos[2] = float(position.z());
|
||||
m_current_pos[4] = float(m_config.travel_speed.value);
|
||||
m_current_pos[4] = float(m_config.travel_speed.get_at(m_current_nozzle));
|
||||
m_fan_speed = -1;
|
||||
m_additional_fan_speed = -1;
|
||||
m_current_fan_speed = -1;
|
||||
@@ -744,6 +744,13 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
||||
int close_fan_the_first_x_layers = EXTRUDER_CONFIG(close_fan_the_first_x_layers);
|
||||
// Is the fan speed ramp enabled?
|
||||
int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer);
|
||||
// ORCA: explicit per-filament first-layer override (-1 = disabled, 0-100 = forced PWM percent on layer 0).
|
||||
// The override is only honoured when the "No cooling for the first" gate is 0; otherwise the gate would
|
||||
// force layers 1..N-1 to zero while the override sets layer 0 to a non-zero value, which is confusing
|
||||
// and non-monotonic. The UI greys out and resets the value in that case, but we also guard here so
|
||||
// legacy profiles loaded with both set are neutralised at the slicer level.
|
||||
int initial_layer_fan_speed = EXTRUDER_CONFIG(initial_layer_fan_speed);
|
||||
const bool has_initial_layer_override = initial_layer_fan_speed >= 0 && close_fan_the_first_x_layers <= 0;
|
||||
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
||||
|
||||
// ORCA: previously a silent override forced `close_fan_the_first_x_layers` from 0 up to 1 whenever a ramp
|
||||
@@ -751,7 +758,24 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
||||
// That hid the user's literal "no cooling for the first 0 layers" setting and produced a non-zero starting
|
||||
// factor on the ramp denominator. The override has been removed: with N=0 and M>0 the ramp now genuinely
|
||||
// starts on layer 0 at a factor of 1/M and reaches 100% at layer M-1, matching the intent of the option.
|
||||
if (int(layer_id) >= close_fan_the_first_x_layers) {
|
||||
//
|
||||
// ORCA: First-layer hard override (`initial_layer_fan_speed`). When the user has set this option to a
|
||||
// value >= 0, layer 0 emits exactly that percentage so the entire first layer
|
||||
// is at one stable fan speed. The override wins over the `close_fan_the_first_x_layers` gate when
|
||||
// layer_id == 0. From layer 1 onwards the regular logic resumes.
|
||||
if (has_initial_layer_override && layer_id == 0) {
|
||||
fan_speed_new = initial_layer_fan_speed;
|
||||
overhang_fan_speed = initial_layer_fan_speed;
|
||||
overhang_fan_control = false;
|
||||
internal_bridge_fan_speed = initial_layer_fan_speed;
|
||||
internal_bridge_fan_control = false;
|
||||
supp_interface_fan_speed = initial_layer_fan_speed;
|
||||
supp_interface_fan_control = false;
|
||||
ironing_fan_speed = initial_layer_fan_speed;
|
||||
ironing_fan_control = false;
|
||||
// additional_fan_speed_new is left at its configured value (auxiliary fan is independent of the
|
||||
// part-cooling override).
|
||||
} else if (int(layer_id) >= close_fan_the_first_x_layers) {
|
||||
float fan_max_speed = EXTRUDER_CONFIG(fan_max_speed);
|
||||
float slow_down_layer_time = float(EXTRUDER_CONFIG(slow_down_layer_time));
|
||||
float fan_cooling_layer_time = float(EXTRUDER_CONFIG(fan_cooling_layer_time));
|
||||
@@ -769,10 +793,25 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
||||
//}
|
||||
overhang_fan_speed = EXTRUDER_CONFIG(overhang_fan_speed);
|
||||
if (int(layer_id) >= close_fan_the_first_x_layers && int(layer_id) + 1 < full_fan_speed_layer) {
|
||||
// Ramp up the fan speed from close_fan_the_first_x_layers to full_fan_speed_layer.
|
||||
float factor = float(int(layer_id + 1) - close_fan_the_first_x_layers) / float(full_fan_speed_layer - close_fan_the_first_x_layers);
|
||||
fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255);
|
||||
overhang_fan_speed = std::clamp(int(float(overhang_fan_speed) * factor + 0.5f), 0, 255);
|
||||
if (has_initial_layer_override && close_fan_the_first_x_layers == 0 && full_fan_speed_layer > 1) {
|
||||
// ORCA: Option-B anchored ramp. When the first-layer override is configured and there's
|
||||
// no "no cooling" gate, the ramp interpolates linearly from `initial_layer_fan_speed` on
|
||||
// layer 0 up to the computed target on layer `full_fan_speed_layer - 1` instead of
|
||||
// scaling the target by `factor` from zero. Layer 0 itself is handled by the override
|
||||
// branch above; this branch only runs for layer_id >= 1, but the formula uses t = 0 at
|
||||
// layer 0 conceptually so the curve is continuous. Guarantees a monotonic transition
|
||||
// even when the override is larger than the natural 1/M starting value.
|
||||
const float anchor = float(initial_layer_fan_speed);
|
||||
const float denom = float(full_fan_speed_layer - 1);
|
||||
const float t = float(int(layer_id)) / denom;
|
||||
fan_speed_new = std::clamp(int(anchor + t * (float(fan_speed_new) - anchor) + 0.5f), 0, 255);
|
||||
overhang_fan_speed = std::clamp(int(anchor + t * (float(overhang_fan_speed) - anchor) + 0.5f), 0, 255);
|
||||
} else {
|
||||
// Ramp up the fan speed from close_fan_the_first_x_layers to full_fan_speed_layer.
|
||||
float factor = float(int(layer_id + 1) - close_fan_the_first_x_layers) / float(full_fan_speed_layer - close_fan_the_first_x_layers);
|
||||
fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255);
|
||||
overhang_fan_speed = std::clamp(int(float(overhang_fan_speed) * factor + 0.5f), 0, 255);
|
||||
}
|
||||
}
|
||||
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
||||
supp_interface_fan_control = supp_interface_fan_speed >= 0;
|
||||
|
||||
@@ -25,7 +25,7 @@ class CoolingBuffer {
|
||||
public:
|
||||
CoolingBuffer(GCode &gcodegen);
|
||||
void reset(const Vec3d &position);
|
||||
void set_current_extruder(unsigned int extruder_id) { m_current_extruder = extruder_id; }
|
||||
void set_current_extruder(unsigned int extruder_id, unsigned int nozzle_id) { m_current_extruder = extruder_id; m_current_nozzle = nozzle_id; }
|
||||
std::string process_layer(std::string &&gcode, size_t layer_id, bool flush);
|
||||
|
||||
private:
|
||||
@@ -55,6 +55,7 @@ private:
|
||||
// the PrintConfig slice of FullPrintConfig is constant, thus no thread synchronization is required.
|
||||
const PrintConfig &m_config;
|
||||
unsigned int m_current_extruder;
|
||||
unsigned int m_current_nozzle;
|
||||
//BBS: current fan speed
|
||||
int m_current_fan_speed;
|
||||
};
|
||||
|
||||
@@ -1472,7 +1472,7 @@ WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origi
|
||||
m_bridging(10.f),
|
||||
m_no_sparse_layers(config.wipe_tower_no_sparse_layers),
|
||||
m_gcode_flavor(config.gcode_flavor),
|
||||
m_travel_speed(config.travel_speed),
|
||||
m_travel_speed(config.travel_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_current_tool(initial_tool),
|
||||
//wipe_volumes(flush_matrix)
|
||||
m_enable_timelapse_print(config.timelapse_type.value == TimelapseType::tlSmooth),
|
||||
@@ -1497,7 +1497,7 @@ WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origi
|
||||
// it is taken over following default. Speeds from config are not
|
||||
// easily accessible here.
|
||||
const float default_speed = 60.f;
|
||||
m_first_layer_speed = config.get_abs_value("initial_layer_speed");
|
||||
m_first_layer_speed = config.initial_layer_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool));
|
||||
if (m_first_layer_speed == 0.f) // just to make sure autospeed doesn't break it.
|
||||
m_first_layer_speed = default_speed / 2.f;
|
||||
|
||||
|
||||
@@ -1262,9 +1262,9 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
|
||||
m_bridging(float(config.wipe_tower_bridging)),
|
||||
m_no_sparse_layers(config.wipe_tower_no_sparse_layers),
|
||||
m_gcode_flavor(config.gcode_flavor),
|
||||
m_travel_speed(config.travel_speed),
|
||||
m_infill_speed(default_region_config.sparse_infill_speed),
|
||||
m_perimeter_speed(default_region_config.inner_wall_speed),
|
||||
m_travel_speed(config.travel_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_infill_speed(default_region_config.sparse_infill_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_perimeter_speed(default_region_config.inner_wall_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_current_tool(initial_tool),
|
||||
wipe_volumes(wiping_matrix), m_wipe_tower_max_purge_speed(float(config.wipe_tower_max_purge_speed)),
|
||||
m_enable_arc_fitting(config.enable_arc_fitting),
|
||||
@@ -1280,7 +1280,7 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
|
||||
// it is taken over following default. Speeds from config are not
|
||||
// easily accessible here.
|
||||
const float default_speed = 60.f;
|
||||
m_first_layer_speed = config.initial_layer_speed;
|
||||
m_first_layer_speed = config.initial_layer_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool));
|
||||
if (m_first_layer_speed == 0.f) // just to make sure autospeed doesn't break it.
|
||||
m_first_layer_speed = default_speed / 2.f;
|
||||
|
||||
|
||||
+103
-55
@@ -28,6 +28,39 @@ bool GCodeWriter::supports_separate_travel_acceleration(GCodeFlavor flavor)
|
||||
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
||||
{
|
||||
this->config.apply(print_config, true);
|
||||
|
||||
// Some machine limits are stride-2 (normal, silent) pairs, here we extract the value that will be used,
|
||||
// which is always normal mode at the moment
|
||||
// TODO: support silent? Any printer actually have that?
|
||||
auto get_machine_limits = [](const std::string key, const ConfigOptionFloats& opt) -> std::vector<double> {
|
||||
unsigned int stride = 1;
|
||||
unsigned int offset = 0;
|
||||
if (printer_options_with_variant_2.count(key) > 0) {
|
||||
stride = 2;
|
||||
// offset = <TODO: current print mode>;
|
||||
}
|
||||
|
||||
std::vector<double> results;
|
||||
results.reserve(opt.values.size() / stride);
|
||||
|
||||
for (unsigned int i = offset; i < opt.values.size(); i += stride) {
|
||||
results.emplace_back(opt.values[i]);
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
auto rounded = [](std::vector<double>&& vec) -> std::vector<double>&&{
|
||||
std::transform(vec.cbegin(), vec.cend(), vec.begin(), [](const double v) { return std::round(v); });
|
||||
return std::move(vec);
|
||||
};
|
||||
auto to_uint = [](const std::vector<double>& vec) {
|
||||
std::vector<unsigned int> r;
|
||||
std::transform(vec.begin(), vec.end(), std::back_inserter(r), [](const double v) { return static_cast<unsigned int>(v); });
|
||||
return r;
|
||||
};
|
||||
#define LIMITS(OPT) get_machine_limits(#OPT, print_config.OPT)
|
||||
#define LIMITS_UINT(OPT) to_uint(rounded(LIMITS(OPT)))
|
||||
|
||||
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
|
||||
bool use_mach_limits = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware ||
|
||||
print_config.gcode_flavor.value == gcfKlipper || print_config.gcode_flavor.value == gcfRepRapFirmware;
|
||||
@@ -35,29 +68,40 @@ void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
||||
// For Klipper, SET_VELOCITY_LIMIT ACCEL= applies to all moves, so the effective cap
|
||||
// is the minimum of the extruding limit and the per-axis X/Y limits.
|
||||
// This ensures user-configured Motion Ability limits are honoured (#12244).
|
||||
unsigned int extruding_limit = std::lrint(print_config.machine_max_acceleration_extruding.values.front());
|
||||
auto extruding_limit = LIMITS_UINT(machine_max_acceleration_extruding);
|
||||
if (print_config.gcode_flavor.value == gcfKlipper) {
|
||||
unsigned int x_limit = std::lrint(print_config.machine_max_acceleration_x.values.front());
|
||||
unsigned int y_limit = std::lrint(print_config.machine_max_acceleration_y.values.front());
|
||||
if (x_limit > 0) extruding_limit = std::min(extruding_limit, x_limit);
|
||||
if (y_limit > 0) extruding_limit = std::min(extruding_limit, y_limit);
|
||||
auto x_limit = LIMITS_UINT(machine_max_acceleration_x);
|
||||
auto y_limit = LIMITS_UINT(machine_max_acceleration_y);
|
||||
|
||||
for (size_t i = 0; i < extruding_limit.size(); i++) {
|
||||
if (x_limit[i] > 0) extruding_limit[i] = std::min(extruding_limit[i], x_limit[i]);
|
||||
if (y_limit[i] > 0) extruding_limit[i] = std::min(extruding_limit[i], y_limit[i]);
|
||||
}
|
||||
}
|
||||
m_max_acceleration = extruding_limit;
|
||||
m_max_acceleration = std::move(extruding_limit);
|
||||
} else {
|
||||
m_max_acceleration = 0;
|
||||
m_max_acceleration.clear();
|
||||
}
|
||||
if (use_mach_limits && supports_separate_travel_acceleration(print_config.gcode_flavor.value)) {
|
||||
m_max_travel_acceleration = LIMITS_UINT(machine_max_acceleration_travel);
|
||||
} else {
|
||||
m_max_travel_acceleration.clear();
|
||||
}
|
||||
m_max_travel_acceleration = static_cast<unsigned int>(
|
||||
std::round((use_mach_limits && supports_separate_travel_acceleration(print_config.gcode_flavor.value)) ?
|
||||
print_config.machine_max_acceleration_travel.values.front() :
|
||||
0));
|
||||
if (use_mach_limits) {
|
||||
m_max_jerk_x = std::lrint(print_config.machine_max_jerk_x.values.front());
|
||||
m_max_jerk_y = std::lrint(print_config.machine_max_jerk_y.values.front());
|
||||
m_max_junction_deviation = (print_config.machine_max_junction_deviation.values.front());
|
||||
};
|
||||
m_max_jerk_z = print_config.machine_max_jerk_z.values.front();
|
||||
m_max_jerk_e = print_config.machine_max_jerk_e.values.front();
|
||||
m_max_jerk_x = rounded(LIMITS(machine_max_jerk_x));
|
||||
m_max_jerk_y = rounded(LIMITS(machine_max_jerk_y));
|
||||
m_max_junction_deviation = LIMITS(machine_max_junction_deviation);
|
||||
} else {
|
||||
m_max_jerk_x.clear();
|
||||
m_max_jerk_y.clear();
|
||||
m_max_junction_deviation.clear();
|
||||
}
|
||||
m_max_jerk_z = LIMITS(machine_max_jerk_z);
|
||||
m_max_jerk_e = LIMITS(machine_max_jerk_e);
|
||||
m_resolution = print_config.resolution.value;
|
||||
|
||||
#undef LIMITS
|
||||
#undef LIMITS_UINT
|
||||
}
|
||||
|
||||
void GCodeWriter::set_extruders(std::vector<unsigned int> extruder_ids)
|
||||
@@ -212,14 +256,18 @@ std::string GCodeWriter::set_chamber_temperature(int temperature, bool wait)
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
#define EXTRUDER_LIMIT(OPT) \
|
||||
(filament() ? ((OPT).size() <= filament()->extruder_id() ? 0 : (OPT)[filament()->extruder_id()]) : \
|
||||
((OPT).empty() ? 0 : *std::max_element((OPT).cbegin(), (OPT).cend())))
|
||||
|
||||
// copied from PrusaSlicer
|
||||
std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned int acceleration)
|
||||
{
|
||||
// Clamp the acceleration to the allowed maximum.
|
||||
if (type == Acceleration::Print && m_max_acceleration > 0 && acceleration > m_max_acceleration)
|
||||
acceleration = m_max_acceleration;
|
||||
if (type == Acceleration::Travel && m_max_travel_acceleration > 0 && acceleration > m_max_travel_acceleration)
|
||||
acceleration = m_max_travel_acceleration;
|
||||
if (type == Acceleration::Print && EXTRUDER_LIMIT(m_max_acceleration) > 0 && acceleration > EXTRUDER_LIMIT(m_max_acceleration))
|
||||
acceleration = EXTRUDER_LIMIT(m_max_acceleration);
|
||||
if (type == Acceleration::Travel && EXTRUDER_LIMIT(m_max_travel_acceleration) > 0 && acceleration > EXTRUDER_LIMIT(m_max_travel_acceleration))
|
||||
acceleration = EXTRUDER_LIMIT(m_max_travel_acceleration);
|
||||
|
||||
// Are we setting travel acceleration for a flavour that supports separate travel and print acc?
|
||||
bool separate_travel = (type == Acceleration::Travel && supports_separate_travel_acceleration(this->config.gcode_flavor));
|
||||
@@ -262,10 +310,10 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
std::ostringstream gcode;
|
||||
if (FLAVOR_IS(gcfKlipper)) {
|
||||
// Clamp the jerk to the allowed maximum.
|
||||
if (m_max_jerk_x > 0 && jerk > m_max_jerk_x)
|
||||
jerk = m_max_jerk_x;
|
||||
if (m_max_jerk_y > 0 && jerk > m_max_jerk_y)
|
||||
jerk = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
|
||||
|
||||
@@ -274,12 +322,12 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
double jerk_xy = jerk;
|
||||
|
||||
// Clamp against the X machine limit
|
||||
if (m_max_jerk_x > 0 && jerk_xy > m_max_jerk_x)
|
||||
jerk_xy = m_max_jerk_x;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk_xy > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk_xy = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
|
||||
// Clamp against the Y machine limit as well to be safe
|
||||
if (m_max_jerk_y > 0 && jerk_xy > m_max_jerk_y)
|
||||
jerk_xy = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk_xy > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk_xy = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
// Output the lowest safe limit using ONLY the X parameter
|
||||
gcode << "M207 X" << jerk_xy;
|
||||
@@ -287,16 +335,16 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
double jerk_x = jerk;
|
||||
double jerk_y = jerk;
|
||||
// Clamp the axis jerk to the allowed maximum.
|
||||
if (m_max_jerk_x > 0 && jerk > m_max_jerk_x)
|
||||
jerk_x = m_max_jerk_x;
|
||||
if (m_max_jerk_y > 0 && jerk > m_max_jerk_y)
|
||||
jerk_y = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk_x = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk_y = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
gcode << "M205 X" << jerk_x << " Y" << jerk_y;
|
||||
}
|
||||
//the is_bbl check should be in the else statement above so that it doesn't inadverently added Z & E to klipper
|
||||
if (m_is_bbl_printers)
|
||||
gcode << std::setprecision(2) << " Z" << m_max_jerk_z << " E" << m_max_jerk_e;
|
||||
gcode << std::setprecision(2) << " Z" << EXTRUDER_LIMIT(m_max_jerk_z) << " E" << EXTRUDER_LIMIT(m_max_jerk_e);
|
||||
|
||||
if (GCodeWriter::full_gcode_comment) gcode << " ; adjust jerk";
|
||||
gcode << "\n";
|
||||
@@ -312,8 +360,8 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je
|
||||
throw std::runtime_error(_u8L("set_accel_and_jerk() is only supported by Klipper"));
|
||||
|
||||
// Clamp the acceleration to the allowed maximum.
|
||||
if (m_max_acceleration > 0 && acceleration > m_max_acceleration)
|
||||
acceleration = m_max_acceleration;
|
||||
if (EXTRUDER_LIMIT(m_max_acceleration) > 0 && acceleration > EXTRUDER_LIMIT(m_max_acceleration))
|
||||
acceleration = EXTRUDER_LIMIT(m_max_acceleration);
|
||||
|
||||
bool is_empty = true;
|
||||
std::ostringstream gcode;
|
||||
@@ -327,10 +375,10 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je
|
||||
is_empty = false;
|
||||
}
|
||||
// Clamp the jerk to the allowed maximum.
|
||||
if (m_max_jerk_x > 0 && jerk > m_max_jerk_x)
|
||||
jerk = m_max_jerk_x;
|
||||
if (m_max_jerk_y > 0 && jerk > m_max_jerk_y)
|
||||
jerk = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
if (jerk > 0.01 && !is_approx(jerk, m_last_jerk)) {
|
||||
gcode << " SQUARE_CORNER_VELOCITY=" << jerk;
|
||||
@@ -351,13 +399,13 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je
|
||||
|
||||
std::string GCodeWriter::set_junction_deviation(double junction_deviation){
|
||||
std::ostringstream gcode;
|
||||
if (FLAVOR_IS(gcfMarlinFirmware) && m_max_junction_deviation > 0 && junction_deviation > 0) {
|
||||
if (FLAVOR_IS(gcfMarlinFirmware) && EXTRUDER_LIMIT(m_max_junction_deviation) > 0 && junction_deviation > 0) {
|
||||
// Clamp the junction deviation to the allowed maximum.
|
||||
gcode << "M205 J";
|
||||
if (junction_deviation <= m_max_junction_deviation) {
|
||||
if (junction_deviation <= EXTRUDER_LIMIT(m_max_junction_deviation)) {
|
||||
gcode << std::fixed << std::setprecision(3) << junction_deviation;
|
||||
} else {
|
||||
gcode << std::fixed << std::setprecision(3) << m_max_junction_deviation;
|
||||
gcode << std::fixed << std::setprecision(3) << EXTRUDER_LIMIT(m_max_junction_deviation);
|
||||
}
|
||||
if (GCodeWriter::full_gcode_comment) {
|
||||
gcode << " ; Junction Deviation";
|
||||
@@ -462,10 +510,10 @@ std::string GCodeWriter::set_input_shaping(char axis, float damp, float freq, st
|
||||
break;
|
||||
}
|
||||
case gcfMarlinLegacy: {
|
||||
throw std::runtime_error(_u8L("Input shaping is not supported by Marlin < 2.1.2.\nCheck your firmware version and update your G-code flavor to ´Marlin 2´"));
|
||||
throw std::runtime_error(_u8L("Input shaping is not supported by Marlin < 2.1.2.\nCheck your firmware version and update your G-code flavor to ´Marlin 2´."));
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error(_u8L("Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2"));
|
||||
throw std::runtime_error(_u8L("Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2."));
|
||||
}
|
||||
if (!gcode.str().empty()) {
|
||||
if (GCodeWriter::full_gcode_comment) {
|
||||
@@ -610,7 +658,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
|
||||
GCodeG1Formatter w;
|
||||
w.emit_xy(point_on_plate);
|
||||
auto speed = m_is_first_layer
|
||||
? this->config.get_abs_value("initial_layer_travel_speed") : this->config.travel_speed.value;
|
||||
? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
w.emit_f(speed * 60.0);
|
||||
//BBS
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
@@ -696,7 +744,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
// BBS
|
||||
Vec3d dest_point = point;
|
||||
auto travel_speed =
|
||||
m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed") : this->config.travel_speed.value;
|
||||
m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
//BBS: a z_hop need to be handle when travel
|
||||
if (std::abs(m_to_lift) > EPSILON) {
|
||||
assert(std::abs(m_lifted) < EPSILON);
|
||||
@@ -793,13 +841,13 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
{
|
||||
//force to move xy first then z after filament change
|
||||
w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y()));
|
||||
w.emit_f(this->config.travel_speed.value * 60.0);
|
||||
w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0);
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
out_string = w.string() + _travel_to_z(point_on_plate.z(), comment);
|
||||
} else {
|
||||
GCodeG1Formatter w;
|
||||
w.emit_xyz(point_on_plate);
|
||||
w.emit_f(this->config.travel_speed.value * 60.0);
|
||||
w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0);
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
out_string = w.string();
|
||||
}
|
||||
@@ -832,10 +880,10 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
|
||||
{
|
||||
m_pos(2) = z;
|
||||
|
||||
double speed = this->config.travel_speed_z.value;
|
||||
double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
if (speed == 0.) {
|
||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||
: this->config.travel_speed.value;
|
||||
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id()))
|
||||
: this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
}
|
||||
|
||||
GCodeG1Formatter w;
|
||||
@@ -849,11 +897,11 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
|
||||
std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment)
|
||||
{
|
||||
std::string output;
|
||||
double speed = this->config.travel_speed_z.value;
|
||||
double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
|
||||
if (speed == 0.) {
|
||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||
: this->config.travel_speed.value;
|
||||
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id()))
|
||||
: this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
}
|
||||
|
||||
if (!this->config.enable_arc_fitting) { // Orca: if arc fitting is disabled, approximate the arc with small linear segments
|
||||
|
||||
@@ -135,22 +135,22 @@ public:
|
||||
bool m_single_extruder_multi_material;
|
||||
std::vector<Extruder*> m_curr_filament_extruder;
|
||||
int m_curr_extruder_id;
|
||||
unsigned int m_last_acceleration;
|
||||
unsigned int m_last_travel_acceleration;
|
||||
unsigned int m_max_travel_acceleration;
|
||||
unsigned int m_last_acceleration;
|
||||
unsigned int m_last_travel_acceleration;
|
||||
std::vector<unsigned int> m_max_travel_acceleration;
|
||||
|
||||
// Limit for setting the acceleration, to respect the machine limits set for the Marlin firmware.
|
||||
// If set to zero, the limit is not in action.
|
||||
unsigned int m_max_acceleration;
|
||||
double m_max_jerk_x;
|
||||
double m_max_jerk_y;
|
||||
double m_last_jerk;
|
||||
double m_max_jerk_z;
|
||||
double m_max_jerk_e;
|
||||
double m_max_junction_deviation;
|
||||
// If set to zero, the limit is not in action. Indexed by 0-based physical nozzle id.
|
||||
std::vector<unsigned int> m_max_acceleration;
|
||||
std::vector<double> m_max_jerk_x;
|
||||
std::vector<double> m_max_jerk_y;
|
||||
double m_last_jerk;
|
||||
std::vector<double> m_max_jerk_z;
|
||||
std::vector<double> m_max_jerk_e;
|
||||
std::vector<double> m_max_junction_deviation;
|
||||
|
||||
unsigned int m_travel_acceleration;
|
||||
unsigned int m_travel_jerk;
|
||||
// unsigned int m_travel_acceleration;
|
||||
// unsigned int m_travel_jerk;
|
||||
|
||||
|
||||
//BBS
|
||||
|
||||
@@ -1236,7 +1236,7 @@ std::vector<Vec2d> edge_offset_contour_intersections(
|
||||
// 2) offset_distance == dmin_new -> one duplicate point is found.
|
||||
// If 2) is ignored, then two tangentially touching offset curves are created.
|
||||
// If not ignored, then the two offset curves merge at this double point.
|
||||
// We should merge the contours while pushing the the two copies of the tangent point away a bit.
|
||||
// We should merge the contours while pushing the two copies of the tangent point away a bit.
|
||||
dmin = dmin_new;
|
||||
num_intersections = (offset_distance > dmin) + 1;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ ExPolygons Layer::merged(float offset_scaled) const
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
bool Layer::is_perimeter_compatible(const Print& print, const PrintRegion& a, const PrintRegion& b)
|
||||
{
|
||||
const PrintRegionConfig& config = a.config();
|
||||
const PrintRegionConfig& other_config = b.config();
|
||||
@@ -146,10 +146,10 @@ bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
&& config.wall_loops == other_config.wall_loops
|
||||
&& config.wall_sequence == other_config.wall_sequence
|
||||
&& config.is_infill_first == other_config.is_infill_first
|
||||
&& config.inner_wall_speed == other_config.inner_wall_speed
|
||||
&& config.outer_wall_speed == other_config.outer_wall_speed
|
||||
&& config.small_perimeter_speed == other_config.small_perimeter_speed
|
||||
&& config.gap_infill_speed.value == other_config.gap_infill_speed.value
|
||||
&& config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.filter_out_gap_fill.value == other_config.filter_out_gap_fill.value
|
||||
&& config.detect_overhang_wall == other_config.detect_overhang_wall
|
||||
&& config.overhang_reverse == other_config.overhang_reverse
|
||||
@@ -209,7 +209,7 @@ void Layer::make_perimeters()
|
||||
if (! (*it)->slices.empty()) {
|
||||
LayerRegion* other_layerm = *it;
|
||||
const PrintRegion &other_region = other_layerm->region();
|
||||
if (is_perimeter_compatible(this_region, other_region))
|
||||
if (is_perimeter_compatible(*m_object->print(), this_region, other_region))
|
||||
{
|
||||
other_layerm->perimeters.clear();
|
||||
other_layerm->fills.clear();
|
||||
|
||||
@@ -17,6 +17,7 @@ class LayerRegion;
|
||||
using LayerRegionPtrs = std::vector<LayerRegion*>;
|
||||
class PrintRegion;
|
||||
class PrintObject;
|
||||
class Print;
|
||||
|
||||
namespace FillAdaptive {
|
||||
struct Octree;
|
||||
@@ -186,7 +187,7 @@ public:
|
||||
}
|
||||
|
||||
// Whether two regions can be printed in a continues perimeter
|
||||
static bool is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b);
|
||||
static bool is_perimeter_compatible(const Print& print, const PrintRegion& a, const PrintRegion& b);
|
||||
void make_perimeters();
|
||||
// Phony version of make_fills() without parameters for Perl integration only.
|
||||
void make_fills() { this->make_fills(nullptr, nullptr); }
|
||||
|
||||
+21
-27
@@ -225,7 +225,7 @@ _finished:
|
||||
}
|
||||
|
||||
if (model.objects.empty())
|
||||
throw Slic3r::RuntimeError(_L("The supplied file couldn't be read because it's empty"));
|
||||
throw Slic3r::RuntimeError(_L("The supplied file couldn\'t be read because it\'s empty."));
|
||||
|
||||
for (ModelObject *o : model.objects)
|
||||
o->input_file = input_file;
|
||||
@@ -337,7 +337,7 @@ Model Model::read_from_file(const std::string&
|
||||
}
|
||||
#endif
|
||||
else
|
||||
throw Slic3r::RuntimeError(_L("Unknown file format. Input file must have .stl, .obj, .amf(.xml) extension."));
|
||||
throw Slic3r::RuntimeError(_L("Unknown file format: input file must have .stl, .obj, or .amf(.xml) extension."));
|
||||
|
||||
if (is_cb_cancel) {
|
||||
Model empty_model;
|
||||
@@ -352,7 +352,7 @@ Model Model::read_from_file(const std::string&
|
||||
}
|
||||
|
||||
if (model.objects.empty())
|
||||
throw Slic3r::RuntimeError(_L("The supplied file couldn't be read because it's empty"));
|
||||
throw Slic3r::RuntimeError(_L("The supplied file couldn\'t be read because it\'s empty."));
|
||||
|
||||
for (ModelObject *o : model.objects)
|
||||
o->input_file = input_file;
|
||||
@@ -399,7 +399,7 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig
|
||||
else if (boost::algorithm::iends_with(input_file, ".zip.amf"))
|
||||
result = load_amf(input_file.c_str(), config, config_substitutions, &model, &is_bbl_3mf);
|
||||
else
|
||||
throw Slic3r::RuntimeError(_L("Unknown file format. Input file must have .3mf or .zip.amf extension."));
|
||||
throw Slic3r::RuntimeError(_L("Unknown file format: input file must have .3mf or .zip.amf extension."));
|
||||
|
||||
if (out_file_type != En3mfType::From_Prusa) {
|
||||
if (is_orca_3mf)
|
||||
@@ -696,8 +696,7 @@ unsigned int Model::update_print_volume_state(const BuildVolume &build_volume)
|
||||
num_printable += model_object->update_instances_print_volume_state(build_volume);
|
||||
//BBS: add logs for build_volume
|
||||
const BoundingBoxf3& print_volume = build_volume.bounding_volume();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", print_volume {%1%, %2%, %3%} to {%4%, %5%, %6%}, got %7% printable istances")\
|
||||
%print_volume.min.x() %print_volume.min.y() %print_volume.min.z()%print_volume.max.x() %print_volume.max.y() %print_volume.max.z() %num_printable;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", print_volume {%1%, %2%, %3%} to {%4%, %5%, %6%}, got %7% printable istances") %print_volume.min.x() %print_volume.min.y() %print_volume.min.z()%print_volume.max.x() %print_volume.max.y() %print_volume.max.z() %num_printable;
|
||||
return num_printable;
|
||||
}
|
||||
|
||||
@@ -2127,10 +2126,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects, const bool remap_paint)
|
||||
|
||||
if (is_multi_volume_object) {
|
||||
// BBS: volume geometry not changed, so we can keep the paint facets
|
||||
#define COPY_FACETS(f) \
|
||||
if (new_vol->f.timestamp() == volume->f.timestamp()) \
|
||||
new_vol->f.reset(); /* BBS: let next assign take effect */ \
|
||||
new_vol->f.assign(volume->f)
|
||||
#define COPY_FACETS(f) if (new_vol->f.timestamp() == volume->f.timestamp()) new_vol->f.reset(); /* BBS: let next assign take effect */ new_vol->f.assign(volume->f)
|
||||
|
||||
COPY_FACETS(supported_facets);
|
||||
COPY_FACETS(seam_facets);
|
||||
@@ -2372,8 +2368,7 @@ unsigned int ModelObject::update_instances_print_volume_state(const BuildVolume
|
||||
unsigned int num_printable = 0;
|
||||
//BBS: add logs for build_volume
|
||||
//const BoundingBoxf3& print_volume = build_volume.bounding_volume();
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", print_volume {%1%, %2%, %3%} to {%4%, %5%, %6%}")\
|
||||
// %print_volume.min.x() %print_volume.min.y() %print_volume.min.z()%print_volume.max.x() %print_volume.max.y() %print_volume.max.z();
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", print_volume {%1%, %2%, %3%} to {%4%, %5%, %6%}") // %print_volume.min.x() %print_volume.min.y() %print_volume.min.z()%print_volume.max.x() %print_volume.max.y() %print_volume.max.z();
|
||||
for (ModelInstance* model_instance : this->instances) {
|
||||
if (model_instance->update_print_volume_state(build_volume) == ModelInstancePVS_Inside) {
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", object %1%'s instance inside print volum")%this->name;
|
||||
@@ -2977,31 +2972,31 @@ void Model::setPrintSpeedTable(const DynamicPrintConfig& config, const PrintConf
|
||||
//Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config();
|
||||
printSpeedMap.maxSpeed = 0;
|
||||
if (config.has("inner_wall_speed")) {
|
||||
printSpeedMap.perimeterSpeed = config.opt_float("inner_wall_speed");
|
||||
printSpeedMap.perimeterSpeed = config.opt_float_nullable("inner_wall_speed", 0);
|
||||
if (printSpeedMap.perimeterSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.perimeterSpeed;
|
||||
}
|
||||
if (config.has("outer_wall_speed")) {
|
||||
printSpeedMap.externalPerimeterSpeed = config.opt_float("outer_wall_speed");
|
||||
printSpeedMap.externalPerimeterSpeed = config.opt_float_nullable("outer_wall_speed", 0);
|
||||
printSpeedMap.maxSpeed = std::max(printSpeedMap.maxSpeed, printSpeedMap.externalPerimeterSpeed);
|
||||
}
|
||||
if (config.has("sparse_infill_speed")) {
|
||||
printSpeedMap.infillSpeed = config.opt_float("sparse_infill_speed");
|
||||
printSpeedMap.infillSpeed = config.opt_float_nullable("sparse_infill_speed", 0);
|
||||
if (printSpeedMap.infillSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.infillSpeed;
|
||||
}
|
||||
if (config.has("internal_solid_infill_speed")) {
|
||||
printSpeedMap.solidInfillSpeed = config.opt_float("internal_solid_infill_speed");
|
||||
printSpeedMap.solidInfillSpeed = config.opt_float_nullable("internal_solid_infill_speed", 0);
|
||||
if (printSpeedMap.solidInfillSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.solidInfillSpeed;
|
||||
}
|
||||
if (config.has("top_surface_speed")) {
|
||||
printSpeedMap.topSolidInfillSpeed = config.opt_float("top_surface_speed");
|
||||
printSpeedMap.topSolidInfillSpeed = config.opt_float_nullable("top_surface_speed", 0);
|
||||
if (printSpeedMap.topSolidInfillSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.topSolidInfillSpeed;
|
||||
}
|
||||
if (config.has("support_speed")) {
|
||||
printSpeedMap.supportSpeed = config.opt_float("support_speed");
|
||||
printSpeedMap.supportSpeed = config.opt_float_nullable("support_speed", 0);
|
||||
|
||||
if (printSpeedMap.supportSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.supportSpeed;
|
||||
@@ -3233,21 +3228,21 @@ double Model::findMaxSpeed(const ModelObject* object) {
|
||||
double smallPerimeterSpeedObj = Model::printSpeedMap.smallPerimeterSpeed;
|
||||
for (std::string objectKey : objectKeys) {
|
||||
if (objectKey == "inner_wall_speed"){
|
||||
perimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
perimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
externalPerimeterSpeedObj = Model::printSpeedMap.externalPerimeterSpeed / Model::printSpeedMap.perimeterSpeed * perimeterSpeedObj;
|
||||
}
|
||||
if (objectKey == "sparse_infill_speed")
|
||||
infillSpeedObj = object->config.opt_float(objectKey);
|
||||
infillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "internal_solid_infill_speed")
|
||||
solidInfillSpeedObj = object->config.opt_float(objectKey);
|
||||
solidInfillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "top_surface_speed")
|
||||
topSolidInfillSpeedObj = object->config.opt_float(objectKey);
|
||||
topSolidInfillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "support_speed")
|
||||
supportSpeedObj = object->config.opt_float(objectKey);
|
||||
supportSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "outer_wall_speed")
|
||||
externalPerimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
externalPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "small_perimeter_speed")
|
||||
smallPerimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
smallPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
}
|
||||
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, objMaxSpeed)))))));
|
||||
if (objMaxSpeed <= 0) objMaxSpeed = 250.;
|
||||
@@ -3434,8 +3429,7 @@ ModelInstanceEPrintVolumeState ModelInstance::calc_print_volume_state(const Buil
|
||||
BoundingBoxf3 bb = vol->get_convex_hull().bounding_box();
|
||||
Vec3d size = bb.size();
|
||||
if ((size.x() == 0.f) || (size.y() == 0.f) || (size.z() == 0.f)) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", object %1%'s vol %2% is empty, skip it, box: {%3%, %4%, %5%} to {%6%, %7%, %8%}")%this->object->name %vol->name\
|
||||
%bb.min.x() %bb.min.y() %bb.min.z()%bb.max.x() %bb.max.y() %bb.max.z();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", object %1%'s vol %2% is empty, skip it, box: {%3%, %4%, %5%} to {%6%, %7%, %8%}")%this->object->name %vol->name %bb.min.x() %bb.min.y() %bb.min.z()%bb.max.x() %bb.max.y() %bb.max.z();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1352,7 +1352,7 @@ static inline std::vector<std::vector<ExPolygons>> segmentation_top_and_bottom_l
|
||||
out.extrusion_width = std::max<float>(out.extrusion_width, outer_wall_line_width);
|
||||
out.top_shell_layers = std::max<int>(out.top_shell_layers, config.top_shell_layers);
|
||||
out.bottom_shell_layers = std::max<int>(out.bottom_shell_layers, config.bottom_shell_layers);
|
||||
out.small_region_threshold = config.gap_infill_speed.value > 0 ?
|
||||
out.small_region_threshold = config.gap_infill_speed.get_at(print_object.print()->get_extruder_id(config.outer_wall_filament_id - 1)) > 0 ?
|
||||
// Gap fill enabled. Enable a single line of 1/2 extrusion width.
|
||||
0.5f * outer_wall_line_width :
|
||||
// Gap fill disabled. Enable two lines slightly overlapping.
|
||||
|
||||
@@ -179,7 +179,7 @@ static bool clip_narrow_corner(
|
||||
bool blocked = forward == Blocked || backward == Blocked;
|
||||
assert(polygon.size() < 3 ||
|
||||
// Remaining triangle is CCW oriented. Both sides must be "blocked", but the other side may have not been
|
||||
// updated after the the p02 / p22 became united into a single point.
|
||||
// updated after the p02 / p22 became united into a single point.
|
||||
blocked ||
|
||||
// Remaining triangle is concave, however both of its arms are long.
|
||||
(forward == Far && backward == Far));
|
||||
|
||||
@@ -581,7 +581,7 @@ void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExP
|
||||
coord_t ext_perimeter_width = this->ext_perimeter_flow.scaled_width();
|
||||
coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
|
||||
|
||||
bool has_gap_fill = this->config->gap_infill_speed.value > 0;
|
||||
bool has_gap_fill = this->config->gap_infill_speed.get_at(get_extruder_index(*print_config, this->config->outer_wall_filament_id - 1)) > 0;
|
||||
|
||||
// split the polygons with top/not_top
|
||||
// get the offset from solid surface anchor
|
||||
@@ -1189,7 +1189,7 @@ void PerimeterGenerator::process_classic()
|
||||
// internal flow which is unrelated.
|
||||
coord_t min_spacing = coord_t(perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||
coord_t ext_min_spacing = coord_t(ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||
bool has_gap_fill = this->config->gap_infill_speed.value > 0;
|
||||
bool has_gap_fill = this->config->gap_infill_speed.get_at(get_extruder_index(*print_config, this->config->outer_wall_filament_id - 1)) > 0;
|
||||
|
||||
// BBS: this flow is for smaller external perimeter for small area
|
||||
coord_t ext_min_spacing_smaller = coord_t(ext_perimeter_spacing * (1 - SMALLER_EXT_INSET_OVERLAP_TOLERANCE));
|
||||
|
||||
@@ -1318,7 +1318,7 @@ static std::vector<std::string> s_Preset_filament_options {/*"filament_colour",
|
||||
// "bed_type",
|
||||
//BBS:temperature_vitrification
|
||||
"temperature_vitrification", "reduce_fan_stop_start_freq","dont_slow_down_outer_wall", "slow_down_for_layer_cooling", "fan_min_speed",
|
||||
"fan_max_speed", "enable_overhang_bridge_fan", "overhang_fan_speed", "overhang_fan_threshold", "close_fan_the_first_x_layers", "close_additional_fan_first_x_layers", "first_x_layer_fan_speed", "full_fan_speed_layer", "additional_fan_full_speed_layer", "fan_cooling_layer_time", "slow_down_layer_time", "slow_down_min_speed",
|
||||
"fan_max_speed", "enable_overhang_bridge_fan", "overhang_fan_speed", "overhang_fan_threshold", "close_fan_the_first_x_layers", "close_additional_fan_first_x_layers", "first_x_layer_fan_speed", "full_fan_speed_layer", "initial_layer_fan_speed", "additional_fan_full_speed_layer", "fan_cooling_layer_time", "slow_down_layer_time", "slow_down_min_speed",
|
||||
"filament_start_gcode", "filament_end_gcode", "filament_change_extrusion_role_gcode",
|
||||
//exhaust fan control
|
||||
"activate_air_filtration","activate_air_filtration_during_print","activate_air_filtration_on_completion","during_print_exhaust_fan_speed","complete_print_exhaust_fan_speed",
|
||||
|
||||
@@ -3832,9 +3832,9 @@ void PresetBundle::update_filament_count()
|
||||
: filament_presets.back());
|
||||
}
|
||||
|
||||
bool PresetBundle::support_different_extruders()
|
||||
bool PresetBundle::support_different_extruders() const
|
||||
{
|
||||
Preset& printer_preset = this->printers.get_edited_preset();
|
||||
const Preset& printer_preset = this->printers.get_edited_preset();
|
||||
int extruder_count;
|
||||
bool supported = printer_preset.config.support_different_extruders(extruder_count);
|
||||
|
||||
|
||||
@@ -370,7 +370,7 @@ public:
|
||||
|
||||
//BBS: add some functions for multiple extruders
|
||||
int get_printer_extruder_count() const;
|
||||
bool support_different_extruders();
|
||||
bool support_different_extruders() const;
|
||||
|
||||
// Orca: Ensure filament_presets has at least one slot per nozzle on FFF printers.
|
||||
// Called from (load|update)_selections before the parallel project_config arrays
|
||||
|
||||
+228
-208
@@ -25,6 +25,7 @@
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
#include <unordered_set>
|
||||
#include <sstream>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
@@ -133,6 +134,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
"dont_slow_down_outer_wall",
|
||||
"fan_cooling_layer_time",
|
||||
"full_fan_speed_layer",
|
||||
"initial_layer_fan_speed",
|
||||
"fan_kickstart",
|
||||
"part_cooling_fan_min_pwm",
|
||||
"fan_speedup_overhangs",
|
||||
@@ -672,13 +674,13 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
||||
//juedge the exclude area
|
||||
if (!intersection(exclude_polys, convex_hull_no_offset).empty()) {
|
||||
if (single_object_exception.string.empty()) {
|
||||
single_object_exception.string = (boost::format(L("%1% is too close to exclusion area, there may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
|
||||
single_object_exception.string = (boost::format(L("%1% is too close to exclusion area. There may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
|
||||
// single_object_exception.object = instance.model_instance->get_object();
|
||||
//ORCA: Pass ModelInstance instead of ModelObject
|
||||
single_object_exception.object = instance.model_instance;
|
||||
}
|
||||
else {
|
||||
single_object_exception.string += "\n"+(boost::format(L("%1% is too close to exclusion area, there may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
|
||||
single_object_exception.string += "\n"+(boost::format(L("%1% is too close to exclusion area. There may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
|
||||
single_object_exception.object = nullptr;
|
||||
}
|
||||
//if (polygons) {
|
||||
@@ -1041,7 +1043,7 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
|
||||
/*if (warning) {
|
||||
warning->string += L("Prime Tower is too close to exclusion area, there may be collisions when printing.\n");
|
||||
}*/
|
||||
return {L("Prime Tower") + L(" is too close to exclusion area, and collisions will be caused.\n")};
|
||||
return {L("Prime Tower") + L(" is too close to an exclusion area, and collisions will be caused.\n")};
|
||||
}
|
||||
if (print_config.enable_wrapping_detection.value && !intersection({wrapping_poly}, convex_hulls_temp).empty()) {
|
||||
return {L("Prime Tower") + L(" is too close to clumping detection area, and collisions will be caused.\n")};
|
||||
@@ -1258,9 +1260,22 @@ StringObjectException Print::check_multi_filament_valid(const Print& print)
|
||||
}
|
||||
|
||||
// Precondition: Print::validate() requires the Print::apply() to be called its invocation.
|
||||
//BBS: refine seq-print validation logic.....FIXME:StringObjectException *warning can only contain one warning, but there might be many warnings, need a vector<StringObjectException>
|
||||
StringObjectException Print::validate(StringObjectException *warning, Polygons* collison_polygons, std::vector<std::pair<Polygon, float>>* height_polygons) const
|
||||
//BBS: refine seq-print validation logic
|
||||
StringObjectException Print::validate(std::vector<StringObjectException> *warnings, Polygons* collison_polygons, std::vector<std::pair<Polygon, float>>* height_polygons) const
|
||||
{
|
||||
auto add_warning = [warnings](StringObjectException w) {
|
||||
w.is_warning = true;
|
||||
if (warnings != nullptr)
|
||||
warnings->push_back(std::move(w));
|
||||
};
|
||||
auto warn = [&](std::string msg, std::string opt_key = "", const ObjectBase* object = nullptr) {
|
||||
StringObjectException w;
|
||||
w.string = std::move(msg);
|
||||
w.opt_key = std::move(opt_key);
|
||||
w.object = object;
|
||||
add_warning(std::move(w));
|
||||
};
|
||||
|
||||
std::vector<unsigned int> extruders = this->extruders();
|
||||
unsigned int nozzles = m_config.nozzle_diameter.size();
|
||||
|
||||
@@ -1275,9 +1290,8 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
if (!ret.string.empty())
|
||||
{
|
||||
ret.type = STRING_EXCEPT_FILAMENTS_DIFFERENT_TEMP;
|
||||
if (ret.is_warning && warning != nullptr) {
|
||||
*warning = ret;
|
||||
//return {};
|
||||
if (ret.is_warning) {
|
||||
add_warning(ret);
|
||||
}else
|
||||
return ret;
|
||||
}
|
||||
@@ -1303,32 +1317,26 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
}
|
||||
else {
|
||||
//BBS
|
||||
auto ret = layered_print_cleareance_valid(*this, warning);
|
||||
StringObjectException layer_warning;
|
||||
auto ret = layered_print_cleareance_valid(*this, &layer_warning);
|
||||
if (!ret.string.empty()) {
|
||||
ret.type = STRING_EXCEPT_OBJECT_COLLISION_IN_LAYER_PRINT;
|
||||
return ret;
|
||||
}
|
||||
if (!layer_warning.string.empty())
|
||||
add_warning(layer_warning);
|
||||
}
|
||||
|
||||
if (m_config.enable_prime_tower) {
|
||||
for (const PrintObject* object : m_objects) {
|
||||
if (object->config().precise_z_height.value && warning != nullptr) {
|
||||
StringObjectException warningtemp;
|
||||
warningtemp.string = L("Enabling both precise Z height and the prime tower may cause slicing errors.");
|
||||
warningtemp.opt_key = "precise_z_height";
|
||||
warningtemp.is_warning = true;
|
||||
*warning = warningtemp;
|
||||
if (object->config().precise_z_height.value) {
|
||||
warn(L("Enabling both precise Z height and the prime tower may cause slicing errors."), "precise_z_height");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_config.enable_wrapping_detection && warning!=nullptr) {
|
||||
StringObjectException warningtemp;
|
||||
warningtemp.string = L("A prime tower is required for clumping detection; otherwise, there may be flaws on the model.");
|
||||
warningtemp.opt_key = "enable_prime_tower";
|
||||
warningtemp.is_warning = true;
|
||||
*warning = warningtemp;
|
||||
}
|
||||
if (m_config.enable_wrapping_detection)
|
||||
warn(L("A prime tower is required for clumping detection; otherwise, there may be flaws on the model."), "enable_prime_tower");
|
||||
}
|
||||
|
||||
if (m_config.spiral_mode) {
|
||||
@@ -1342,10 +1350,10 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
const auto all_regions = m_objects.front()->all_regions();
|
||||
if (all_regions.size() > 1) {
|
||||
// Orca: make sure regions are not compatible
|
||||
if (std::any_of(all_regions.begin() + 1, all_regions.end(), [ra = all_regions.front()](const auto rb) {
|
||||
return !Layer::is_perimeter_compatible(ra, rb);
|
||||
if (std::any_of(all_regions.begin() + 1, all_regions.end(), [this, ra = all_regions.front()](const auto rb) {
|
||||
return !Layer::is_perimeter_compatible(*this, ra, rb);
|
||||
})) {
|
||||
return {L("The spiral vase mode does not work when an object contains more than one materials."), nullptr, "spiral_mode"};
|
||||
return {L("Spiral (vase) mode does not work when an object contains more than one material."), nullptr, "spiral_mode"};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1424,8 +1432,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
if (nozzle_diam - EPSILON > first_nozzle_diam || nozzle_diam + EPSILON < first_nozzle_diam
|
||||
|| std::abs((filament_diam - first_filament_diam) / first_filament_diam) > 0.1) {
|
||||
// return { L("Different nozzle diameters and different filament diameters may not work well when prime tower is enabled. It's very experimental, please proceed with caucious.") };
|
||||
warning->string = L("Different nozzle diameters and different filament diameters may not work well when the prime tower is enabled. It's very experimental, so please proceed with caution.");
|
||||
warning->opt_key = "nozzle_diameter";
|
||||
warn(L("Different nozzle diameters and different filament diameters may not work well when the prime tower is enabled. It's very experimental, so please proceed with caution."), "nozzle_diameter");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1442,14 +1449,14 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
return { L("The prime tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors.")};
|
||||
|
||||
if ((m_config.print_sequence == PrintSequence::ByObject) && extruders.size() > 1)
|
||||
return { L("The prime tower is not supported in \"By object\" print."), nullptr, "enable_prime_tower" };
|
||||
return { L("A prime tower is not supported in \u201cBy object\u201d print."), nullptr, "enable_prime_tower" };
|
||||
|
||||
// BBS: When prime tower is on, object layer and support layer must be aligned. So support gap should be multiple of object layer height.
|
||||
for (size_t i = 0; i < m_objects.size(); i++) {
|
||||
const PrintObject* object = m_objects[i];
|
||||
const SlicingParameters& slicing_params = object->slicing_parameters();
|
||||
if (object->config().adaptive_layer_height) {
|
||||
return { L("The prime tower is not supported when adaptive layer height is on. It requires that all objects have the same layer height."), object, "adaptive_layer_height" };
|
||||
return { L("A prime tower is not supported when adaptive layer height is on. It requires that all objects have the same layer height."), object, "adaptive_layer_height" };
|
||||
}
|
||||
|
||||
if (!object->config().enable_support)
|
||||
@@ -1457,7 +1464,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
|
||||
double gap_layers = slicing_params.gap_object_support / slicing_params.layer_height;
|
||||
if (gap_layers - (int)gap_layers > EPSILON) {
|
||||
return {L("The prime tower requires \"support gap\" to be multiple of layer height."), object};
|
||||
return {L("A prime tower requires any \u201csupport gap\u201d to be a multiple of layer height."), object};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1470,9 +1477,9 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
const SlicingParameters &slicing_params = object->slicing_parameters();
|
||||
if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
|
||||
std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
|
||||
return {L("The prime tower requires that all objects have the same layer heights."), object, "initial_layer_print_height"};
|
||||
return {L("A prime tower requires that all objects have the same layer height."), object, "initial_layer_print_height"};
|
||||
if (slicing_params.raft_layers() != slicing_params0.raft_layers())
|
||||
return {L("The prime tower requires that all objects are printed over the same number of raft layers."), object, "raft_layers"};
|
||||
return {L("A prime tower requires that all objects are printed over the same number of raft layers."), object, "raft_layers"};
|
||||
// BBS: support gap can be multiple of object layer height, remove _L()
|
||||
#if 0
|
||||
if (slicing_params0.gap_object_support != slicing_params.gap_object_support ||
|
||||
@@ -1480,7 +1487,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
return {L("The prime tower is only supported for multiple objects if they are printed with the same support_top_z_distance."), object};
|
||||
#endif
|
||||
if (!equal_layering(slicing_params, slicing_params0))
|
||||
return { L("The prime tower requires that all objects are sliced with the same layer heights."), object };
|
||||
return { L("A prime tower requires that all objects are sliced with the same layer height."), object };
|
||||
if (has_custom_layering) {
|
||||
auto &lh = layer_height_profile(i);
|
||||
auto &lh_tallest = layer_height_profile(tallest_object_idx);
|
||||
@@ -1546,10 +1553,10 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
if (extrusion_width_min == 0) {
|
||||
// Default "auto-generated" extrusion width is always valid.
|
||||
} else if (extrusion_width_min <= layer_height) {
|
||||
err_msg = L("Too small line width");
|
||||
err_msg = L("Line width too small");
|
||||
return false;
|
||||
} else if (extrusion_width_max > max_nozzle_diameter * MAX_LINE_WIDTH_MULTIPLIER) {
|
||||
err_msg = L("Too large line width");
|
||||
err_msg = L("Line width too large");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1571,7 +1578,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
// BBS
|
||||
#if 0
|
||||
if (this->has_wipe_tower() && object->config().independent_support_layer_height) {
|
||||
return {L("The prime tower requires that support has the same layer height with object."), object, "support_filament"};
|
||||
return {L("A prime tower requires that support has the same layer height as the object."), object, "support_filament"};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1582,22 +1589,15 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
// Orca: use organic as default
|
||||
object->config().support_style == smsDefault) {
|
||||
|
||||
if (warning) {
|
||||
// Orca: check the support wall count and the base pattern
|
||||
if (object->config().tree_support_wall_count > 1 &&
|
||||
object->config().support_base_pattern != SupportMaterialPattern::smpNone &&
|
||||
object->config().support_base_pattern != SupportMaterialPattern::smpDefault) {
|
||||
warning->string = L("For Organic supports, two walls are supported only with the Hollow/Default base pattern.");
|
||||
warning->opt_key = "support_base_pattern";
|
||||
}
|
||||
// Orca: check the support wall count and the base pattern
|
||||
if (object->config().tree_support_wall_count > 1 &&
|
||||
object->config().support_base_pattern != SupportMaterialPattern::smpNone &&
|
||||
object->config().support_base_pattern != SupportMaterialPattern::smpDefault)
|
||||
warn(L("For Organic supports, two walls are supported only with the Hollow/Default base pattern."), "support_base_pattern");
|
||||
|
||||
// Orca: check if the Lightning base pattern selected
|
||||
if (object->config().support_base_pattern == SupportMaterialPattern::smpLightning) {
|
||||
warning->string = L(
|
||||
"The Lightning base pattern is not supported by this support type; Rectilinear will be used instead.");
|
||||
warning->opt_key = "support_base_pattern";
|
||||
}
|
||||
}
|
||||
// Orca: check if the Lightning base pattern selected
|
||||
if (object->config().support_base_pattern == SupportMaterialPattern::smpLightning)
|
||||
warn(L("The Lightning base pattern is not supported by this support type; Rectilinear will be used instead."), "support_base_pattern");
|
||||
|
||||
float extrusion_width = std::min(
|
||||
support_material_flow(object).width(),
|
||||
@@ -1609,28 +1609,23 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
if (object->config().tree_support_branch_diameter_organic < object->config().tree_support_tip_diameter)
|
||||
return { L("Organic support branch diameter must not be smaller than support tree tip diameter."), object, "tree_support_branch_diameter_organic" };
|
||||
}
|
||||
} else if (object->config().support_base_pattern == SupportMaterialPattern::smpLightning && warning) {
|
||||
} else if (object->config().support_base_pattern == SupportMaterialPattern::smpLightning) {
|
||||
// Orca: check if the Lightning base pattern selected
|
||||
warning->string = L("The Lightning base pattern is not supported by this support type; Rectilinear will be used instead.");
|
||||
warning->opt_key = "support_base_pattern";
|
||||
} else if (object->config().support_base_pattern == SupportMaterialPattern::smpNone && warning) {
|
||||
warn(L("The Lightning base pattern is not supported by this support type; Rectilinear will be used instead."), "support_base_pattern");
|
||||
} else if (object->config().support_base_pattern == SupportMaterialPattern::smpNone) {
|
||||
// Orca: check if the Hollow base pattern selected
|
||||
warning->string = L("The Hollow base pattern is not supported by this support type; Rectilinear will be used instead.");
|
||||
warning->opt_key = "support_base_pattern";
|
||||
warn(L("The Hollow base pattern is not supported by this support type; Rectilinear will be used instead."), "support_base_pattern");
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have custom support data that would not be used?
|
||||
// Notify the user in that case.
|
||||
if (! object->has_support() && warning) {
|
||||
if (! object->has_support()) {
|
||||
for (const ModelVolume* mv : object->model_object()->volumes) {
|
||||
bool has_enforcers = mv->is_support_enforcer() ||
|
||||
(mv->is_model_part() && mv->supported_facets.has_facets(*mv, EnforcerBlockerType::ENFORCER));
|
||||
if (has_enforcers) {
|
||||
StringObjectException warningtemp;
|
||||
warningtemp.string = L("Support enforcers are used but support is not enabled. Please enable support.");
|
||||
warningtemp.object = object;
|
||||
*warning = warningtemp;
|
||||
warn(L("Support enforcers are used but support is not enabled. Please enable support."), "", object);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1684,7 +1679,7 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
return { err_msg, object, "bridge_line_width" };
|
||||
}
|
||||
if (!allow_thin_bridge_width && bridge_width <= layer_height) {
|
||||
err_msg = L("Too small line width");
|
||||
err_msg = L("Line width too small");
|
||||
return { err_msg, object, "bridge_line_width" };
|
||||
}
|
||||
}
|
||||
@@ -1782,163 +1777,188 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
}
|
||||
|
||||
// check if print speed/accel/jerk is higher than the maximum speed of the printer
|
||||
if (warning) {
|
||||
if (warnings) {
|
||||
// The motion-ability checks are mutually exclusive (gated on warning_key), so collect the
|
||||
// single one that fires into a local and push it once - separate from the precise-wall and
|
||||
// shrinkage warnings below.
|
||||
StringObjectException motion_warning;
|
||||
try {
|
||||
auto check_motion_ability_object_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_object_config.get_abs_value(key) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
auto check_motion_ability_region_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_region_config.get_abs_value(key) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
std::string warning_key;
|
||||
|
||||
const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0];
|
||||
const bool ignore_jerk_validation = m_config.gcode_flavor == gcfMarlinFirmware && max_junction_deviation > 0;
|
||||
|
||||
// check jerk
|
||||
if (!ignore_jerk_validation) {
|
||||
if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 ||
|
||||
m_default_object_config.inner_wall_jerk == 1) {
|
||||
warning->string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces");
|
||||
if (m_default_object_config.outer_wall_jerk == 1)
|
||||
warning_key = "outer_wall_jerk";
|
||||
else if (m_default_object_config.inner_wall_jerk == 1)
|
||||
warning_key = "inner_wall_jerk";
|
||||
else
|
||||
warning_key = "default_jerk";
|
||||
|
||||
warning->opt_key = warning_key;
|
||||
}
|
||||
|
||||
if (warning_key.empty() && m_default_object_config.default_jerk > 0) {
|
||||
std::vector<std::string> jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk",
|
||||
"top_surface_jerk", "initial_layer_jerk", "travel_jerk"};
|
||||
const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]);
|
||||
warning_key.clear();
|
||||
warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk);
|
||||
if (!warning_key.empty()) {
|
||||
warning->string = L(
|
||||
"The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\n"
|
||||
"Orca will automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the maximum jerk setting in your printer's configuration to get higher speeds.");
|
||||
warning->opt_key = warning_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check junction deviation
|
||||
else if (m_default_object_config.default_junction_deviation.value > max_junction_deviation) {
|
||||
warning->string = L( "Junction deviation setting exceeds the printer's maximum value (machine_max_junction_deviation).\n"
|
||||
"Orca will automatically cap the junction deviation to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the machine_max_junction_deviation value in your printer's configuration to get higher limits.");
|
||||
warning->opt_key = "default_junction_deviation";
|
||||
}
|
||||
|
||||
// check acceleration
|
||||
const auto max_accel = m_config.machine_max_acceleration_extruding.values[0];
|
||||
if (warning_key.empty() && m_default_object_config.default_acceleration > 0 && max_accel > 0) {
|
||||
const bool support_travel_acc = (m_config.gcode_flavor == gcfRepetier || m_config.gcode_flavor == gcfMarlinFirmware ||
|
||||
m_config.gcode_flavor == gcfRepRapFirmware);
|
||||
|
||||
std::vector<std::string> accel_to_check;
|
||||
if (!support_travel_acc)
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
"travel_acceleration",
|
||||
};
|
||||
else
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_accel);
|
||||
if (!warning_key.empty()) {
|
||||
warning->string = L("The acceleration setting exceeds the printer's maximum acceleration "
|
||||
"(machine_max_acceleration_extruding).\nOrca will "
|
||||
"automatically cap the acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_extruding value in your printer's configuration to get higher speeds.");
|
||||
warning->opt_key = warning_key;
|
||||
}
|
||||
if (support_travel_acc) {
|
||||
const auto max_travel = m_config.machine_max_acceleration_travel.values[0];
|
||||
if (max_travel > 0) {
|
||||
accel_to_check = {
|
||||
"travel_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_travel);
|
||||
if (!warning_key.empty()) {
|
||||
warning->string = L(
|
||||
"The travel acceleration setting exceeds the printer's maximum travel acceleration "
|
||||
"(machine_max_acceleration_travel).\nOrca will "
|
||||
"automatically cap the travel acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_travel value in your printer's configuration to get higher speeds.");
|
||||
warning->opt_key = warning_key;
|
||||
auto check_extruder = [&](const int extruder_id) {
|
||||
auto check_motion_ability_object_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_object_config.get_abs_value_at(key, extruder_id) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
auto check_motion_ability_region_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_region_config.get_abs_value_at(key, extruder_id) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
std::string warning_key;
|
||||
|
||||
// check speed
|
||||
// Orca: disable the speed check for now as we don't cap the speed
|
||||
// if (warning_key.empty()) {
|
||||
// auto speed_to_check = {"inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed",
|
||||
// "top_surface_speed", "bridge_speed", "internal_bridge_speed", "gap_infill_speed"};
|
||||
// const auto max_speed = std::min(m_config.machine_max_speed_x.values[0], m_config.machine_max_speed_y.values[0]);
|
||||
// warning_key.clear();
|
||||
// warning_key = check_motion_ability_region_setting(speed_to_check, max_speed);
|
||||
// if (warning_key.empty() && m_config.travel_speed > max_speed)
|
||||
// warning_key = "travel_speed";
|
||||
// if (!warning_key.empty()) {
|
||||
// warning->string = L(
|
||||
// "The speed setting exceeds the printer's maximum speed (machine_max_speed_x/machine_max_speed_y).\nOrca will "
|
||||
// "automatically cap the print speed to ensure it doesn't surpass the printer's capabilities.\nYou can adjust the "
|
||||
// "maximum speed setting in your printer's configuration to get higher speeds.");
|
||||
// warning->opt_key = warning_key;
|
||||
// }
|
||||
// }
|
||||
const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0]; // TODO: fix this
|
||||
const bool ignore_jerk_validation = m_config.gcode_flavor == gcfMarlinFirmware && max_junction_deviation > 0;
|
||||
|
||||
// check jerk
|
||||
if (!ignore_jerk_validation) {
|
||||
if (m_default_object_config.default_jerk.get_at(extruder_id) == 1 || m_default_object_config.outer_wall_jerk.get_at(extruder_id) == 1 ||
|
||||
m_default_object_config.inner_wall_jerk.get_at(extruder_id) == 1) {
|
||||
motion_warning.string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces");
|
||||
if (m_default_object_config.outer_wall_jerk.get_at(extruder_id) == 1)
|
||||
warning_key = "outer_wall_jerk";
|
||||
else if (m_default_object_config.inner_wall_jerk.get_at(extruder_id) == 1)
|
||||
warning_key = "inner_wall_jerk";
|
||||
else
|
||||
warning_key = "default_jerk";
|
||||
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
|
||||
if (warning_key.empty() && m_default_object_config.default_jerk.get_at(extruder_id) > 0) {
|
||||
std::vector<std::string> jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk",
|
||||
"top_surface_jerk", "initial_layer_jerk", "travel_jerk"};
|
||||
const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]);
|
||||
warning_key.clear();
|
||||
warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L(
|
||||
"The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\n"
|
||||
"Orca will automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the maximum jerk setting in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check junction deviation
|
||||
// Orca: Only marlin FW supports max junction deviation. Dont display warning if firmware is not supporting it.
|
||||
const bool support_max_junction_deviation = ( m_config.gcode_flavor == gcfMarlinFirmware);
|
||||
if (warning_key.empty() && m_default_object_config.default_junction_deviation.get_at(extruder_id) > max_junction_deviation && support_max_junction_deviation) {
|
||||
motion_warning.string = L( "Junction deviation setting exceeds the printer's maximum value (machine_max_junction_deviation).\n"
|
||||
"Orca will automatically cap the junction deviation to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the machine_max_junction_deviation value in your printer's configuration to get higher limits.");
|
||||
motion_warning.opt_key = "default_junction_deviation";
|
||||
}
|
||||
|
||||
// check acceleration
|
||||
const auto max_accel = m_config.machine_max_acceleration_extruding.values[0];
|
||||
if (warning_key.empty() && m_default_object_config.default_acceleration.get_at(extruder_id) > 0 && max_accel > 0) {
|
||||
const bool support_travel_acc = (m_config.gcode_flavor == gcfRepetier || m_config.gcode_flavor == gcfMarlinFirmware ||
|
||||
m_config.gcode_flavor == gcfRepRapFirmware);
|
||||
|
||||
std::vector<std::string> accel_to_check;
|
||||
if (!support_travel_acc)
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
"travel_acceleration",
|
||||
};
|
||||
else
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_accel);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L("The acceleration setting exceeds the printer's maximum acceleration "
|
||||
"(machine_max_acceleration_extruding).\nOrca will "
|
||||
"automatically cap the acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_extruding value in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
if (support_travel_acc) {
|
||||
const auto max_travel = m_config.machine_max_acceleration_travel.values[0];
|
||||
if (max_travel > 0) {
|
||||
accel_to_check = {
|
||||
"travel_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_travel);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L(
|
||||
"The travel acceleration setting exceeds the printer's maximum travel acceleration "
|
||||
"(machine_max_acceleration_travel).\nOrca will "
|
||||
"automatically cap the travel acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_travel value in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check speed
|
||||
// Orca: disable the speed check for now as we don't cap the speed
|
||||
// if (warning_key.empty()) {
|
||||
// auto speed_to_check = {"inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed",
|
||||
// "top_surface_speed", "bridge_speed", "internal_bridge_speed", "gap_infill_speed"};
|
||||
// const auto max_speed = std::min(m_config.machine_max_speed_x.values[0], m_config.machine_max_speed_y.values[0]);
|
||||
// warning_key.clear();
|
||||
// warning_key = check_motion_ability_region_setting(speed_to_check, max_speed);
|
||||
// if (warning_key.empty() && m_config.travel_speed > max_speed)
|
||||
// warning_key = "travel_speed";
|
||||
// if (!warning_key.empty()) {
|
||||
// motion_warning.string = L(
|
||||
// "The speed setting exceeds the printer's maximum speed (machine_max_speed_x/machine_max_speed_y).\nOrca will "
|
||||
// "automatically cap the print speed to ensure it doesn't surpass the printer's capabilities.\nYou can adjust the "
|
||||
// "maximum speed setting in your printer's configuration to get higher speeds.");
|
||||
// motion_warning.opt_key = warning_key;
|
||||
// }
|
||||
// }
|
||||
};
|
||||
check_extruder(0); // TODO: check used extruder variants
|
||||
|
||||
// check wall sequence and precise outer wall
|
||||
if (m_default_region_config.precise_outer_wall && m_default_region_config.wall_sequence != WallSequence::InnerOuter) {
|
||||
warning->string = L("The precise wall option will be ignored for outer-inner or inner-outer-inner wall sequences.");
|
||||
warning->opt_key = "precise_outer_wall";
|
||||
if (m_default_region_config.precise_outer_wall && m_default_region_config.wall_sequence != WallSequence::InnerOuter)
|
||||
warn(L("The precise wall option will be ignored for outer-inner or inner-outer-inner wall sequences."), "precise_outer_wall");
|
||||
|
||||
// check adaptive pressure advance model
|
||||
for (unsigned int extruder_id : extruders) {
|
||||
if (m_config.adaptive_pressure_advance.get_at(extruder_id) &&
|
||||
m_config.enable_pressure_advance.get_at(extruder_id)) {
|
||||
|
||||
const std::string pa_model = m_config.adaptive_pressure_advance_model.get_at(extruder_id);
|
||||
if (!pa_model.empty()) {
|
||||
std::string validation_error = AdaptivePAProcessor::validate_adaptive_pa_model(pa_model);
|
||||
if (!validation_error.empty()) {
|
||||
warn(L("The Adaptive Pressure Advance model for one or more extruders may contain invalid values."),
|
||||
"adaptive_pressure_advance_model");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Orca: validate motion ability failed: " << e.what() << std::endl;
|
||||
}
|
||||
if (!motion_warning.string.empty())
|
||||
add_warning(motion_warning);
|
||||
}
|
||||
if (!this->has_same_shrinkage_compensations()){
|
||||
warning->string = L("Filament shrinkage will not be used because filament shrinkage for the used filaments does not match.");
|
||||
warning->opt_key = "";
|
||||
}
|
||||
if (!this->has_same_shrinkage_compensations())
|
||||
warn(L("Filament shrinkage will not be used because filament shrinkage for the used filaments does not match."));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -932,7 +932,7 @@ public:
|
||||
}
|
||||
|
||||
// Returns an empty string if valid, otherwise returns an error message.
|
||||
StringObjectException validate(StringObjectException *warning = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr) const override;
|
||||
StringObjectException validate(std::vector<StringObjectException> *warnings = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr) const override;
|
||||
double skirt_first_layer_height() const;
|
||||
Flow brim_flow() const;
|
||||
Flow skirt_flow() const;
|
||||
@@ -1189,7 +1189,7 @@ private:
|
||||
std::vector<unsigned int> m_slice_used_filaments_first_layer;
|
||||
|
||||
//BBS: plate's origin
|
||||
Vec3d m_origin;
|
||||
Vec3d m_origin {0, 0, 0};
|
||||
//BBS: modified_count
|
||||
int m_modified_count {0};
|
||||
//BBS
|
||||
|
||||
@@ -1163,8 +1163,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
|
||||
//apply extruder related values
|
||||
if (!extruder_applied) {
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant");
|
||||
// variant_2 must be processed first, because variant_1 will make `printer_extruder_id` and `printer_extruder_variant` half of the size that makes `get_index_for_extruder` no longer work properly
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2);
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant");
|
||||
//update print config related with variants
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, print_options_with_variant, "print_extruder_id", "print_extruder_variant");
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ std::string PrintBase::output_filename(const std::string &format, const std::str
|
||||
filename.replace_extension(default_ext);
|
||||
return filename.string();
|
||||
} catch (std::runtime_error &err) {
|
||||
throw Slic3r::PlaceholderParserError(L("Failed processing of the filename_format template.") + "\n" + err.what());
|
||||
throw Slic3r::PlaceholderParserError(L("Processing of the filename_format template failed.") + "\n" + err.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ struct StringObjectException
|
||||
std::string string;
|
||||
ObjectBase const *object = nullptr;
|
||||
std::string opt_key;
|
||||
StringExceptionType type; // warning type for tips
|
||||
StringExceptionType type = STRING_EXCEPT_NOT_DEFINED; // warning type for tips
|
||||
bool is_warning = false;
|
||||
std::vector<std::string> params; // warning params for tips
|
||||
};
|
||||
@@ -396,7 +396,7 @@ public:
|
||||
|
||||
// Validate the print, return empty string if valid, return error if process() cannot (or should not) be started.
|
||||
//BBS: add more paremeters to validate
|
||||
virtual StringObjectException validate(StringObjectException *warning = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr) const { return {}; }
|
||||
virtual StringObjectException validate(std::vector<StringObjectException> *warnings = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr) const { return {}; }
|
||||
|
||||
enum ApplyStatus {
|
||||
// No change after the Print::apply() call.
|
||||
|
||||
+530
-552
File diff suppressed because it is too large
Load Diff
@@ -430,6 +430,17 @@ enum FilamentMapMode {
|
||||
|
||||
extern std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type);
|
||||
|
||||
static std::set<NozzleVolumeType> get_valid_nozzle_volume_type() {
|
||||
std::set<NozzleVolumeType> type;
|
||||
for (int i = 0; i <= nvtMaxNozzleVolumeType; ++i) {
|
||||
auto t = static_cast<NozzleVolumeType>(i);
|
||||
// TODO: Orca: Support hybrid
|
||||
//if (t == nvtHybrid) continue;
|
||||
type.insert(t);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string get_nozzle_volume_type_string(NozzleVolumeType nozzle_volume_type);
|
||||
|
||||
static std::string bed_type_to_gcode_string(const BedType type)
|
||||
@@ -658,7 +669,7 @@ public:
|
||||
|
||||
//BBS
|
||||
bool is_using_different_extruders();
|
||||
bool support_different_extruders(int& extruder_count);
|
||||
bool support_different_extruders(int& extruder_count) const;
|
||||
int get_index_for_extruder(int extruder_or_filament_id, std::string id_name, ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type, std::string variant_name, unsigned int stride = 1) const;
|
||||
void update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name, unsigned int stride = 1, unsigned int extruder_id = 0);
|
||||
void update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name);
|
||||
@@ -965,13 +976,13 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, support_interface_bottom_layers))
|
||||
// Spacing between interface lines (the hatching distance). Set zero to get a solid interface.
|
||||
((ConfigOptionFloat, support_interface_spacing))
|
||||
((ConfigOptionFloat, support_interface_speed))
|
||||
((ConfigOptionFloatsNullable, support_interface_speed))
|
||||
((ConfigOptionEnum<SupportMaterialPattern>, support_base_pattern))
|
||||
((ConfigOptionEnum<SupportMaterialInterfacePattern>, support_interface_pattern))
|
||||
// Spacing between support material lines (the hatching distance).
|
||||
((ConfigOptionFloat, support_base_pattern_spacing))
|
||||
((ConfigOptionFloat, support_expansion))
|
||||
((ConfigOptionFloat, support_speed))
|
||||
((ConfigOptionFloatsNullable, support_speed))
|
||||
((ConfigOptionEnum<SupportMaterialStyle>, support_style))
|
||||
|
||||
// Orca: a flag enabling the ability to override flow ratios
|
||||
@@ -1039,25 +1050,25 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, min_length_factor))
|
||||
|
||||
// Move all acceleration and jerk settings to object
|
||||
((ConfigOptionFloat, default_acceleration))
|
||||
((ConfigOptionFloat, outer_wall_acceleration))
|
||||
((ConfigOptionFloat, inner_wall_acceleration))
|
||||
((ConfigOptionFloat, top_surface_acceleration))
|
||||
((ConfigOptionFloat, initial_layer_acceleration))
|
||||
((ConfigOptionFloatOrPercent, bridge_acceleration))
|
||||
((ConfigOptionFloat, travel_acceleration))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_acceleration))
|
||||
((ConfigOptionFloatOrPercent, internal_solid_infill_acceleration))
|
||||
((ConfigOptionFloatsNullable, default_acceleration))
|
||||
((ConfigOptionFloatsNullable, outer_wall_acceleration))
|
||||
((ConfigOptionFloatsNullable, inner_wall_acceleration))
|
||||
((ConfigOptionFloatsNullable, top_surface_acceleration))
|
||||
((ConfigOptionFloatsNullable, initial_layer_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, bridge_acceleration))
|
||||
((ConfigOptionFloatsNullable, travel_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, sparse_infill_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, internal_solid_infill_acceleration))
|
||||
|
||||
((ConfigOptionFloat, default_jerk))
|
||||
((ConfigOptionFloat, outer_wall_jerk))
|
||||
((ConfigOptionFloat, inner_wall_jerk))
|
||||
((ConfigOptionFloat, infill_jerk))
|
||||
((ConfigOptionFloat, top_surface_jerk))
|
||||
((ConfigOptionFloat, initial_layer_jerk))
|
||||
((ConfigOptionFloat, travel_jerk))
|
||||
((ConfigOptionFloatsNullable, default_jerk))
|
||||
((ConfigOptionFloatsNullable, outer_wall_jerk))
|
||||
((ConfigOptionFloatsNullable, inner_wall_jerk))
|
||||
((ConfigOptionFloatsNullable, infill_jerk))
|
||||
((ConfigOptionFloatsNullable, top_surface_jerk))
|
||||
((ConfigOptionFloatsNullable, initial_layer_jerk))
|
||||
((ConfigOptionFloatsNullable, travel_jerk))
|
||||
((ConfigOptionBool, precise_z_height))
|
||||
((ConfigOptionFloat, default_junction_deviation))
|
||||
((ConfigOptionFloatsNullable, default_junction_deviation))
|
||||
|
||||
((ConfigOptionBool, interlocking_beam))
|
||||
((ConfigOptionFloat,interlocking_beam_width))
|
||||
@@ -1084,8 +1095,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, bridge_flow))
|
||||
((ConfigOptionFloatOrPercent, bridge_line_width))
|
||||
((ConfigOptionFloat, internal_bridge_flow))
|
||||
((ConfigOptionFloat, bridge_speed))
|
||||
((ConfigOptionFloatOrPercent, internal_bridge_speed))
|
||||
((ConfigOptionFloatsNullable, bridge_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, internal_bridge_speed))
|
||||
((ConfigOptionEnum<EnsureVerticalShellThickness>, ensure_vertical_shell_thickness))
|
||||
((ConfigOptionPercent, top_surface_density))
|
||||
((ConfigOptionPercent, bottom_surface_density))
|
||||
@@ -1093,7 +1104,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionEnum<InfillPattern>, bottom_surface_pattern))
|
||||
((ConfigOptionEnum<InfillPattern>, internal_solid_infill_pattern))
|
||||
((ConfigOptionFloatOrPercent, outer_wall_line_width))
|
||||
((ConfigOptionFloat, outer_wall_speed))
|
||||
((ConfigOptionFloatsNullable, outer_wall_speed))
|
||||
((ConfigOptionFloat, infill_direction))
|
||||
((ConfigOptionFloat, solid_infill_direction))
|
||||
((ConfigOptionString, solid_infill_rotate_template))
|
||||
@@ -1122,12 +1133,12 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, fuzzy_skin_ripples_per_layer))
|
||||
((ConfigOptionPercent, fuzzy_skin_ripple_offset))
|
||||
((ConfigOptionInt, fuzzy_skin_layers_between_ripple_offset))
|
||||
((ConfigOptionFloat, gap_infill_speed))
|
||||
((ConfigOptionFloatsNullable, gap_infill_speed))
|
||||
((ConfigOptionInt, sparse_infill_filament_id))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_line_width))
|
||||
((ConfigOptionPercent, infill_wall_overlap))
|
||||
((ConfigOptionPercent, top_bottom_infill_wall_overlap))
|
||||
((ConfigOptionFloat, sparse_infill_speed))
|
||||
((ConfigOptionFloatsNullable, sparse_infill_speed))
|
||||
((ConfigOptionPercent, skeleton_infill_density))
|
||||
((ConfigOptionPercent, skin_infill_density))
|
||||
((ConfigOptionFloat, infill_lock_depth))
|
||||
@@ -1159,7 +1170,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, outer_wall_filament_id))
|
||||
((ConfigOptionInt, inner_wall_filament_id))
|
||||
((ConfigOptionFloatOrPercent, inner_wall_line_width))
|
||||
((ConfigOptionFloat, inner_wall_speed))
|
||||
((ConfigOptionFloatsNullable, inner_wall_speed))
|
||||
// Total number of perimeters.
|
||||
((ConfigOptionInt, wall_loops))
|
||||
((ConfigOptionBool, alternate_extra_wall))
|
||||
@@ -1168,19 +1179,19 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, top_surface_filament_id))
|
||||
((ConfigOptionInt, bottom_surface_filament_id))
|
||||
((ConfigOptionFloatOrPercent, internal_solid_infill_line_width))
|
||||
((ConfigOptionFloat, internal_solid_infill_speed))
|
||||
((ConfigOptionFloatsNullable, internal_solid_infill_speed))
|
||||
// Detect thin walls.
|
||||
((ConfigOptionBool, detect_thin_wall))
|
||||
((ConfigOptionFloatOrPercent, top_surface_line_width))
|
||||
((ConfigOptionInt, top_shell_layers))
|
||||
((ConfigOptionFloat, top_shell_thickness))
|
||||
((ConfigOptionFloat, top_surface_speed))
|
||||
((ConfigOptionFloatsNullable, top_surface_speed))
|
||||
//BBS
|
||||
((ConfigOptionBool, enable_overhang_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_1_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_2_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_3_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_4_4_speed))
|
||||
((ConfigOptionBoolsNullable, enable_overhang_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_1_4_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_2_4_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_3_4_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_4_4_speed))
|
||||
((ConfigOptionBool, only_one_wall_top))
|
||||
|
||||
//SoftFever
|
||||
@@ -1196,8 +1207,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, precise_outer_wall))
|
||||
((ConfigOptionPercent, bridge_density))
|
||||
((ConfigOptionFloat, filter_out_gap_fill))
|
||||
((ConfigOptionFloatOrPercent, small_perimeter_speed))
|
||||
((ConfigOptionFloat, small_perimeter_threshold))
|
||||
((ConfigOptionFloatsOrPercentsNullable, small_perimeter_speed))
|
||||
((ConfigOptionFloatsNullable, small_perimeter_threshold))
|
||||
((ConfigOptionFloat, top_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloat, bottom_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloatOrPercent, infill_anchor))
|
||||
@@ -1206,7 +1217,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
// Orca
|
||||
((ConfigOptionBool, make_overhang_printable))
|
||||
((ConfigOptionBool, extra_perimeters_on_overhangs))
|
||||
((ConfigOptionBool, slowdown_for_curled_perimeters))
|
||||
((ConfigOptionBoolsNullable, slowdown_for_curled_perimeters))
|
||||
((ConfigOptionBool, hole_to_polyhole))
|
||||
((ConfigOptionFloatOrPercent, hole_to_polyhole_threshold))
|
||||
((ConfigOptionBool, hole_to_polyhole_twisted))
|
||||
@@ -1369,7 +1380,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
|
||||
((ConfigOptionFloat, max_volumetric_extrusion_rate_slope))
|
||||
((ConfigOptionFloat, max_volumetric_extrusion_rate_slope_segment_length))
|
||||
((ConfigOptionBool, extrusion_rate_smoothing_external_perimeter_only))
|
||||
((ConfigOptionBool, extrusion_rate_smoothing_external_perimeter_only))
|
||||
|
||||
|
||||
((ConfigOptionPercents, retract_before_wipe))
|
||||
@@ -1401,8 +1412,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionString, change_extrusion_role_gcode))
|
||||
((ConfigOptionString, process_change_extrusion_role_gcode))
|
||||
((ConfigOptionStrings, filament_change_extrusion_role_gcode))
|
||||
((ConfigOptionFloat, travel_speed))
|
||||
((ConfigOptionFloat, travel_speed_z))
|
||||
((ConfigOptionFloatsNullable, travel_speed))
|
||||
((ConfigOptionFloatsNullable, travel_speed_z))
|
||||
((ConfigOptionBool, silent_mode))
|
||||
((ConfigOptionString, machine_pause_gcode))
|
||||
((ConfigOptionString, template_custom_gcode))
|
||||
@@ -1426,9 +1437,9 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, use_relative_e_distances))
|
||||
((ConfigOptionBool, accel_to_decel_enable))
|
||||
((ConfigOptionPercent, accel_to_decel_factor))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_travel_speed))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_travel_acceleration))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_travel_jerk))
|
||||
((ConfigOptionFloatsOrPercentsNullable, initial_layer_travel_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, initial_layer_travel_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, initial_layer_travel_jerk))
|
||||
((ConfigOptionBool, bbl_calib_mark_logo))
|
||||
((ConfigOptionBool, disable_m73))
|
||||
|
||||
@@ -1538,12 +1549,14 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionInts, complete_print_exhaust_fan_speed))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_line_width))
|
||||
((ConfigOptionFloat, initial_layer_print_height))
|
||||
((ConfigOptionFloat, initial_layer_speed))
|
||||
((ConfigOptionFloatsNullable, initial_layer_speed))
|
||||
|
||||
//BBS
|
||||
((ConfigOptionFloat, initial_layer_infill_speed))
|
||||
((ConfigOptionFloatsNullable, initial_layer_infill_speed))
|
||||
((ConfigOptionInts, nozzle_temperature_initial_layer))
|
||||
((ConfigOptionInts, full_fan_speed_layer))
|
||||
// ORCA: explicit override for the part cooling fan speed on the first printed layer.
|
||||
((ConfigOptionInts, initial_layer_fan_speed))
|
||||
((ConfigOptionFloats, fan_max_speed))
|
||||
((ConfigOptionFloats, max_layer_height))
|
||||
((ConfigOptionFloats, fan_min_speed))
|
||||
|
||||
@@ -897,13 +897,15 @@ void PrintObject::generate_support_material()
|
||||
void PrintObject::estimate_curled_extrusions()
|
||||
{
|
||||
if (this->set_started(posEstimateCurledExtrusions)) {
|
||||
if ( std::any_of(this->print()->m_print_regions.begin(), this->print()->m_print_regions.end(),
|
||||
[](const PrintRegion *region) { return region->config().enable_overhang_speed.getBool(); })) {
|
||||
if ( std::any_of(this->print()->m_print_regions.begin(), this->print()->m_print_regions.end(), [](const PrintRegion* region) {
|
||||
const auto& cfg = region->config().enable_overhang_speed.values;
|
||||
return std::any_of(cfg.begin(), cfg.end(), [](const unsigned char v) { return (bool) v; });
|
||||
})) {
|
||||
|
||||
// Estimate curling of support material and add it to the malformaition lines of each layer
|
||||
float support_flow_width = support_material_flow(this, this->config().layer_height).width();
|
||||
SupportSpotsGenerator::Params params{this->print()->m_config.filament_type.values,
|
||||
float(this->print()->default_object_config().inner_wall_acceleration.getFloat()),
|
||||
/*float(this->print()->default_object_config().inner_wall_acceleration.getFloat()),*/
|
||||
this->config().raft_layers.getInt(), this->config().brim_type.value,
|
||||
float(this->config().brim_width.getFloat())};
|
||||
SupportSpotsGenerator::estimate_malformations(this->layers(), params);
|
||||
@@ -1150,11 +1152,11 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
// todo multi_extruders: Parameter migration between single and double extruder printers
|
||||
auto is_gap_fill_changed_state_due_to_speed = [&opt_key, &old_config, &new_config]() -> bool {
|
||||
if (opt_key == "gap_infill_speed") {
|
||||
const auto *old_gap_fill_speed = old_config.option<ConfigOptionFloat>(opt_key);
|
||||
const auto *new_gap_fill_speed = new_config.option<ConfigOptionFloat>(opt_key);
|
||||
const auto *old_gap_fill_speed = old_config.option<ConfigOptionFloatsNullable>(opt_key);
|
||||
const auto *new_gap_fill_speed = new_config.option<ConfigOptionFloatsNullable>(opt_key);
|
||||
assert(old_gap_fill_speed && new_gap_fill_speed);
|
||||
return (old_gap_fill_speed->value > 0.f && new_gap_fill_speed->value == 0.f) ||
|
||||
(old_gap_fill_speed->value == 0.f && new_gap_fill_speed->value > 0.f);
|
||||
return (old_gap_fill_speed->values.size() != new_gap_fill_speed->values.size())
|
||||
|| (old_gap_fill_speed->values != new_gap_fill_speed->values);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -613,7 +613,7 @@ std::string SLAPrint::output_filename(const std::string &filename_base) const
|
||||
return this->PrintBase::output_filename(m_print_config.filename_format.value, ".sl1", filename_base, &config);
|
||||
}
|
||||
|
||||
StringObjectException SLAPrint::validate(StringObjectException *exception, Polygons *collison_polygons, std::vector<std::pair<Polygon, float>> *height_polygons) const
|
||||
StringObjectException SLAPrint::validate(std::vector<StringObjectException> *warnings, Polygons *collison_polygons, std::vector<std::pair<Polygon, float>> *height_polygons) const
|
||||
{
|
||||
for(SLAPrintObject * po : m_objects) {
|
||||
|
||||
|
||||
@@ -488,7 +488,7 @@ public:
|
||||
|
||||
const SLAPrintStatistics& print_statistics() const { return m_print_statistics; }
|
||||
|
||||
StringObjectException validate(StringObjectException * warning = nullptr,
|
||||
StringObjectException validate(std::vector<StringObjectException> * warnings = nullptr,
|
||||
Polygons * collison_polygons = nullptr,
|
||||
std::vector<std::pair<Polygon, float>> *height_polygons = nullptr) const override;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <libslic3r/MeshBoolean.hpp>
|
||||
#include <libslic3r/TriangleMeshSlicer.hpp>
|
||||
|
||||
// Need the cylinder method for the the drainholes in hollowing step
|
||||
// Need the cylinder method for the drainholes in hollowing step
|
||||
#include <libslic3r/SLA/SupportTreeBuilder.hpp>
|
||||
|
||||
#include <libslic3r/SLA/Concurrency.hpp>
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace SupportSpotsGenerator {
|
||||
struct Params
|
||||
{
|
||||
Params(
|
||||
const std::vector<std::string> &filament_types, float max_acceleration, int raft_layers_count, BrimType brim_type, float brim_width)
|
||||
: max_acceleration(max_acceleration), raft_layers_count(raft_layers_count), brim_type(brim_type), brim_width(brim_width)
|
||||
const std::vector<std::string> &filament_types/*, float max_acceleration*/, int raft_layers_count, BrimType brim_type, float brim_width)
|
||||
: /*max_acceleration(max_acceleration), */raft_layers_count(raft_layers_count), brim_type(brim_type), brim_width(brim_width)
|
||||
{
|
||||
if (filament_types.size() > 1) {
|
||||
BOOST_LOG_TRIVIAL(warning)
|
||||
@@ -36,8 +36,8 @@ struct Params
|
||||
|
||||
// the algorithm should use the following units for all computations: distance [mm], mass [g], time [s], force [g*mm/s^2]
|
||||
const float bridge_distance = 16.0f; // mm
|
||||
const float max_acceleration; // mm/s^2 ; max acceleration of object in XY -- should be applicable only to printers with bed slinger,
|
||||
// however we do not have such info yet. The force is usually small anyway, so not such a big deal to include it everytime
|
||||
// const float max_acceleration; // mm/s^2 ; max acceleration of object in XY -- should be applicable only to printers with bed slinger,
|
||||
// // however we do not have such info yet. The force is usually small anyway, so not such a big deal to include it everytime
|
||||
const int raft_layers_count;
|
||||
std::string filament_type;
|
||||
|
||||
|
||||
@@ -1197,7 +1197,7 @@ void sample_overhang_area(
|
||||
point_count += poly.size();
|
||||
const size_t min_support_points = std::max(coord_t(1), std::min(coord_t(3), coord_t(total_length(overhang_area) / connect_length)));
|
||||
if (point_count <= min_support_points) {
|
||||
// add the outer wall (of the overhang) to ensure it is correct supported instead. Try placing the support points in a way that they fully support the outer wall, instead of just the with half of the the support line width.
|
||||
// add the outer wall (of the overhang) to ensure it is correct supported instead. Try placing the support points in a way that they fully support the outer wall, instead of just the with half of the support line width.
|
||||
// I assume that even small overhangs are over one line width wide, so lets try to place the support points in a way that the full support area generated from them
|
||||
// will support the overhang (if this is not done it may only be half). This WILL NOT be the case when supporting an angle of about < 60 degrees so there is a fallback,
|
||||
// as some support is better than none.
|
||||
@@ -1378,7 +1378,7 @@ static void generate_initial_areas(
|
||||
}
|
||||
#if 0
|
||||
// If the xy distance overrides the z distance, some support needs to be inserted further down.
|
||||
//=> Analyze which support points do not fit on this layer and check if they will fit a few layers down (while adding them an infinite amount of layers down would technically be closer the the setting description, it would not produce reasonable results. )
|
||||
//=> Analyze which support points do not fit on this layer and check if they will fit a few layers down (while adding them an infinite amount of layers down would technically be closer the setting description, it would not produce reasonable results. )
|
||||
if (! min_xy_dist) {
|
||||
LineInformations overhang_lines;
|
||||
{
|
||||
|
||||
+11
-1
@@ -16,7 +16,7 @@ float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &conf
|
||||
const float nozzle_diameter = config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(extruder_id);
|
||||
if (line_width <= 0.) line_width = Flow::auto_extrusion_width(frPerimeter, nozzle_diameter);
|
||||
Flow pattern_line = Flow(line_width, layer_height, nozzle_diameter);
|
||||
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloat>("outer_wall_speed")->value),
|
||||
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloatsNullable>("outer_wall_speed")->get_at(extruder_id)),
|
||||
filament_max_volumetric_speed / pattern_line.mm3_per_mm());
|
||||
|
||||
return std::floor(pa_speed);
|
||||
@@ -756,6 +756,16 @@ Vec3d CalibPressureAdvancePattern::get_start_offset()
|
||||
return m_starting_point;
|
||||
}
|
||||
|
||||
double CalibPressureAdvancePattern::line_width_first_layer() const
|
||||
{
|
||||
// TODO: FIXME: find out current filament/extruder?
|
||||
const double nozzle_diameter = m_config.opt_float("nozzle_diameter", m_params.extruder_id);
|
||||
const double width = m_config.get_abs_value("initial_layer_line_width", nozzle_diameter);
|
||||
if (width <= 0.)
|
||||
return Flow::auto_extrusion_width(frExternalPerimeter, nozzle_diameter);
|
||||
return width;
|
||||
};
|
||||
|
||||
double CalibPressureAdvancePattern::line_width() const
|
||||
{
|
||||
// TODO: FIXME: find out current filament/extruder?
|
||||
|
||||
+5
-10
@@ -280,7 +280,7 @@ private:
|
||||
|
||||
struct SuggestedConfigCalibPAPattern
|
||||
{
|
||||
const std::vector<std::pair<std::string, double>> float_pairs{{"initial_layer_speed", 30}};
|
||||
const std::vector<std::pair<std::string, std::vector<double>>> floats_pairs{{"initial_layer_speed", {30}}};
|
||||
|
||||
const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs{{"line_width", 112.5}, {"initial_layer_line_width", 140}};
|
||||
|
||||
@@ -312,15 +312,10 @@ public:
|
||||
|
||||
protected:
|
||||
// todo multi_extruders:
|
||||
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
|
||||
double speed_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_speed")->value; };
|
||||
double accel_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_acceleration")->value; }
|
||||
double line_width_first_layer() const
|
||||
{
|
||||
// TODO: FIXME: find out current filament/extruder?
|
||||
const double nozzle_diameter = m_config.opt_float("nozzle_diameter", 0);
|
||||
return m_config.get_abs_value("initial_layer_line_width", nozzle_diameter);
|
||||
};
|
||||
double speed_first_layer() const { return m_config.get_abs_value_at("initial_layer_speed", m_params.extruder_id); };
|
||||
double speed_perimeter() const { return m_config.get_abs_value_at("outer_wall_speed", m_params.extruder_id); };
|
||||
double accel_perimeter() const { return m_config.get_abs_value_at("outer_wall_acceleration", m_params.extruder_id); }
|
||||
double line_width_first_layer() const;
|
||||
double line_width() const;
|
||||
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ std::string MZ_Archive::get_errorstr(mz_zip_error mz_err)
|
||||
case MZ_ZIP_TOO_MANY_FILES:
|
||||
return L("too many files");
|
||||
case MZ_ZIP_FILE_TOO_LARGE:
|
||||
return L("file too large");
|
||||
return L("File too large");
|
||||
case MZ_ZIP_UNSUPPORTED_METHOD:
|
||||
return L("unsupported method");
|
||||
case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
|
||||
@@ -106,7 +106,7 @@ std::string MZ_Archive::get_errorstr(mz_zip_error mz_err)
|
||||
case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
|
||||
return L("invalid header or corrupted");
|
||||
case MZ_ZIP_UNSUPPORTED_MULTIDISK:
|
||||
return L("unsupported multidisk");
|
||||
return L("Saving to RAID is not supported.");
|
||||
case MZ_ZIP_DECOMPRESSION_FAILED:
|
||||
return L("decompression failed");
|
||||
case MZ_ZIP_COMPRESSION_FAILED:
|
||||
@@ -138,13 +138,13 @@ std::string MZ_Archive::get_errorstr(mz_zip_error mz_err)
|
||||
case MZ_ZIP_INVALID_FILENAME:
|
||||
return L("invalid filename");
|
||||
case MZ_ZIP_BUF_TOO_SMALL:
|
||||
return L("buffer too small");
|
||||
return L("Buffer too small");
|
||||
case MZ_ZIP_INTERNAL_ERROR:
|
||||
return L("internal error");
|
||||
case MZ_ZIP_FILE_NOT_FOUND:
|
||||
return L("file not found");
|
||||
case MZ_ZIP_ARCHIVE_TOO_LARGE:
|
||||
return L("archive too large");
|
||||
return L("Archive too large");
|
||||
case MZ_ZIP_VALIDATION_FAILED:
|
||||
return L("validation failed");
|
||||
case MZ_ZIP_WRITE_CALLBACK_FAILED:
|
||||
|
||||
@@ -69,7 +69,7 @@ void AMSSetting::create()
|
||||
|
||||
// tip line1
|
||||
m_tip_Insert_material_line1 = new Label(m_panel_Insert_material,
|
||||
_L("The AMS will automatically read the filament information when inserting a new Bambu Lab filament. This takes about 20 seconds.")
|
||||
_L("The AMS will automatically read the filament information when inserting a new Bambu Lab filament spool. This takes about 20 seconds.")
|
||||
);
|
||||
m_tip_Insert_material_line1->SetFont(::Label::Body_13);
|
||||
m_tip_Insert_material_line1->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
@@ -112,7 +112,7 @@ void AMSSetting::create()
|
||||
m_checkbox_starting_auto_read->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_starting_read, this);
|
||||
m_sizer_starting->Add(m_checkbox_starting_auto_read, 0, wxALIGN_CENTER_VERTICAL);
|
||||
m_sizer_starting->Add(0, 0, 0, wxLEFT, 12);
|
||||
m_title_starting_auto_read = new wxStaticText(m_panel_body, wxID_ANY, _L("Power on update"), wxDefaultPosition,wxDefaultSize, 0);
|
||||
m_title_starting_auto_read = new wxStaticText(m_panel_body, wxID_ANY, _L("Update on startup"), wxDefaultPosition,wxDefaultSize, 0);
|
||||
m_title_starting_auto_read->SetFont(::Label::Head_13);
|
||||
m_title_starting_auto_read->SetForegroundColour(AMS_SETTING_GREY800);
|
||||
m_title_starting_auto_read->Wrap(AMS_SETTING_BODY_WIDTH);
|
||||
@@ -125,7 +125,7 @@ void AMSSetting::create()
|
||||
m_sizer_starting_tip_inline = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_tip_starting_line1 = new Label(m_panel_body,
|
||||
_L("The AMS will automatically read the information of inserted filament on start-up. It will take about 1 minute. The reading process will roll the filament spools.")
|
||||
_L("The AMS will automatically read the information of inserted filament on start-up. It will take about 1 minute. The reading process will rotate the filament spools.")
|
||||
);
|
||||
m_tip_starting_line1->SetFont(::Label::Body_13);
|
||||
m_tip_starting_line1->SetForegroundColour(AMS_SETTING_GREY700);
|
||||
|
||||
@@ -44,7 +44,7 @@ void AboutDialogLogo::onRepaint(wxEvent &event)
|
||||
CopyrightsDialog::CopyrightsDialog()
|
||||
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, from_u8((boost::format("%1% - %2%")
|
||||
% (wxGetApp().is_editor() ? SLIC3R_APP_FULL_NAME : GCODEVIEWER_APP_NAME)
|
||||
% _utf8(L("Portions copyright"))).str()),
|
||||
% _utf8(L("License Info"))).str()),
|
||||
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
{
|
||||
this->SetFont(wxGetApp().normal_font());
|
||||
@@ -337,7 +337,7 @@ AboutDialog::AboutDialog()
|
||||
m_html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);
|
||||
}
|
||||
//Add "Portions copyright" button
|
||||
Button* button_portions = new Button(this,_L("Portions copyright"));
|
||||
Button* button_portions = new Button(this,_L("License Info"));
|
||||
button_portions->SetStyle(ButtonStyle::Regular, ButtonType::Window);
|
||||
|
||||
wxBoxSizer *copyright_button_ver = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
@@ -1686,7 +1686,7 @@ AmsMapingTipPopup::AmsMapingTipPopup(wxWindow *parent)
|
||||
m_title_enable_ams->Wrap(-1);
|
||||
sizer_enable_ams->Add(m_title_enable_ams, 0, 0, 0);
|
||||
|
||||
m_tip_enable_ams = new wxStaticText(m_panel_enable_ams, wxID_ANY, _L("Print with filaments in the AMS"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_enable_ams = new wxStaticText(m_panel_enable_ams, wxID_ANY, _L("Print with filament in the AMS"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_enable_ams->SetMinSize(wxSize(FromDIP(200), FromDIP(50)));
|
||||
m_tip_enable_ams->Wrap(FromDIP(200));
|
||||
m_tip_enable_ams->SetForegroundColour(*wxBLACK);
|
||||
@@ -1722,7 +1722,7 @@ AmsMapingTipPopup::AmsMapingTipPopup(wxWindow *parent)
|
||||
m_title_disable_ams->Wrap(-1);
|
||||
sizer_disable_ams->Add(m_title_disable_ams, 0, 0, 0);
|
||||
|
||||
m_tip_disable_ams = new wxStaticText(m_panel_disable_ams, wxID_ANY, _L("Print with the filament mounted on the back of chassis"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_disable_ams = new wxStaticText(m_panel_disable_ams, wxID_ANY, _L("Print with filament on external spool"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_tip_disable_ams->SetMinSize(wxSize(FromDIP(200), FromDIP(50)));
|
||||
m_tip_disable_ams->Wrap(FromDIP(200));
|
||||
m_tip_disable_ams->SetForegroundColour(*wxBLACK);
|
||||
@@ -1783,9 +1783,7 @@ AmsHumidityTipPopup::AmsHumidityTipPopup(wxWindow* parent)
|
||||
humidity_level_list = new AmsHumidityLevelList(this);
|
||||
curr_humidity_img = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("hum_level1_light", this, 132), wxDefaultPosition, wxSize(FromDIP(132), FromDIP(132)), 0);
|
||||
|
||||
m_staticText_note = new Label(this, _L("Please change the desiccant when it is too wet. "
|
||||
"The indicator may not represent accurately in following cases: when the lid is open or the desiccant pack is changed. "
|
||||
"It take hours to absorb the moisture, and low temperatures also slow down the process."));
|
||||
m_staticText_note = new Label(this, _L("Please change the desiccant when it is too wet. The indicator may not represent accurately in following cases: when the lid is open or the desiccant pack is changed. It takes a few hours to absorb the moisture, and low temperatures also slow down the process."));
|
||||
m_staticText_note->SetMinSize(wxSize(FromDIP(680), -1));
|
||||
m_staticText_note->SetMaxSize(wxSize(FromDIP(680), -1));
|
||||
m_staticText_note->Wrap(FromDIP(680));
|
||||
@@ -2021,7 +2019,7 @@ AmsIntroducePopup::AmsIntroducePopup(wxWindow* parent)
|
||||
m_staticText_top->Wrap(-1);
|
||||
bSizer4->Add(m_staticText_top, 0, wxALL, 5);
|
||||
|
||||
m_staticText_bottom = new Label(this, _L("Print using materials mounted on the back of the case"));
|
||||
m_staticText_bottom = new Label(this, _L("Print using filament on external spool."));
|
||||
m_staticText_bottom->Wrap(-1);
|
||||
m_staticText_bottom->SetFont(::Label::Body_13);
|
||||
m_staticText_bottom->SetForegroundColour(wxColour("#6B6B6B"));
|
||||
@@ -2057,13 +2055,13 @@ void AmsIntroducePopup::set_mode(bool enable_ams)
|
||||
{
|
||||
if (enable_ams) {
|
||||
m_staticText_top->SetLabelText(_L("Enable AMS"));
|
||||
m_staticText_bottom->SetLabelText(_L("Print with filaments in AMS"));
|
||||
m_staticText_bottom->SetLabelText(_L("Print with filament in AMS"));
|
||||
m_img_enable_ams->Show();
|
||||
m_img_disable_ams->Hide();
|
||||
}
|
||||
else {
|
||||
m_staticText_top->SetLabelText(_L("Do not Enable AMS"));
|
||||
m_staticText_bottom->SetLabelText(_L("Print with filaments mounted on the back of the chassis"));
|
||||
m_staticText_bottom->SetLabelText(_L("Print with filament on external spool"));
|
||||
m_staticText_bottom->SetMinSize(wxSize(FromDIP(180), -1));
|
||||
m_staticText_bottom->Wrap(FromDIP(180));
|
||||
m_img_enable_ams->Hide();
|
||||
@@ -2437,7 +2435,7 @@ void AmsReplaceMaterialDialog::update_to_nozzle(int nozzle_id)
|
||||
}
|
||||
else if (!m_obj->GetFilaSystem()->IsAutoRefillEnabled())
|
||||
{
|
||||
label_txt->SetLabelText(_L("AMS filament backup is not enabled, please enable it in the AMS settings."));
|
||||
label_txt->SetLabelText(_L("AMS filament backup is not enabled; please enable it in the AMS settings."));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -380,17 +380,17 @@ void AuFile::on_input_enter(wxCommandEvent &evt)
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && new_file_name.empty()) {
|
||||
info_line = _L("The name is not allowed to be empty.");
|
||||
info_line = _L("The name field is not allowed to be empty.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && new_file_name.find_first_of(' ') == 0) {
|
||||
info_line = _L("The name is not allowed to start with space character.");
|
||||
info_line = _L("The name is not allowed to start with a space.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
if (m_valid_type == Valid && new_file_name.find_last_of(' ') == new_file_name.length() - 1) {
|
||||
info_line = _L("The name is not allowed to end with space character.");
|
||||
info_line = _L("The name is not allowed to end with a space.");
|
||||
m_valid_type = NoValid;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,12 +77,11 @@ std::pair<std::string, std::vector<size_t>> SlicingProcessCompletedEvent::format
|
||||
try {
|
||||
this->rethrow_exception();
|
||||
} catch (const std::bad_alloc &ex) {
|
||||
wxString errmsg = GUI::from_u8(boost::format(_utf8(L("A error occurred. Maybe memory of system is not enough or it's a bug "
|
||||
"of the program"))).str());
|
||||
wxString errmsg = GUI::from_u8(boost::format(_utf8(L("An error occurred. The system may have run out of memory, or a bug may have occurred."))).str());
|
||||
error = std::string(errmsg.ToUTF8()) + "\n" + std::string(ex.what());
|
||||
} catch (const HardCrash &ex) {
|
||||
error = GUI::format(_u8L("A fatal error occurred: \"%1%\""), ex.what()) + "\n" +
|
||||
_u8L("Please save project and restart the program.");
|
||||
_u8L("Please save your project and restart the application.");
|
||||
} catch (PlaceholderParserError &ex) {
|
||||
error = ex.what();
|
||||
monospace = 1;
|
||||
@@ -200,7 +199,7 @@ void BackgroundSlicingProcess::process_fff()
|
||||
//BBS: add the logic to process from an existed gcode file
|
||||
if (m_print->finished()) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: skip slicing, to process previous gcode file")%__LINE__;
|
||||
m_fff_print->set_status(80, _utf8(L("Processing G-code from Previous file...")));
|
||||
m_fff_print->set_status(80, _utf8(L("Processing G-Code from previous file\u2026")));
|
||||
wxCommandEvent evt(m_event_slicing_completed_id);
|
||||
// Post the Slicing Finished message for the G-code viewer to update.
|
||||
// Passing the timestamp
|
||||
@@ -675,13 +674,13 @@ bool BackgroundSlicingProcess::empty() const
|
||||
return m_print->empty();
|
||||
}
|
||||
|
||||
StringObjectException BackgroundSlicingProcess::validate(StringObjectException *warning, Polygons* collison_polygons, std::vector<std::pair<Polygon, float>>* height_polygons)
|
||||
StringObjectException BackgroundSlicingProcess::validate(std::vector<StringObjectException> *warnings, Polygons* collison_polygons, std::vector<std::pair<Polygon, float>>* height_polygons)
|
||||
{
|
||||
assert(m_print != nullptr);
|
||||
assert(m_print == m_fff_print);
|
||||
|
||||
m_fff_print->is_BBL_printer() = wxGetApp().preset_bundle->is_bbl_vendor();
|
||||
return m_print->validate(warning, collison_polygons, height_polygons);
|
||||
return m_print->validate(warnings, collison_polygons, height_polygons);
|
||||
}
|
||||
|
||||
// Apply config over the print. Returns false, if the new config values caused any of the already
|
||||
@@ -869,7 +868,7 @@ void BackgroundSlicingProcess::export_gcode()
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw Slic3r::ExportError(_utf8(L("Unknown error when exporting G-code.")));
|
||||
throw Slic3r::ExportError(_utf8(L("Unknown error with G-code export")));
|
||||
}
|
||||
switch (copy_ret_val) {
|
||||
case CopyFileResult::SUCCESS: break; // no error
|
||||
@@ -920,7 +919,7 @@ void BackgroundSlicingProcess::prepare_upload()
|
||||
m_print->set_status(95, _utf8(L("Running post-processing scripts")));
|
||||
std::string error_message;
|
||||
if (copy_file(m_temp_output_path, source_path.string(), error_message) != SUCCESS)
|
||||
throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed")));
|
||||
throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed.")));
|
||||
m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
|
||||
// Orca: skip post-processing scripts for BBL printers as we have run them already in finalize_gcode()
|
||||
// todo: do we need to copy the file?
|
||||
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
bool empty() const;
|
||||
// Validate the print. Returns an empty string if valid, returns an error message if invalid.
|
||||
// Call validate before calling start().
|
||||
StringObjectException validate(StringObjectException *warning = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr);
|
||||
StringObjectException validate(std::vector<StringObjectException> *warnings = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr);
|
||||
|
||||
// Set the export path of the G-code.
|
||||
// Once the path is set, the G-code
|
||||
|
||||
@@ -566,7 +566,7 @@ void BedShapePanel::load_stl()
|
||||
model = Model::read_from_file(file_name);
|
||||
}
|
||||
catch (std::exception &) {
|
||||
show_error(this, _L("Error! Invalid model"));
|
||||
show_error(this, _L("Error: invalid model"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -578,7 +578,7 @@ void BedShapePanel::load_stl()
|
||||
return;
|
||||
}
|
||||
if (expolygons.size() > 1) {
|
||||
show_error(this, _L("The selected file contains several disjoint areas. This is not supported."));
|
||||
show_error(this, _L("The selected file contains several disjointed areas. This is not supported."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ wxString get_fail_reason(int code)
|
||||
return _L("Failed to publish login request");
|
||||
|
||||
else if (code == BAMBU_NETWORK_ERR_BIND_GET_PRINTER_TICKET_TIMEOUT)
|
||||
return _L("Get ticket from device timeout");
|
||||
return _L("Timeout getting ticket from device");
|
||||
|
||||
else if (code == BAMBU_NETWORK_ERR_BIND_GET_CLOUD_TICKET_TIMEOUT)
|
||||
return _L("Get ticket from server timeout");
|
||||
return _L("Timeout getting ticket from server");
|
||||
|
||||
else if (code == BAMBU_NETWORK_ERR_BIND_POST_TICKET_TO_CLOUD_FAILED)
|
||||
return _L("Failed to post ticket to server");
|
||||
|
||||
@@ -304,7 +304,7 @@ void HistoryWindow::reqeust_history_result(MachineObject* obj)
|
||||
cali_info.use_nozzle_volume_type = false;
|
||||
cali_info.use_extruder_id = false;
|
||||
CalibUtils::emit_get_PA_calib_infos(cali_info);
|
||||
m_tips->SetLabel(_L("Refreshing the historical Flow Dynamics Calibration records"));
|
||||
m_tips->SetLabel(_L("Refreshing the previous Flow Dynamics Calibration records"));
|
||||
BOOST_LOG_TRIVIAL(info) << "request calib history";
|
||||
}
|
||||
}
|
||||
@@ -476,7 +476,7 @@ int HistoryWindow::get_extruder_id()
|
||||
void HistoryWindow::on_click_new_button(wxCommandEvent& event)
|
||||
{
|
||||
if (curr_obj && curr_obj->get_printer_series() == PrinterSeries::SERIES_P1P && m_calib_results_history.size() >= 16) {
|
||||
MessageDialog msg_dlg(nullptr, wxString::Format(_L("This machine type can only hold %d history results per nozzle."), 16), wxEmptyString, wxICON_WARNING | wxOK);
|
||||
MessageDialog msg_dlg(nullptr, wxString::Format(_L("This machine type can only hold %d historical results per nozzle."), 16), wxEmptyString, wxICON_WARNING | wxOK);
|
||||
msg_dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
@@ -913,8 +913,7 @@ void NewCalibrationHistoryDialog::on_ok(wxCommandEvent &event)
|
||||
|
||||
if (iter != m_history_results.end()) {
|
||||
|
||||
wxString duplicate_name_info = wxString::Format(_L("There is already a historical calibration result with the same name: %s. Only one of the results with the same name "
|
||||
"is saved. Are you sure you want to override the historical result?"), m_new_result.name);
|
||||
wxString duplicate_name_info = wxString::Format(_L("There is already a previous calibration result with the same name: %s. Only one result with a name is saved. Are you sure you want to overwrite the previous result\?"), m_new_result.name);
|
||||
|
||||
duplicate_name_info = wxString::Format(_L("Within the same extruder, the name(%s) must be unique when the filament type, nozzle diameter, and nozzle flow are the same.\n"
|
||||
"Are you sure you want to override the historical result?"), m_new_result.name);
|
||||
|
||||
@@ -805,10 +805,7 @@ void PressureAdvanceWizard::on_cali_start()
|
||||
curr_obj->manual_pa_cali_method = pa_cali_method;
|
||||
|
||||
if (curr_obj->get_printer_series() != PrinterSeries::SERIES_X1 && curr_obj->pa_calib_tab.size() >= MAX_PA_HISTORY_RESULTS_NUMS) {
|
||||
MessageDialog msg_dlg(nullptr, wxString::Format(_L("This machine type can only hold 16 history results per nozzle. "
|
||||
"You can delete the existing historical results and then start calibration. "
|
||||
"Or you can continue the calibration, but you cannot create new calibration historical results.\n"
|
||||
"Do you still want to continue the calibration?"), MAX_PA_HISTORY_RESULTS_NUMS), wxEmptyString, wxICON_WARNING | wxYES | wxCANCEL);
|
||||
MessageDialog msg_dlg(nullptr, wxString::Format(_L("This machine type can only hold 16 historical results per nozzle. You can delete the existing historical results and then start calibration. Or you can continue the calibration, but you cannot create new calibration historical results.\nDo you still want to continue the calibration\?"), MAX_PA_HISTORY_RESULTS_NUMS), wxEmptyString, wxICON_WARNING | wxYES | wxCANCEL);
|
||||
if (msg_dlg.ShowModal() != wxID_YES) {
|
||||
return;
|
||||
}
|
||||
@@ -930,8 +927,7 @@ bool PressureAdvanceWizard::can_save_cali_result(const std::vector<PACalibResult
|
||||
|
||||
if (!same_pa_names.empty()) {
|
||||
same_pa_names.erase(same_pa_names.size() - 2);
|
||||
wxString duplicate_name_info = wxString::Format(_L("There is already a historical calibration result with the same name: %s. Only one of the results with the same name "
|
||||
"is saved. Are you sure you want to override the historical result?"), same_pa_names);
|
||||
wxString duplicate_name_info = wxString::Format(_L("There is already a previous calibration result with the same name: %s. Only one result with a name is saved. Are you sure you want to overwrite the previous result\?"), same_pa_names);
|
||||
|
||||
if (curr_obj->is_multi_extruders())
|
||||
duplicate_name_info = wxString::Format(_L("Within the same extruder, the name(%s) must be unique when the filament type, nozzle diameter, and nozzle flow are the same.\n"
|
||||
@@ -943,7 +939,7 @@ bool PressureAdvanceWizard::can_save_cali_result(const std::vector<PACalibResult
|
||||
}
|
||||
|
||||
if (curr_obj->get_printer_series() != PrinterSeries::SERIES_X1 && curr_obj->pa_calib_tab.size() >= MAX_PA_HISTORY_RESULTS_NUMS) {
|
||||
MessageDialog msg_dlg(nullptr, wxString::Format(_L("This machine type can only hold %d history results per nozzle. This result will not be saved."), MAX_PA_HISTORY_RESULTS_NUMS),
|
||||
MessageDialog msg_dlg(nullptr, wxString::Format(_L("This machine type can only hold %d historical results per nozzle. This result will not be saved."), MAX_PA_HISTORY_RESULTS_NUMS),
|
||||
wxEmptyString, wxICON_WARNING | wxOK);
|
||||
msg_dlg.ShowModal();
|
||||
return false;
|
||||
|
||||
@@ -326,7 +326,7 @@ void CalibrationCaliPage::update_subtask(MachineObject* obj)
|
||||
prepare_text = wxString::Format(_L("Cloud Slicing..."));
|
||||
}
|
||||
else {
|
||||
prepare_text = wxString::Format(_L("In Cloud Slicing Queue, there are %s tasks ahead."), std::to_string(obj->queue_number));
|
||||
prepare_text = wxString::Format(_L("In Cloud Slicing Queue, there are %s tasks ahead of you."), std::to_string(obj->queue_number));
|
||||
show_percent = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,7 +601,7 @@ PAPageHelpPanel::PAPageHelpPanel(wxWindow* parent, bool ground_panel, wxWindowID
|
||||
wxBoxSizer* top_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
top_sizer->AddSpacer(FromDIP(10));
|
||||
|
||||
auto help_text_title = new Label(this, _L("How to use calibration result?"));
|
||||
auto help_text_title = new Label(this, _L("How can I use calibration results\?"));
|
||||
help_text_title->SetFont(Label::Head_14);
|
||||
top_sizer->Add(help_text_title, 0, wxLEFT | wxRIGHT, left_align_padding);
|
||||
|
||||
|
||||
@@ -1882,12 +1882,12 @@ void CalibrationPresetPage::show_status(CaliPresetPageStatus status)
|
||||
Enable_Send_Button(false);
|
||||
}
|
||||
else if (status == CaliPresetPageStatus::CaliPresetStatusNeedForceUpgrading) {
|
||||
wxString msg_text = _L("Cannot send the print job to a printer whose firmware is required to get updated.");
|
||||
wxString msg_text = _L("Cannot send the print job to a printer whose firmware must be updated.");
|
||||
update_print_status_msg(msg_text, true);
|
||||
Enable_Send_Button(false);
|
||||
}
|
||||
else if (status == CaliPresetPageStatus::CaliPresetStatusNeedConsistencyUpgrading) {
|
||||
wxString msg_text = _L("Cannot send the print job to a printer whose firmware is required to get updated.");
|
||||
wxString msg_text = _L("Cannot send the print job to a printer whose firmware must be updated.");
|
||||
update_print_status_msg(msg_text, true);
|
||||
Enable_Send_Button(false);
|
||||
}
|
||||
|
||||
@@ -116,10 +116,7 @@ void CalibrationPAStartPage::create_page(wxWindow* parent)
|
||||
|
||||
create_about(parent,
|
||||
_L("About this calibration"),
|
||||
_L("Please find the details of Flow Dynamics Calibration from our wiki.\
|
||||
\n\nUsually the calibration is unnecessary. When you start a single color/material print, with the \"flow dynamics calibration\" option checked in the print start menu, the printer will follow the old way, calibrate the filament before the print; When you start a multi color/material print, the printer will use the default compensation parameter for the filament during every filament switch which will have a good result in most cases.\
|
||||
\n\nPlease note that there are a few cases that can make the calibration results unreliable, such as insufficient adhesion on the build plate. Improving adhesion can be achieved by washing the build plate or applying glue. For more information on this topic, please refer to our Wiki.\
|
||||
\n\nThe calibration results have about 10 percent jitter in our test, which may cause the result not exactly the same in each calibration. We are still investigating the root cause to do improvements with new updates."));
|
||||
_L("Please find the details of Flow Dynamics Calibration from our wiki.\n\nUsually the calibration is unnecessary. When you start a single color/material print, with the \"flow dynamics calibration\" option checked in the print start menu, the printer will follow the old way, calibrate the filament before the print; When you start a multi color/material print, the printer will use the default compensation parameter for the filament during every filament switch which will have a good result in most cases.\n\nPlease note that there are a few cases that can make the calibration results unreliable, such as insufficient adhesion on the build plate. Improving adhesion can be achieved by washing the build plate or applying glue. For more information on this topic, please refer to our Wiki.\n\nThe calibration results have about 10 percent jitter in our test, which may cause the result not exactly the same in each calibration. We are still investigating the root cause to do improvements with new updates."));
|
||||
m_top_sizer->Add(m_about_title);
|
||||
m_top_sizer->Add(m_about_content);
|
||||
m_top_sizer->AddSpacer(PRESET_GAP);
|
||||
@@ -255,9 +252,7 @@ void CalibrationFlowRateStartPage::create_page(wxWindow* parent)
|
||||
auto_cali_title->SetMinSize({CALIBRATION_START_PAGE_TEXT_MAX_LENGTH, -1});
|
||||
|
||||
auto auto_cali_content = new Label(this,
|
||||
_L("Auto Flow Rate Calibration utilizes Bambu Lab's Micro-Lidar technology, directly measuring the calibration patterns. However, please be advised that the efficacy and accuracy of this method may be compromised with specific types of materials. Particularly, filaments that are transparent or semi-transparent, sparkling-particled, or have a high-reflective finish may not be suitable for this calibration and can produce less-than-desirable results.\
|
||||
\n\nThe calibration results may vary between each calibration or filament. We are still improving the accuracy and compatibility of this calibration through firmware updates over time.\
|
||||
\n\nCaution: Flow Rate Calibration is an advanced process, to be attempted only by those who fully understand its purpose and implications. Incorrect usage can lead to sub-par prints or printer damage. Please make sure to carefully read and understand the process before doing it."));
|
||||
_L("Auto Flow Rate Calibration utilizes Bambu Lab\'s Micro-Lidar technology, directly measuring the calibration patterns. However, please be advised that the efficacy and accuracy of this method may be compromised with specific types of materials. Particularly, filaments that are transparent or semi-transparent, have sparkles, or have a highly-reflective finish may not be suitable for this calibration and can produce less-than-desirable results.\n\nThe calibration results may vary between each calibration or filament. We are still improving the accuracy and compatibility of this calibration through firmware updates over time.\n\nCaution: Flow Rate Calibration is an advanced process, to be attempted only by those who fully understand its purpose and implications. Incorrect usage can lead to sub-par prints or printer damage. Please make sure to carefully read and understand the process before doing it."));
|
||||
auto_cali_content->SetFont(Label::Body_14);
|
||||
auto_cali_content->Wrap(CALIBRATION_START_PAGE_TEXT_MAX_LENGTH);
|
||||
auto_cali_content->SetMinSize({CALIBRATION_START_PAGE_TEXT_MAX_LENGTH, -1});
|
||||
|
||||
@@ -9,13 +9,29 @@
|
||||
#include "libslic3r/MaterialType.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/GCode/AdaptivePAProcessor.hpp"
|
||||
#include "Plater.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string trim_copy(const std::string& text)
|
||||
{
|
||||
const auto first = text.find_first_not_of(" \t\r\n");
|
||||
if (first == std::string::npos)
|
||||
return {};
|
||||
|
||||
const auto last = text.find_last_not_of(" \t\r\n");
|
||||
return text.substr(first, last - first + 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ConfigManipulation::apply(DynamicPrintConfig* config, DynamicPrintConfig* new_config)
|
||||
{
|
||||
bool modified = false;
|
||||
@@ -109,8 +125,7 @@ void ConfigManipulation::check_nozzle_temperature_range(DynamicPrintConfig *conf
|
||||
|
||||
if (config->has("nozzle_temperature")) {
|
||||
if (config->opt_int("nozzle_temperature", 0) < temperature_range_low || config->opt_int("nozzle_temperature", 0) > temperature_range_high) {
|
||||
wxString msg_text = _(L("Nozzle may be blocked when the temperature is out of recommended range.\n"
|
||||
"Please make sure whether to use the temperature to print.\n\n"));
|
||||
wxString msg_text = _(L("The nozzle may become clogged when the temperature is out of the recommended range.\nPlease make sure whether to use this temperature to print.\n\n"));
|
||||
msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high);
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -132,8 +147,7 @@ void ConfigManipulation::check_nozzle_temperature_initial_layer_range(DynamicPri
|
||||
if (config->opt_int("nozzle_temperature_initial_layer", 0) < temperature_range_low ||
|
||||
config->opt_int("nozzle_temperature_initial_layer", 0) > temperature_range_high)
|
||||
{
|
||||
wxString msg_text = _(L("Nozzle may be blocked when the temperature is out of recommended range.\n"
|
||||
"Please make sure whether to use the temperature to print.\n\n"));
|
||||
wxString msg_text = _(L("The nozzle may become clogged when the temperature is out of the recommended range.\nPlease make sure whether to use this temperature to print.\n\n"));
|
||||
msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high);
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -143,6 +157,30 @@ void ConfigManipulation::check_nozzle_temperature_initial_layer_range(DynamicPri
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManipulation::check_adaptive_pressure_advance_model(DynamicPrintConfig* config)
|
||||
{
|
||||
if (is_msg_dlg_already_exist || !config->has("adaptive_pressure_advance_model"))
|
||||
return;
|
||||
|
||||
const auto* model = config->option<ConfigOptionStrings>("adaptive_pressure_advance_model");
|
||||
if (model == nullptr || model->values.empty())
|
||||
return;
|
||||
|
||||
std::string raw_model;
|
||||
for (const std::string& chunk : model->values)
|
||||
raw_model += chunk;
|
||||
|
||||
std::string error = AdaptivePAProcessor::validate_adaptive_pa_model(raw_model);
|
||||
if (!error.empty()) {
|
||||
wxString msg_text = _L("Adaptive Pressure Advance model validation failed:\n");
|
||||
msg_text += from_u8(error);
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
is_msg_dlg_already_exist = true;
|
||||
dialog.ShowModal();
|
||||
is_msg_dlg_already_exist = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConfigManipulation::check_filament_max_volumetric_speed(DynamicPrintConfig *config)
|
||||
{
|
||||
@@ -152,7 +190,7 @@ void ConfigManipulation::check_filament_max_volumetric_speed(DynamicPrintConfig
|
||||
float max_volumetric_speed = config->has("filament_max_volumetric_speed") ? config->opt_float("filament_max_volumetric_speed", (float) 0.5) : 0.5;
|
||||
// BBS: limite the min max_volumetric_speed
|
||||
if (max_volumetric_speed < 0.5) {
|
||||
const wxString msg_text = _(L("Too small max volumetric speed.\nReset to 0.5."));
|
||||
const wxString msg_text = _(L("Too small max volumetric speed.\nValue was reset to 0.5"));
|
||||
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -172,8 +210,7 @@ void ConfigManipulation::check_chamber_temperature(DynamicPrintConfig* config)
|
||||
int chamber_min_temp, chamber_max_temp;
|
||||
if (MaterialType::get_chamber_temperature_range(filament_type, chamber_min_temp, chamber_max_temp)) {
|
||||
if (chamber_max_temp < config->option<ConfigOptionInts>("chamber_temperature")->get_at(0)) {
|
||||
wxString msg_text = wxString::Format(_L("Current chamber temperature is higher than the material's safe temperature, this may result in material softening and clogging. "
|
||||
"The maximum safe temperature for the material is %d"), chamber_max_temp);
|
||||
wxString msg_text = wxString::Format(_L("Current chamber temperature is higher than the material\'s safe temperature; this may result in material softening and nozzle clogs. The maximum safe temperature for the material is %d"), chamber_max_temp);
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
is_msg_dlg_already_exist = true;
|
||||
dialog.ShowModal();
|
||||
@@ -224,7 +261,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
auto gpreset = GUI::wxGetApp().preset_bundle->printers.get_edited_preset();
|
||||
if (layer_height < EPSILON)
|
||||
{
|
||||
const wxString msg_text = _(L("Too small layer height.\nReset to 0.2."));
|
||||
const wxString msg_text = _(L("Layer height too small\nIt has been reset to 0.2"));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -251,7 +288,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
//BBS: ironing_spacing shouldn't be too small or equal to zero
|
||||
if (config->opt_float("ironing_spacing") < 0.05)
|
||||
{
|
||||
const wxString msg_text = _(L("Too small ironing spacing.\nReset to 0.1."));
|
||||
const wxString msg_text = _(L("Ironing spacing too small\nIt has been reset to 0.1"));
|
||||
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -262,7 +299,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
}
|
||||
if (config->opt_float("support_ironing_spacing") < 0.05)
|
||||
{
|
||||
const wxString msg_text = _(L("Too small ironing spacing.\nReset to 0.1."));
|
||||
const wxString msg_text = _(L("Ironing spacing too small\nIt has been reset to 0.1"));
|
||||
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -286,10 +323,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
|
||||
if (abs(config->option<ConfigOptionFloat>("xy_hole_compensation")->value) > 2)
|
||||
{
|
||||
const wxString msg_text = _(L("This setting is only used for model size tunning with small value in some cases.\n"
|
||||
"For example, when model size has small error and hard to be assembled.\n"
|
||||
"For large size tuning, please use model scale function.\n\n"
|
||||
"The value will be reset to 0."));
|
||||
const wxString msg_text = _(L("This setting is only used for tuning model size by small amounts.\nFor example, when the model size has small errors or when tolerances are incorrect. For large adjustments, please use the model scale function.\n\nThe value will be reset to 0."));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -301,10 +335,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
|
||||
if (abs(config->option<ConfigOptionFloat>("xy_contour_compensation")->value) > 2)
|
||||
{
|
||||
const wxString msg_text = _(L("This setting is only used for model size tunning with small value in some cases.\n"
|
||||
"For example, when model size has small error and hard to be assembled.\n"
|
||||
"For large size tuning, please use model scale function.\n\n"
|
||||
"The value will be reset to 0."));
|
||||
const wxString msg_text = _(L("This setting is only used for tuning model size by small amounts.\nFor example, when the model size has small errors or when tolerances are incorrect. For large adjustments, please use the model scale function.\n\nThe value will be reset to 0."));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -316,10 +347,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
|
||||
if (config->option<ConfigOptionFloat>("elefant_foot_compensation")->value > 1)
|
||||
{
|
||||
const wxString msg_text = _(L("Too large elephant foot compensation is unreasonable.\n"
|
||||
"If really have serious elephant foot effect, please check other settings.\n"
|
||||
"For example, whether bed temperature is too high.\n\n"
|
||||
"The value will be reset to 0."));
|
||||
const wxString msg_text = _(L("The elephant foot compensation value is too large.\nIf there are significant elephant foot issues, please check other settings.\nThe bed temperature may be too high, for example.\n\nThe value will be reset to 0."));
|
||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
is_msg_dlg_already_exist = true;
|
||||
@@ -591,7 +619,7 @@ void ConfigManipulation::apply_null_fff_config(DynamicPrintConfig *config, std::
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, const bool is_global_config)
|
||||
void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, int variant_index, const bool is_global_config)
|
||||
{
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
|
||||
@@ -615,9 +643,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
|
||||
bool have_perimeters = config->opt_int("wall_loops") > 0;
|
||||
for (auto el : { "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "detect_thin_wall", "detect_overhang_wall",
|
||||
"seam_position", "staggered_inner_seams", "wall_sequence", "outer_wall_line_width",
|
||||
"inner_wall_speed", "outer_wall_speed", "small_perimeter_speed", "small_perimeter_threshold" })
|
||||
"seam_position", "staggered_inner_seams", "wall_sequence", "outer_wall_line_width" })
|
||||
toggle_field(el, have_perimeters);
|
||||
for (auto el : { "inner_wall_speed", "outer_wall_speed", "small_perimeter_speed", "small_perimeter_threshold" })
|
||||
toggle_field(el, have_perimeters, variant_index);
|
||||
|
||||
bool have_infill = config->option<ConfigOptionPercent>("sparse_infill_density")->value > 0;
|
||||
// sparse_infill_filament_id uses the same logic as in Print::extruders()
|
||||
@@ -683,50 +712,47 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
toggle_field("bottom_surface_density", has_bottom_shell);
|
||||
|
||||
for (auto el : { "infill_direction", "sparse_infill_line_width", "gap_fill_target","filter_out_gap_fill","infill_wall_overlap",
|
||||
"sparse_infill_speed", "bridge_speed", "internal_bridge_speed", "bridge_angle", "internal_bridge_angle", "relative_bridge_angle",
|
||||
"bridge_angle", "internal_bridge_angle", "relative_bridge_angle",
|
||||
"solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id",
|
||||
})
|
||||
toggle_field(el, have_infill || has_solid_infill);
|
||||
for (auto el : { "sparse_infill_speed", "bridge_speed", "internal_bridge_speed"})
|
||||
toggle_field(el, have_infill || has_solid_infill, variant_index);
|
||||
|
||||
toggle_field("top_shell_thickness", ! has_spiral_vase && has_top_shell);
|
||||
toggle_field("bottom_shell_thickness", ! has_spiral_vase && has_bottom_shell);
|
||||
|
||||
// Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
|
||||
toggle_field("gap_infill_speed", have_perimeters);
|
||||
toggle_field("gap_infill_speed", have_perimeters, variant_index);
|
||||
|
||||
toggle_field("top_surface_line_width", has_top_shell);
|
||||
toggle_field("top_surface_speed", has_top_shell, variant_index);
|
||||
|
||||
for (auto el : { "top_surface_line_width", "top_surface_speed" })
|
||||
toggle_field(el, has_top_shell);
|
||||
|
||||
bool have_default_acceleration = config->opt_float("default_acceleration") > 0;
|
||||
bool have_default_acceleration = config->opt_float_nullable("default_acceleration", variant_index) > 0;
|
||||
|
||||
for (auto el : {"outer_wall_acceleration", "inner_wall_acceleration", "initial_layer_acceleration", "initial_layer_travel_acceleration",
|
||||
"top_surface_acceleration", "travel_acceleration", "bridge_acceleration", "sparse_infill_acceleration", "internal_solid_infill_acceleration"})
|
||||
toggle_field(el, have_default_acceleration);
|
||||
toggle_field(el, have_default_acceleration, variant_index);
|
||||
|
||||
const bool junction_deviation_enabled =
|
||||
gcf_is_marlin_firmware &&
|
||||
[&]() {
|
||||
const auto *machine_jd = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("machine_max_junction_deviation");
|
||||
return machine_jd && !machine_jd->values.empty() && machine_jd->values.front() > 0.0;
|
||||
}();
|
||||
|
||||
toggle_line("default_junction_deviation", gcf_is_marlin_firmware);
|
||||
toggle_field("default_junction_deviation", junction_deviation_enabled);
|
||||
toggle_field("default_jerk", !junction_deviation_enabled);
|
||||
|
||||
const std::initializer_list<const char*> jerk_options = {
|
||||
"outer_wall_jerk", "inner_wall_jerk", "initial_layer_jerk",
|
||||
"initial_layer_travel_jerk", "top_surface_jerk", "travel_jerk", "infill_jerk"
|
||||
};
|
||||
|
||||
if (junction_deviation_enabled) {
|
||||
for (auto el : jerk_options)
|
||||
toggle_line(el, false);
|
||||
bool machine_supports_junction_deviation = false;
|
||||
if (gcf_is_marlin_firmware) {
|
||||
if (const auto *machine_jd = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("machine_max_junction_deviation")) {
|
||||
machine_supports_junction_deviation = !machine_jd->values.empty() && machine_jd->values.front() > 0.0;
|
||||
}
|
||||
}
|
||||
toggle_line("default_junction_deviation", gcf_is_marlin_firmware, variant_index);
|
||||
if (machine_supports_junction_deviation) {
|
||||
toggle_field("default_junction_deviation", true, variant_index);
|
||||
toggle_field("default_jerk", false, variant_index);
|
||||
for (auto el : { "outer_wall_jerk", "inner_wall_jerk", "initial_layer_jerk", "initial_layer_travel_jerk", "top_surface_jerk", "travel_jerk", "infill_jerk"})
|
||||
toggle_line(el, false, variant_index);
|
||||
} else {
|
||||
const bool have_default_jerk = config->has("default_jerk") && config->opt_float("default_jerk") > 0;
|
||||
for (auto el : jerk_options) {
|
||||
toggle_line(el, true);
|
||||
toggle_field(el, have_default_jerk);
|
||||
toggle_field("default_junction_deviation", false, variant_index);
|
||||
toggle_field("default_jerk", true, variant_index);
|
||||
bool have_default_jerk = config->has("default_jerk") && config->opt_float_nullable("default_jerk", variant_index) > 0;
|
||||
for (auto el : { "outer_wall_jerk", "inner_wall_jerk", "initial_layer_jerk", "initial_layer_travel_jerk", "top_surface_jerk", "travel_jerk", "infill_jerk"}) {
|
||||
toggle_line(el, true, variant_index);
|
||||
toggle_field(el, have_default_jerk, variant_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,11 +926,11 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
for (auto el : {"first_layer_flow_ratio", "outer_wall_flow_ratio", "inner_wall_flow_ratio", "overhang_flow_ratio", "sparse_infill_flow_ratio", "internal_solid_infill_flow_ratio", "gap_fill_flow_ratio", "support_flow_ratio", "support_interface_flow_ratio"})
|
||||
toggle_line(el, has_set_other_flow_ratios);
|
||||
|
||||
bool has_overhang_speed = config->opt_bool("enable_overhang_speed");
|
||||
bool has_overhang_speed = config->opt_bool_nullable("enable_overhang_speed", variant_index);
|
||||
for (auto el : {"overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed"})
|
||||
toggle_line(el, has_overhang_speed);
|
||||
toggle_line(el, has_overhang_speed, variant_index);
|
||||
|
||||
toggle_line("slowdown_for_curled_perimeters", has_overhang_speed);
|
||||
toggle_line("slowdown_for_curled_perimeters", has_overhang_speed, variant_index);
|
||||
|
||||
toggle_line("flush_into_objects", !is_global_config);
|
||||
|
||||
@@ -1098,9 +1124,7 @@ int ConfigManipulation::show_spiral_mode_settings_dialog(bool is_object_config)
|
||||
msg_text += _(L(" But machines with I3 structure will not generate timelapse videos."));
|
||||
}
|
||||
if (!is_object_config)
|
||||
msg_text += "\n\n" + _(L("Change these settings automatically?\n"
|
||||
"Yes - Change these settings and enable spiral mode automatically\n"
|
||||
"No - Give up using spiral mode this time"));
|
||||
msg_text += "\n\n" + _(L("Change these settings automatically\?\nYes - Change these settings and enable spiral/vase mode automatically\nNo - Cancel enabling spiral mode"));
|
||||
|
||||
MessageDialog dialog(wxGetApp().plater(), msg_text, "",
|
||||
wxICON_WARNING | (!is_object_config ? wxYES | wxNO : wxOK));
|
||||
|
||||
@@ -70,13 +70,14 @@ public:
|
||||
|
||||
// FFF print
|
||||
void update_print_fff_config(DynamicPrintConfig* config, const bool is_global_config = false, const bool is_plate_config = false);
|
||||
void toggle_print_fff_options(DynamicPrintConfig* config, const bool is_global_config = false);
|
||||
void toggle_print_fff_options(DynamicPrintConfig* config, int variant_index, const bool is_global_config = false);
|
||||
void apply_null_fff_config(DynamicPrintConfig *config, std::vector<std::string> const &keys, std::map<ObjectBase*, ModelConfig*> const & configs);
|
||||
|
||||
//BBS: FFF filament nozzle temperature range
|
||||
void check_nozzle_recommended_temperature_range(DynamicPrintConfig *config);
|
||||
void check_nozzle_temperature_range(DynamicPrintConfig* config);
|
||||
void check_nozzle_temperature_initial_layer_range(DynamicPrintConfig* config);
|
||||
void check_adaptive_pressure_advance_model(DynamicPrintConfig* config);
|
||||
void check_filament_max_volumetric_speed(DynamicPrintConfig *config);
|
||||
void check_chamber_temperature(DynamicPrintConfig* config);
|
||||
void check_chamber_minimal_temperature(DynamicPrintConfig* config);
|
||||
|
||||
@@ -159,7 +159,7 @@ void ConnectPrinterDialog::on_button_confirm(wxCommandEvent &event)
|
||||
wxString code = m_textCtrl_code->GetTextCtrl()->GetValue();
|
||||
for (char c : code) {
|
||||
if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))) {
|
||||
show_error(this, _L("Invalid input."));
|
||||
show_error(this, _L("Invalid input"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1049,7 +1049,7 @@ wxWindow *CreateFilamentPresetDialog::create_dialog_buttons()
|
||||
|
||||
if (!m_can_not_find_vendor_checkbox->GetValue()) {
|
||||
if (_L("Select Vendor") == vendor_str) {
|
||||
MessageDialog dlg(this, _L("Vendor is not selected, please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("Vendor is not selected; please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
@@ -1058,7 +1058,7 @@ wxWindow *CreateFilamentPresetDialog::create_dialog_buttons()
|
||||
}
|
||||
} else {
|
||||
if (m_filament_custom_vendor_input->GetTextCtrl()->GetValue().empty()) {
|
||||
MessageDialog dlg(this, _L("Custom vendor is missing, please input custom vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("Custom vendor missing; please input custom vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
@@ -1087,7 +1087,7 @@ wxWindow *CreateFilamentPresetDialog::create_dialog_buttons()
|
||||
wxString serial_str = m_filament_serial_input->GetTextCtrl()->GetValue();
|
||||
std::string serial_name;
|
||||
if (serial_str.empty()) {
|
||||
MessageDialog dlg(this, _L("Filament serial is not entered, please enter serial."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("Filament serial missing; please input serial."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
@@ -1098,7 +1098,7 @@ wxWindow *CreateFilamentPresetDialog::create_dialog_buttons()
|
||||
serial_name = remove_special_key(serial_name);
|
||||
|
||||
if (vendor_name.empty() || serial_name.empty()) {
|
||||
MessageDialog dlg(this, _L("There may be escape characters in the vendor or serial input of filament. Please delete and re-enter."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("There may be disallowed characters in the vendor or serial input of the filament. Please delete and re-enter."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
@@ -1112,7 +1112,7 @@ wxWindow *CreateFilamentPresetDialog::create_dialog_buttons()
|
||||
return;
|
||||
}
|
||||
if (m_can_not_find_vendor_checkbox->GetValue() && str_is_all_digit(vendor_name)) {
|
||||
MessageDialog dlg(this, _L("The vendor cannot be a number. Please re-enter."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("The vendor cannot be a number; please re-enter."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
@@ -1129,8 +1129,7 @@ wxWindow *CreateFilamentPresetDialog::create_dialog_buttons()
|
||||
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
|
||||
if (preset_bundle->filaments.is_alias_exist(filament_preset_name)) {
|
||||
MessageDialog dlg(this,
|
||||
wxString::Format(_L("The Filament name %s you created already exists.\n"
|
||||
"If you continue, the preset created will be displayed with its full name. Do you want to continue?"),
|
||||
wxString::Format(_L("The Filament name %s you created already exists.\nIf you continue, the preset created will be displayed with its full name. Do you want to continue\?"),
|
||||
from_u8(filament_preset_name)),
|
||||
wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
if (wxID_YES != dlg.ShowModal()) { return; }
|
||||
@@ -1593,8 +1592,7 @@ CreatePrinterPresetDialog::CreatePrinterPresetDialog(wxWindow *parent)
|
||||
m_page1 = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_page1->SetBackgroundColour(*wxWHITE);
|
||||
m_page1->SetScrollRate(5, 5);
|
||||
m_page2 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);\
|
||||
m_page2->SetBackgroundColour(*wxWHITE);
|
||||
m_page2 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); m_page2->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
create_printer_page1(m_page1);
|
||||
create_printer_page2(m_page2);
|
||||
@@ -1756,7 +1754,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_printer_item(wxWindow *parent)
|
||||
m_select_model->SetLabelColor(*wxBLACK);
|
||||
}
|
||||
} else {
|
||||
MessageDialog dlg(this, _L("The model was not found, please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
MessageDialog dlg(this, _L("The model was not found; please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
}
|
||||
|
||||
@@ -2190,7 +2188,7 @@ bool CreatePrinterPresetDialog::load_system_and_user_presets_with_curr_model(Pre
|
||||
}
|
||||
if (m_printer_preset_vendor_selected.id.empty() || m_printer_preset_model_selected.id.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "selected id was not found";
|
||||
MessageDialog dlg(this, _L("Preset path was not found, please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
MessageDialog dlg(this, _L("Preset path was not found; please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
@@ -2211,7 +2209,7 @@ bool CreatePrinterPresetDialog::load_system_and_user_presets_with_curr_model(Pre
|
||||
|
||||
if (preset_path.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Preset path was not found";
|
||||
MessageDialog dlg(this, _L("Preset path was not found, please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("Preset path was not found; please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
@@ -2253,7 +2251,7 @@ bool CreatePrinterPresetDialog::load_system_and_user_presets_with_curr_model(Pre
|
||||
varient = model_varient.substr(index_at + 3, index_nozzle - index_at - 4);
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "get nozzle failed";
|
||||
MessageDialog dlg(this, _L("The nozzle diameter was not found, please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
MessageDialog dlg(this, _L("The nozzle diameter was not found; please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
@@ -2264,7 +2262,7 @@ bool CreatePrinterPresetDialog::load_system_and_user_presets_with_curr_model(Pre
|
||||
if (temp_printer_preset) {
|
||||
m_printer_preset = new Preset(*temp_printer_preset);
|
||||
} else {
|
||||
MessageDialog dlg(this, _L("The printer preset was not found, please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
MessageDialog dlg(this, _L("The printer preset was not found; please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
@@ -2280,7 +2278,7 @@ bool CreatePrinterPresetDialog::load_system_and_user_presets_with_curr_model(Pre
|
||||
}
|
||||
if (preset_path.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "Preset path was not found";
|
||||
MessageDialog dlg(this, _L("Preset path was not found, please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("Preset path was not found; please reselect vendor."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
@@ -2767,7 +2765,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren
|
||||
}
|
||||
|
||||
if (!save_printable_area_config(m_printer_preset)) {
|
||||
MessageDialog dlg(this, _L("You have entered an illegal input in the printable area section on the first page. Please check before creating it."),
|
||||
MessageDialog dlg(this, _L("You have entered a disallowed character in the printable area section on the first page. Please use only numbers."),
|
||||
wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
show_page1();
|
||||
@@ -2788,9 +2786,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren
|
||||
// Confirm if the printer preset has a duplicate name
|
||||
if (!rewritten && preset_bundle->printers.find_preset(printer_preset_name)) {
|
||||
MessageDialog dlg(this,
|
||||
_L("The printer preset you created already has a preset with the same name. Do you want to overwrite it?\n\tYes: Overwrite the printer preset with the "
|
||||
"same name, and filament and process presets with the same preset name will be recreated \nand filament and process presets without the same preset name will be reserve.\n\tCancel: Do not create a preset, return to the "
|
||||
"creation interface."),
|
||||
_L("The printer preset you created already has a preset with the same name. Do you want to overwrite it\?\n\tYes: Overwrite the printer preset with the same name, and filament and process presets with the same preset name will be recreated \nand filament and process presets without the same preset name will be reserved.\n\tCancel: Do not create a preset; return to the creation interface."),
|
||||
wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES | wxCANCEL | wxYES_DEFAULT | wxCENTRE);
|
||||
int res = dlg.ShowModal();
|
||||
if (res == wxID_YES) {
|
||||
@@ -3049,7 +3045,7 @@ void CreatePrinterPresetDialog::on_select_printer_model(wxCommandEvent &e)
|
||||
return;
|
||||
}
|
||||
|
||||
MessageDialog dlg(this, _L("Vendor was not found, please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
MessageDialog dlg(this, _L("Vendor was not found; please reselect."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
@@ -3322,7 +3318,7 @@ bool CreatePrinterPresetDialog::validate_input_valid()
|
||||
std::string vendor_name = get_printer_vendor();
|
||||
std::string model_name = get_printer_model();
|
||||
if ((vendor_name.empty() || model_name.empty())) {
|
||||
MessageDialog dlg(this, _L("You have not selected the vendor and model or entered the custom vendor and model."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("You have not selected the vendor and model or input the custom vendor and model."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
@@ -3353,7 +3349,7 @@ bool CreatePrinterPresetDialog::validate_input_valid()
|
||||
} else if (curr_selected_printer_type == m_create_type.create_nozzle) {
|
||||
wxString printer_name = m_select_printer->GetStringSelection();
|
||||
if (printer_name.empty()) {
|
||||
MessageDialog dlg(this, _L("You have not yet selected the printer to replace the nozzle, please choose."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
MessageDialog dlg(this, _L("You have not yet selected the printer to replace the nozzle for; please choose a printer."), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
|
||||
wxYES | wxYES_DEFAULT | wxCENTRE);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
@@ -3487,8 +3483,7 @@ CreatePresetSuccessfulDialog::CreatePresetSuccessfulDialog(wxWindow *parent, con
|
||||
break;
|
||||
case FILAMENT:
|
||||
success_text = new wxStaticText(this, wxID_ANY, _L("Filament Created"));
|
||||
wxString prompt_text = _L("Please go to filament setting to edit your presets if you need.\nPlease note that nozzle temperature, hot bed temperature, and maximum "
|
||||
"volumetric speed has a significant impact on printing quality. Please set them carefully.");
|
||||
wxString prompt_text = _L("Please go to filament settings to edit your presets if you need to.\nPlease note that nozzle temperature, hot bed temperature, and maximum volumetric speed each have a significant impact on printing quality. Please set them carefully.");
|
||||
wxString sync_text = sync_user_preset_need_enabled ? _L("\n\nOrca has detected that your user presets synchronization function is not enabled, "
|
||||
"which may result in unsuccessful Filament settings on the Device page.\n"
|
||||
"Click \"Sync user presets\" to enable the synchronization function.") : "";
|
||||
@@ -3696,8 +3691,7 @@ std::string ExportConfigsDialog::initial_file_name(const wxString &path, const s
|
||||
std::string export_path = into_u8(path);
|
||||
boost::filesystem::path printer_export_path = (boost::filesystem::path(export_path) / file_name).make_preferred();
|
||||
if (boost::filesystem::exists(printer_export_path)) {
|
||||
MessageDialog dlg(this, wxString::Format(_L("The '%s' folder already exists in the current directory. Do you want to clear it and rebuild it.\nIf not, a time suffix will be "
|
||||
"added, and you can modify the name after creation."), file_name), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
MessageDialog dlg(this, wxString::Format(_L("The \'%s\' folder already exists in the current directory. Do you want to clear it and rebuild it\?\nIf not, a time suffix will be added, and you can modify the name after creation."), file_name), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"), wxYES_NO | wxYES_DEFAULT | wxCENTRE);
|
||||
int res = dlg.ShowModal();
|
||||
if (wxID_YES == res) {
|
||||
try {
|
||||
@@ -3869,7 +3863,7 @@ void ExportConfigsDialog::select_curr_radiobox(std::vector<std::pair<RadioBox *,
|
||||
wxString printer_name = wxString::FromUTF8(preset_name);
|
||||
m_preset_sizer->Add(create_checkbox(m_presets_window, preset.second, printer_name, m_preset), 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(5));
|
||||
}
|
||||
m_serial_text->SetLabel(_L("Only display printer names with changes to printer, filament, and process presets."));
|
||||
m_serial_text->SetLabel(_L("Only display printers with changes to printer, filament, and process presets are displayed."));
|
||||
}else if (export_type == m_exprot_type.filament_bundle) {
|
||||
for (std::pair<std::string, std::vector<std::pair<std::string, Preset*>>> filament_name_to_preset : m_filament_name_to_presets) {
|
||||
if (filament_name_to_preset.second.empty()) continue;
|
||||
@@ -4307,7 +4301,7 @@ wxBoxSizer *ExportConfigsDialog::create_select_printer(wxWindow *parent)
|
||||
wxBoxSizer *horizontal_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxBoxSizer * optionSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_serial_text = new wxStaticText(parent, wxID_ANY, _L("Please select a type you want to export"), wxDefaultPosition, wxDefaultSize);
|
||||
m_serial_text = new wxStaticText(parent, wxID_ANY, _L("Please select a preset type you want to export"), wxDefaultPosition, wxDefaultSize);
|
||||
optionSizer->Add(m_serial_text, 0, wxEXPAND | wxALL, 0);
|
||||
optionSizer->SetMinSize(OPTION_SIZE);
|
||||
horizontal_sizer->Add(optionSizer, 0, wxEXPAND | wxALL, FromDIP(10));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user