Compare commits
83 Commits
fix/prewar
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8369e5f75 | ||
|
|
88b4a63228 | ||
|
|
dc12126b78 | ||
|
|
054a173af7 | ||
|
|
248a55abd0 | ||
|
|
b4aa070c40 | ||
|
|
b9ff15054f | ||
|
|
ddeaa4ba82 | ||
|
|
b333b04815 | ||
|
|
e5ca01ba9e | ||
|
|
6a06b63d6f | ||
|
|
d0701b9597 | ||
|
|
232fc30db1 | ||
|
|
f0392ab226 | ||
|
|
3ca7c4b752 | ||
|
|
15451c6c50 | ||
|
|
1447602d43 | ||
|
|
6cf7db1ded | ||
|
|
d52d0a082d | ||
|
|
484ce81e38 | ||
|
|
bcbc581417 | ||
|
|
c965b2a5b3 | ||
|
|
da5a13a032 | ||
|
|
1c0d0b89cc | ||
|
|
873d0ed26e | ||
|
|
b3fe733bf2 | ||
|
|
a0e1aa2507 | ||
|
|
95b23cea0f | ||
|
|
f760f4e462 | ||
|
|
9ec2fe3c45 | ||
|
|
a0717853df | ||
|
|
82cedc0316 | ||
|
|
8dd1dd8921 | ||
|
|
427d0f7a9f | ||
|
|
5a136a25d1 | ||
|
|
83179d5978 | ||
|
|
fb5296aad6 | ||
|
|
74f2becb23 | ||
|
|
1555fc92a5 | ||
|
|
2f7441317b | ||
|
|
b3bb8604c4 | ||
|
|
d614917d1d | ||
|
|
4154785025 | ||
|
|
2167378bbe | ||
|
|
ecab578052 | ||
|
|
b16a461320 | ||
|
|
5b1766b1d5 | ||
|
|
b4b2982106 | ||
|
|
3cbdb092d6 | ||
|
|
ea5119ec3f | ||
|
|
b9c9f42f01 | ||
|
|
66f8d954af | ||
|
|
4aeb6a31db | ||
|
|
89ab4d27cb | ||
|
|
f3fe37eab3 | ||
|
|
a0d1ccaf28 | ||
|
|
1299fcef4a | ||
|
|
d5f964ee4f | ||
|
|
5c754e360e | ||
|
|
51d2c91c9b | ||
|
|
73096a1161 | ||
|
|
219ef664bd | ||
|
|
f8a18e7656 | ||
|
|
3aadd6e080 | ||
|
|
e6b3f6ccef | ||
|
|
b3a513eab9 | ||
|
|
fb0cf966cf | ||
|
|
c2d33bea08 | ||
|
|
bfde91685e | ||
|
|
4490dccade | ||
|
|
2f160ad8bc | ||
|
|
fad680fcc1 | ||
|
|
83e9f17aa8 | ||
|
|
8b716d43e5 | ||
|
|
be141d32c1 | ||
|
|
5978e96ff5 | ||
|
|
368563e14e | ||
|
|
01e0013b16 | ||
|
|
4b489339c6 | ||
|
|
e451df27f7 | ||
|
|
24458ba5a2 | ||
|
|
ded2e72dcc | ||
|
|
07173a8de4 |
@@ -46,3 +46,12 @@ ctest --test-dir ./tests/fff_print
|
||||
- **Cross-platform** — all changes must work on Windows, macOS, and Linux
|
||||
- Profile/format changes need version migration handling
|
||||
- Dependencies built separately in `deps/build/`, then linked to main app
|
||||
|
||||
## Code review focus areas
|
||||
|
||||
- Changes must not cause regressions in existing functionality, defaults, profiles, or project compatibility.
|
||||
- Features gated by options must not affect existing behavior when those options are disabled.
|
||||
- Changes should follow the existing code style and architecture. Architectural changes should be justified in code comments and the PR description.
|
||||
- Add helper functions or utilities only when existing code cannot reasonably be reused. Avoid duplication.
|
||||
- Keep code concise and clear. Manually simplify AI generated bloated codes before review.
|
||||
- Include targeted tests or documented verification for behavior changes, especially in slicing logic, profiles, formats, and GUI defaults.
|
||||
|
||||
@@ -218,7 +218,7 @@ Open-source slicing has always been built on a tradition of collaboration and at
|
||||
|
||||
OrcaSlicer began in that same spirit, drawing from BambuStudio, PrusaSlicer, and ideas inspired by CuraSlicer and SuperSlicer. But it has since grown far beyond its origins. Through relentless innovation — introducing advanced calibration tools, precise wall and seam control, tree supports, adaptive slicing, and hundreds of other features — OrcaSlicer has become the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry.
|
||||
|
||||
The OrcaSlicer logo was designed by community member Justin Levine (@freejstnalxndr).
|
||||
The OrcaSlicer logo was designed by community member [Justin Levine](https://github.com/jal-co).
|
||||
|
||||
# License
|
||||
- **OrcaSlicer** is licensed under the GNU Affero General Public License, version 3.
|
||||
|
||||
1
resources/images/filter.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><polygon points=".5 .5 5.5 7.5 5.5 13.5 9.5 15.5 9.5 7.5 14.5 .5 .5 .5" style="fill:none; stroke:#949494; stroke-linecap:round; stroke-linejoin:round;"/><line x1="8.64" y1="4.5" x2="10.19" y2="2.34" style="fill:none; stroke:#949494; stroke-linecap:round; stroke-linejoin:round;"/></svg>
|
||||
|
After Width: | Height: | Size: 414 B |
BIN
resources/plugins/elegoolink/web/lan_service_web/favicon.ico
Normal file
|
After Width: | Height: | Size: 353 B |
265
resources/plugins/elegoolink/web/lan_service_web/index.html
Normal file
@@ -61,7 +61,7 @@
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 18 KiB |
@@ -97,7 +97,7 @@
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_ramming_volumetric_speed": [
|
||||
"-1"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 29 KiB |
@@ -14,7 +14,7 @@
|
||||
"15"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"8"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"instantiation": "false",
|
||||
"fan_cooling_layer_time": "100",
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_type": [
|
||||
"PLA"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"30"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"3.6"
|
||||
],
|
||||
"filament_type": [
|
||||
"TPU"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 8.6 KiB |
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 24 KiB |
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"15"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"8"
|
||||
],
|
||||
"filament_type": [
|
||||
"PETG"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"100"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_type": [
|
||||
"PLA"
|
||||
|
||||
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 16 KiB |
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 47 KiB |
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 53 KiB |
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 30 KiB |
@@ -70,7 +70,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 38 KiB |
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 39 KiB |
@@ -67,7 +67,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"0"
|
||||
|
||||
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 13 KiB |
@@ -61,7 +61,7 @@
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"1.75"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"nil"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"2.85"
|
||||
],
|
||||
"filament_max_volumetric_speed": [
|
||||
"0"
|
||||
"12"
|
||||
],
|
||||
"filament_minimal_purge_on_wipe_tower": [
|
||||
"15"
|
||||
|
||||
50
resources/shaders/110/fxaa.fs
Normal file
@@ -0,0 +1,50 @@
|
||||
#version 110
|
||||
|
||||
uniform sampler2D uniform_texture;
|
||||
uniform vec2 inv_tex_size;
|
||||
|
||||
varying vec2 tex_coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 rgbNW = texture2D(uniform_texture, tex_coord + vec2(-1.0, -1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbNE = texture2D(uniform_texture, tex_coord + vec2(1.0, -1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbSW = texture2D(uniform_texture, tex_coord + vec2(-1.0, 1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbSE = texture2D(uniform_texture, tex_coord + vec2(1.0, 1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbM = texture2D(uniform_texture, tex_coord).rgb;
|
||||
|
||||
vec3 luma_coeff = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma_coeff);
|
||||
float lumaNE = dot(rgbNE, luma_coeff);
|
||||
float lumaSW = dot(rgbSW, luma_coeff);
|
||||
float lumaSE = dot(rgbSE, luma_coeff);
|
||||
float lumaM = dot(rgbM, luma_coeff);
|
||||
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX), dir * rcpDirMin)) * inv_tex_size;
|
||||
|
||||
vec3 rgbA = 0.5 * (
|
||||
texture2D(uniform_texture, tex_coord + dir * (1.0 / 3.0 - 0.5)).rgb +
|
||||
texture2D(uniform_texture, tex_coord + dir * (2.0 / 3.0 - 0.5)).rgb
|
||||
);
|
||||
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
texture2D(uniform_texture, tex_coord + dir * -0.5).rgb +
|
||||
texture2D(uniform_texture, tex_coord + dir * 0.5).rgb
|
||||
);
|
||||
|
||||
float lumaB = dot(rgbB, luma_coeff);
|
||||
gl_FragColor = (lumaB < lumaMin || lumaB > lumaMax) ? vec4(rgbA, 1.0) : vec4(rgbB, 1.0);
|
||||
}
|
||||
15
resources/shaders/110/fxaa.vs
Normal file
@@ -0,0 +1,15 @@
|
||||
#version 110
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec2 v_tex_coord;
|
||||
|
||||
varying vec2 tex_coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
tex_coord = v_tex_coord;
|
||||
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
|
||||
}
|
||||
52
resources/shaders/140/fxaa.fs
Normal file
@@ -0,0 +1,52 @@
|
||||
#version 140
|
||||
|
||||
uniform sampler2D uniform_texture;
|
||||
uniform vec2 inv_tex_size;
|
||||
|
||||
in vec2 tex_coord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 rgbNW = texture(uniform_texture, tex_coord + vec2(-1.0, -1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbNE = texture(uniform_texture, tex_coord + vec2(1.0, -1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbSW = texture(uniform_texture, tex_coord + vec2(-1.0, 1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbSE = texture(uniform_texture, tex_coord + vec2(1.0, 1.0) * inv_tex_size).rgb;
|
||||
vec3 rgbM = texture(uniform_texture, tex_coord).rgb;
|
||||
|
||||
vec3 luma_coeff = vec3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma_coeff);
|
||||
float lumaNE = dot(rgbNE, luma_coeff);
|
||||
float lumaSW = dot(rgbSW, luma_coeff);
|
||||
float lumaSE = dot(rgbSE, luma_coeff);
|
||||
float lumaM = dot(rgbM, luma_coeff);
|
||||
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
|
||||
vec2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
|
||||
const float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||
const float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(vec2(FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX), dir * rcpDirMin)) * inv_tex_size;
|
||||
|
||||
vec3 rgbA = 0.5 * (
|
||||
texture(uniform_texture, tex_coord + dir * (1.0 / 3.0 - 0.5)).rgb +
|
||||
texture(uniform_texture, tex_coord + dir * (2.0 / 3.0 - 0.5)).rgb
|
||||
);
|
||||
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * (
|
||||
texture(uniform_texture, tex_coord + dir * -0.5).rgb +
|
||||
texture(uniform_texture, tex_coord + dir * 0.5).rgb
|
||||
);
|
||||
|
||||
float lumaB = dot(rgbB, luma_coeff);
|
||||
out_color = (lumaB < lumaMin || lumaB > lumaMax) ? vec4(rgbA, 1.0) : vec4(rgbB, 1.0);
|
||||
}
|
||||
15
resources/shaders/140/fxaa.vs
Normal file
@@ -0,0 +1,15 @@
|
||||
#version 140
|
||||
|
||||
uniform mat4 view_model_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
in vec3 v_position;
|
||||
in vec2 v_tex_coord;
|
||||
|
||||
out vec2 tex_coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
tex_coord = v_tex_coord;
|
||||
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
|
||||
}
|
||||
@@ -17,11 +17,11 @@ var LangText = {
|
||||
t15: "Printer",
|
||||
t16: "Filament type",
|
||||
t17: "Vendor",
|
||||
t18: "error",
|
||||
t18: "Error",
|
||||
t19: "At least one filament must be selected.",
|
||||
t20: "Do you want to use default filament ?",
|
||||
t21: "yes",
|
||||
t22: "no",
|
||||
t21: "Yes",
|
||||
t22: "No",
|
||||
t23: "Release note",
|
||||
t24: "Get Started",
|
||||
t25: "Finish",
|
||||
@@ -35,7 +35,7 @@ var LangText = {
|
||||
t33: "Open Project",
|
||||
t34: "hotspot",
|
||||
t35: "Recently opened",
|
||||
t36: "ok",
|
||||
t36: "OK",
|
||||
t37: "At least one printer must be selected.",
|
||||
t38: "Cancel",
|
||||
t39: "Confirm",
|
||||
@@ -107,7 +107,7 @@ var LangText = {
|
||||
t113: "You may change your choice in preference anytime.",
|
||||
t126: "Loading……",
|
||||
orca1: "Edit Project Info",
|
||||
orca2: "no model information",
|
||||
orca2: "No model information",
|
||||
orca3: "Stealth Mode",
|
||||
orca4: "This stops the transmission of data to Bambu's cloud services. Users who don't use BBL machines or use LAN mode only can safely turn on this function.",
|
||||
orca5: "Enable Stealth Mode.",
|
||||
@@ -131,7 +131,7 @@ var LangText = {
|
||||
t15: "Impressora",
|
||||
t16: "Tipus de filament",
|
||||
t17: "Proveïdor",
|
||||
t18: "error",
|
||||
t18: "Error",
|
||||
t19: "S'ha de seleccionar almenys un filament.",
|
||||
t20: "Vols utilitzar el filament per defecte?",
|
||||
t21: "sí",
|
||||
@@ -149,7 +149,7 @@ var LangText = {
|
||||
t33: "Obrir Projecte",
|
||||
t34: "hotspot",
|
||||
t35: "Obert recentment",
|
||||
t36: "d'acord",
|
||||
t36: "D'acord",
|
||||
t37: "S'ha de seleccionar almenys una impressora.",
|
||||
t38: "Cancel·lar",
|
||||
t39: "Confirmar",
|
||||
@@ -220,7 +220,7 @@ var LangText = {
|
||||
t112: "Unir-se al Programa",
|
||||
t113: "Pots canviar la teva elecció en les preferències en qualsevol moment.",
|
||||
orca1: "Editar Informació del Projecte",
|
||||
orca2: "no hi ha informació del model",
|
||||
orca2: "No hi ha informació del model",
|
||||
orca6: "Bambu Cloud",
|
||||
},
|
||||
es_ES: {
|
||||
@@ -241,11 +241,11 @@ var LangText = {
|
||||
t15: "Impresora",
|
||||
t16: "Tipo de filamento",
|
||||
t17: "Fabricante",
|
||||
t18: "error",
|
||||
t18: "Error",
|
||||
t19: "Al menos se debe seleccionar un filamento.",
|
||||
t20: "¿Desea usar el filamento por defecto?",
|
||||
t21: "sí",
|
||||
t22: "no",
|
||||
t21: "Sí",
|
||||
t22: "No",
|
||||
t23: "Notas de la versión",
|
||||
t24: "Comenzar",
|
||||
t25: "Finalizar",
|
||||
@@ -259,7 +259,7 @@ var LangText = {
|
||||
t33: "Abrir proyecto",
|
||||
t34: "punto de acceso",
|
||||
t35: "Abiertos recientemente",
|
||||
t36: "ok",
|
||||
t36: "OK",
|
||||
t37: "Al menos se debe seleccionar una impresora.",
|
||||
t38: "Cancelar",
|
||||
t39: "Confirmar",
|
||||
@@ -355,11 +355,11 @@ var LangText = {
|
||||
t15: "Stampante",
|
||||
t16: "Tipo di filamento",
|
||||
t17: "Produttore",
|
||||
t18: "errore",
|
||||
t18: "Errore",
|
||||
t19: "È necessario selezionare almeno un filamento.",
|
||||
t20: "Vuoi utilizzare il filamento predefinito?",
|
||||
t21: "sì",
|
||||
t22: "no",
|
||||
t21: "Sì",
|
||||
t22: "No",
|
||||
t23: "Note di rilascio",
|
||||
t24: "Inizia",
|
||||
t25: "Fine",
|
||||
@@ -373,7 +373,7 @@ var LangText = {
|
||||
t33: "Apri progetto",
|
||||
t34: "hotspot",
|
||||
t35: "Aperti di recente",
|
||||
t36: "ok",
|
||||
t36: "OK",
|
||||
t37: "È necessario selezionare almeno una stampante.",
|
||||
t38: "Annulla",
|
||||
t39: "Conferma",
|
||||
@@ -444,7 +444,7 @@ var LangText = {
|
||||
t112: "Unisciti al programma",
|
||||
t113: "Puoi modificare la tua scelta in 'Preferenze' in qualsiasi momento.",
|
||||
orca1: "Modifica informazioni progetto",
|
||||
orca2: "nessuna informazione sul modello",
|
||||
orca2: "Nessuna informazione sul modello",
|
||||
orca3: "Modalità invisibile",
|
||||
orca4: "Con questa modalità, la trasmissione dei dati ai servizi cloud di Bambu sarà interrotta. Gli utenti che non utilizzano macchine BBL o che usano solo la modalità LAN possono attivare questa funzione in modo sicuro.",
|
||||
orca5: "Abilita la modalità invisibile.",
|
||||
@@ -551,7 +551,7 @@ var LangText = {
|
||||
t106: "Profilbeschreibung",
|
||||
t126: "Laden……",
|
||||
orca1: "Edit Project Info",
|
||||
orca2: "no model information",
|
||||
orca2: "No model information",
|
||||
orca6: "Bambu Cloud",
|
||||
},
|
||||
cs_CZ: {
|
||||
@@ -655,7 +655,7 @@ var LangText = {
|
||||
t106: "Popis profilu",
|
||||
t126: "Načtení probíhá……",
|
||||
orca1: "Edit Project Info",
|
||||
orca2: "no model information",
|
||||
orca2: "No model information",
|
||||
orca6: "Bambu Cloud",
|
||||
},
|
||||
fr_FR: {
|
||||
@@ -676,11 +676,11 @@ var LangText = {
|
||||
t15: "Imprimante",
|
||||
t16: "Type de filament",
|
||||
t17: "Fournisseur",
|
||||
t18: "erreur",
|
||||
t18: "Erreur",
|
||||
t19: "Au moins un filament doit être sélectionné.",
|
||||
t20: "Voulez-vous utiliser le filament par défaut ?",
|
||||
t21: "oui",
|
||||
t22: "non",
|
||||
t21: "Oui",
|
||||
t22: "Non",
|
||||
t23: "Note de version",
|
||||
t24: "Commencer",
|
||||
t25: "Terminer",
|
||||
@@ -694,7 +694,7 @@ var LangText = {
|
||||
t33: "Ouvrir un Projet",
|
||||
t34: "hotspot",
|
||||
t35: "Récemment ouvert",
|
||||
t36: "ok",
|
||||
t36: "OK",
|
||||
t37: "Au moins une imprimante doit être sélectionnée.",
|
||||
t38: "Annuler",
|
||||
t39: "Confirmer",
|
||||
@@ -762,7 +762,7 @@ var LangText = {
|
||||
t111: "Créer un nouveau filament",
|
||||
t126: "Chargement en cours……",
|
||||
orca1: "Modifier les informations du projet",
|
||||
orca2: "pas d'information sur le modèle",
|
||||
orca2: "Pas d'information sur le modèle",
|
||||
wk1: "Démarrage rapide",
|
||||
wk2: "Cet article présente l'utilisation la plus basique de Orca Slicer. Il guide les utilisateurs pour configurer le logiciel, créer des projets et effectuer la première tâche d'impression étape par étape.",
|
||||
wk3: "Workflow basé sur des projets",
|
||||
@@ -1032,11 +1032,11 @@ var LangText = {
|
||||
t15: "Принтер",
|
||||
t16: "Тип материала",
|
||||
t17: "Производитель",
|
||||
t18: "ошибка",
|
||||
t18: "Oшибка",
|
||||
t19: "Должна быть выбрана хотя бы одна пластиковая нить.",
|
||||
t20: "Выбрать пластиковые нити по умолчанию?",
|
||||
t21: "да",
|
||||
t22: "нет",
|
||||
t21: "Да",
|
||||
t22: "Нет",
|
||||
t23: "Информация о версии",
|
||||
t24: "Начать",
|
||||
t25: "Закончить",
|
||||
@@ -1218,7 +1218,7 @@ var LangText = {
|
||||
t94: "장치를 보려면 프린터 연결을 설정하세요.",
|
||||
t126: "로딩 중……",
|
||||
orca1: "Edit Project Info",
|
||||
orca2: "no model information",
|
||||
orca2: "No model information",
|
||||
orca6: "Bambu Cloud",
|
||||
},
|
||||
tr_TR: {
|
||||
@@ -1257,7 +1257,7 @@ var LangText = {
|
||||
t33: "Projeyi Aç",
|
||||
t34: "Erişim noktası",
|
||||
t35: "Yakın zamanda açıldı",
|
||||
t36: "Ok",
|
||||
t36: "OK",
|
||||
t37: "En az bir yazıcı seçilmelidir.",
|
||||
t38: "İptal Et",
|
||||
t39: "Onayla",
|
||||
@@ -1329,7 +1329,7 @@ var LangText = {
|
||||
t113: "Tercihinizi istediğiniz zaman değiştirebilirsiniz.",
|
||||
t126: "Yükleme devam ediyor……",
|
||||
orca1: "Proje Bilgilerini Düzenle",
|
||||
orca2: "model bilgisi yok",
|
||||
orca2: "Model bilgisi yok",
|
||||
orca3: "Gizli Mod",
|
||||
orca4: "Bu, Bambu'nun bulut hizmetlerine veri iletimini durdurur. BBL makinelerini kullanmayan veya yalnızca LAN modunu kullanan kullanıcılar bu işlevi güvenle açabilir.",
|
||||
orca5: "Gizli Modu etkinleştirin.",
|
||||
@@ -1353,11 +1353,11 @@ var LangText = {
|
||||
t15: "Drukarka",
|
||||
t16: "Typ filamentu",
|
||||
t17: "Dostawca",
|
||||
t18: "błąd",
|
||||
t18: "Błąd",
|
||||
t19: "Przynajmniej jeden filament musi być wybrany.",
|
||||
t20: "Czy chcesz użyć domyślnego filamentu?",
|
||||
t21: "tak",
|
||||
t22: "nie",
|
||||
t21: "Tak",
|
||||
t22: "Nie",
|
||||
t23: "Informacje o wydaniu",
|
||||
t24: "Rozpocznij",
|
||||
t25: "Zakończ",
|
||||
@@ -1371,7 +1371,7 @@ var LangText = {
|
||||
t33: "Otwórz Projekt",
|
||||
t34: "hotspot",
|
||||
t35: "Ostatnio otwarte",
|
||||
t36: "ok",
|
||||
t36: "OK",
|
||||
t37: "Przynajmniej jedna drukarka musi być wybrana.",
|
||||
t38: "Anuluj",
|
||||
t39: "Potwierdź",
|
||||
@@ -1443,7 +1443,7 @@ var LangText = {
|
||||
t113: "Możesz zmienić swój wybór w preferencjach w dowolnym momencie.",
|
||||
t126: "Ładowanie trwa……",
|
||||
orca1: "Edytuj informacje o projekcie",
|
||||
orca2: "brak informacji o modelu",
|
||||
orca2: "Brak informacji o modelu",
|
||||
orca3: "Tryb «Niewidzialny»",
|
||||
orca4: "To wyłączy przesyłanie danych do usług chmurowych Bambu. Użytkownicy, którzy nie korzystają z maszyn BBL lub używają tylko trybu LAN, mogą bez obaw włączyć tę opcję.",
|
||||
orca5: "Włącz tryb «Niewidzialny»",
|
||||
@@ -1485,7 +1485,7 @@ var LangText = {
|
||||
t33: "Abrir Projeto",
|
||||
t34: "hotspot",
|
||||
t35: "Aberto Recentemente",
|
||||
t36: "Ok",
|
||||
t36: "OK",
|
||||
t37: "Pelo menos uma impressora deve ser selecionada.",
|
||||
t38: "Cancelar",
|
||||
t39: "Confirmar",
|
||||
@@ -1581,11 +1581,11 @@ var LangText = {
|
||||
t15: "Spausdintuvas",
|
||||
t16: "Gijos tipas",
|
||||
t17: "Gamintojas",
|
||||
t18: "klaida",
|
||||
t18: "Klaida",
|
||||
t19: "Turi būti pasirinkta bent viena gija.",
|
||||
t20: "Ar norite naudoti numatytąją giją?",
|
||||
t21: "taip",
|
||||
t22: "ne",
|
||||
t21: "Taip",
|
||||
t22: "Ne",
|
||||
t23: "Išleidimo pastabos",
|
||||
t24: "Pradėti",
|
||||
t25: "Pabaigti",
|
||||
@@ -1599,7 +1599,7 @@ var LangText = {
|
||||
t33: "Atverti projektą",
|
||||
t34: "Prieigos taškas",
|
||||
t35: "Neseniai atidaryti",
|
||||
t36: "gerai",
|
||||
t36: "Gerai",
|
||||
t37: "Turi būti pasirinktas bent vienas spausdintuvas.",
|
||||
t38: "Atšaukti",
|
||||
t39: "Patvirtinti",
|
||||
@@ -1670,7 +1670,7 @@ var LangText = {
|
||||
t112: "Prisijungti prie programos",
|
||||
t113: "Savo pasirinkimą galite bet kada pakeisti.",
|
||||
orca1: "Redaguoti projekto informaciją",
|
||||
orca2: "nėra informacijos apie modelį",
|
||||
orca2: "Nėra informacijos apie modelį",
|
||||
orca3: "Slaptas režimas",
|
||||
orca4: "Tai sustabdo duomenų perdavimą į Bambu debesijos paslaugas. Vartotojai, kurie nenaudoja BBL mašinų arba naudoja tik LAN režimą, gali drąsiai įjungti šią funkciją.",
|
||||
orca5: "Įjungti slaptą režimą.",
|
||||
|
||||
@@ -148,29 +148,6 @@
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 6px 9px;
|
||||
border: 1px solid #dbdbdb;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
appearance: auto;
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
select option {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
select:hover,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: #26A69A;
|
||||
background-color: #edfaf2;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -243,11 +220,6 @@
|
||||
position: sticky;
|
||||
z-index: 11;
|
||||
}
|
||||
body.dark-mode select {
|
||||
background-color: #2d2d31;
|
||||
color: white;
|
||||
border-color: #4c4c55;
|
||||
}
|
||||
|
||||
body.dark-mode .warning-text {
|
||||
color: #f44336;
|
||||
@@ -281,13 +253,16 @@
|
||||
>
|
||||
Re-Calculate
|
||||
</div>
|
||||
<select
|
||||
id="extruders"
|
||||
onchange="handleExtruderSelect(document.getElementById('extruders').value)"
|
||||
>
|
||||
<option value="left" id="extruder_label_0">Left Nozzle</option>
|
||||
<option value="right" id="extruder_label_1">Right Nozzle</option>
|
||||
</select>
|
||||
<div class="ComboBox">
|
||||
<div class="arrow-icon"></div>
|
||||
<select
|
||||
id="extruders"
|
||||
onchange="handleExtruderSelect(document.getElementById('extruders').value)"
|
||||
>
|
||||
<option value="left" id="extruder_label_0">Left Nozzle</option>
|
||||
<option value="right" id="extruder_label_1">Right Nozzle</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="scroll-container">
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<div id="EmptyArea">
|
||||
<div><img src="img/null.png"></div>
|
||||
<div class="Text_Title Text_Bold trans" tid='orca2'>no model information</div>
|
||||
<div class="Text_Title Text_Bold trans" tid='orca2'>No model information</div>
|
||||
<div id="AddModelInfoBtn" class="ButtonStyleConfirm ButtonTypeWindow trans" tid='orca1' onClick="OnClickEditProjectInfo()">Edit Project Info</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -380,4 +380,5 @@ body
|
||||
#AddModelInfoBtn
|
||||
{
|
||||
margin-top: 20px;
|
||||
margin-right:0;
|
||||
}
|
||||
@@ -4456,7 +4456,7 @@ int CLI::run(int argc, char **argv)
|
||||
size_t num_objects = model.objects.size();
|
||||
for (size_t i = 0; i < num_objects; ++ i) {
|
||||
ModelObjectPtrs new_objects;
|
||||
model.objects.front()->split(&new_objects);
|
||||
model.objects.front()->split(&new_objects, false); // TODO: add cli option to enable this?
|
||||
model.delete_object(size_t(0));
|
||||
}
|
||||
}
|
||||
@@ -6435,6 +6435,7 @@ int CLI::run(int argc, char **argv)
|
||||
glfwGetVersion(&gl_major, &gl_minor, &gl_verbos);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("opengl version %1%.%2%.%3%")%gl_major %gl_minor %gl_verbos;
|
||||
|
||||
bool thumbnail_opengl_ready = false;
|
||||
glfwSetErrorCallback(glfw_callback);
|
||||
int ret = glfwInit();
|
||||
if (ret == GLFW_FALSE) {
|
||||
@@ -6463,13 +6464,22 @@ int CLI::run(int argc, char **argv)
|
||||
GLFWwindow* window = glfwCreateWindow(640, 480, "base_window", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to create GLFW window" << std::endl;
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to create GLFW window; skipping thumbnail rendering for CLI export" << std::endl;
|
||||
}
|
||||
else
|
||||
else {
|
||||
glfwMakeContextCurrent(window);
|
||||
thumbnail_opengl_ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
//opengl manager related logic
|
||||
if (!thumbnail_opengl_ready) {
|
||||
BOOST_LOG_TRIVIAL(error) << "OpenGL context unavailable; skip thumbnail generating" << std::endl;
|
||||
need_create_thumbnail_group = false;
|
||||
need_create_no_light_group = false;
|
||||
need_create_top_group = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI::OpenGLManager opengl_mgr;
|
||||
bool opengl_valid = opengl_mgr.init_gl(false);
|
||||
|
||||
@@ -31,16 +31,11 @@ function(encoding_check TARGET)
|
||||
# Define top-level encoding check target for this ${TARGET}
|
||||
add_custom_target(encoding-check-${TARGET}
|
||||
DEPENDS encoding-check ${T_SOURCES}
|
||||
COMMAND $<TARGET_FILE:encoding-check> ${TARGET} ${T_SOURCES}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Checking source files encodings for target ${TARGET}"
|
||||
)
|
||||
|
||||
# Add checking of each source file as a subcommand of encoding-check-${TARGET}
|
||||
foreach(file ${T_SOURCES})
|
||||
add_custom_command(TARGET encoding-check-${TARGET} PRE_BUILD
|
||||
COMMAND $<TARGET_FILE:encoding-check> ${TARGET} ${file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# This adds dependency on encoding-check-${TARGET} to ${TARET}
|
||||
# via the global-encoding-check
|
||||
|
||||
@@ -69,28 +69,24 @@ unsigned char *utf8_check(unsigned char *s)
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
static const char* target;
|
||||
|
||||
void error_exit(const char* error, const char* filename)
|
||||
{
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " <program/library> <file>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cerr << "\n\tError: " << error << ": " << filename << "\n"
|
||||
<< "\tTarget: " << target << "\n"
|
||||
<< std::endl;
|
||||
std::exit(-2);
|
||||
}
|
||||
|
||||
const char* target = argv[1];
|
||||
const char* filename = argv[2];
|
||||
|
||||
const auto error_exit = [=](const char* error) {
|
||||
std::cerr << "\n\tError: " << error << ": " << filename << "\n"
|
||||
<< "\tTarget: " << target << "\n"
|
||||
<< std::endl;
|
||||
std::exit(-2);
|
||||
};
|
||||
|
||||
void utf8_check_file(const char* filename)
|
||||
{
|
||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||
const auto size = file.tellg();
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::beg);
|
||||
@@ -101,7 +97,7 @@ int main(int argc, char const *argv[])
|
||||
|
||||
// Check UTF-8 validity
|
||||
if (utf8_check(reinterpret_cast<unsigned char*>(buffer.data())) != nullptr) {
|
||||
error_exit("Source file does not contain (valid) UTF-8");
|
||||
error_exit("Source file does not contain (valid) UTF-8", filename);
|
||||
}
|
||||
|
||||
// Check against a BOM mark
|
||||
@@ -109,10 +105,25 @@ int main(int argc, char const *argv[])
|
||||
&& buffer[0] == '\xef'
|
||||
&& buffer[1] == '\xbb'
|
||||
&& buffer[2] == '\xbf') {
|
||||
error_exit("Source file is valid UTF-8 but contains a BOM mark");
|
||||
error_exit("Source file is valid UTF-8 but contains a BOM mark", filename);
|
||||
}
|
||||
} else {
|
||||
error_exit("Could not read source file");
|
||||
error_exit("Could not read source file", filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
if (argc < 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " <program/library> <file[s]>" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
target = argv[1];
|
||||
|
||||
for (int i = 2; i < argc; i++) {
|
||||
utf8_check_file(argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -212,8 +212,14 @@ void AppConfig::set_defaults()
|
||||
if (get("camera_navigation_style").empty())
|
||||
set("camera_navigation_style", "0");
|
||||
|
||||
if (get("swap_mouse_buttons").empty())
|
||||
set_bool("swap_mouse_buttons", false);
|
||||
if (get("left_mouse_drag_action").empty())
|
||||
set("left_mouse_drag_action", "2");
|
||||
|
||||
if (get("middle_mouse_drag_action").empty())
|
||||
set("middle_mouse_drag_action", "1");
|
||||
|
||||
if (get("right_mouse_drag_action").empty())
|
||||
set("right_mouse_drag_action", "1");
|
||||
|
||||
if (get("reverse_mouse_wheel_zoom").empty())
|
||||
set_bool("reverse_mouse_wheel_zoom", false);
|
||||
@@ -230,6 +236,29 @@ void AppConfig::set_defaults()
|
||||
if (get("camera_orbit_mult").empty())
|
||||
set("camera_orbit_mult", "1.0");
|
||||
|
||||
if (get(SETTING_OPENGL_AA_SAMPLES).empty())
|
||||
set(SETTING_OPENGL_AA_SAMPLES, "4");
|
||||
|
||||
if (get(SETTING_OPENGL_FXAA_ENABLED).empty())
|
||||
set_bool(SETTING_OPENGL_FXAA_ENABLED, false);
|
||||
|
||||
if (get(SETTING_OPENGL_FPS_CAP).empty())
|
||||
set(SETTING_OPENGL_FPS_CAP, "0");
|
||||
else {
|
||||
int fps_cap = 0;
|
||||
try {
|
||||
fps_cap = std::stoi(get(SETTING_OPENGL_FPS_CAP));
|
||||
}
|
||||
catch (...) {
|
||||
fps_cap = 0;
|
||||
}
|
||||
fps_cap = std::max(0, std::min(fps_cap, 240));
|
||||
set(SETTING_OPENGL_FPS_CAP, std::to_string(fps_cap));
|
||||
}
|
||||
|
||||
if (get(SETTING_OPENGL_SHOW_FPS_OVERLAY).empty())
|
||||
set_bool(SETTING_OPENGL_SHOW_FPS_OVERLAY, false);
|
||||
|
||||
if (get("export_sources_full_pathnames").empty())
|
||||
set_bool("export_sources_full_pathnames", false);
|
||||
|
||||
@@ -834,8 +863,10 @@ std::string AppConfig::load()
|
||||
|
||||
void AppConfig::save()
|
||||
{
|
||||
if (! is_main_thread_active())
|
||||
if (!is_main_thread_active()) {
|
||||
BOOST_LOG_TRIVIAL(fatal) << "Calling AppConfig::save() from a worker thread!";
|
||||
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
||||
}
|
||||
|
||||
// The config is first written to a file with a PID suffix and then moved
|
||||
// to avoid race conditions with multiple instances of Slic3r
|
||||
|
||||
@@ -30,6 +30,10 @@ using namespace nlohmann;
|
||||
#define SETTING_NETWORK_PLUGIN_REMIND_LATER "network_plugin_remind_later"
|
||||
#define SETTING_USE_ENCRYPTED_TOKEN_FILE "use_encrypted_token_file"
|
||||
#define SETTING_CLOUD_PROVIDERS "cloud_providers"
|
||||
#define SETTING_OPENGL_AA_SAMPLES "opengl_antialiasing_samples"
|
||||
#define SETTING_OPENGL_FXAA_ENABLED "opengl_fxaa_enabled"
|
||||
#define SETTING_OPENGL_FPS_CAP "opengl_fps_cap"
|
||||
#define SETTING_OPENGL_SHOW_FPS_OVERLAY "opengl_show_fps_overlay"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define BAMBU_NETWORK_AGENT_VERSION_LEGACY "01.10.01.09"
|
||||
|
||||
@@ -330,6 +330,8 @@ public:
|
||||
|
||||
size_t hash() const throw() override { return std::hash<T>{}(this->value); }
|
||||
|
||||
// Warning mitigation: Indicate that virtual serialize() is not forgotten
|
||||
using ConfigOption::serialize;
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive & ar) { ar(this->value); }
|
||||
@@ -752,6 +754,8 @@ public:
|
||||
return modified;
|
||||
}
|
||||
|
||||
// Warning mitigation: Indicate that virtual serialize() is not forgotten
|
||||
using ConfigOptionVectorBase::serialize;
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive & ar) { ar(this->values); }
|
||||
|
||||
@@ -63,7 +63,7 @@ static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelV
|
||||
vol->cut_info = src_volume->cut_info;
|
||||
}
|
||||
|
||||
static void process_volume_cut( ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
|
||||
static void process_volume_cut( const ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
|
||||
ModelObjectCutAttributes attributes, TriangleMesh& upper_mesh, TriangleMesh& lower_mesh)
|
||||
{
|
||||
const auto volume_matrix = volume->get_matrix();
|
||||
@@ -178,7 +178,7 @@ static void process_modifier_cut(ModelVolume* volume, const Transform3d& instanc
|
||||
lower->add_volume(*volume);
|
||||
}
|
||||
|
||||
static void process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
|
||||
static void process_solid_part_cut(const ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix,
|
||||
ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower)
|
||||
{
|
||||
// Perform cut
|
||||
@@ -279,9 +279,22 @@ void Cut::post_process(ModelObject* upper, ModelObject* lower, ModelObjectPtrs&
|
||||
}
|
||||
|
||||
|
||||
void Cut::finalize(const ModelObjectPtrs& objects)
|
||||
void Cut::finalize(const ModelObjectPtrs& objects, const std::vector<std::optional<TriangleSelector::SavedPainting>>& saved_paintings)
|
||||
{
|
||||
//clear model from temporarry objects
|
||||
// Paint volumes
|
||||
for (const auto& saved_painting : saved_paintings) {
|
||||
if (saved_painting) {
|
||||
for (const auto object : objects) {
|
||||
for (const auto volume : object->volumes) {
|
||||
if (volume->is_model_part() && !volume->is_cut_connector()) {
|
||||
volume->restore_painting(saved_painting, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//clear model from temporary objects
|
||||
m_model.clear_objects();
|
||||
|
||||
// add to model result objects
|
||||
@@ -320,7 +333,17 @@ const ModelObjectPtrs& Cut::perform_with_plane()
|
||||
const Transformation cut_transformation = Transformation(m_cut_matrix);
|
||||
const Transform3d inverse_cut_matrix = cut_transformation.get_rotation_matrix().inverse() * translation_transform(-1. * cut_transformation.get_offset());
|
||||
|
||||
std::vector<std::optional<TriangleSelector::SavedPainting>> saved_paintings;
|
||||
for (ModelVolume* volume : mo->volumes) {
|
||||
// Save painting data before reset_extra_facets() discards it.
|
||||
if (m_attributes.has(ModelObjectCutAttribute::KeepPaint)) {
|
||||
saved_paintings.emplace_back(volume->save_painting());
|
||||
if (saved_paintings.back()) {
|
||||
// Transform mesh to cut space (same transform as process_volume_cut applies)
|
||||
saved_paintings.back()->mesh.transform(instance_matrix * volume->get_matrix(), true);
|
||||
}
|
||||
}
|
||||
|
||||
volume->reset_extra_facets();
|
||||
|
||||
if (!volume->is_model_part()) {
|
||||
@@ -376,9 +399,9 @@ const ModelObjectPtrs& Cut::perform_with_plane()
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(trace) << "ModelObject::cut - end";
|
||||
finalize(cut_object_ptrs, saved_paintings);
|
||||
|
||||
finalize(cut_object_ptrs);
|
||||
BOOST_LOG_TRIVIAL(trace) << "ModelObject::cut - end";
|
||||
|
||||
return m_model.objects;
|
||||
}
|
||||
@@ -431,7 +454,7 @@ static void merge_solid_parts_inside_object(ModelObjectPtrs& objects)
|
||||
}
|
||||
|
||||
|
||||
const ModelObjectPtrs& Cut::perform_by_contour(std::vector<Part> parts, int dowels_count)
|
||||
const ModelObjectPtrs& Cut::perform_by_contour(const ModelObject* src_object, std::vector<Part> parts, int dowels_count)
|
||||
{
|
||||
ModelObject* cut_mo = m_model.objects.front();
|
||||
|
||||
@@ -446,6 +469,19 @@ const ModelObjectPtrs& Cut::perform_by_contour(std::vector<Part> parts, int dowe
|
||||
lower->name = lower->name + "_B";
|
||||
}
|
||||
|
||||
// Save painting data so we later can remap it.
|
||||
std::vector<std::optional<TriangleSelector::SavedPainting>> saved_paintings;
|
||||
if (m_attributes.has(ModelObjectCutAttribute::KeepPaint)) {
|
||||
const auto instance_matrix = src_object->instances[m_instance]->get_transformation().get_matrix_no_offset();
|
||||
for (const auto volume : src_object->volumes) {
|
||||
saved_paintings.emplace_back(volume->save_painting());
|
||||
if (saved_paintings.back()) {
|
||||
// Transform mesh to cut space (same transform as process_volume_cut applies)
|
||||
saved_paintings.back()->mesh.transform(instance_matrix * volume->get_matrix(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const size_t cut_parts_cnt = parts.size();
|
||||
bool has_modifiers = false;
|
||||
|
||||
@@ -475,7 +511,7 @@ const ModelObjectPtrs& Cut::perform_by_contour(std::vector<Part> parts, int dowe
|
||||
merge_solid_parts_inside_object(cut_object_ptrs);
|
||||
|
||||
// replace initial objects in model with cut object
|
||||
finalize(cut_object_ptrs);
|
||||
finalize(cut_object_ptrs, saved_paintings);
|
||||
}
|
||||
else if (volumes.size() > cut_parts_cnt) {
|
||||
// Means that object is cut with connectors
|
||||
@@ -506,7 +542,7 @@ const ModelObjectPtrs& Cut::perform_by_contour(std::vector<Part> parts, int dowe
|
||||
merge_solid_parts_inside_object(cut_object_ptrs);
|
||||
|
||||
// replace initial objects in model with cut object
|
||||
finalize(cut_object_ptrs);
|
||||
finalize(cut_object_ptrs, saved_paintings);
|
||||
|
||||
// Add Dowel-connectors as separate objects to model
|
||||
if (cut_connectors_obj.size() >= 3)
|
||||
@@ -518,7 +554,12 @@ const ModelObjectPtrs& Cut::perform_by_contour(std::vector<Part> parts, int dowe
|
||||
}
|
||||
|
||||
|
||||
const ModelObjectPtrs& Cut::perform_with_groove(const Groove& groove, const Transform3d& rotation_m, bool keep_as_parts/* = false*/)
|
||||
const ModelObjectPtrs& Cut::perform_with_groove(const Groove& groove,
|
||||
const Transform3d& rotation_m,
|
||||
const int groove_count,
|
||||
const float groove_gap,
|
||||
const float m_radius,
|
||||
bool keep_as_parts /* = false*/)
|
||||
{
|
||||
ModelObject* cut_mo = m_model.objects.front();
|
||||
|
||||
@@ -532,6 +573,20 @@ const ModelObjectPtrs& Cut::perform_with_groove(const Groove& groove, const Tran
|
||||
upper->name = upper->name + "_A";
|
||||
lower->name = lower->name + "_B";
|
||||
}
|
||||
|
||||
// Save painting data so we later can remap it.
|
||||
std::vector<std::optional<TriangleSelector::SavedPainting>> saved_paintings;
|
||||
if (m_attributes.has(ModelObjectCutAttribute::KeepPaint)) {
|
||||
const auto instance_matrix = cut_mo->instances[m_instance]->get_transformation().get_matrix_no_offset();
|
||||
for (const auto volume : cut_mo->volumes) {
|
||||
saved_paintings.emplace_back(volume->save_painting());
|
||||
if (saved_paintings.back()) {
|
||||
// Transform mesh to cut space (same transform as process_volume_cut applies)
|
||||
saved_paintings.back()->mesh.transform(instance_matrix * volume->get_matrix(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const double groove_half_depth = 0.5 * double(groove.depth);
|
||||
|
||||
Model tmp_model_for_cut = Model();
|
||||
@@ -565,61 +620,108 @@ const ModelObjectPtrs& Cut::perform_with_groove(const Groove& groove, const Tran
|
||||
reset_instance_transformation(object, m_instance);
|
||||
};
|
||||
|
||||
// cut by upper plane
|
||||
|
||||
const Transform3d cut_matrix_upper = translation_transform(rotation_m * (groove_half_depth * Vec3d::UnitZ())) * m_cut_matrix;
|
||||
// cut by upper plane (+Z)
|
||||
{
|
||||
const Transform3d cut_matrix_upper = translation_transform(rotation_m * (groove_half_depth * Vec3d::UnitZ())) * m_cut_matrix;
|
||||
|
||||
cut(tmp_object, cut_matrix_upper, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
add_volumes_from_cut(upper, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
// cut by lower plane
|
||||
|
||||
const Transform3d cut_matrix_lower = translation_transform(rotation_m * (-groove_half_depth * Vec3d::UnitZ())) * m_cut_matrix;
|
||||
// cut by lower plane (-Z)
|
||||
{
|
||||
const Transform3d cut_matrix_lower = translation_transform(rotation_m * (-groove_half_depth * Vec3d::UnitZ())) * m_cut_matrix;
|
||||
|
||||
cut(tmp_object, cut_matrix_lower, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
add_volumes_from_cut(lower, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
// cut middle part with 2 angles and add parts to related upper/lower objects
|
||||
// Compute same slot outer width used in preview plane
|
||||
const float groove_width = calculate_groove_width(groove, m_radius);
|
||||
|
||||
const double h_side_shift = 0.5 * double(groove.width + groove.depth / tan(groove.flaps_angle));
|
||||
ModelObject* groove_object{nullptr};
|
||||
|
||||
// cut by angle1 plane
|
||||
{
|
||||
const Transform3d cut_matrix_angle1 = translation_transform(rotation_m * (-h_side_shift * Vec3d::UnitX())) * m_cut_matrix * rotation_transform(Vec3d(0, -groove.flaps_angle, -groove.angle));
|
||||
// multiple cuts
|
||||
for (int i = 0; i < groove_count; i++) {
|
||||
bool is_first_groove = i == 0;
|
||||
bool is_last_groove = i == groove_count - 1;
|
||||
|
||||
cut(tmp_object, cut_matrix_angle1, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
add_volumes_from_cut(lower, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
// Calculate the x-axis offset for this dovetail
|
||||
float groove_offset_factor_start = -.5 * ((groove_count - 1));
|
||||
float groove_offset_factor = groove_offset_factor_start + i;
|
||||
|
||||
float offset_x = groove_offset_factor * (groove_gap + groove_width);
|
||||
|
||||
|
||||
tmp_object->clone_for_cut(&groove_object);
|
||||
for (ModelVolume* volume : tmp_object->volumes) {
|
||||
ModelVolume* new_vol = groove_object->add_volume(*volume);
|
||||
new_vol->reset_from_upper();
|
||||
}
|
||||
|
||||
// isolate area of current groove
|
||||
if (!is_first_groove) {
|
||||
float left_cut_position = (-groove_gap / 2.f) - (groove_width / 2.f) + offset_x;
|
||||
|
||||
const Transform3d cut_matrix_left = translation_transform(rotation_m * (left_cut_position * Vec3d::UnitX())) *
|
||||
m_cut_matrix * rotation_transform(Vec3d(0, M_PI / 2.0, 0));
|
||||
|
||||
cut(groove_object, cut_matrix_left, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
}
|
||||
if (!is_last_groove) {
|
||||
float right_cut_position = (groove_gap / 2.f) + (groove_width / 2.f) + offset_x;
|
||||
|
||||
const Transform3d cut_matrix_right = translation_transform(rotation_m * (right_cut_position * Vec3d::UnitX())) *
|
||||
m_cut_matrix * rotation_transform(Vec3d(0, M_PI / 2.0, 0));
|
||||
cut(groove_object, cut_matrix_right, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
const Transform3d groove_translation = translation_transform(rotation_m * (offset_x * Vec3d::UnitX()));
|
||||
// cut middle part with 2 angles and add parts to related upper/lower objects
|
||||
const double h_side_shift = 0.5 * double(groove.width + groove.depth / tan(groove.flaps_angle));
|
||||
|
||||
// cut by angle1 plane
|
||||
{
|
||||
const Transform3d cut_matrix_angle1 = groove_translation * translation_transform(rotation_m * (-h_side_shift * Vec3d::UnitX())) *
|
||||
m_cut_matrix * rotation_transform(Vec3d(0, -groove.flaps_angle, -groove.angle));
|
||||
|
||||
cut(groove_object, cut_matrix_angle1, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
add_volumes_from_cut(lower, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
// cut by angle2 plane
|
||||
{
|
||||
const Transform3d cut_matrix_angle2 = groove_translation * translation_transform(rotation_m * (h_side_shift * Vec3d::UnitX())) *
|
||||
m_cut_matrix * rotation_transform(Vec3d(0, groove.flaps_angle, groove.angle));
|
||||
|
||||
cut(groove_object, cut_matrix_angle2, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
add_volumes_from_cut(lower, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
// apply tolerance to the middle part
|
||||
{
|
||||
const double h_groove_shift_tolerance = groove_half_depth - (double)groove.depth_tolerance;
|
||||
|
||||
const Transform3d cut_matrix_lower_tolerance = groove_translation * translation_transform(rotation_m * (-h_groove_shift_tolerance * Vec3d::UnitZ())) *
|
||||
m_cut_matrix;
|
||||
cut(groove_object, cut_matrix_lower_tolerance, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
|
||||
const double h_side_shift_tolerance = h_side_shift - 0.5 * double(groove.width_tolerance);
|
||||
|
||||
const Transform3d cut_matrix_angle1_tolerance = groove_translation * translation_transform(rotation_m * (-h_side_shift_tolerance * Vec3d::UnitX())) *
|
||||
m_cut_matrix * rotation_transform(Vec3d(0, -groove.flaps_angle, -groove.angle));
|
||||
cut(groove_object, cut_matrix_angle1_tolerance, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
|
||||
const Transform3d cut_matrix_angle2_tolerance = groove_translation * translation_transform(rotation_m * (h_side_shift_tolerance * Vec3d::UnitX())) *
|
||||
m_cut_matrix * rotation_transform(Vec3d(0, groove.flaps_angle, groove.angle));
|
||||
cut(groove_object, cut_matrix_angle2_tolerance, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
add_volumes_from_cut(upper, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
|
||||
groove_object->clear_volumes();
|
||||
}
|
||||
|
||||
// cut by angle2 plane
|
||||
{
|
||||
const Transform3d cut_matrix_angle2 = translation_transform(rotation_m * (h_side_shift * Vec3d::UnitX())) * m_cut_matrix * rotation_transform(Vec3d(0, groove.flaps_angle, groove.angle));
|
||||
|
||||
cut(tmp_object, cut_matrix_angle2, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
add_volumes_from_cut(lower, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
// apply tolerance to the middle part
|
||||
{
|
||||
const double h_groove_shift_tolerance = groove_half_depth - (double)groove.depth_tolerance;
|
||||
|
||||
const Transform3d cut_matrix_lower_tolerance = translation_transform(rotation_m * (-h_groove_shift_tolerance * Vec3d::UnitZ())) * m_cut_matrix;
|
||||
cut(tmp_object, cut_matrix_lower_tolerance, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
|
||||
const double h_side_shift_tolerance = h_side_shift - 0.5 * double(groove.width_tolerance);
|
||||
|
||||
const Transform3d cut_matrix_angle1_tolerance = translation_transform(rotation_m * (-h_side_shift_tolerance * Vec3d::UnitX())) * m_cut_matrix * rotation_transform(Vec3d(0, -groove.flaps_angle, -groove.angle));
|
||||
cut(tmp_object, cut_matrix_angle1_tolerance, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
|
||||
const Transform3d cut_matrix_angle2_tolerance = translation_transform(rotation_m * (h_side_shift_tolerance * Vec3d::UnitX())) * m_cut_matrix * rotation_transform(Vec3d(0, groove.flaps_angle, groove.angle));
|
||||
cut(tmp_object, cut_matrix_angle2_tolerance, ModelObjectCutAttribute::KeepUpper, tmp_model_for_cut);
|
||||
}
|
||||
|
||||
// this part can be added to the upper object now
|
||||
add_volumes_from_cut(upper, ModelObjectCutAttribute::KeepLower, tmp_model_for_cut);
|
||||
|
||||
ModelObjectPtrs cut_object_ptrs;
|
||||
|
||||
if (keep_as_parts) {
|
||||
@@ -658,10 +760,24 @@ const ModelObjectPtrs& Cut::perform_with_groove(const Groove& groove, const Tran
|
||||
merge_solid_parts_inside_object(cut_object_ptrs);
|
||||
}
|
||||
|
||||
finalize(cut_object_ptrs);
|
||||
finalize(cut_object_ptrs, saved_paintings);
|
||||
|
||||
return m_model.objects;
|
||||
}
|
||||
|
||||
float Cut::calculate_groove_width (const Cut::Groove& groove, const float m_radius)
|
||||
{
|
||||
// Compute same slot outer width used in preview plane
|
||||
const double flap_width = is_approx(groove.flaps_angle, 0.f) ? groove.depth : groove.depth / sin(groove.flaps_angle);
|
||||
const double total_flap_width = 2.0 * flap_width * cos(groove.flaps_angle);
|
||||
const double slot_neck_half_width = 0.5f * (groove.width);
|
||||
const double slot_mouth_half_width = 0.5 * (groove.width + total_flap_width);
|
||||
const double plane_half_height = 0.5f* (1.5f * (1.5f *m_radius));
|
||||
const double flap_taper_offset = plane_half_height * tan(groove.angle);
|
||||
const double slot_outer_x_max = std::max(slot_mouth_half_width + flap_taper_offset, slot_neck_half_width + flap_taper_offset);
|
||||
|
||||
return float(2.0 * slot_outer_x_max);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Slic3r {
|
||||
|
||||
using ModelObjectPtrs = std::vector<ModelObject*>;
|
||||
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, KeepAsParts, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels, InvalidateCutInfo };
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, KeepAsParts, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels, InvalidateCutInfo, KeepPaint };
|
||||
using ModelObjectCutAttributes = enum_bitmask<ModelObjectCutAttribute>;
|
||||
ENABLE_ENUM_BITMASK_OPERATORS(ModelObjectCutAttribute);
|
||||
|
||||
@@ -25,7 +25,7 @@ class Cut {
|
||||
|
||||
void post_process(ModelObject* object, ModelObjectPtrs& objects, bool keep, bool place_on_cut, bool flip);
|
||||
void post_process(ModelObject* upper_object, ModelObject* lower_object, ModelObjectPtrs& objects);
|
||||
void finalize(const ModelObjectPtrs& objects);
|
||||
void finalize(const ModelObjectPtrs& objects, const std::vector<std::optional<TriangleSelector::SavedPainting>>& saved_paintings);
|
||||
|
||||
public:
|
||||
|
||||
@@ -56,10 +56,16 @@ public:
|
||||
};
|
||||
|
||||
const ModelObjectPtrs& perform_with_plane();
|
||||
const ModelObjectPtrs& perform_by_contour(std::vector<Part> parts, int dowels_count);
|
||||
const ModelObjectPtrs& perform_with_groove(const Groove& groove, const Transform3d& rotation_m, bool keep_as_parts = false);
|
||||
const ModelObjectPtrs& perform_by_contour(const ModelObject* src_object, std::vector<Part> parts, int dowels_count);
|
||||
const ModelObjectPtrs& perform_with_groove(const Groove& groove,
|
||||
const Transform3d& rotation_m,
|
||||
const int groove_count,
|
||||
const float groove_gap,
|
||||
const float m_radius,
|
||||
bool keep_as_parts = false);
|
||||
|
||||
}; // namespace Cut
|
||||
static float calculate_groove_width(const Cut::Groove& groove, const float m_radius);
|
||||
}; // namespace Cut
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
|
||||
@@ -1161,10 +1161,15 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
const bool is_ramming = (gcodegen.config().single_extruder_multi_material) ||
|
||||
(!gcodegen.config().single_extruder_multi_material &&
|
||||
gcodegen.config().filament_multitool_ramming.get_at(tcr.initial_tool));
|
||||
// Orca: user-facing override (Printer Settings > Wipe tower > "Tool change on wipe tower").
|
||||
// Forces the toolhead to travel over the wipe tower before issuing Tx even on multi-toolhead
|
||||
// printers without ramming, where Orca would otherwise emit Tx in place (potentially over the part).
|
||||
const bool tool_change_on_wipe_tower = gcodegen.config().tool_change_on_wipe_tower.value;
|
||||
const bool should_travel_to_tower = !tcr.priming && (tcr.force_travel // wipe tower says so
|
||||
|| !needs_toolchange // this is just finishing the tower with no toolchange
|
||||
|| will_go_down // Make sure to move to prime tower before moving down
|
||||
|| is_ramming);
|
||||
|| is_ramming
|
||||
|| tool_change_on_wipe_tower);
|
||||
|
||||
if (should_travel_to_tower || gcodegen.m_need_change_layer_lift_z) {
|
||||
// FIXME: It would be better if the wipe tower set the force_travel flag for all toolchanges,
|
||||
|
||||
@@ -298,7 +298,11 @@ bool directions_perpendicular(double angle1, double angle2, double max_diff = 0)
|
||||
template<class T> bool contains(const std::vector<T> &vector, const Point &point);
|
||||
template<typename T> T rad2deg(T angle) { return T(180.0) * angle / T(PI); }
|
||||
double rad2deg_dir(double angle);
|
||||
template<typename T> constexpr T deg2rad(const T angle) { return T(PI) * angle / T(180.0); }
|
||||
template<typename T> constexpr T deg2rad(const T angle)
|
||||
{
|
||||
static_assert(std::is_floating_point<T>::value, "Why do you want to calculate angle in integer?");
|
||||
return T(PI) * angle / T(180.0);
|
||||
}
|
||||
template<typename T> T angle_to_0_2PI(T angle)
|
||||
{
|
||||
static const T TWO_PI = T(2) * T(PI);
|
||||
|
||||
@@ -159,6 +159,12 @@ bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
&& config.detect_thin_wall == other_config.detect_thin_wall
|
||||
&& config.infill_wall_overlap == other_config.infill_wall_overlap
|
||||
&& config.top_bottom_infill_wall_overlap == other_config.top_bottom_infill_wall_overlap
|
||||
// Orca: these flags directly change the effective wall count produced by the perimeter
|
||||
// generator. If two regions disagree on any of them, merging their slices into one shared make_perimeters
|
||||
// call would silently use the first region's flag for both.
|
||||
&& config.only_one_wall_first_layer == other_config.only_one_wall_first_layer
|
||||
&& config.only_one_wall_top == other_config.only_one_wall_top
|
||||
&& config.min_width_top_surface == other_config.min_width_top_surface
|
||||
&& config.seam_slope_type == other_config.seam_slope_type
|
||||
&& config.seam_slope_conditional == other_config.seam_slope_conditional
|
||||
&& config.scarf_angle_threshold == other_config.scarf_angle_threshold
|
||||
|
||||
@@ -1980,6 +1980,49 @@ void ModelVolume::reset_extra_facets()
|
||||
this->fuzzy_skin_facets.reset();
|
||||
}
|
||||
|
||||
std::optional<TriangleSelector::SavedPainting> ModelVolume::save_painting() const
|
||||
{
|
||||
if (is_any_painted() && is_model_part() && !mesh().empty()) {
|
||||
TriangleSelector::SavedPainting sp;
|
||||
sp.mesh = mesh();
|
||||
sp.supported = supported_facets.get_data();
|
||||
sp.seam = seam_facets.get_data();
|
||||
sp.mmu = mmu_segmentation_facets.get_data();
|
||||
sp.fuzzy = fuzzy_skin_facets.get_data();
|
||||
return sp;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ModelVolume::restore_painting(const std::optional<TriangleSelector::SavedPainting>& saved, const bool keep_existing_paint)
|
||||
{
|
||||
if (!keep_existing_paint) {
|
||||
reset_extra_facets();
|
||||
}
|
||||
|
||||
if (!saved) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto remap_one = [&](const TriangleSelector::TriangleSplittingData& src_data,
|
||||
FacetsAnnotation& target_facets) {
|
||||
if (src_data.bitstream.empty())
|
||||
return;
|
||||
auto result =
|
||||
TriangleSelector::remap_painting(saved->mesh.its, src_data, mesh().its, Geometry::translation_transform(mesh().get_init_shift()),
|
||||
keep_existing_paint ?
|
||||
std::optional<std::reference_wrapper<const TriangleSelector::TriangleSplittingData>>{std::ref(target_facets.get_data())} :
|
||||
std::optional<std::reference_wrapper<const TriangleSelector::TriangleSplittingData>>{});
|
||||
if (!result.bitstream.empty())
|
||||
target_facets.set_data(std::move(result));
|
||||
};
|
||||
remap_one(saved->supported, supported_facets);
|
||||
remap_one(saved->seam, seam_facets);
|
||||
remap_one(saved->mmu, mmu_segmentation_facets);
|
||||
remap_one(saved->fuzzy, fuzzy_skin_facets);
|
||||
}
|
||||
|
||||
static void invalidate_translations(ModelObject* object, const ModelInstance* src_instance)
|
||||
{
|
||||
if (!object->origin_translation.isApprox(Vec3d::Zero()) && src_instance->get_offset().isApprox(Vec3d::Zero())) {
|
||||
@@ -1993,13 +2036,14 @@ static void invalidate_translations(ModelObject* object, const ModelInstance* sr
|
||||
}
|
||||
}
|
||||
|
||||
void ModelObject::split(ModelObjectPtrs* new_objects)
|
||||
void ModelObject::split(ModelObjectPtrs* new_objects, const bool remap_paint)
|
||||
{
|
||||
std::vector<TriangleMesh> all_meshes;
|
||||
std::vector<Transform3d> all_transfos;
|
||||
std::vector<std::pair<int, int>> volume_mesh_counts;
|
||||
all_meshes.reserve(this->volumes.size() * 5);
|
||||
bool is_multi_volume_object = (this->volumes.size() > 1);
|
||||
std::optional<TriangleSelector::SavedPainting> saved_painting;
|
||||
|
||||
for (int volume_idx = 0; volume_idx < this->volumes.size(); volume_idx++) {
|
||||
ModelVolume* volume = this->volumes[volume_idx];
|
||||
@@ -2011,6 +2055,10 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
||||
volume->text_configuration.reset();
|
||||
|
||||
if (!is_multi_volume_object) {
|
||||
if (remap_paint) {
|
||||
// Save painting so we could restore them after the mesh split
|
||||
saved_painting = volume->save_painting();
|
||||
}
|
||||
//BBS: not multi volume object, then split mesh.
|
||||
std::vector<TriangleMesh> volume_meshes = volume->mesh().split();
|
||||
int mesh_count = 0;
|
||||
@@ -2078,10 +2126,19 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
||||
ModelVolume* new_vol = new_object->add_volume(*volume, std::move(mesh));
|
||||
|
||||
if (is_multi_volume_object) {
|
||||
// BBS: volume geometry not changed, so we can keep the color paint facets
|
||||
if (new_vol->mmu_segmentation_facets.timestamp() == volume->mmu_segmentation_facets.timestamp())
|
||||
new_vol->mmu_segmentation_facets.reset(); // BBS: let next assign take effect
|
||||
new_vol->mmu_segmentation_facets.assign(volume->mmu_segmentation_facets);
|
||||
// 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)
|
||||
|
||||
COPY_FACETS(supported_facets);
|
||||
COPY_FACETS(seam_facets);
|
||||
COPY_FACETS(mmu_segmentation_facets);
|
||||
COPY_FACETS(fuzzy_skin_facets);
|
||||
} else if (saved_painting) {
|
||||
// Geometry changed, attempt to remap them to the new mesh
|
||||
new_vol->restore_painting(saved_painting);
|
||||
}
|
||||
|
||||
// BBS: clear volume's config, as we already set them into object
|
||||
@@ -2682,7 +2739,7 @@ std::string ModelVolume::type_to_string(const ModelVolumeType t)
|
||||
// Split this volume, append the result to the object owning this volume.
|
||||
// Return the number of volumes created from this one.
|
||||
// This is useful to assign different materials to different volumes of an object.
|
||||
size_t ModelVolume::split(unsigned int max_extruders)
|
||||
size_t ModelVolume::split(unsigned int max_extruders, bool remap_paint)
|
||||
{
|
||||
std::vector<TriangleMesh> meshes = this->mesh().split();
|
||||
if (meshes.size() <= 1)
|
||||
@@ -2692,6 +2749,9 @@ size_t ModelVolume::split(unsigned int max_extruders)
|
||||
if (text_configuration.has_value())
|
||||
text_configuration.reset();
|
||||
|
||||
std::optional<TriangleSelector::SavedPainting> saved_painting = remap_paint ? save_painting() :
|
||||
std::optional<TriangleSelector::SavedPainting>{};
|
||||
|
||||
size_t idx = 0;
|
||||
size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin();
|
||||
const std::string name = this->name;
|
||||
@@ -2714,11 +2774,7 @@ size_t ModelVolume::split(unsigned int max_extruders)
|
||||
this->source = ModelVolume::Source();
|
||||
|
||||
// BBS: reset facet annotations
|
||||
this->mmu_segmentation_facets.reset();
|
||||
this->exterior_facets.reset();
|
||||
this->supported_facets.reset();
|
||||
this->seam_facets.reset();
|
||||
this->fuzzy_skin_facets.reset();
|
||||
this->reset_extra_facets();
|
||||
}
|
||||
else
|
||||
this->object->volumes.insert(this->object->volumes.begin() + (++ivolume), new ModelVolume(object, *this, std::move(mesh)));
|
||||
@@ -2731,6 +2787,8 @@ size_t ModelVolume::split(unsigned int max_extruders)
|
||||
this->object->volumes[ivolume]->config.set("extruder", this->extruder_id());
|
||||
//this->object->volumes[ivolume]->config.set("extruder", auto_extruder_id(max_extruders, extruder_counter));
|
||||
this->object->volumes[ivolume]->m_is_splittable = 0;
|
||||
this->object->volumes[ivolume]->restore_painting(saved_painting);
|
||||
|
||||
++ idx;
|
||||
}
|
||||
|
||||
|
||||