mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-18 04:08:02 -06:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_custom_gcode_detection
This commit is contained in:
commit
c7771a576b
73 changed files with 2263 additions and 2165 deletions
4
deps/deps-linux.cmake
vendored
4
deps/deps-linux.cmake
vendored
|
@ -13,7 +13,7 @@ include("deps-unix-common.cmake")
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND ./bootstrap.sh
|
CONFIGURE_COMMAND ./bootstrap.sh
|
||||||
|
@ -100,5 +100,5 @@ ExternalProject_Add(dep_libcurl
|
||||||
BUILD_COMMAND make "-j${NPROC}"
|
BUILD_COMMAND make "-j${NPROC}"
|
||||||
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies(dep_openvdb dep_boost)
|
add_dependencies(dep_openvdb dep_boost)
|
||||||
|
|
||||||
|
|
4
deps/deps-macos.cmake
vendored
4
deps/deps-macos.cmake
vendored
|
@ -18,7 +18,7 @@ include("deps-unix-common.cmake")
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND ./bootstrap.sh
|
CONFIGURE_COMMAND ./bootstrap.sh
|
||||||
|
@ -87,5 +87,5 @@ ExternalProject_Add(dep_libcurl
|
||||||
BUILD_COMMAND make "-j${NPROC}"
|
BUILD_COMMAND make "-j${NPROC}"
|
||||||
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies(dep_openvdb dep_boost)
|
add_dependencies(dep_openvdb dep_boost)
|
||||||
|
|
||||||
|
|
3
deps/deps-mingw.cmake
vendored
3
deps/deps-mingw.cmake
vendored
|
@ -9,7 +9,7 @@ include("deps-unix-common.cmake")
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND bootstrap.bat
|
CONFIGURE_COMMAND bootstrap.bat
|
||||||
|
@ -59,3 +59,4 @@ ExternalProject_Add(dep_libcurl
|
||||||
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
|
||||||
${DEP_CMAKE_OPTS}
|
${DEP_CMAKE_OPTS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
3
deps/deps-windows.cmake
vendored
3
deps/deps-windows.cmake
vendored
|
@ -55,7 +55,7 @@ endmacro()
|
||||||
|
|
||||||
ExternalProject_Add(dep_boost
|
ExternalProject_Add(dep_boost
|
||||||
EXCLUDE_FROM_ALL 1
|
EXCLUDE_FROM_ALL 1
|
||||||
URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
|
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
|
||||||
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND bootstrap.bat
|
CONFIGURE_COMMAND bootstrap.bat
|
||||||
|
@ -296,3 +296,4 @@ if (${DEP_DEBUG})
|
||||||
WORKING_DIRECTORY "${BINARY_DIR}"
|
WORKING_DIRECTORY "${BINARY_DIR}"
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
BIN
resources/icons/info.png
Normal file
BIN
resources/icons/info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 308 B |
|
@ -1,3 +1,5 @@
|
||||||
|
min_slic3r_version = 2.3.1-beta
|
||||||
|
0.0.9 Updated bed textures
|
||||||
min_slic3r_version = 2.3.0-beta2
|
min_slic3r_version = 2.3.0-beta2
|
||||||
0.0.8 Updated start and end g-code for Anycubic Mega.
|
0.0.8 Updated start and end g-code for Anycubic Mega.
|
||||||
0.0.7 Updated start g-code for Anycubic Mega.
|
0.0.7 Updated start g-code for Anycubic Mega.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
name = Anycubic
|
name = Anycubic
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
||||||
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.0.8
|
config_version = 0.0.9
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
min_slic3r_version = 2.4.0-alpha0
|
min_slic3r_version = 2.3.1-beta
|
||||||
0.0.1 Initial Artillery bundle
|
0.0.1 Initial Artillery bundle
|
||||||
|
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
@ -1,3 +1,6 @@
|
||||||
|
min_slic3r_version = 2.3.1-beta
|
||||||
|
0.0.16 Updated CR6-SE start g-code. Added and updated filament profiles.
|
||||||
|
0.0.15 Added new printer models, filament profiles. Various improvements.
|
||||||
min_slic3r_version = 2.3.0-rc2
|
min_slic3r_version = 2.3.0-rc2
|
||||||
0.0.14 Optimized start g-code. Added filament profile. Various improvements.
|
0.0.14 Optimized start g-code. Added filament profile. Various improvements.
|
||||||
0.0.13 Optimized start and end g-code. General improvements.
|
0.0.13 Optimized start and end g-code. General improvements.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
name = Creality
|
name = Creality
|
||||||
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
# Configuration version of this file. Config file will only be installed, if the config_version differs.
|
||||||
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
# This means, the server may force the PrusaSlicer configuration to be downgraded.
|
||||||
config_version = 0.0.14
|
config_version = 0.0.16
|
||||||
# Where to get the updates from?
|
# Where to get the updates from?
|
||||||
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
|
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
|
||||||
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
|
||||||
|
@ -21,7 +21,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = ender3.svg
|
bed_texture = ender3.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER3BLTOUCH]
|
[printer_model:ENDER3BLTOUCH]
|
||||||
name = Creality Ender-3 BLTouch
|
name = Creality Ender-3 BLTouch
|
||||||
|
@ -30,7 +30,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = ender3.svg
|
bed_texture = ender3.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER3V2]
|
[printer_model:ENDER3V2]
|
||||||
name = Creality Ender-3 V2
|
name = Creality Ender-3 V2
|
||||||
|
@ -39,7 +39,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3v2_bed.stl
|
bed_model = ender3v2_bed.stl
|
||||||
bed_texture = ender3v2.svg
|
bed_texture = ender3v2.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER3MAX]
|
[printer_model:ENDER3MAX]
|
||||||
name = Creality Ender-3 Max
|
name = Creality Ender-3 Max
|
||||||
|
@ -48,7 +48,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10spro.svg
|
bed_texture = cr10spro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER4]
|
[printer_model:ENDER4]
|
||||||
name = Creality Ender-4
|
name = Creality Ender-4
|
||||||
|
@ -57,7 +57,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3v2_bed.stl
|
bed_model = ender3v2_bed.stl
|
||||||
bed_texture = ender3v2.svg
|
bed_texture = ender3v2.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER5]
|
[printer_model:ENDER5]
|
||||||
name = Creality Ender-5
|
name = Creality Ender-5
|
||||||
|
@ -66,7 +66,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = ender3.svg
|
bed_texture = ender3.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER5PLUS]
|
[printer_model:ENDER5PLUS]
|
||||||
name = Creality Ender-5 Plus
|
name = Creality Ender-5 Plus
|
||||||
|
@ -75,7 +75,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender5plus_bed.stl
|
bed_model = ender5plus_bed.stl
|
||||||
bed_texture = ender5plus.svg
|
bed_texture = ender5plus.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER6]
|
[printer_model:ENDER6]
|
||||||
name = Creality Ender-6
|
name = Creality Ender-6
|
||||||
|
@ -84,7 +84,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender6_bed.stl
|
bed_model = ender6_bed.stl
|
||||||
bed_texture = ender6.svg
|
bed_texture = ender6.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:ENDER2]
|
[printer_model:ENDER2]
|
||||||
name = Creality Ender-2
|
name = Creality Ender-2
|
||||||
|
@ -93,7 +93,7 @@ technology = FFF
|
||||||
family = ENDER
|
family = ENDER
|
||||||
bed_model = ender2_bed.stl
|
bed_model = ender2_bed.stl
|
||||||
bed_texture = ender2.svg
|
bed_texture = ender2.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR5PRO]
|
[printer_model:CR5PRO]
|
||||||
name = Creality CR-5 Pro
|
name = Creality CR-5 Pro
|
||||||
|
@ -102,7 +102,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr5pro_bed.stl
|
bed_model = cr5pro_bed.stl
|
||||||
bed_texture = cr5pro.svg
|
bed_texture = cr5pro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR5PROH]
|
[printer_model:CR5PROH]
|
||||||
name = Creality CR-5 Pro H
|
name = Creality CR-5 Pro H
|
||||||
|
@ -111,7 +111,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr5pro_bed.stl
|
bed_model = cr5pro_bed.stl
|
||||||
bed_texture = cr5pro.svg
|
bed_texture = cr5pro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR6SE]
|
[printer_model:CR6SE]
|
||||||
name = Creality CR-6 SE
|
name = Creality CR-6 SE
|
||||||
|
@ -120,7 +120,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr6se_bed.stl
|
bed_model = cr6se_bed.stl
|
||||||
bed_texture = cr6se.svg
|
bed_texture = cr6se.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR6MAX]
|
[printer_model:CR6MAX]
|
||||||
name = Creality CR-6 Max
|
name = Creality CR-6 Max
|
||||||
|
@ -129,7 +129,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10s4_bed.stl
|
bed_model = cr10s4_bed.stl
|
||||||
bed_texture = cr10s4.svg
|
bed_texture = cr10s4.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10MINI]
|
[printer_model:CR10MINI]
|
||||||
name = Creality CR-10 Mini
|
name = Creality CR-10 Mini
|
||||||
|
@ -138,7 +138,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10mini_bed.stl
|
bed_model = cr10mini_bed.stl
|
||||||
bed_texture = cr10mini.svg
|
bed_texture = cr10mini.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10MAX]
|
[printer_model:CR10MAX]
|
||||||
name = Creality CR-10 Max
|
name = Creality CR-10 Max
|
||||||
|
@ -147,7 +147,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10max_bed.stl
|
bed_model = cr10max_bed.stl
|
||||||
bed_texture = cr10max.svg
|
bed_texture = cr10max.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10]
|
[printer_model:CR10]
|
||||||
name = Creality CR-10
|
name = Creality CR-10
|
||||||
|
@ -156,7 +156,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10_bed.stl
|
bed_model = cr10_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10V2]
|
[printer_model:CR10V2]
|
||||||
name = Creality CR-10 V2
|
name = Creality CR-10 V2
|
||||||
|
@ -165,7 +165,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10V3]
|
[printer_model:CR10V3]
|
||||||
name = Creality CR-10 V3
|
name = Creality CR-10 V3
|
||||||
|
@ -174,7 +174,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10S]
|
[printer_model:CR10S]
|
||||||
name = Creality CR-10 S
|
name = Creality CR-10 S
|
||||||
|
@ -183,7 +183,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10_bed.stl
|
bed_model = cr10_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10SPRO]
|
[printer_model:CR10SPRO]
|
||||||
name = Creality CR-10 S Pro
|
name = Creality CR-10 S Pro
|
||||||
|
@ -192,7 +192,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10spro.svg
|
bed_texture = cr10spro.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10SPROV2]
|
[printer_model:CR10SPROV2]
|
||||||
name = Creality CR-10 S Pro V2
|
name = Creality CR-10 S Pro V2
|
||||||
|
@ -201,7 +201,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10v2_bed.stl
|
bed_model = cr10v2_bed.stl
|
||||||
bed_texture = cr10.svg
|
bed_texture = cr10.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10S4]
|
[printer_model:CR10S4]
|
||||||
name = Creality CR-10 S4
|
name = Creality CR-10 S4
|
||||||
|
@ -210,7 +210,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10s4_bed.stl
|
bed_model = cr10s4_bed.stl
|
||||||
bed_texture = cr10s4.svg
|
bed_texture = cr10s4.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR10S5]
|
[printer_model:CR10S5]
|
||||||
name = Creality CR-10 S5
|
name = Creality CR-10 S5
|
||||||
|
@ -219,7 +219,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr10s5_bed.stl
|
bed_model = cr10s5_bed.stl
|
||||||
bed_texture = cr10s5.svg
|
bed_texture = cr10s5.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR20]
|
[printer_model:CR20]
|
||||||
name = Creality CR-20
|
name = Creality CR-20
|
||||||
|
@ -228,7 +228,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = cr20.svg
|
bed_texture = cr20.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR20PRO]
|
[printer_model:CR20PRO]
|
||||||
name = Creality CR-20 Pro
|
name = Creality CR-20 Pro
|
||||||
|
@ -237,7 +237,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = ender3_bed.stl
|
bed_model = ender3_bed.stl
|
||||||
bed_texture = cr20.svg
|
bed_texture = cr20.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR200B]
|
[printer_model:CR200B]
|
||||||
name = Creality CR-200B
|
name = Creality CR-200B
|
||||||
|
@ -246,7 +246,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr200b_bed.stl
|
bed_model = cr200b_bed.stl
|
||||||
bed_texture = cr200b.svg
|
bed_texture = cr200b.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
[printer_model:CR8]
|
[printer_model:CR8]
|
||||||
name = Creality CR-8
|
name = Creality CR-8
|
||||||
|
@ -255,7 +255,7 @@ technology = FFF
|
||||||
family = CR
|
family = CR
|
||||||
bed_model = cr8_bed.stl
|
bed_model = cr8_bed.stl
|
||||||
bed_texture = cr8.svg
|
bed_texture = cr8.svg
|
||||||
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
#[printer_model:CRX]
|
#[printer_model:CRX]
|
||||||
#name = Creality CR-X
|
#name = Creality CR-X
|
||||||
|
@ -264,7 +264,7 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
|
||||||
#family = CR-X
|
#family = CR-X
|
||||||
#bed_model = cr10v2_bed.stl
|
#bed_model = cr10v2_bed.stl
|
||||||
#bed_texture = cr10spro.svg
|
#bed_texture = cr10spro.svg
|
||||||
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
#[printer_model:CRXPRO]
|
#[printer_model:CRXPRO]
|
||||||
#name = Creality CR-X Pro
|
#name = Creality CR-X Pro
|
||||||
|
@ -273,7 +273,7 @@ default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @
|
||||||
#family = CR-X
|
#family = CR-X
|
||||||
#bed_model = cr10v2_bed.stl
|
#bed_model = cr10v2_bed.stl
|
||||||
#bed_texture = cr10spro.svg
|
#bed_texture = cr10spro.svg
|
||||||
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA (Galaxy) @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
#default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
|
||||||
|
|
||||||
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
||||||
# not make it into the user interface.
|
# not make it into the user interface.
|
||||||
|
@ -637,9 +637,11 @@ first_layer_bed_temperature = 60
|
||||||
filament_cost = 19.00
|
filament_cost = 19.00
|
||||||
filament_density = 1.24
|
filament_density = 1.24
|
||||||
filament_colour = #FF0000
|
filament_colour = #FF0000
|
||||||
|
filament_spool_weight = 256
|
||||||
|
|
||||||
[filament:Devil Design PLA (Galaxy) @CREALITY]
|
[filament:Devil Design PLA Galaxy @CREALITY]
|
||||||
inherits = *PLA*
|
inherits = *PLA*
|
||||||
|
renamed_from = "Devil Design PLA (Galaxy) @CREALITY"
|
||||||
filament_vendor = Devil Design
|
filament_vendor = Devil Design
|
||||||
temperature = 225
|
temperature = 225
|
||||||
bed_temperature = 65
|
bed_temperature = 65
|
||||||
|
@ -648,6 +650,7 @@ first_layer_bed_temperature = 65
|
||||||
filament_cost = 19.00
|
filament_cost = 19.00
|
||||||
filament_density = 1.24
|
filament_density = 1.24
|
||||||
filament_colour = #FF0000
|
filament_colour = #FF0000
|
||||||
|
filament_spool_weight = 256
|
||||||
|
|
||||||
[filament:Extrudr PLA NX2 @CREALITY]
|
[filament:Extrudr PLA NX2 @CREALITY]
|
||||||
inherits = *PLA*
|
inherits = *PLA*
|
||||||
|
@ -706,6 +709,18 @@ filament_density = 1.24
|
||||||
filament_colour = #125467
|
filament_colour = #125467
|
||||||
filament_spool_weight = 238
|
filament_spool_weight = 238
|
||||||
|
|
||||||
|
[filament:3DJAKE ecoPLA Matt @CREALITY]
|
||||||
|
inherits = *PLA*
|
||||||
|
filament_vendor = 3DJAKE
|
||||||
|
temperature = 195
|
||||||
|
bed_temperature = 60
|
||||||
|
first_layer_temperature = 195
|
||||||
|
first_layer_bed_temperature = 60
|
||||||
|
filament_cost = 24.99
|
||||||
|
filament_density = 1.38
|
||||||
|
filament_colour = #125467
|
||||||
|
filament_spool_weight = 238
|
||||||
|
|
||||||
[filament:3DJAKE ecoPLA Tough @CREALITY]
|
[filament:3DJAKE ecoPLA Tough @CREALITY]
|
||||||
inherits = *PLA*
|
inherits = *PLA*
|
||||||
filament_vendor = 3DJAKE
|
filament_vendor = 3DJAKE
|
||||||
|
@ -954,7 +969,7 @@ printer_model = CR5PROH
|
||||||
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PROH\nPRINTER_HAS_BOWDEN
|
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR5PROH\nPRINTER_HAS_BOWDEN
|
||||||
|
|
||||||
[printer:Creality CR-6 SE]
|
[printer:Creality CR-6 SE]
|
||||||
inherits = *common*; *fastabl*; *pauseprint*
|
inherits = *common*; *pauseprint*
|
||||||
bed_shape = 5x0,230x0,230x235,5x235
|
bed_shape = 5x0,230x0,230x235,5x235
|
||||||
printer_model = CR6SE
|
printer_model = CR6SE
|
||||||
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN
|
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_CR6SE\nPRINTER_HAS_BOWDEN
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
min_slic3r_version = 2.4.0-alpha0
|
min_slic3r_version = 2.3.1-beta
|
||||||
0.0.1 Initial version
|
0.0.1 Initial version
|
||||||
0.0.2 Improved start gcode, changed filename format
|
0.0.2 Improved start gcode, changed filename format
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
min_slic3r_version = 2.4.0-alpha0
|
||||||
|
1.3.0-alpha0 Disabled thick bridges, updated support settings.
|
||||||
min_slic3r_version = 2.3.0-rc1
|
min_slic3r_version = 2.3.0-rc1
|
||||||
1.2.4 Updated cost/density values in filament settings. Various changes in print settings.
|
1.2.4 Updated cost/density values in filament settings. Various changes in print settings.
|
||||||
1.2.3 Updated firmware version. Updated end g-code in MMU2 printer profiles.
|
1.2.3 Updated firmware version. Updated end g-code in MMU2 printer profiles.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -287,6 +287,11 @@ bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef CLIPPERLIB_INT32
|
||||||
|
inline bool SlopesEqual(const cInt dx1, const cInt dy1, const cInt dx2, const cInt dy2, bool /* UseFullInt64Range */) {
|
||||||
|
return int64_t(dy1) * int64_t(dx2) == int64_t(dx1) * int64_t(dy2);
|
||||||
|
}
|
||||||
|
#else
|
||||||
inline bool SlopesEqual(const cInt dx1, const cInt dy1, const cInt dx2, const cInt dy2, bool UseFullInt64Range) {
|
inline bool SlopesEqual(const cInt dx1, const cInt dy1, const cInt dx2, const cInt dy2, bool UseFullInt64Range) {
|
||||||
return (UseFullInt64Range) ?
|
return (UseFullInt64Range) ?
|
||||||
// |dx1| < 2^63, |dx2| < 2^63 etc,
|
// |dx1| < 2^63, |dx2| < 2^63 etc,
|
||||||
|
@ -296,6 +301,8 @@ inline bool SlopesEqual(const cInt dx1, const cInt dy1, const cInt dx2, const cI
|
||||||
// therefore the following computation could be done with 64bit arithmetics.
|
// therefore the following computation could be done with 64bit arithmetics.
|
||||||
dy1 * dx2 == dx1 * dy2;
|
dy1 * dx2 == dx1 * dy2;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
|
inline bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
|
||||||
{ return SlopesEqual(e1.Delta.X, e1.Delta.Y, e2.Delta.X, e2.Delta.Y, UseFullInt64Range); }
|
{ return SlopesEqual(e1.Delta.X, e1.Delta.Y, e2.Delta.X, e2.Delta.Y, UseFullInt64Range); }
|
||||||
inline bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, bool UseFullInt64Range)
|
inline bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2, const IntPoint &pt3, bool UseFullInt64Range)
|
||||||
|
@ -363,8 +370,8 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx;
|
b1 = double(Edge1.Bot.X) - double(Edge1.Bot.Y) * Edge1.Dx;
|
||||||
b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx;
|
b2 = double(Edge2.Bot.X) - double(Edge2.Bot.Y) * Edge2.Dx;
|
||||||
double q = (b2-b1) / (Edge1.Dx - Edge2.Dx);
|
double q = (b2-b1) / (Edge1.Dx - Edge2.Dx);
|
||||||
ip.Y = Round(q);
|
ip.Y = Round(q);
|
||||||
ip.X = (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) ?
|
ip.X = (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) ?
|
||||||
|
@ -569,6 +576,7 @@ bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
|
||||||
// ClipperBase class methods ...
|
// ClipperBase class methods ...
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
// Called from ClipperBase::AddPath() to verify the scale of the input polygon coordinates.
|
// Called from ClipperBase::AddPath() to verify the scale of the input polygon coordinates.
|
||||||
inline void RangeTest(const IntPoint& Pt, bool& useFullRange)
|
inline void RangeTest(const IntPoint& Pt, bool& useFullRange)
|
||||||
{
|
{
|
||||||
|
@ -583,6 +591,7 @@ inline void RangeTest(const IntPoint& Pt, bool& useFullRange)
|
||||||
RangeTest(Pt, useFullRange);
|
RangeTest(Pt, useFullRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Called from ClipperBase::AddPath() to construct the Local Minima List.
|
// Called from ClipperBase::AddPath() to construct the Local Minima List.
|
||||||
|
@ -805,13 +814,17 @@ bool ClipperBase::AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, b
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
edges[1].Curr = pg[1];
|
edges[1].Curr = pg[1];
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
RangeTest(pg[0], m_UseFullRange);
|
RangeTest(pg[0], m_UseFullRange);
|
||||||
RangeTest(pg[highI], m_UseFullRange);
|
RangeTest(pg[highI], m_UseFullRange);
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]);
|
InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]);
|
||||||
InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]);
|
InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]);
|
||||||
for (int i = highI - 1; i >= 1; --i)
|
for (int i = highI - 1; i >= 1; --i)
|
||||||
{
|
{
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
RangeTest(pg[i], m_UseFullRange);
|
RangeTest(pg[i], m_UseFullRange);
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
|
InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -967,7 +980,9 @@ void ClipperBase::Clear()
|
||||||
CLIPPERLIB_PROFILE_FUNC();
|
CLIPPERLIB_PROFILE_FUNC();
|
||||||
m_MinimaList.clear();
|
m_MinimaList.clear();
|
||||||
m_edges.clear();
|
m_edges.clear();
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
m_UseFullRange = false;
|
m_UseFullRange = false;
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
m_HasOpenPaths = false;
|
m_HasOpenPaths = false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -3322,9 +3337,9 @@ DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
|
||||||
if(pt2.X == pt1.X && pt2.Y == pt1.Y)
|
if(pt2.X == pt1.X && pt2.Y == pt1.Y)
|
||||||
return DoublePoint(0, 0);
|
return DoublePoint(0, 0);
|
||||||
|
|
||||||
double Dx = (double)(pt2.X - pt1.X);
|
double Dx = double(pt2.X - pt1.X);
|
||||||
double dy = (double)(pt2.Y - pt1.Y);
|
double dy = double(pt2.Y - pt1.Y);
|
||||||
double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy );
|
double f = 1.0 / std::sqrt( Dx*Dx + dy*dy );
|
||||||
Dx *= f;
|
Dx *= f;
|
||||||
dy *= f;
|
dy *= f;
|
||||||
return DoublePoint(dy, -Dx);
|
return DoublePoint(dy, -Dx);
|
||||||
|
@ -3530,8 +3545,9 @@ void ClipperOffset::DoOffset(double delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
//see offset_triginometry3.svg in the documentation folder ...
|
//see offset_triginometry3.svg in the documentation folder ...
|
||||||
if (MiterLimit > 2) m_miterLim = 2/(MiterLimit * MiterLimit);
|
m_miterLim = (MiterLimit > 2) ?
|
||||||
else m_miterLim = 0.5;
|
2. / (MiterLimit * MiterLimit) :
|
||||||
|
0.5;
|
||||||
|
|
||||||
double y;
|
double y;
|
||||||
if (ArcTolerance <= 0.0) y = def_arc_tolerance;
|
if (ArcTolerance <= 0.0) y = def_arc_tolerance;
|
||||||
|
@ -3633,11 +3649,9 @@ void ClipperOffset::DoOffset(double delta)
|
||||||
if (node.m_endtype == etOpenButt)
|
if (node.m_endtype == etOpenButt)
|
||||||
{
|
{
|
||||||
int j = len - 1;
|
int j = len - 1;
|
||||||
pt1 = IntPoint(Round(m_srcPoly[j].X + m_normals[j].X *
|
pt1 = IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * delta), Round(m_srcPoly[j].Y + m_normals[j].Y * delta));
|
||||||
delta), Round(m_srcPoly[j].Y + m_normals[j].Y * delta));
|
|
||||||
m_destPoly.push_back(pt1);
|
m_destPoly.push_back(pt1);
|
||||||
pt1 = IntPoint(Round(m_srcPoly[j].X - m_normals[j].X *
|
pt1 = IntPoint(Round(m_srcPoly[j].X - m_normals[j].X * delta), Round(m_srcPoly[j].Y - m_normals[j].Y * delta));
|
||||||
delta), Round(m_srcPoly[j].Y - m_normals[j].Y * delta));
|
|
||||||
m_destPoly.push_back(pt1);
|
m_destPoly.push_back(pt1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3662,11 +3676,9 @@ void ClipperOffset::DoOffset(double delta)
|
||||||
|
|
||||||
if (node.m_endtype == etOpenButt)
|
if (node.m_endtype == etOpenButt)
|
||||||
{
|
{
|
||||||
pt1 = IntPoint(Round(m_srcPoly[0].X - m_normals[0].X * delta),
|
pt1 = IntPoint(Round(m_srcPoly[0].X - m_normals[0].X * delta), Round(m_srcPoly[0].Y - m_normals[0].Y * delta));
|
||||||
Round(m_srcPoly[0].Y - m_normals[0].Y * delta));
|
|
||||||
m_destPoly.push_back(pt1);
|
m_destPoly.push_back(pt1);
|
||||||
pt1 = IntPoint(Round(m_srcPoly[0].X + m_normals[0].X * delta),
|
pt1 = IntPoint(Round(m_srcPoly[0].X + m_normals[0].X * delta), Round(m_srcPoly[0].Y + m_normals[0].Y * delta));
|
||||||
Round(m_srcPoly[0].Y + m_normals[0].Y * delta));
|
|
||||||
m_destPoly.push_back(pt1);
|
m_destPoly.push_back(pt1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3753,7 +3765,7 @@ void ClipperOffset::DoRound(int j, int k)
|
||||||
{
|
{
|
||||||
double a = std::atan2(m_sinA,
|
double a = std::atan2(m_sinA,
|
||||||
m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y);
|
m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y);
|
||||||
int steps = std::max((int)Round(m_StepsPerRad * std::fabs(a)), 1);
|
auto steps = std::max<int>(Round(m_StepsPerRad * std::fabs(a)), 1);
|
||||||
|
|
||||||
double X = m_normals[k].X, Y = m_normals[k].Y, X2;
|
double X = m_normals[k].X, Y = m_normals[k].Y, X2;
|
||||||
for (int i = 0; i < steps; ++i)
|
for (int i = 0; i < steps; ++i)
|
||||||
|
@ -3885,8 +3897,8 @@ void SimplifyPolygons(Paths &polys, PolyFillType fillType)
|
||||||
|
|
||||||
inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2)
|
inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2)
|
||||||
{
|
{
|
||||||
double Dx = ((double)pt1.X - pt2.X);
|
auto Dx = double(pt1.X - pt2.X);
|
||||||
double dy = ((double)pt1.Y - pt2.Y);
|
auto dy = double(pt1.Y - pt2.Y);
|
||||||
return (Dx*Dx + dy*dy);
|
return (Dx*Dx + dy*dy);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -3937,8 +3949,8 @@ bool SlopesNearCollinear(const IntPoint& pt1,
|
||||||
|
|
||||||
bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd)
|
bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd)
|
||||||
{
|
{
|
||||||
double Dx = (double)pt1.X - pt2.X;
|
auto Dx = double(pt1.X - pt2.X);
|
||||||
double dy = (double)pt1.Y - pt2.Y;
|
auto dy = double(pt1.Y - pt2.Y);
|
||||||
return ((Dx * Dx) + (dy * dy) <= distSqrd);
|
return ((Dx * Dx) + (dy * dy) <= distSqrd);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
|
@ -71,12 +71,22 @@ enum PolyType { ptSubject, ptClip };
|
||||||
//see http://glprogramming.com/red/chapter11.html
|
//see http://glprogramming.com/red/chapter11.html
|
||||||
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
||||||
|
|
||||||
|
// If defined, Clipper will work with 32bit signed int coordinates to reduce memory
|
||||||
|
// consumption and to speed up exact orientation predicate calculation.
|
||||||
|
// In that case, coordinates and their differences (vectors of the coordinates) have to fit int32_t.
|
||||||
|
#define CLIPPERLIB_INT32
|
||||||
|
|
||||||
// Point coordinate type
|
// Point coordinate type
|
||||||
typedef int64_t cInt;
|
#ifdef CLIPPERLIB_INT32
|
||||||
// Maximum cInt value to allow a cross product calculation using 32bit expressions.
|
// Coordinates and their differences (vectors of the coordinates) have to fit int32_t.
|
||||||
static cInt const loRange = 0x3FFFFFFF;
|
typedef int32_t cInt;
|
||||||
// Maximum allowed cInt value.
|
#else
|
||||||
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
|
typedef int64_t cInt;
|
||||||
|
// Maximum cInt value to allow a cross product calculation using 32bit expressions.
|
||||||
|
static constexpr cInt const loRange = 0x3FFFFFFF; // 0x3FFFFFFF = 1 073 741 823
|
||||||
|
// Maximum allowed cInt value.
|
||||||
|
static constexpr cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
|
||||||
struct IntPoint {
|
struct IntPoint {
|
||||||
cInt X;
|
cInt X;
|
||||||
|
@ -289,7 +299,11 @@ enum EdgeSide { esLeft = 1, esRight = 2};
|
||||||
class ClipperBase
|
class ClipperBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClipperBase() : m_UseFullRange(false), m_HasOpenPaths(false) {}
|
ClipperBase() :
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
|
m_UseFullRange(false),
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
m_HasOpenPaths(false) {}
|
||||||
~ClipperBase() { Clear(); }
|
~ClipperBase() { Clear(); }
|
||||||
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
||||||
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
|
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
|
||||||
|
@ -310,9 +324,14 @@ protected:
|
||||||
// Local minima (Y, left edge, right edge) sorted by ascending Y.
|
// Local minima (Y, left edge, right edge) sorted by ascending Y.
|
||||||
std::vector<LocalMinimum> m_MinimaList;
|
std::vector<LocalMinimum> m_MinimaList;
|
||||||
|
|
||||||
|
#ifdef CLIPPERLIB_INT32
|
||||||
|
static constexpr const bool m_UseFullRange = false;
|
||||||
|
#else // CLIPPERLIB_INT32
|
||||||
// True if the input polygons have abs values higher than loRange, but lower than hiRange.
|
// True if the input polygons have abs values higher than loRange, but lower than hiRange.
|
||||||
// False if the input polygons have abs values lower or equal to loRange.
|
// False if the input polygons have abs values lower or equal to loRange.
|
||||||
bool m_UseFullRange;
|
bool m_UseFullRange;
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
|
||||||
// A vector of edges per each input path.
|
// A vector of edges per each input path.
|
||||||
std::vector<std::vector<TEdge>> m_edges;
|
std::vector<std::vector<TEdge>> m_edges;
|
||||||
// Don't remove intermediate vertices of a collinear sequence of points.
|
// Don't remove intermediate vertices of a collinear sequence of points.
|
||||||
|
|
|
@ -474,8 +474,8 @@ inline _Box<P> _Box<P>::infinite(const P& center) {
|
||||||
|
|
||||||
// It is important for Mx and My to be strictly less than half of the
|
// It is important for Mx and My to be strictly less than half of the
|
||||||
// range of type C. width(), height() and area() will not overflow this way.
|
// range of type C. width(), height() and area() will not overflow this way.
|
||||||
C Mx = C((std::numeric_limits<C>::lowest() + 2 * getX(center)) / 2.01);
|
C Mx = C((std::numeric_limits<C>::lowest() + 2 * getX(center)) / 4.01);
|
||||||
C My = C((std::numeric_limits<C>::lowest() + 2 * getY(center)) / 2.01);
|
C My = C((std::numeric_limits<C>::lowest() + 2 * getY(center)) / 4.01);
|
||||||
|
|
||||||
ret.maxCorner() = center - P{Mx, My};
|
ret.maxCorner() = center - P{Mx, My};
|
||||||
ret.minCorner() = center + P{Mx, My};
|
ret.minCorner() = center + P{Mx, My};
|
||||||
|
|
|
@ -220,7 +220,9 @@ inline NfpResult<RawShape> nfpConvexOnly(const RawShape& sh,
|
||||||
auto next = std::next(first);
|
auto next = std::next(first);
|
||||||
|
|
||||||
while(next != sl::cend(sh)) {
|
while(next != sl::cend(sh)) {
|
||||||
|
if (pl::magnsq(*next - *first) > 0)
|
||||||
edgelist.emplace_back(*(first), *(next));
|
edgelist.emplace_back(*(first), *(next));
|
||||||
|
|
||||||
++first; ++next;
|
++first; ++next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,7 +232,9 @@ inline NfpResult<RawShape> nfpConvexOnly(const RawShape& sh,
|
||||||
auto next = std::next(first);
|
auto next = std::next(first);
|
||||||
|
|
||||||
while(next != sl::cend(other)) {
|
while(next != sl::cend(other)) {
|
||||||
|
if (pl::magnsq(*next - *first) > 0)
|
||||||
edgelist.emplace_back(*(next), *(first));
|
edgelist.emplace_back(*(next), *(first));
|
||||||
|
|
||||||
++first; ++next;
|
++first; ++next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ void BridgeDetector::initialize()
|
||||||
this->angle = -1.;
|
this->angle = -1.;
|
||||||
|
|
||||||
// Outset our bridge by an arbitrary amout; we'll use this outer margin for detecting anchors.
|
// Outset our bridge by an arbitrary amout; we'll use this outer margin for detecting anchors.
|
||||||
Polygons grown = offset(to_polygons(this->expolygons), float(this->spacing));
|
Polygons grown = offset(this->expolygons, float(this->spacing));
|
||||||
|
|
||||||
// Detect possible anchoring edges of this bridging region.
|
// Detect possible anchoring edges of this bridging region.
|
||||||
// Detect what edges lie on lower slices by turning bridge contour and holes
|
// Detect what edges lie on lower slices by turning bridge contour and holes
|
||||||
|
|
|
@ -57,6 +57,7 @@ err:
|
||||||
}
|
}
|
||||||
#endif /* CLIPPER_UTILS_DEBUG */
|
#endif /* CLIPPER_UTILS_DEBUG */
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
void scaleClipperPolygon(ClipperLib::Path &polygon)
|
void scaleClipperPolygon(ClipperLib::Path &polygon)
|
||||||
{
|
{
|
||||||
CLIPPERUTILS_PROFILE_FUNC();
|
CLIPPERUTILS_PROFILE_FUNC();
|
||||||
|
@ -98,6 +99,7 @@ void unscaleClipperPolygons(ClipperLib::Paths &polygons)
|
||||||
pit->Y >>= CLIPPER_OFFSET_POWER_OF_2;
|
pit->Y >>= CLIPPER_OFFSET_POWER_OF_2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
|
||||||
//-----------------------------------------------------------
|
//-----------------------------------------------------------
|
||||||
// legacy code from Clipper documentation
|
// legacy code from Clipper documentation
|
||||||
|
@ -222,8 +224,10 @@ ClipperLib::Paths Slic3rMultiPoints_to_ClipperPaths(const Polylines &input)
|
||||||
|
|
||||||
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit)
|
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit)
|
||||||
{
|
{
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// scale input
|
// scale input
|
||||||
scaleClipperPolygons(input);
|
scaleClipperPolygons(input);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
|
||||||
// perform offset
|
// perform offset
|
||||||
ClipperLib::ClipperOffset co;
|
ClipperLib::ClipperOffset co;
|
||||||
|
@ -231,14 +235,20 @@ ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType
|
||||||
co.ArcTolerance = miterLimit;
|
co.ArcTolerance = miterLimit;
|
||||||
else
|
else
|
||||||
co.MiterLimit = miterLimit;
|
co.MiterLimit = miterLimit;
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
float delta_scaled = delta;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||||
co.AddPaths(input, joinType, endType);
|
co.AddPaths(input, joinType, endType);
|
||||||
ClipperLib::Paths retval;
|
ClipperLib::Paths retval;
|
||||||
co.Execute(retval, delta_scaled);
|
co.Execute(retval, delta_scaled);
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// unscale output
|
// unscale output
|
||||||
unscaleClipperPolygons(retval);
|
unscaleClipperPolygons(retval);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,14 +267,24 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
||||||
{
|
{
|
||||||
// printf("new ExPolygon offset\n");
|
// printf("new ExPolygon offset\n");
|
||||||
// 1) Offset the outer contour.
|
// 1) Offset the outer contour.
|
||||||
const float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
float delta_scaled = delta;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
ClipperLib::Paths contours;
|
ClipperLib::Paths contours;
|
||||||
{
|
{
|
||||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(expolygon.contour);
|
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(expolygon.contour);
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
scaleClipperPolygon(input);
|
scaleClipperPolygon(input);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
ClipperLib::ClipperOffset co;
|
ClipperLib::ClipperOffset co;
|
||||||
if (joinType == jtRound)
|
if (joinType == jtRound)
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
co.ArcTolerance = miterLimit;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
else
|
else
|
||||||
co.MiterLimit = miterLimit;
|
co.MiterLimit = miterLimit;
|
||||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||||
|
@ -278,17 +298,23 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
||||||
holes.reserve(expolygon.holes.size());
|
holes.reserve(expolygon.holes.size());
|
||||||
for (Polygons::const_iterator it_hole = expolygon.holes.begin(); it_hole != expolygon.holes.end(); ++ it_hole) {
|
for (Polygons::const_iterator it_hole = expolygon.holes.begin(); it_hole != expolygon.holes.end(); ++ it_hole) {
|
||||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath_reversed(*it_hole);
|
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath_reversed(*it_hole);
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
scaleClipperPolygon(input);
|
scaleClipperPolygon(input);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
ClipperLib::ClipperOffset co;
|
ClipperLib::ClipperOffset co;
|
||||||
if (joinType == jtRound)
|
if (joinType == jtRound)
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
co.ArcTolerance = miterLimit;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
else
|
else
|
||||||
co.MiterLimit = miterLimit;
|
co.MiterLimit = miterLimit;
|
||||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||||
co.AddPath(input, joinType, ClipperLib::etClosedPolygon);
|
co.AddPath(input, joinType, ClipperLib::etClosedPolygon);
|
||||||
ClipperLib::Paths out;
|
ClipperLib::Paths out;
|
||||||
co.Execute(out, - delta_scaled);
|
co.Execute(out, - delta_scaled);
|
||||||
holes.insert(holes.end(), out.begin(), out.end());
|
append(holes, std::move(out));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +331,9 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) Unscale the output.
|
// 4) Unscale the output.
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
unscaleClipperPolygons(output);
|
unscaleClipperPolygons(output);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +343,11 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygon &expolygon, const float delta,
|
||||||
ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delta,
|
ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delta,
|
||||||
ClipperLib::JoinType joinType, double miterLimit)
|
ClipperLib::JoinType joinType, double miterLimit)
|
||||||
{
|
{
|
||||||
const float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
float delta_scaled = delta * float(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
float delta_scaled = delta;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
// Offsetted ExPolygons before they are united.
|
// Offsetted ExPolygons before they are united.
|
||||||
ClipperLib::Paths contours_cummulative;
|
ClipperLib::Paths contours_cummulative;
|
||||||
contours_cummulative.reserve(expolygons.size());
|
contours_cummulative.reserve(expolygons.size());
|
||||||
|
@ -327,10 +359,16 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delt
|
||||||
ClipperLib::Paths contours;
|
ClipperLib::Paths contours;
|
||||||
{
|
{
|
||||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(it_expoly->contour);
|
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath(it_expoly->contour);
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
scaleClipperPolygon(input);
|
scaleClipperPolygon(input);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
ClipperLib::ClipperOffset co;
|
ClipperLib::ClipperOffset co;
|
||||||
if (joinType == jtRound)
|
if (joinType == jtRound)
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
co.ArcTolerance = miterLimit;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
else
|
else
|
||||||
co.MiterLimit = miterLimit;
|
co.MiterLimit = miterLimit;
|
||||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||||
|
@ -351,10 +389,16 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delt
|
||||||
{
|
{
|
||||||
for (Polygons::const_iterator it_hole = it_expoly->holes.begin(); it_hole != it_expoly->holes.end(); ++ it_hole) {
|
for (Polygons::const_iterator it_hole = it_expoly->holes.begin(); it_hole != it_expoly->holes.end(); ++ it_hole) {
|
||||||
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath_reversed(*it_hole);
|
ClipperLib::Path input = Slic3rMultiPoint_to_ClipperPath_reversed(*it_hole);
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
scaleClipperPolygon(input);
|
scaleClipperPolygon(input);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
ClipperLib::ClipperOffset co;
|
ClipperLib::ClipperOffset co;
|
||||||
if (joinType == jtRound)
|
if (joinType == jtRound)
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
co.ArcTolerance = miterLimit * double(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
co.ArcTolerance = miterLimit;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
else
|
else
|
||||||
co.MiterLimit = miterLimit;
|
co.MiterLimit = miterLimit;
|
||||||
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
co.ShortestEdgeLength = double(std::abs(delta_scaled * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR));
|
||||||
|
@ -413,8 +457,10 @@ ClipperLib::Paths _offset(const Slic3r::ExPolygons &expolygons, const float delt
|
||||||
output = std::move(contours_cummulative);
|
output = std::move(contours_cummulative);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// 4) Unscale the output.
|
// 4) Unscale the output.
|
||||||
unscaleClipperPolygons(output);
|
unscaleClipperPolygons(output);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,8 +471,10 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
|
||||||
// read input
|
// read input
|
||||||
ClipperLib::Paths input = Slic3rMultiPoints_to_ClipperPaths(polygons);
|
ClipperLib::Paths input = Slic3rMultiPoints_to_ClipperPaths(polygons);
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// scale input
|
// scale input
|
||||||
scaleClipperPolygons(input);
|
scaleClipperPolygons(input);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
|
||||||
// prepare ClipperOffset object
|
// prepare ClipperOffset object
|
||||||
ClipperLib::ClipperOffset co;
|
ClipperLib::ClipperOffset co;
|
||||||
|
@ -435,8 +483,13 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
|
||||||
} else {
|
} else {
|
||||||
co.MiterLimit = miterLimit;
|
co.MiterLimit = miterLimit;
|
||||||
}
|
}
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
float delta_scaled1 = delta1 * float(CLIPPER_OFFSET_SCALE);
|
float delta_scaled1 = delta1 * float(CLIPPER_OFFSET_SCALE);
|
||||||
float delta_scaled2 = delta2 * float(CLIPPER_OFFSET_SCALE);
|
float delta_scaled2 = delta2 * float(CLIPPER_OFFSET_SCALE);
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
float delta_scaled1 = delta1;
|
||||||
|
float delta_scaled2 = delta2;
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
co.ShortestEdgeLength = double(std::max(std::abs(delta_scaled1), std::abs(delta_scaled2)) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR);
|
co.ShortestEdgeLength = double(std::max(std::abs(delta_scaled1), std::abs(delta_scaled2)) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR);
|
||||||
|
|
||||||
// perform first offset
|
// perform first offset
|
||||||
|
@ -450,8 +503,10 @@ _offset2(const Polygons &polygons, const float delta1, const float delta2,
|
||||||
ClipperLib::Paths retval;
|
ClipperLib::Paths retval;
|
||||||
co.Execute(retval, delta_scaled2);
|
co.Execute(retval, delta_scaled2);
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// unscale output
|
// unscale output
|
||||||
unscaleClipperPolygons(retval);
|
unscaleClipperPolygons(retval);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,8 +844,10 @@ void safety_offset(ClipperLib::Paths* paths)
|
||||||
{
|
{
|
||||||
CLIPPERUTILS_PROFILE_FUNC();
|
CLIPPERUTILS_PROFILE_FUNC();
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// scale input
|
// scale input
|
||||||
scaleClipperPolygons(*paths);
|
scaleClipperPolygons(*paths);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
|
||||||
// perform offset (delta = scale 1e-05)
|
// perform offset (delta = scale 1e-05)
|
||||||
ClipperLib::ClipperOffset co;
|
ClipperLib::ClipperOffset co;
|
||||||
|
@ -816,7 +873,11 @@ void safety_offset(ClipperLib::Paths* paths)
|
||||||
CLIPPERUTILS_PROFILE_BLOCK(safety_offset_Execute);
|
CLIPPERUTILS_PROFILE_BLOCK(safety_offset_Execute);
|
||||||
// offset outside by 10um
|
// offset outside by 10um
|
||||||
ClipperLib::Paths out_this;
|
ClipperLib::Paths out_this;
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
co.Execute(out_this, ccw ? 10.f * float(CLIPPER_OFFSET_SCALE) : -10.f * float(CLIPPER_OFFSET_SCALE));
|
co.Execute(out_this, ccw ? 10.f * float(CLIPPER_OFFSET_SCALE) : -10.f * float(CLIPPER_OFFSET_SCALE));
|
||||||
|
#else // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
co.Execute(out_this, ccw ? 10.f : -10.f);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
if (! ccw) {
|
if (! ccw) {
|
||||||
// Reverse the resulting contours once again.
|
// Reverse the resulting contours once again.
|
||||||
for (ClipperLib::Paths::iterator it = out_this.begin(); it != out_this.end(); ++ it)
|
for (ClipperLib::Paths::iterator it = out_this.begin(); it != out_this.end(); ++ it)
|
||||||
|
@ -830,8 +891,10 @@ void safety_offset(ClipperLib::Paths* paths)
|
||||||
}
|
}
|
||||||
*paths = std::move(out);
|
*paths = std::move(out);
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// unscale output
|
// unscale output
|
||||||
unscaleClipperPolygons(*paths);
|
unscaleClipperPolygons(*paths);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons top_level_islands(const Slic3r::Polygons &polygons)
|
Polygons top_level_islands(const Slic3r::Polygons &polygons)
|
||||||
|
@ -925,7 +988,9 @@ ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::v
|
||||||
|
|
||||||
// Add a new point to the output, scale by CLIPPER_OFFSET_SCALE and round to ClipperLib::cInt.
|
// Add a new point to the output, scale by CLIPPER_OFFSET_SCALE and round to ClipperLib::cInt.
|
||||||
auto add_offset_point = [&out](Vec2d pt) {
|
auto add_offset_point = [&out](Vec2d pt) {
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
pt *= double(CLIPPER_OFFSET_SCALE);
|
pt *= double(CLIPPER_OFFSET_SCALE);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
pt += Vec2d(0.5 - (pt.x() < 0), 0.5 - (pt.y() < 0));
|
pt += Vec2d(0.5 - (pt.x() < 0), 0.5 - (pt.y() < 0));
|
||||||
out.emplace_back(ClipperLib::cInt(pt.x()), ClipperLib::cInt(pt.y()));
|
out.emplace_back(ClipperLib::cInt(pt.x()), ClipperLib::cInt(pt.y()));
|
||||||
};
|
};
|
||||||
|
@ -1075,8 +1140,10 @@ Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector<std::v
|
||||||
clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// 4) Unscale the output.
|
// 4) Unscale the output.
|
||||||
unscaleClipperPolygons(output);
|
unscaleClipperPolygons(output);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
return ClipperPaths_to_Slic3rPolygons(output);
|
return ClipperPaths_to_Slic3rPolygons(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,8 +1186,10 @@ for (const std::vector<float>& ds : deltas)
|
||||||
clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// 4) Unscale the output.
|
// 4) Unscale the output.
|
||||||
unscaleClipperPolygons(output);
|
unscaleClipperPolygons(output);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
return ClipperPaths_to_Slic3rPolygons(output);
|
return ClipperPaths_to_Slic3rPolygons(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,7 +1221,9 @@ for (const std::vector<float>& ds : deltas)
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
// 3) Subtract holes from the contours.
|
// 3) Subtract holes from the contours.
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
unscaleClipperPolygons(contours);
|
unscaleClipperPolygons(contours);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
ExPolygons output;
|
ExPolygons output;
|
||||||
if (holes.empty()) {
|
if (holes.empty()) {
|
||||||
output.reserve(contours.size());
|
output.reserve(contours.size());
|
||||||
|
@ -1160,7 +1231,9 @@ for (const std::vector<float>& ds : deltas)
|
||||||
output.emplace_back(ClipperPath_to_Slic3rPolygon(path));
|
output.emplace_back(ClipperPath_to_Slic3rPolygon(path));
|
||||||
} else {
|
} else {
|
||||||
ClipperLib::Clipper clipper;
|
ClipperLib::Clipper clipper;
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
unscaleClipperPolygons(holes);
|
unscaleClipperPolygons(holes);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
clipper.AddPaths(contours, ClipperLib::ptSubject, true);
|
clipper.AddPaths(contours, ClipperLib::ptSubject, true);
|
||||||
clipper.AddPaths(holes, ClipperLib::ptClip, true);
|
clipper.AddPaths(holes, ClipperLib::ptClip, true);
|
||||||
ClipperLib::PolyTree polytree;
|
ClipperLib::PolyTree polytree;
|
||||||
|
@ -1200,7 +1273,9 @@ ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector<s
|
||||||
#endif /* NDEBUG */
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
// 3) Subtract holes from the contours.
|
// 3) Subtract holes from the contours.
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
unscaleClipperPolygons(contours);
|
unscaleClipperPolygons(contours);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
ExPolygons output;
|
ExPolygons output;
|
||||||
if (holes.empty()) {
|
if (holes.empty()) {
|
||||||
output.reserve(contours.size());
|
output.reserve(contours.size());
|
||||||
|
@ -1208,7 +1283,9 @@ ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector<s
|
||||||
output.emplace_back(ClipperPath_to_Slic3rPolygon(path));
|
output.emplace_back(ClipperPath_to_Slic3rPolygon(path));
|
||||||
} else {
|
} else {
|
||||||
ClipperLib::Clipper clipper;
|
ClipperLib::Clipper clipper;
|
||||||
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
unscaleClipperPolygons(holes);
|
unscaleClipperPolygons(holes);
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
clipper.AddPaths(contours, ClipperLib::ptSubject, true);
|
clipper.AddPaths(contours, ClipperLib::ptSubject, true);
|
||||||
clipper.AddPaths(holes, ClipperLib::ptClip, true);
|
clipper.AddPaths(holes, ClipperLib::ptClip, true);
|
||||||
ClipperLib::PolyTree polytree;
|
ClipperLib::PolyTree polytree;
|
||||||
|
|
|
@ -12,17 +12,23 @@ using ClipperLib::jtMiter;
|
||||||
using ClipperLib::jtRound;
|
using ClipperLib::jtRound;
|
||||||
using ClipperLib::jtSquare;
|
using ClipperLib::jtSquare;
|
||||||
|
|
||||||
// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library
|
#define CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
// for general offsetting (the offset(), offset2(), offset_ex() functions) and for the safety offset,
|
|
||||||
// which is optionally executed by other functions (union, intersection, diff).
|
// #define CLIPPERUTILS_OFFSET_SCALE
|
||||||
// This scaling (cca 130t) is applied over the usual SCALING_FACTOR.
|
|
||||||
// By the way, is the scalling for offset needed at all?
|
#ifdef CLIPPERUTILS_OFFSET_SCALE
|
||||||
// The reason to apply this scaling may be to match the resolution of the double mantissa.
|
// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library
|
||||||
#define CLIPPER_OFFSET_POWER_OF_2 17
|
// for general offsetting (the offset(), offset2(), offset_ex() functions) and for the safety offset,
|
||||||
// 2^17=131072
|
// which is optionally executed by other functions (union, intersection, diff).
|
||||||
#define CLIPPER_OFFSET_SCALE (1 << CLIPPER_OFFSET_POWER_OF_2)
|
// This scaling (cca 130t) is applied over the usual SCALING_FACTOR.
|
||||||
#define CLIPPER_OFFSET_SCALE_ROUNDING_DELTA ((1 << (CLIPPER_OFFSET_POWER_OF_2 - 1)) - 1)
|
// By the way, is the scalling for offset needed at all?
|
||||||
#define CLIPPER_MAX_COORD_UNSCALED (ClipperLib::hiRange / CLIPPER_OFFSET_SCALE)
|
// The reason to apply this scaling may be to match the resolution of the double mantissa.
|
||||||
|
#define CLIPPER_OFFSET_POWER_OF_2 17
|
||||||
|
// 2^17=131072
|
||||||
|
#define CLIPPER_OFFSET_SCALE (1 << CLIPPER_OFFSET_POWER_OF_2)
|
||||||
|
#define CLIPPER_OFFSET_SCALE_ROUNDING_DELTA ((1 << (CLIPPER_OFFSET_POWER_OF_2 - 1)) - 1)
|
||||||
|
#define CLIPPER_MAX_COORD_UNSCALED (ClipperLib::hiRange / CLIPPER_OFFSET_SCALE)
|
||||||
|
#endif // CLIPPERUTILS_OFFSET_SCALE
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
@ -47,8 +53,11 @@ ClipperLib::Paths _offset(ClipperLib::Path &&input, ClipperLib::EndType endType,
|
||||||
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit);
|
ClipperLib::Paths _offset(ClipperLib::Paths &&input, ClipperLib::EndType endType, const float delta, ClipperLib::JoinType joinType, double miterLimit);
|
||||||
inline Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
inline Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
inline Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
inline Slic3r::Polygons offset(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
{ return ClipperPaths_to_Slic3rPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||||
|
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
|
|
||||||
// offset Polylines
|
// offset Polylines
|
||||||
inline Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3)
|
inline Slic3r::Polygons offset(const Slic3r::Polyline &polyline, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtSquare, double miterLimit = 3)
|
||||||
|
@ -65,13 +74,18 @@ inline Slic3r::Polygons offset(const Slic3r::ExPolygons &expolygons, const float
|
||||||
{ return ClipperPaths_to_Slic3rPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
|
{ return ClipperPaths_to_Slic3rPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoint_to_ClipperPath(polygon), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
inline Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
{ return ClipperPaths_to_Slic3rExPolygons(_offset(Slic3rMultiPoints_to_ClipperPaths(polygons), ClipperLib::etClosedPolygon, delta, joinType, miterLimit)); }
|
||||||
|
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
|
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygon &expolygon, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygon, delta, joinType, miterLimit)); }
|
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygon, delta, joinType, miterLimit)); }
|
||||||
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
inline Slic3r::ExPolygons offset_ex(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = ClipperLib::jtMiter, double miterLimit = 3)
|
||||||
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
|
{ return ClipperPaths_to_Slic3rExPolygons(_offset(expolygons, delta, joinType, miterLimit)); }
|
||||||
|
|
||||||
|
#ifdef CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1,
|
ClipperLib::Paths _offset2(const Slic3r::Polygons &polygons, const float delta1,
|
||||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||||
double miterLimit = 3);
|
double miterLimit = 3);
|
||||||
|
@ -81,6 +95,8 @@ Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1,
|
||||||
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1,
|
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1,
|
||||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||||
double miterLimit = 3);
|
double miterLimit = 3);
|
||||||
|
#endif // CLIPPERUTILS_UNSAFE_OFFSET
|
||||||
|
|
||||||
Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1,
|
Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1,
|
||||||
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
|
||||||
double miterLimit = 3);
|
double miterLimit = 3);
|
||||||
|
@ -319,6 +335,7 @@ void safety_offset(ClipperLib::Paths* paths);
|
||||||
|
|
||||||
Polygons top_level_islands(const Slic3r::Polygons &polygons);
|
Polygons top_level_islands(const Slic3r::Polygons &polygons);
|
||||||
|
|
||||||
|
ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::vector<float> &deltas, double miter_limit);
|
||||||
Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||||
Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||||
ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector<std::vector<float>> &deltas, double miter_limit = 2.);
|
||||||
|
|
|
@ -471,8 +471,8 @@ bool ConfigBase::set_deserialize_nothrow(const t_config_option_key &opt_key_src,
|
||||||
{
|
{
|
||||||
t_config_option_key opt_key = opt_key_src;
|
t_config_option_key opt_key = opt_key_src;
|
||||||
std::string value = value_src;
|
std::string value = value_src;
|
||||||
// Both opt_key and value may be modified by _handle_legacy().
|
// Both opt_key and value may be modified by handle_legacy().
|
||||||
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by _handle_legacy().
|
// If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
|
||||||
this->handle_legacy(opt_key, value);
|
this->handle_legacy(opt_key, value);
|
||||||
if (opt_key.empty())
|
if (opt_key.empty())
|
||||||
// Ignore the option.
|
// Ignore the option.
|
||||||
|
|
|
@ -1967,8 +1967,9 @@ public:
|
||||||
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(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
||||||
|
|
||||||
// In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*.
|
// 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.
|
||||||
template<typename ENUM>
|
template<typename ENUM>
|
||||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return this->option<ConfigOptionEnum<ENUM>>(opt_key)->value; }
|
ENUM opt_enum(const t_config_option_key &opt_key) const { return static_cast<ENUM>(this->option(opt_key)->getInt()); }
|
||||||
|
|
||||||
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) 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 { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||||
|
|
|
@ -217,6 +217,28 @@ inline Polygons to_polygons(const ExPolygons &src)
|
||||||
return polygons;
|
return polygons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygon &src)
|
||||||
|
{
|
||||||
|
ConstPolygonPtrs polygons;
|
||||||
|
polygons.reserve(src.holes.size() + 1);
|
||||||
|
polygons.emplace_back(&src.contour);
|
||||||
|
for (const Polygon &hole : src.holes)
|
||||||
|
polygons.emplace_back(&hole);
|
||||||
|
return polygons;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygons &src)
|
||||||
|
{
|
||||||
|
ConstPolygonPtrs polygons;
|
||||||
|
polygons.reserve(number_polygons(src));
|
||||||
|
for (const ExPolygon &expoly : src) {
|
||||||
|
polygons.emplace_back(&expoly.contour);
|
||||||
|
for (const Polygon &hole : expoly.holes)
|
||||||
|
polygons.emplace_back(&hole);
|
||||||
|
}
|
||||||
|
return polygons;
|
||||||
|
}
|
||||||
|
|
||||||
inline Polygons to_polygons(ExPolygon &&src)
|
inline Polygons to_polygons(ExPolygon &&src)
|
||||||
{
|
{
|
||||||
Polygons polygons;
|
Polygons polygons;
|
||||||
|
|
|
@ -24,11 +24,11 @@ void FillConcentric::_fill_surface_single(
|
||||||
this->spacing = unscale<double>(distance);
|
this->spacing = unscale<double>(distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons loops = to_polygons(std::move(expolygon));
|
Polygons loops = to_polygons(expolygon);
|
||||||
Polygons last = loops;
|
ExPolygons last { std::move(expolygon) };
|
||||||
while (! last.empty()) {
|
while (! last.empty()) {
|
||||||
last = offset2(last, -(distance + min_spacing/2), +min_spacing/2);
|
last = offset2_ex(last, -(distance + min_spacing/2), +min_spacing/2);
|
||||||
append(loops, last);
|
append(loops, to_polygons(last));
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate paths from the outermost to the innermost, to avoid
|
// generate paths from the outermost to the innermost, to avoid
|
||||||
|
|
|
@ -58,7 +58,7 @@ void FillLine::_fill_surface_single(
|
||||||
pts.push_back(it->a);
|
pts.push_back(it->a);
|
||||||
pts.push_back(it->b);
|
pts.push_back(it->b);
|
||||||
}
|
}
|
||||||
Polylines polylines = intersection_pl(polylines_src, offset(to_polygons(expolygon), scale_(0.02)), false);
|
Polylines polylines = intersection_pl(polylines_src, offset(expolygon, scale_(0.02)), false);
|
||||||
|
|
||||||
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
|
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
|
||||||
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
|
const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
|
||||||
|
|
|
@ -238,13 +238,14 @@ Flow support_material_flow(const PrintObject *object, float layer_height)
|
||||||
|
|
||||||
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
|
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
|
||||||
{
|
{
|
||||||
const auto &width = (object->print()->config().first_layer_extrusion_width.value > 0) ? object->print()->config().first_layer_extrusion_width : object->config().support_material_extrusion_width;
|
const PrintConfig &print_config = object->print()->config();
|
||||||
|
const auto &width = (print_config.first_layer_extrusion_width.value > 0) ? print_config.first_layer_extrusion_width : object->config().support_material_extrusion_width;
|
||||||
return Flow::new_from_config_width(
|
return Flow::new_from_config_width(
|
||||||
frSupportMaterial,
|
frSupportMaterial,
|
||||||
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
|
||||||
(width.value > 0) ? width : object->config().extrusion_width,
|
(width.value > 0) ? width : object->config().extrusion_width,
|
||||||
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
|
float(print_config.nozzle_diameter.get_at(object->config().support_material_extruder-1)),
|
||||||
(layer_height > 0.f) ? layer_height : float(object->config().first_layer_height.get_abs_value(object->config().layer_height.value)));
|
(layer_height > 0.f) ? layer_height : float(print_config.first_layer_height.get_abs_value(object->config().layer_height.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
|
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
|
||||||
|
|
|
@ -1111,7 +1111,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
||||||
// Write some terse information on the slicing parameters.
|
// Write some terse information on the slicing parameters.
|
||||||
const PrintObject *first_object = print.objects().front();
|
const PrintObject *first_object = print.objects().front();
|
||||||
const double layer_height = first_object->config().layer_height.value;
|
const double layer_height = first_object->config().layer_height.value;
|
||||||
const double first_layer_height = first_object->config().first_layer_height.get_abs_value(layer_height);
|
const double first_layer_height = print.config().first_layer_height.get_abs_value(layer_height);
|
||||||
for (const PrintRegion* region : print.regions()) {
|
for (const PrintRegion* region : print.regions()) {
|
||||||
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width());
|
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width());
|
||||||
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width());
|
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width());
|
||||||
|
@ -1778,6 +1778,10 @@ namespace ProcessLayer
|
||||||
else {
|
else {
|
||||||
gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id);
|
gcode += gcodegen.placeholder_parser_process("color_change_gcode", config.color_change_gcode, current_extruder_id);
|
||||||
gcode += "\n";
|
gcode += "\n";
|
||||||
|
//FIXME Tell G-code writer that M600 filled the extruder, thus the G-code writer shall reset the extruder to unretracted state after
|
||||||
|
// return from M600. Thus the G-code generated by the following line is ignored.
|
||||||
|
// see GH issue #6362
|
||||||
|
gcodegen.writer().unretract();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1087,11 +1087,13 @@ bool
|
||||||
MedialAxis::validate_edge(const VD::edge_type* edge)
|
MedialAxis::validate_edge(const VD::edge_type* edge)
|
||||||
{
|
{
|
||||||
// prevent overflows and detect almost-infinite edges
|
// prevent overflows and detect almost-infinite edges
|
||||||
|
#ifndef CLIPPERLIB_INT32
|
||||||
if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||||
std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||||
std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) ||
|
||||||
std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED))
|
std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED))
|
||||||
return false;
|
return false;
|
||||||
|
#endif // CLIPPERLIB_INT32
|
||||||
|
|
||||||
// construct the line representing this edge of the Voronoi diagram
|
// construct the line representing this edge of the Voronoi diagram
|
||||||
const Line line(
|
const Line line(
|
||||||
|
|
|
@ -216,7 +216,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Grown by 3mm.
|
// Grown by 3mm.
|
||||||
Polygons polys = offset(to_polygons(bridges[i].expolygon), margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
Polygons polys = offset(bridges[i].expolygon, margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
|
||||||
if (idx_island == -1) {
|
if (idx_island == -1) {
|
||||||
BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!";
|
BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
class Polygon;
|
class Polygon;
|
||||||
typedef std::vector<Polygon> Polygons;
|
using Polygons = std::vector<Polygon>;
|
||||||
|
using PolygonPtrs = std::vector<Polygon*>;
|
||||||
|
using ConstPolygonPtrs = std::vector<const Polygon*>;
|
||||||
|
|
||||||
class Polygon : public MultiPoint
|
class Polygon : public MultiPoint
|
||||||
{
|
{
|
||||||
|
|
|
@ -296,6 +296,13 @@ void Preset::normalize(DynamicPrintConfig &config)
|
||||||
if (auto *gap_fill_enabled = config.option<ConfigOptionBool>("gap_fill_enabled", false); gap_fill_enabled)
|
if (auto *gap_fill_enabled = config.option<ConfigOptionBool>("gap_fill_enabled", false); gap_fill_enabled)
|
||||||
gap_fill_enabled->value = false;
|
gap_fill_enabled->value = false;
|
||||||
}
|
}
|
||||||
|
if (auto *first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height", false); first_layer_height && first_layer_height->percent)
|
||||||
|
if (const auto *layer_height = config.option<ConfigOptionFloat>("layer_height", false); layer_height) {
|
||||||
|
// Legacy conversion - first_layer_height moved from PrintObject setting to a Print setting, thus we are getting rid of the dependency
|
||||||
|
// of first_layer_height on PrintObject specific layer_height. Covert the first layer heigth to an absolute value.
|
||||||
|
first_layer_height->value = first_layer_height->get_abs_value(layer_height->value);
|
||||||
|
first_layer_height->percent = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config)
|
std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config)
|
||||||
|
@ -427,7 +434,7 @@ const std::vector<std::string>& Preset::print_options()
|
||||||
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
||||||
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_style",
|
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_closing_radius", "support_material_style",
|
||||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
|
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",
|
||||||
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
|
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
|
||||||
"support_material_contact_distance", "support_material_bottom_contact_distance",
|
"support_material_contact_distance", "support_material_bottom_contact_distance",
|
||||||
|
|
|
@ -995,10 +995,8 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->label = L("First layer height");
|
def->label = L("First layer height");
|
||||||
def->category = L("Layers and Perimeters");
|
def->category = L("Layers and Perimeters");
|
||||||
def->tooltip = L("When printing with very low layer heights, you might still want to print a thicker "
|
def->tooltip = L("When printing with very low layer heights, you might still want to print a thicker "
|
||||||
"bottom layer to improve adhesion and tolerance for non perfect build plates. "
|
"bottom layer to improve adhesion and tolerance for non perfect build plates.");
|
||||||
"This can be expressed as an absolute value or as a percentage (for example: 150%) "
|
def->sidetext = L("mm");
|
||||||
"over the default layer height.");
|
|
||||||
def->sidetext = L("mm or %");
|
|
||||||
def->ratio_over = "layer_height";
|
def->ratio_over = "layer_height";
|
||||||
def->set_default_value(new ConfigOptionFloatOrPercent(0.35, false));
|
def->set_default_value(new ConfigOptionFloatOrPercent(0.35, false));
|
||||||
|
|
||||||
|
@ -2366,6 +2364,16 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionInt(-1));
|
def->set_default_value(new ConfigOptionInt(-1));
|
||||||
|
|
||||||
|
def = this->add("support_material_closing_radius", coFloat);
|
||||||
|
def->label = L("Closing radius");
|
||||||
|
def->category = L("Support material");
|
||||||
|
def->tooltip = L("For snug supports, the support regions will be merged using morphological closing operation."
|
||||||
|
" Gaps smaller than the closing radius will be filled in.");
|
||||||
|
def->sidetext = L("mm");
|
||||||
|
def->min = 0;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionFloat(2));
|
||||||
|
|
||||||
def = this->add("support_material_interface_spacing", coFloat);
|
def = this->add("support_material_interface_spacing", coFloat);
|
||||||
def->label = L("Interface pattern spacing");
|
def->label = L("Interface pattern spacing");
|
||||||
def->category = L("Support material");
|
def->category = L("Support material");
|
||||||
|
@ -3618,7 +3626,7 @@ std::string FullPrintConfig::validate()
|
||||||
return "--layer-height must be a multiple of print resolution";
|
return "--layer-height must be a multiple of print resolution";
|
||||||
|
|
||||||
// --first-layer-height
|
// --first-layer-height
|
||||||
if (this->get_abs_value("first_layer_height") <= 0)
|
if (first_layer_height.value <= 0)
|
||||||
return "Invalid value for --first-layer-height";
|
return "Invalid value for --first-layer-height";
|
||||||
|
|
||||||
// --filament-diameter
|
// --filament-diameter
|
||||||
|
|
|
@ -496,7 +496,6 @@ public:
|
||||||
ConfigOptionBool dont_support_bridges;
|
ConfigOptionBool dont_support_bridges;
|
||||||
ConfigOptionFloat elefant_foot_compensation;
|
ConfigOptionFloat elefant_foot_compensation;
|
||||||
ConfigOptionFloatOrPercent extrusion_width;
|
ConfigOptionFloatOrPercent extrusion_width;
|
||||||
ConfigOptionFloatOrPercent first_layer_height;
|
|
||||||
ConfigOptionBool infill_only_where_needed;
|
ConfigOptionBool infill_only_where_needed;
|
||||||
// Force the generation of solid shells between adjacent materials/volumes.
|
// Force the generation of solid shells between adjacent materials/volumes.
|
||||||
ConfigOptionBool interface_shells;
|
ConfigOptionBool interface_shells;
|
||||||
|
@ -530,6 +529,8 @@ public:
|
||||||
ConfigOptionFloatOrPercent support_material_interface_speed;
|
ConfigOptionFloatOrPercent support_material_interface_speed;
|
||||||
ConfigOptionEnum<SupportMaterialPattern> support_material_pattern;
|
ConfigOptionEnum<SupportMaterialPattern> support_material_pattern;
|
||||||
ConfigOptionEnum<SupportMaterialInterfacePattern> support_material_interface_pattern;
|
ConfigOptionEnum<SupportMaterialInterfacePattern> support_material_interface_pattern;
|
||||||
|
// Morphological closing of support areas. Only used for "sung" supports.
|
||||||
|
ConfigOptionFloat support_material_closing_radius;
|
||||||
// Spacing between support material lines (the hatching distance).
|
// Spacing between support material lines (the hatching distance).
|
||||||
ConfigOptionFloat support_material_spacing;
|
ConfigOptionFloat support_material_spacing;
|
||||||
ConfigOptionFloat support_material_speed;
|
ConfigOptionFloat support_material_speed;
|
||||||
|
@ -553,7 +554,6 @@ protected:
|
||||||
OPT_PTR(dont_support_bridges);
|
OPT_PTR(dont_support_bridges);
|
||||||
OPT_PTR(elefant_foot_compensation);
|
OPT_PTR(elefant_foot_compensation);
|
||||||
OPT_PTR(extrusion_width);
|
OPT_PTR(extrusion_width);
|
||||||
OPT_PTR(first_layer_height);
|
|
||||||
OPT_PTR(infill_only_where_needed);
|
OPT_PTR(infill_only_where_needed);
|
||||||
OPT_PTR(interface_shells);
|
OPT_PTR(interface_shells);
|
||||||
OPT_PTR(layer_height);
|
OPT_PTR(layer_height);
|
||||||
|
@ -579,6 +579,7 @@ protected:
|
||||||
OPT_PTR(support_material_interface_extruder);
|
OPT_PTR(support_material_interface_extruder);
|
||||||
OPT_PTR(support_material_interface_layers);
|
OPT_PTR(support_material_interface_layers);
|
||||||
OPT_PTR(support_material_bottom_interface_layers);
|
OPT_PTR(support_material_bottom_interface_layers);
|
||||||
|
OPT_PTR(support_material_closing_radius);
|
||||||
OPT_PTR(support_material_interface_spacing);
|
OPT_PTR(support_material_interface_spacing);
|
||||||
OPT_PTR(support_material_interface_speed);
|
OPT_PTR(support_material_interface_speed);
|
||||||
OPT_PTR(support_material_pattern);
|
OPT_PTR(support_material_pattern);
|
||||||
|
@ -947,6 +948,7 @@ public:
|
||||||
ConfigOptionFloat first_layer_acceleration;
|
ConfigOptionFloat first_layer_acceleration;
|
||||||
ConfigOptionInts first_layer_bed_temperature;
|
ConfigOptionInts first_layer_bed_temperature;
|
||||||
ConfigOptionFloatOrPercent first_layer_extrusion_width;
|
ConfigOptionFloatOrPercent first_layer_extrusion_width;
|
||||||
|
ConfigOptionFloatOrPercent first_layer_height;
|
||||||
ConfigOptionFloatOrPercent first_layer_speed;
|
ConfigOptionFloatOrPercent first_layer_speed;
|
||||||
ConfigOptionInts first_layer_temperature;
|
ConfigOptionInts first_layer_temperature;
|
||||||
ConfigOptionInts full_fan_speed_layer;
|
ConfigOptionInts full_fan_speed_layer;
|
||||||
|
@ -1022,6 +1024,7 @@ protected:
|
||||||
OPT_PTR(first_layer_acceleration);
|
OPT_PTR(first_layer_acceleration);
|
||||||
OPT_PTR(first_layer_bed_temperature);
|
OPT_PTR(first_layer_bed_temperature);
|
||||||
OPT_PTR(first_layer_extrusion_width);
|
OPT_PTR(first_layer_extrusion_width);
|
||||||
|
OPT_PTR(first_layer_height);
|
||||||
OPT_PTR(first_layer_speed);
|
OPT_PTR(first_layer_speed);
|
||||||
OPT_PTR(first_layer_temperature);
|
OPT_PTR(first_layer_temperature);
|
||||||
OPT_PTR(full_fan_speed_layer);
|
OPT_PTR(full_fan_speed_layer);
|
||||||
|
|
|
@ -591,6 +591,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||||
|| opt_key == "support_material_style"
|
|| opt_key == "support_material_style"
|
||||||
|| opt_key == "support_material_xy_spacing"
|
|| opt_key == "support_material_xy_spacing"
|
||||||
|| opt_key == "support_material_spacing"
|
|| opt_key == "support_material_spacing"
|
||||||
|
|| opt_key == "support_material_closing_radius"
|
||||||
|| opt_key == "support_material_synchronize_layers"
|
|| opt_key == "support_material_synchronize_layers"
|
||||||
|| opt_key == "support_material_threshold"
|
|| opt_key == "support_material_threshold"
|
||||||
|| opt_key == "support_material_with_sheath"
|
|| opt_key == "support_material_with_sheath"
|
||||||
|
|
|
@ -64,9 +64,9 @@ SlicingParameters SlicingParameters::create_from_config(
|
||||||
coordf_t object_height,
|
coordf_t object_height,
|
||||||
const std::vector<unsigned int> &object_extruders)
|
const std::vector<unsigned int> &object_extruders)
|
||||||
{
|
{
|
||||||
coordf_t first_layer_height = (object_config.first_layer_height.value <= 0) ?
|
coordf_t first_layer_height = (print_config.first_layer_height.value <= 0) ?
|
||||||
object_config.layer_height.value :
|
object_config.layer_height.value :
|
||||||
object_config.first_layer_height.get_abs_value(object_config.layer_height.value);
|
print_config.first_layer_height.get_abs_value(object_config.layer_height.value);
|
||||||
// If object_config.support_material_extruder == 0 resp. object_config.support_material_interface_extruder == 0,
|
// If object_config.support_material_extruder == 0 resp. object_config.support_material_interface_extruder == 0,
|
||||||
// print_config.nozzle_diameter.get_at(size_t(-1)) returns the 0th nozzle diameter,
|
// print_config.nozzle_diameter.get_at(size_t(-1)) returns the 0th nozzle diameter,
|
||||||
// which is consistent with the requirement that if support_material_extruder == 0 resp. support_material_interface_extruder == 0,
|
// which is consistent with the requirement that if support_material_extruder == 0 resp. support_material_interface_extruder == 0,
|
||||||
|
|
|
@ -672,6 +672,7 @@ struct SupportGridParams {
|
||||||
grid_resolution(object_config.support_material_spacing.value + support_material_flow.spacing()),
|
grid_resolution(object_config.support_material_spacing.value + support_material_flow.spacing()),
|
||||||
support_angle(Geometry::deg2rad(object_config.support_material_angle.value)),
|
support_angle(Geometry::deg2rad(object_config.support_material_angle.value)),
|
||||||
extrusion_width(support_material_flow.spacing()),
|
extrusion_width(support_material_flow.spacing()),
|
||||||
|
support_material_closing_radius(object_config.support_material_closing_radius.value),
|
||||||
expansion_to_slice(coord_t(support_material_flow.scaled_spacing() / 2 + 5)),
|
expansion_to_slice(coord_t(support_material_flow.scaled_spacing() / 2 + 5)),
|
||||||
expansion_to_propagate(-3) {}
|
expansion_to_propagate(-3) {}
|
||||||
|
|
||||||
|
@ -679,6 +680,7 @@ struct SupportGridParams {
|
||||||
double grid_resolution;
|
double grid_resolution;
|
||||||
double support_angle;
|
double support_angle;
|
||||||
double extrusion_width;
|
double extrusion_width;
|
||||||
|
double support_material_closing_radius;
|
||||||
coord_t expansion_to_slice;
|
coord_t expansion_to_slice;
|
||||||
coord_t expansion_to_propagate;
|
coord_t expansion_to_propagate;
|
||||||
};
|
};
|
||||||
|
@ -694,7 +696,9 @@ public:
|
||||||
const SupportGridParams ¶ms) :
|
const SupportGridParams ¶ms) :
|
||||||
m_style(params.style),
|
m_style(params.style),
|
||||||
m_support_polygons(support_polygons), m_trimming_polygons(trimming_polygons),
|
m_support_polygons(support_polygons), m_trimming_polygons(trimming_polygons),
|
||||||
m_support_spacing(params.grid_resolution), m_support_angle(params.support_angle)
|
m_support_spacing(params.grid_resolution), m_support_angle(params.support_angle),
|
||||||
|
m_extrusion_width(params.extrusion_width),
|
||||||
|
m_support_material_closing_radius(params.support_material_closing_radius)
|
||||||
{
|
{
|
||||||
switch (m_style) {
|
switch (m_style) {
|
||||||
case smsGrid:
|
case smsGrid:
|
||||||
|
@ -878,9 +882,10 @@ public:
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
case smsSnug:
|
case smsSnug:
|
||||||
// Just close the gaps.
|
// Merge the support polygons by applying morphological closing and inwards smoothing.
|
||||||
float thr = scaled<float>(0.5);
|
auto closing_distance = scaled<float>(m_support_material_closing_radius);
|
||||||
return smooth_outward(offset(offset_ex(*m_support_polygons, thr), - thr), thr);
|
auto smoothing_distance = scaled<float>(m_extrusion_width);
|
||||||
|
return smooth_outward(offset(offset_ex(*m_support_polygons, closing_distance), - closing_distance), smoothing_distance);
|
||||||
}
|
}
|
||||||
assert(false);
|
assert(false);
|
||||||
return Polygons();
|
return Polygons();
|
||||||
|
@ -1128,6 +1133,9 @@ private:
|
||||||
coordf_t m_support_angle;
|
coordf_t m_support_angle;
|
||||||
// X spacing of the support lines parallel with the Y axis.
|
// X spacing of the support lines parallel with the Y axis.
|
||||||
coordf_t m_support_spacing;
|
coordf_t m_support_spacing;
|
||||||
|
coordf_t m_extrusion_width;
|
||||||
|
// For snug supports: Morphological closing of support areas.
|
||||||
|
coordf_t m_support_material_closing_radius;
|
||||||
|
|
||||||
#ifdef SUPPORT_USE_AGG_RASTERIZER
|
#ifdef SUPPORT_USE_AGG_RASTERIZER
|
||||||
Vec2i m_grid_size;
|
Vec2i m_grid_size;
|
||||||
|
@ -3178,7 +3186,7 @@ struct MyLayerExtruded
|
||||||
MyLayerExtruded& operator=(MyLayerExtruded &&rhs) {
|
MyLayerExtruded& operator=(MyLayerExtruded &&rhs) {
|
||||||
this->layer = rhs.layer;
|
this->layer = rhs.layer;
|
||||||
this->extrusions = std::move(rhs.extrusions);
|
this->extrusions = std::move(rhs.extrusions);
|
||||||
this->m_polygons_to_extrude = std::move(m_polygons_to_extrude);
|
this->m_polygons_to_extrude = std::move(rhs.m_polygons_to_extrude);
|
||||||
rhs.layer = nullptr;
|
rhs.layer = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
#define ENABLE_GCODE_WINDOW (1 && ENABLE_2_4_0_ALPHA0)
|
#define ENABLE_GCODE_WINDOW (1 && ENABLE_2_4_0_ALPHA0)
|
||||||
// Enable exporting lines M73 for remaining time to next printer stop to gcode
|
// Enable exporting lines M73 for remaining time to next printer stop to gcode
|
||||||
#define ENABLE_EXTENDED_M73_LINES (1 && ENABLE_VALIDATE_CUSTOM_GCODE)
|
#define ENABLE_EXTENDED_M73_LINES (1 && ENABLE_VALIDATE_CUSTOM_GCODE)
|
||||||
|
// Enable a modified version of automatic downscale on load of objects too big
|
||||||
|
#define ENABLE_MODIFIED_DOWNSCALE_ON_LOAD_OBJECTS_TOO_BIG (1 && ENABLE_2_4_0_ALPHA0)
|
||||||
|
|
||||||
|
|
||||||
#endif // _prusaslicer_technologies_h_
|
#endif // _prusaslicer_technologies_h_
|
||||||
|
|
|
@ -511,20 +511,22 @@ void TriangleMesh::merge(const TriangleMesh &mesh)
|
||||||
//FIXME This could be extremely slow! Use it for tiny meshes only!
|
//FIXME This could be extremely slow! Use it for tiny meshes only!
|
||||||
ExPolygons TriangleMesh::horizontal_projection() const
|
ExPolygons TriangleMesh::horizontal_projection() const
|
||||||
{
|
{
|
||||||
Polygons pp;
|
ClipperLib::Paths paths;
|
||||||
pp.reserve(this->stl.stats.number_of_facets);
|
|
||||||
for (const stl_facet &facet : this->stl.facet_start) {
|
|
||||||
Polygon p;
|
Polygon p;
|
||||||
p.points.resize(3);
|
p.points.assign(3, Point());
|
||||||
|
auto delta = scaled<float>(0.01);
|
||||||
|
std::vector<float> deltas { delta, delta, delta };
|
||||||
|
paths.reserve(this->stl.stats.number_of_facets);
|
||||||
|
for (const stl_facet &facet : this->stl.facet_start) {
|
||||||
p.points[0] = Point::new_scale(facet.vertex[0](0), facet.vertex[0](1));
|
p.points[0] = Point::new_scale(facet.vertex[0](0), facet.vertex[0](1));
|
||||||
p.points[1] = Point::new_scale(facet.vertex[1](0), facet.vertex[1](1));
|
p.points[1] = Point::new_scale(facet.vertex[1](0), facet.vertex[1](1));
|
||||||
p.points[2] = Point::new_scale(facet.vertex[2](0), facet.vertex[2](1));
|
p.points[2] = Point::new_scale(facet.vertex[2](0), facet.vertex[2](1));
|
||||||
p.make_counter_clockwise(); // do this after scaling, as winding order might change while doing that
|
p.make_counter_clockwise();
|
||||||
pp.emplace_back(p);
|
paths.emplace_back(mittered_offset_path_scaled(p.points, deltas, 3.));
|
||||||
}
|
}
|
||||||
|
|
||||||
// the offset factor was tuned using groovemount.stl
|
// the offset factor was tuned using groovemount.stl
|
||||||
return union_ex(offset(pp, scale_(0.01)), true);
|
return ClipperPaths_to_Slic3rExPolygons(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2D convex hull of a 3D mesh projected into the Z=0 plane.
|
// 2D convex hull of a 3D mesh projected into the Z=0 plane.
|
||||||
|
@ -1797,7 +1799,7 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, const float clos
|
||||||
|
|
||||||
// append to the supplied collection
|
// append to the supplied collection
|
||||||
if (safety_offset > 0)
|
if (safety_offset > 0)
|
||||||
expolygons_append(*slices, offset2_ex(union_(loops, false), +safety_offset, -safety_offset));
|
expolygons_append(*slices, offset2_ex(union_ex(loops, false), +safety_offset, -safety_offset));
|
||||||
else
|
else
|
||||||
expolygons_append(*slices, union_ex(loops, false));
|
expolygons_append(*slices, union_ex(loops, false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ void Bed3D::Axes::render() const
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
};
|
};
|
||||||
|
|
||||||
m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
|
const_cast<GLModel*>(&m_arrow)->init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
|
||||||
|
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||||
if (shader == nullptr)
|
if (shader == nullptr)
|
||||||
|
@ -143,13 +143,6 @@ void Bed3D::Axes::render() const
|
||||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||||
}
|
}
|
||||||
|
|
||||||
Bed3D::Bed3D()
|
|
||||||
: m_type(Custom)
|
|
||||||
, m_vbo_id(0)
|
|
||||||
, m_scale_factor(1.0f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
|
bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
|
||||||
{
|
{
|
||||||
auto check_texture = [](const std::string& texture) {
|
auto check_texture = [](const std::string& texture) {
|
||||||
|
@ -193,7 +186,7 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c
|
||||||
|
|
||||||
ExPolygon poly;
|
ExPolygon poly;
|
||||||
for (const Vec2d& p : m_shape) {
|
for (const Vec2d& p : m_shape) {
|
||||||
poly.contour.append(Point(scale_(p(0)), scale_(p(1))));
|
poly.contour.append({ scale_(p(0)), scale_(p(1)) });
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_triangles(poly);
|
calc_triangles(poly);
|
||||||
|
@ -228,7 +221,8 @@ Point Bed3D::point_projection(const Point& point) const
|
||||||
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||||
bool show_axes, bool show_texture) const
|
bool show_axes, bool show_texture) const
|
||||||
{
|
{
|
||||||
m_scale_factor = scale_factor;
|
float* factor = const_cast<float*>(&m_scale_factor);
|
||||||
|
*factor = scale_factor;
|
||||||
|
|
||||||
if (show_axes)
|
if (show_axes)
|
||||||
render_axes();
|
render_axes();
|
||||||
|
@ -247,22 +241,24 @@ void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||||
|
|
||||||
void Bed3D::calc_bounding_boxes() const
|
void Bed3D::calc_bounding_boxes() const
|
||||||
{
|
{
|
||||||
m_bounding_box = BoundingBoxf3();
|
BoundingBoxf3* bounding_box = const_cast<BoundingBoxf3*>(&m_bounding_box);
|
||||||
|
*bounding_box = BoundingBoxf3();
|
||||||
for (const Vec2d& p : m_shape) {
|
for (const Vec2d& p : m_shape) {
|
||||||
m_bounding_box.merge(Vec3d(p(0), p(1), 0.0));
|
bounding_box->merge({ p(0), p(1), 0.0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
m_extended_bounding_box = m_bounding_box;
|
BoundingBoxf3* extended_bounding_box = const_cast<BoundingBoxf3*>(&m_extended_bounding_box);
|
||||||
|
*extended_bounding_box = m_bounding_box;
|
||||||
|
|
||||||
// extend to contain axes
|
// extend to contain axes
|
||||||
m_extended_bounding_box.merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones());
|
extended_bounding_box->merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones());
|
||||||
m_extended_bounding_box.merge(m_extended_bounding_box.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, m_extended_bounding_box.max(2)));
|
extended_bounding_box->merge(extended_bounding_box->min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, extended_bounding_box->max(2)));
|
||||||
|
|
||||||
// extend to contain model, if any
|
// extend to contain model, if any
|
||||||
BoundingBoxf3 model_bb = m_model.get_bounding_box();
|
BoundingBoxf3 model_bb = m_model.get_bounding_box();
|
||||||
if (model_bb.defined) {
|
if (model_bb.defined) {
|
||||||
model_bb.translate(m_model_offset);
|
model_bb.translate(m_model_offset);
|
||||||
m_extended_bounding_box.merge(model_bb);
|
extended_bounding_box->merge(model_bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,21 +335,24 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) co
|
||||||
|
|
||||||
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
||||||
{
|
{
|
||||||
|
GLTexture* texture = const_cast<GLTexture*>(&m_texture);
|
||||||
|
GLTexture* temp_texture = const_cast<GLTexture*>(&m_temp_texture);
|
||||||
|
|
||||||
if (m_texture_filename.empty()) {
|
if (m_texture_filename.empty()) {
|
||||||
m_texture.reset();
|
texture->reset();
|
||||||
render_default(bottom);
|
render_default(bottom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_texture.get_id() == 0) || (m_texture.get_source() != m_texture_filename)) {
|
if (texture->get_id() == 0 || texture->get_source() != m_texture_filename) {
|
||||||
m_texture.reset();
|
texture->reset();
|
||||||
|
|
||||||
if (boost::algorithm::iends_with(m_texture_filename, ".svg")) {
|
if (boost::algorithm::iends_with(m_texture_filename, ".svg")) {
|
||||||
// use higher resolution images if graphic card and opengl version allow
|
// use higher resolution images if graphic card and opengl version allow
|
||||||
GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
|
GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
|
||||||
if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) {
|
if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
|
||||||
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
|
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
|
||||||
if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
|
if (!temp_texture->load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
|
||||||
render_default(bottom);
|
render_default(bottom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -361,15 +360,15 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// starts generating the main texture, compression will run asynchronously
|
// starts generating the main texture, compression will run asynchronously
|
||||||
if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
|
if (!texture->load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
|
||||||
render_default(bottom);
|
render_default(bottom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (boost::algorithm::iends_with(m_texture_filename, ".png")) {
|
else if (boost::algorithm::iends_with(m_texture_filename, ".png")) {
|
||||||
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
|
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
|
||||||
if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) {
|
if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
|
||||||
if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) {
|
if (!temp_texture->load_from_file(m_texture_filename, false, GLTexture::None, false)) {
|
||||||
render_default(bottom);
|
render_default(bottom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +376,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// starts generating the main texture, compression will run asynchronously
|
// starts generating the main texture, compression will run asynchronously
|
||||||
if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
|
if (!texture->load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
|
||||||
render_default(bottom);
|
render_default(bottom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -387,13 +386,13 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_texture.unsent_compressed_data_available()) {
|
else if (texture->unsent_compressed_data_available()) {
|
||||||
// sends to gpu the already available compressed levels of the main texture
|
// sends to gpu the already available compressed levels of the main texture
|
||||||
m_texture.send_compressed_data_to_gpu();
|
texture->send_compressed_data_to_gpu();
|
||||||
|
|
||||||
// the temporary texture is not needed anymore, reset it
|
// the temporary texture is not needed anymore, reset it
|
||||||
if (m_temp_texture.get_id() != 0)
|
if (temp_texture->get_id() != 0)
|
||||||
m_temp_texture.reset();
|
temp_texture->reset();
|
||||||
|
|
||||||
canvas.request_extra_frame();
|
canvas.request_extra_frame();
|
||||||
|
|
||||||
|
@ -406,9 +405,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
||||||
shader->set_uniform("transparent_background", bottom);
|
shader->set_uniform("transparent_background", bottom);
|
||||||
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
|
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
|
||||||
|
|
||||||
if (m_vbo_id == 0) {
|
unsigned int* vbo_id = const_cast<unsigned int*>(&m_vbo_id);
|
||||||
glsafe(::glGenBuffers(1, &m_vbo_id));
|
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
if (*vbo_id == 0) {
|
||||||
|
glsafe(::glGenBuffers(1, vbo_id));
|
||||||
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, *vbo_id));
|
||||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_triangles.get_vertices_data_size(), (const GLvoid*)m_triangles.get_vertices_data(), GL_STATIC_DRAW));
|
glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_triangles.get_vertices_data_size(), (const GLvoid*)m_triangles.get_vertices_data(), GL_STATIC_DRAW));
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||||
}
|
}
|
||||||
|
@ -428,12 +429,12 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
||||||
GLint tex_coords_id = shader->get_attrib_location("v_tex_coords");
|
GLint tex_coords_id = shader->get_attrib_location("v_tex_coords");
|
||||||
|
|
||||||
// show the temporary texture while no compressed data is available
|
// show the temporary texture while no compressed data is available
|
||||||
GLuint tex_id = (GLuint)m_temp_texture.get_id();
|
GLuint tex_id = (GLuint)temp_texture->get_id();
|
||||||
if (tex_id == 0)
|
if (tex_id == 0)
|
||||||
tex_id = (GLuint)m_texture.get_id();
|
tex_id = (GLuint)texture->get_id();
|
||||||
|
|
||||||
glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id));
|
glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id));
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, *vbo_id));
|
||||||
|
|
||||||
if (position_id != -1) {
|
if (position_id != -1) {
|
||||||
glsafe(::glEnableVertexAttribArray(position_id));
|
glsafe(::glEnableVertexAttribArray(position_id));
|
||||||
|
@ -471,24 +472,26 @@ void Bed3D::render_model() const
|
||||||
if (m_model_filename.empty())
|
if (m_model_filename.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((m_model.get_filename() != m_model_filename) && m_model.init_from_file(m_model_filename)) {
|
GLModel* model = const_cast<GLModel*>(&m_model);
|
||||||
|
|
||||||
|
if (model->get_filename() != m_model_filename && model->init_from_file(m_model_filename)) {
|
||||||
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
|
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
|
||||||
Vec3d shift = m_bounding_box.center();
|
Vec3d shift = m_bounding_box.center();
|
||||||
shift(2) = -0.03;
|
shift(2) = -0.03;
|
||||||
m_model_offset = shift;
|
*const_cast<Vec3d*>(&m_model_offset) = shift;
|
||||||
|
|
||||||
// update extended bounding box
|
// update extended bounding box
|
||||||
calc_bounding_boxes();
|
calc_bounding_boxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_model.get_filename().empty()) {
|
if (!model->get_filename().empty()) {
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||||
if (shader != nullptr) {
|
if (shader != nullptr) {
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
shader->set_uniform("uniform_color", m_model_color);
|
shader->set_uniform("uniform_color", m_model_color);
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2));
|
::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2));
|
||||||
m_model.render();
|
model->render();
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
}
|
}
|
||||||
|
@ -511,7 +514,7 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) co
|
||||||
|
|
||||||
void Bed3D::render_default(bool bottom) const
|
void Bed3D::render_default(bool bottom) const
|
||||||
{
|
{
|
||||||
m_texture.reset();
|
const_cast<GLTexture*>(&m_texture)->reset();
|
||||||
|
|
||||||
unsigned int triangles_vcount = m_triangles.get_vertices_count();
|
unsigned int triangles_vcount = m_triangles.get_vertices_count();
|
||||||
if (triangles_vcount > 0) {
|
if (triangles_vcount > 0) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ class Bed3D
|
||||||
private:
|
private:
|
||||||
Vec3d m_origin{ Vec3d::Zero() };
|
Vec3d m_origin{ Vec3d::Zero() };
|
||||||
float m_stem_length{ DefaultStemLength };
|
float m_stem_length{ DefaultStemLength };
|
||||||
mutable GLModel m_arrow;
|
GLModel m_arrow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Vec3d& get_origin() const { return m_origin; }
|
const Vec3d& get_origin() const { return m_origin; }
|
||||||
|
@ -67,28 +67,28 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EType m_type;
|
EType m_type{ Custom };
|
||||||
Pointfs m_shape;
|
Pointfs m_shape;
|
||||||
std::string m_texture_filename;
|
std::string m_texture_filename;
|
||||||
std::string m_model_filename;
|
std::string m_model_filename;
|
||||||
mutable BoundingBoxf3 m_bounding_box;
|
BoundingBoxf3 m_bounding_box;
|
||||||
mutable BoundingBoxf3 m_extended_bounding_box;
|
BoundingBoxf3 m_extended_bounding_box;
|
||||||
Polygon m_polygon;
|
Polygon m_polygon;
|
||||||
GeometryBuffer m_triangles;
|
GeometryBuffer m_triangles;
|
||||||
GeometryBuffer m_gridlines;
|
GeometryBuffer m_gridlines;
|
||||||
mutable GLTexture m_texture;
|
GLTexture m_texture;
|
||||||
mutable GLModel m_model;
|
|
||||||
mutable Vec3d m_model_offset{ Vec3d::Zero() };
|
|
||||||
std::array<float, 4> m_model_color{ 0.235f, 0.235f, 0.235f, 1.0f };
|
|
||||||
// temporary texture shown until the main texture has still no levels compressed
|
// temporary texture shown until the main texture has still no levels compressed
|
||||||
mutable GLTexture m_temp_texture;
|
GLTexture m_temp_texture;
|
||||||
mutable unsigned int m_vbo_id;
|
GLModel m_model;
|
||||||
|
Vec3d m_model_offset{ Vec3d::Zero() };
|
||||||
|
std::array<float, 4> m_model_color{ 0.235f, 0.235f, 0.235f, 1.0f };
|
||||||
|
unsigned int m_vbo_id{ 0 };
|
||||||
Axes m_axes;
|
Axes m_axes;
|
||||||
|
|
||||||
mutable float m_scale_factor;
|
float m_scale_factor{ 1.0f };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Bed3D();
|
Bed3D() = default;
|
||||||
~Bed3D() { reset(); }
|
~Bed3D() { reset(); }
|
||||||
|
|
||||||
EType get_type() const { return m_type; }
|
EType get_type() const { return m_type; }
|
||||||
|
|
|
@ -421,20 +421,24 @@ const BoundingBoxf3& GLVolume::transformed_bounding_box() const
|
||||||
const BoundingBoxf3& box = bounding_box();
|
const BoundingBoxf3& box = bounding_box();
|
||||||
assert(box.defined || box.min(0) >= box.max(0) || box.min(1) >= box.max(1) || box.min(2) >= box.max(2));
|
assert(box.defined || box.min(0) >= box.max(0) || box.min(1) >= box.max(1) || box.min(2) >= box.max(2));
|
||||||
|
|
||||||
if (m_transformed_bounding_box_dirty)
|
BoundingBoxf3* transformed_bounding_box = const_cast<BoundingBoxf3*>(&m_transformed_bounding_box);
|
||||||
{
|
bool* transformed_bounding_box_dirty = const_cast<bool*>(&m_transformed_bounding_box_dirty);
|
||||||
m_transformed_bounding_box = box.transformed(world_matrix());
|
if (*transformed_bounding_box_dirty) {
|
||||||
m_transformed_bounding_box_dirty = false;
|
*transformed_bounding_box = box.transformed(world_matrix());
|
||||||
|
*transformed_bounding_box_dirty = false;
|
||||||
}
|
}
|
||||||
|
return *transformed_bounding_box;
|
||||||
return m_transformed_bounding_box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const
|
const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const
|
||||||
{
|
{
|
||||||
if (m_transformed_convex_hull_bounding_box_dirty)
|
BoundingBoxf3* transformed_convex_hull_bounding_box = const_cast<BoundingBoxf3*>(&m_transformed_convex_hull_bounding_box);
|
||||||
m_transformed_convex_hull_bounding_box = this->transformed_convex_hull_bounding_box(world_matrix());
|
bool* transformed_convex_hull_bounding_box_dirty = const_cast<bool*>(&m_transformed_convex_hull_bounding_box_dirty);
|
||||||
return m_transformed_convex_hull_bounding_box;
|
if (*transformed_convex_hull_bounding_box_dirty) {
|
||||||
|
*transformed_convex_hull_bounding_box = this->transformed_convex_hull_bounding_box(world_matrix());
|
||||||
|
*transformed_convex_hull_bounding_box_dirty = false;
|
||||||
|
}
|
||||||
|
return *transformed_convex_hull_bounding_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d &trafo) const
|
BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box(const Transform3d &trafo) const
|
||||||
|
@ -795,7 +799,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state)
|
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const
|
||||||
{
|
{
|
||||||
if (config == nullptr)
|
if (config == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
@ -805,7 +809,7 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
|
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
|
||||||
BoundingBoxf3 print_volume(Vec3d(unscale<double>(bed_box_2D.min(0)), unscale<double>(bed_box_2D.min(1)), 0.0), Vec3d(unscale<double>(bed_box_2D.max(0)), unscale<double>(bed_box_2D.max(1)), config->opt_float("max_print_height")));
|
BoundingBoxf3 print_volume({ unscale<double>(bed_box_2D.min(0)), unscale<double>(bed_box_2D.min(1)), 0.0 }, { unscale<double>(bed_box_2D.max(0)), unscale<double>(bed_box_2D.max(1)), config->opt_float("max_print_height") });
|
||||||
// Allow the objects to protrude below the print bed
|
// Allow the objects to protrude below the print bed
|
||||||
print_volume.min(2) = -1e10;
|
print_volume.min(2) = -1e10;
|
||||||
print_volume.min(0) -= BedEpsilon;
|
print_volume.min(0) -= BedEpsilon;
|
||||||
|
@ -817,9 +821,8 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
||||||
|
|
||||||
bool contained_min_one = false;
|
bool contained_min_one = false;
|
||||||
|
|
||||||
for (GLVolume* volume : this->volumes)
|
for (GLVolume* volume : this->volumes) {
|
||||||
{
|
if (volume == nullptr || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || (volume->composite_id.volume_id < 0 && !volume->shader_outside_printer_detection_enabled))
|
||||||
if ((volume == nullptr) || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || ((volume->composite_id.volume_id < 0) && !volume->shader_outside_printer_detection_enabled))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
||||||
|
@ -832,10 +835,10 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
||||||
if (contained)
|
if (contained)
|
||||||
contained_min_one = true;
|
contained_min_one = true;
|
||||||
|
|
||||||
if ((state == ModelInstancePVS_Inside) && volume->is_outside)
|
if (state == ModelInstancePVS_Inside && volume->is_outside)
|
||||||
state = ModelInstancePVS_Fully_Outside;
|
state = ModelInstancePVS_Fully_Outside;
|
||||||
|
|
||||||
if ((state == ModelInstancePVS_Fully_Outside) && volume->is_outside && print_volume.intersects(bb))
|
if (state == ModelInstancePVS_Fully_Outside && volume->is_outside && print_volume.intersects(bb))
|
||||||
state = ModelInstancePVS_Partly_Outside;
|
state = ModelInstancePVS_Partly_Outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +848,7 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
|
||||||
return contained_min_one;
|
return contained_min_one;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, bool& partlyOut, bool& fullyOut)
|
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, bool& partlyOut, bool& fullyOut) const
|
||||||
{
|
{
|
||||||
if (config == nullptr)
|
if (config == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
@ -867,9 +870,8 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, b
|
||||||
|
|
||||||
partlyOut = false;
|
partlyOut = false;
|
||||||
fullyOut = false;
|
fullyOut = false;
|
||||||
for (GLVolume* volume : this->volumes)
|
for (GLVolume* volume : this->volumes) {
|
||||||
{
|
if (volume == nullptr || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || (volume->composite_id.volume_id < 0 && !volume->shader_outside_printer_detection_enabled))
|
||||||
if ((volume == nullptr) || volume->is_modifier || (volume->is_wipe_tower && !volume->shader_outside_printer_detection_enabled) || ((volume->composite_id.volume_id < 0) && !volume->shader_outside_printer_detection_enabled))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
|
||||||
|
|
|
@ -267,15 +267,15 @@ private:
|
||||||
// Shift in z required by sla supports+pad
|
// Shift in z required by sla supports+pad
|
||||||
double m_sla_shift_z;
|
double m_sla_shift_z;
|
||||||
// Bounding box of this volume, in unscaled coordinates.
|
// Bounding box of this volume, in unscaled coordinates.
|
||||||
mutable BoundingBoxf3 m_transformed_bounding_box;
|
BoundingBoxf3 m_transformed_bounding_box;
|
||||||
// Whether or not is needed to recalculate the transformed bounding box.
|
// Whether or not is needed to recalculate the transformed bounding box.
|
||||||
mutable bool m_transformed_bounding_box_dirty;
|
bool m_transformed_bounding_box_dirty;
|
||||||
// Convex hull of the volume, if any.
|
// Convex hull of the volume, if any.
|
||||||
std::shared_ptr<const TriangleMesh> m_convex_hull;
|
std::shared_ptr<const TriangleMesh> m_convex_hull;
|
||||||
// Bounding box of this volume, in unscaled coordinates.
|
// Bounding box of this volume, in unscaled coordinates.
|
||||||
mutable BoundingBoxf3 m_transformed_convex_hull_bounding_box;
|
BoundingBoxf3 m_transformed_convex_hull_bounding_box;
|
||||||
// Whether or not is needed to recalculate the transformed convex hull bounding box.
|
// Whether or not is needed to recalculate the transformed convex hull bounding box.
|
||||||
mutable bool m_transformed_convex_hull_bounding_box_dirty;
|
bool m_transformed_convex_hull_bounding_box_dirty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Color of the triangles / quads held by this volume.
|
// Color of the triangles / quads held by this volume.
|
||||||
|
@ -568,8 +568,8 @@ public:
|
||||||
|
|
||||||
// returns true if all the volumes are completely contained in the print volume
|
// returns true if all the volumes are completely contained in the print volume
|
||||||
// returns the containment state in the given out_state, if non-null
|
// returns the containment state in the given out_state, if non-null
|
||||||
bool check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state);
|
bool check_outside_state(const DynamicPrintConfig* config, ModelInstanceEPrintVolumeState* out_state) const;
|
||||||
bool check_outside_state(const DynamicPrintConfig* config, bool& partlyOut, bool& fullyOut);
|
bool check_outside_state(const DynamicPrintConfig* config, bool& partlyOut, bool& fullyOut) const;
|
||||||
void reset_outside_state();
|
void reset_outside_state();
|
||||||
|
|
||||||
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
||||||
|
|
|
@ -21,12 +21,6 @@ double Camera::FrustrumMinNearZ = 100.0;
|
||||||
double Camera::FrustrumZMargin = 10.0;
|
double Camera::FrustrumZMargin = 10.0;
|
||||||
double Camera::MaxFovDeg = 60.0;
|
double Camera::MaxFovDeg = 60.0;
|
||||||
|
|
||||||
Camera::Camera()
|
|
||||||
: requires_zoom_to_bed(false)
|
|
||||||
{
|
|
||||||
set_default_orientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Camera::get_type_as_string() const
|
std::string Camera::get_type_as_string() const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
|
@ -49,11 +43,6 @@ void Camera::set_type(EType type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::set_type(const std::string& type)
|
|
||||||
{
|
|
||||||
set_type((type == "1") ? Perspective : Ortho);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::select_next_type()
|
void Camera::select_next_type()
|
||||||
{
|
{
|
||||||
unsigned char next = (unsigned char)m_type + 1;
|
unsigned char next = (unsigned char)m_type + 1;
|
||||||
|
@ -65,24 +54,18 @@ void Camera::select_next_type()
|
||||||
|
|
||||||
void Camera::set_target(const Vec3d& target)
|
void Camera::set_target(const Vec3d& target)
|
||||||
{
|
{
|
||||||
Vec3d new_target = validate_target(target);
|
const Vec3d new_target = validate_target(target);
|
||||||
Vec3d new_displacement = new_target - m_target;
|
const Vec3d new_displacement = new_target - m_target;
|
||||||
if (!new_displacement.isApprox(Vec3d::Zero()))
|
if (!new_displacement.isApprox(Vec3d::Zero())) {
|
||||||
{
|
|
||||||
m_target = new_target;
|
m_target = new_target;
|
||||||
m_view_matrix.translate(-new_displacement);
|
m_view_matrix.translate(-new_displacement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::update_zoom(double delta_zoom)
|
|
||||||
{
|
|
||||||
set_zoom(m_zoom / (1.0 - std::max(std::min(delta_zoom, 4.0), -4.0) * 0.1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::set_zoom(double zoom)
|
void Camera::set_zoom(double zoom)
|
||||||
{
|
{
|
||||||
// Don't allow to zoom too far outside the scene.
|
// Don't allow to zoom too far outside the scene.
|
||||||
double zoom_min = min_zoom();
|
const double zoom_min = min_zoom();
|
||||||
if (zoom_min > 0.0)
|
if (zoom_min > 0.0)
|
||||||
zoom = std::max(zoom, zoom_min);
|
zoom = std::max(zoom, zoom_min);
|
||||||
|
|
||||||
|
@ -123,7 +106,7 @@ double Camera::get_fov() const
|
||||||
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const
|
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const
|
||||||
{
|
{
|
||||||
glsafe(::glViewport(0, 0, w, h));
|
glsafe(::glViewport(0, 0, w, h));
|
||||||
glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
|
glsafe(::glGetIntegerv(GL_VIEWPORT, const_cast<std::array<int, 4>*>(&m_viewport)->data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::apply_view_matrix() const
|
void Camera::apply_view_matrix() const
|
||||||
|
@ -138,22 +121,23 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
|
||||||
double w = 0.0;
|
double w = 0.0;
|
||||||
double h = 0.0;
|
double h = 0.0;
|
||||||
|
|
||||||
double old_distance = m_distance;
|
const double old_distance = m_distance;
|
||||||
m_frustrum_zs = calc_tight_frustrum_zs_around(box);
|
std::pair<double, double>* frustrum_zs = const_cast<std::pair<double, double>*>(&m_frustrum_zs);
|
||||||
|
*frustrum_zs = calc_tight_frustrum_zs_around(box);
|
||||||
if (m_distance != old_distance)
|
if (m_distance != old_distance)
|
||||||
// the camera has been moved re-apply view matrix
|
// the camera has been moved re-apply view matrix
|
||||||
apply_view_matrix();
|
apply_view_matrix();
|
||||||
|
|
||||||
if (near_z > 0.0)
|
if (near_z > 0.0)
|
||||||
m_frustrum_zs.first = std::max(std::min(m_frustrum_zs.first, near_z), FrustrumMinNearZ);
|
frustrum_zs->first = std::max(std::min(frustrum_zs->first, near_z), FrustrumMinNearZ);
|
||||||
|
|
||||||
if (far_z > 0.0)
|
if (far_z > 0.0)
|
||||||
m_frustrum_zs.second = std::max(m_frustrum_zs.second, far_z);
|
frustrum_zs->second = std::max(frustrum_zs->second, far_z);
|
||||||
|
|
||||||
w = 0.5 * (double)m_viewport[2];
|
w = 0.5 * (double)m_viewport[2];
|
||||||
h = 0.5 * (double)m_viewport[3];
|
h = 0.5 * (double)m_viewport[3];
|
||||||
|
|
||||||
double inv_zoom = get_inv_zoom();
|
const double inv_zoom = get_inv_zoom();
|
||||||
w *= inv_zoom;
|
w *= inv_zoom;
|
||||||
h *= inv_zoom;
|
h *= inv_zoom;
|
||||||
|
|
||||||
|
@ -162,16 +146,16 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
|
||||||
default:
|
default:
|
||||||
case Ortho:
|
case Ortho:
|
||||||
{
|
{
|
||||||
m_gui_scale = 1.0;
|
*const_cast<double*>(&m_gui_scale) = 1.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Perspective:
|
case Perspective:
|
||||||
{
|
{
|
||||||
// scale near plane to keep w and h constant on the plane at z = m_distance
|
// scale near plane to keep w and h constant on the plane at z = m_distance
|
||||||
double scale = m_frustrum_zs.first / m_distance;
|
const double scale = frustrum_zs->first / m_distance;
|
||||||
w *= scale;
|
w *= scale;
|
||||||
h *= scale;
|
h *= scale;
|
||||||
m_gui_scale = scale;
|
*const_cast<double*>(&m_gui_scale) = scale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,26 +168,25 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
|
||||||
default:
|
default:
|
||||||
case Ortho:
|
case Ortho:
|
||||||
{
|
{
|
||||||
glsafe(::glOrtho(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
|
glsafe(::glOrtho(-w, w, -h, h, frustrum_zs->first, frustrum_zs->second));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Perspective:
|
case Perspective:
|
||||||
{
|
{
|
||||||
glsafe(::glFrustum(-w, w, -h, h, m_frustrum_zs.first, m_frustrum_zs.second));
|
glsafe(::glFrustum(-w, w, -h, h, frustrum_zs->first, frustrum_zs->second));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
|
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, const_cast<Transform3d*>(&m_projection_matrix)->data()));
|
||||||
glsafe(::glMatrixMode(GL_MODELVIEW));
|
glsafe(::glMatrixMode(GL_MODELVIEW));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)
|
void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)
|
||||||
{
|
{
|
||||||
// Calculate the zoom factor needed to adjust the view around the given box.
|
// Calculate the zoom factor needed to adjust the view around the given box.
|
||||||
double zoom = calc_zoom_to_bounding_box_factor(box, margin_factor);
|
const double zoom = calc_zoom_to_bounding_box_factor(box, margin_factor);
|
||||||
if (zoom > 0.0)
|
if (zoom > 0.0) {
|
||||||
{
|
|
||||||
m_zoom = zoom;
|
m_zoom = zoom;
|
||||||
// center view around box center
|
// center view around box center
|
||||||
set_target(box.center());
|
set_target(box.center());
|
||||||
|
@ -213,9 +196,8 @@ void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)
|
||||||
void Camera::zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor)
|
void Camera::zoom_to_volumes(const GLVolumePtrs& volumes, double margin_factor)
|
||||||
{
|
{
|
||||||
Vec3d center;
|
Vec3d center;
|
||||||
double zoom = calc_zoom_to_volumes_factor(volumes, center, margin_factor);
|
const double zoom = calc_zoom_to_volumes_factor(volumes, center, margin_factor);
|
||||||
if (zoom > 0.0)
|
if (zoom > 0.0) {
|
||||||
{
|
|
||||||
m_zoom = zoom;
|
m_zoom = zoom;
|
||||||
// center view around the calculated center
|
// center view around the calculated center
|
||||||
set_target(center);
|
set_target(center);
|
||||||
|
@ -289,8 +271,8 @@ void Camera::rotate_on_sphere(double delta_azimut_rad, double delta_zenit_rad, b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target;
|
const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target;
|
||||||
auto rot_z = Eigen::AngleAxisd(delta_azimut_rad, Vec3d::UnitZ());
|
const auto rot_z = Eigen::AngleAxisd(delta_azimut_rad, Vec3d::UnitZ());
|
||||||
m_view_rotation *= rot_z * Eigen::AngleAxisd(delta_zenit_rad, rot_z.inverse() * get_dir_right());
|
m_view_rotation *= rot_z * Eigen::AngleAxisd(delta_zenit_rad, rot_z.inverse() * get_dir_right());
|
||||||
m_view_rotation.normalize();
|
m_view_rotation.normalize();
|
||||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (- m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (- m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
||||||
|
@ -299,10 +281,10 @@ void Camera::rotate_on_sphere(double delta_azimut_rad, double delta_zenit_rad, b
|
||||||
// Virtual trackball, rotate around an axis, where the eucledian norm of the axis gives the rotation angle in radians.
|
// Virtual trackball, rotate around an axis, where the eucledian norm of the axis gives the rotation angle in radians.
|
||||||
void Camera::rotate_local_around_target(const Vec3d& rotation_rad)
|
void Camera::rotate_local_around_target(const Vec3d& rotation_rad)
|
||||||
{
|
{
|
||||||
double angle = rotation_rad.norm();
|
const double angle = rotation_rad.norm();
|
||||||
if (std::abs(angle) > EPSILON) {
|
if (std::abs(angle) > EPSILON) {
|
||||||
Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target;
|
const Vec3d translation = m_view_matrix.translation() + m_view_rotation * m_target;
|
||||||
Vec3d axis = m_view_rotation.conjugate() * rotation_rad.normalized();
|
const Vec3d axis = m_view_rotation.conjugate() * rotation_rad.normalized();
|
||||||
m_view_rotation *= Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis));
|
m_view_rotation *= Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis));
|
||||||
m_view_rotation.normalize();
|
m_view_rotation.normalize();
|
||||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (-m_target) + translation, m_view_rotation, Vec3d(1., 1., 1.));
|
||||||
|
@ -310,18 +292,13 @@ void Camera::rotate_local_around_target(const Vec3d& rotation_rad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double Camera::min_zoom() const
|
|
||||||
{
|
|
||||||
return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const
|
std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
std::pair<double, double> ret;
|
std::pair<double, double> ret;
|
||||||
auto& [near_z, far_z] = ret;
|
auto& [near_z, far_z] = ret;
|
||||||
|
|
||||||
// box in eye space
|
// box in eye space
|
||||||
BoundingBoxf3 eye_box = box.transformed(m_view_matrix);
|
const BoundingBoxf3 eye_box = box.transformed(m_view_matrix);
|
||||||
near_z = -eye_box.max(2);
|
near_z = -eye_box.max(2);
|
||||||
far_z = -eye_box.min(2);
|
far_z = -eye_box.min(2);
|
||||||
|
|
||||||
|
@ -330,73 +307,71 @@ std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBo
|
||||||
far_z += FrustrumZMargin;
|
far_z += FrustrumZMargin;
|
||||||
|
|
||||||
// ensure min size
|
// ensure min size
|
||||||
if (far_z - near_z < FrustrumMinZRange)
|
if (far_z - near_z < FrustrumMinZRange) {
|
||||||
{
|
const double mid_z = 0.5 * (near_z + far_z);
|
||||||
double mid_z = 0.5 * (near_z + far_z);
|
const double half_size = 0.5 * FrustrumMinZRange;
|
||||||
double half_size = 0.5 * FrustrumMinZRange;
|
|
||||||
near_z = mid_z - half_size;
|
near_z = mid_z - half_size;
|
||||||
far_z = mid_z + half_size;
|
far_z = mid_z + half_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (near_z < FrustrumMinNearZ)
|
if (near_z < FrustrumMinNearZ) {
|
||||||
{
|
const double delta = FrustrumMinNearZ - near_z;
|
||||||
float delta = FrustrumMinNearZ - near_z;
|
|
||||||
set_distance(m_distance + delta);
|
set_distance(m_distance + delta);
|
||||||
near_z += delta;
|
near_z += delta;
|
||||||
far_z += delta;
|
far_z += delta;
|
||||||
}
|
}
|
||||||
else if ((near_z > 2.0 * FrustrumMinNearZ) && (m_distance > DefaultDistance))
|
// The following is commented out because it causes flickering of the 3D scene GUI
|
||||||
{
|
// when the bounding box of the scene gets large enough
|
||||||
float delta = m_distance - DefaultDistance;
|
// We need to introduce some smarter code to move the camera back and forth in such case
|
||||||
set_distance(DefaultDistance);
|
// else if (near_z > 2.0 * FrustrumMinNearZ && m_distance > DefaultDistance) {
|
||||||
near_z -= delta;
|
// float delta = m_distance - DefaultDistance;
|
||||||
far_z -= delta;
|
// set_distance(DefaultDistance);
|
||||||
}
|
// near_z -= delta;
|
||||||
|
// far_z -= delta;
|
||||||
|
// }
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, double margin_factor) const
|
double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, double margin_factor) const
|
||||||
{
|
{
|
||||||
double max_bb_size = box.max_size();
|
const double max_bb_size = box.max_size();
|
||||||
if (max_bb_size == 0.0)
|
if (max_bb_size == 0.0)
|
||||||
return -1.0;
|
return -1.0;
|
||||||
|
|
||||||
// project the box vertices on a plane perpendicular to the camera forward axis
|
// project the box vertices on a plane perpendicular to the camera forward axis
|
||||||
// then calculates the vertices coordinate on this plane along the camera xy axes
|
// then calculates the vertices coordinate on this plane along the camera xy axes
|
||||||
|
|
||||||
Vec3d right = get_dir_right();
|
const Vec3d right = get_dir_right();
|
||||||
Vec3d up = get_dir_up();
|
const Vec3d up = get_dir_up();
|
||||||
Vec3d forward = get_dir_forward();
|
const Vec3d forward = get_dir_forward();
|
||||||
|
const Vec3d bb_center = box.center();
|
||||||
Vec3d bb_center = box.center();
|
|
||||||
|
|
||||||
// box vertices in world space
|
// box vertices in world space
|
||||||
std::vector<Vec3d> vertices;
|
const std::vector<Vec3d> vertices = {
|
||||||
vertices.reserve(8);
|
box.min,
|
||||||
vertices.push_back(box.min);
|
{ box.max(0), box.min(1), box.min(2) },
|
||||||
vertices.emplace_back(box.max(0), box.min(1), box.min(2));
|
{ box.max(0), box.max(1), box.min(2) },
|
||||||
vertices.emplace_back(box.max(0), box.max(1), box.min(2));
|
{ box.min(0), box.max(1), box.min(2) },
|
||||||
vertices.emplace_back(box.min(0), box.max(1), box.min(2));
|
{ box.min(0), box.min(1), box.max(2) },
|
||||||
vertices.emplace_back(box.min(0), box.min(1), box.max(2));
|
{ box.max(0), box.min(1), box.max(2) },
|
||||||
vertices.emplace_back(box.max(0), box.min(1), box.max(2));
|
box.max,
|
||||||
vertices.push_back(box.max);
|
{ box.min(0), box.max(1), box.max(2) }
|
||||||
vertices.emplace_back(box.min(0), box.max(1), box.max(2));
|
};
|
||||||
|
|
||||||
double min_x = DBL_MAX;
|
double min_x = DBL_MAX;
|
||||||
double min_y = DBL_MAX;
|
double min_y = DBL_MAX;
|
||||||
double max_x = -DBL_MAX;
|
double max_x = -DBL_MAX;
|
||||||
double max_y = -DBL_MAX;
|
double max_y = -DBL_MAX;
|
||||||
|
|
||||||
for (const Vec3d& v : vertices)
|
for (const Vec3d& v : vertices) {
|
||||||
{
|
|
||||||
// project vertex on the plane perpendicular to camera forward axis
|
// project vertex on the plane perpendicular to camera forward axis
|
||||||
Vec3d pos = v - bb_center;
|
const Vec3d pos = v - bb_center;
|
||||||
Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
|
const Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
|
||||||
|
|
||||||
// calculates vertex coordinate along camera xy axes
|
// calculates vertex coordinate along camera xy axes
|
||||||
double x_on_plane = proj_on_plane.dot(right);
|
const double x_on_plane = proj_on_plane.dot(right);
|
||||||
double y_on_plane = proj_on_plane.dot(up);
|
const double y_on_plane = proj_on_plane.dot(up);
|
||||||
|
|
||||||
min_x = std::min(min_x, x_on_plane);
|
min_x = std::min(min_x, x_on_plane);
|
||||||
min_y = std::min(min_y, y_on_plane);
|
min_y = std::min(min_y, y_on_plane);
|
||||||
|
@ -406,7 +381,7 @@ double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, double
|
||||||
|
|
||||||
double dx = max_x - min_x;
|
double dx = max_x - min_x;
|
||||||
double dy = max_y - min_y;
|
double dy = max_y - min_y;
|
||||||
if ((dx <= 0.0) || (dy <= 0.0))
|
if (dx <= 0.0 || dy <= 0.0)
|
||||||
return -1.0f;
|
return -1.0f;
|
||||||
|
|
||||||
dx *= margin_factor;
|
dx *= margin_factor;
|
||||||
|
@ -423,13 +398,12 @@ double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, Vec3d& c
|
||||||
// project the volumes vertices on a plane perpendicular to the camera forward axis
|
// project the volumes vertices on a plane perpendicular to the camera forward axis
|
||||||
// then calculates the vertices coordinate on this plane along the camera xy axes
|
// then calculates the vertices coordinate on this plane along the camera xy axes
|
||||||
|
|
||||||
Vec3d right = get_dir_right();
|
const Vec3d right = get_dir_right();
|
||||||
Vec3d up = get_dir_up();
|
const Vec3d up = get_dir_up();
|
||||||
Vec3d forward = get_dir_forward();
|
const Vec3d forward = get_dir_forward();
|
||||||
|
|
||||||
BoundingBoxf3 box;
|
BoundingBoxf3 box;
|
||||||
for (const GLVolume* volume : volumes)
|
for (const GLVolume* volume : volumes) {
|
||||||
{
|
|
||||||
box.merge(volume->transformed_bounding_box());
|
box.merge(volume->transformed_bounding_box());
|
||||||
}
|
}
|
||||||
center = box.center();
|
center = box.center();
|
||||||
|
@ -439,24 +413,22 @@ double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, Vec3d& c
|
||||||
double max_x = -DBL_MAX;
|
double max_x = -DBL_MAX;
|
||||||
double max_y = -DBL_MAX;
|
double max_y = -DBL_MAX;
|
||||||
|
|
||||||
for (const GLVolume* volume : volumes)
|
for (const GLVolume* volume : volumes) {
|
||||||
{
|
|
||||||
const Transform3d& transform = volume->world_matrix();
|
const Transform3d& transform = volume->world_matrix();
|
||||||
const TriangleMesh* hull = volume->convex_hull();
|
const TriangleMesh* hull = volume->convex_hull();
|
||||||
if (hull == nullptr)
|
if (hull == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const Vec3f& vertex : hull->its.vertices)
|
for (const Vec3f& vertex : hull->its.vertices) {
|
||||||
{
|
const Vec3d v = transform * vertex.cast<double>();
|
||||||
Vec3d v = transform * vertex.cast<double>();
|
|
||||||
|
|
||||||
// project vertex on the plane perpendicular to camera forward axis
|
// project vertex on the plane perpendicular to camera forward axis
|
||||||
Vec3d pos = v - center;
|
const Vec3d pos = v - center;
|
||||||
Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
|
const Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
|
||||||
|
|
||||||
// calculates vertex coordinate along camera xy axes
|
// calculates vertex coordinate along camera xy axes
|
||||||
double x_on_plane = proj_on_plane.dot(right);
|
const double x_on_plane = proj_on_plane.dot(right);
|
||||||
double y_on_plane = proj_on_plane.dot(up);
|
const double y_on_plane = proj_on_plane.dot(up);
|
||||||
|
|
||||||
min_x = std::min(min_x, x_on_plane);
|
min_x = std::min(min_x, x_on_plane);
|
||||||
min_y = std::min(min_y, y_on_plane);
|
min_y = std::min(min_y, y_on_plane);
|
||||||
|
@ -467,10 +439,10 @@ double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, Vec3d& c
|
||||||
|
|
||||||
center += 0.5 * (max_x + min_x) * right + 0.5 * (max_y + min_y) * up;
|
center += 0.5 * (max_x + min_x) * right + 0.5 * (max_y + min_y) * up;
|
||||||
|
|
||||||
double dx = margin_factor * (max_x - min_x);
|
const double dx = margin_factor * (max_x - min_x);
|
||||||
double dy = margin_factor * (max_y - min_y);
|
const double dy = margin_factor * (max_y - min_y);
|
||||||
|
|
||||||
if ((dx <= 0.0) || (dy <= 0.0))
|
if (dx <= 0.0 || dy <= 0.0)
|
||||||
return -1.0f;
|
return -1.0f;
|
||||||
|
|
||||||
return std::min((double)m_viewport[2] / dx, (double)m_viewport[3] / dy);
|
return std::min((double)m_viewport[2] / dx, (double)m_viewport[3] / dy);
|
||||||
|
@ -478,22 +450,21 @@ double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, Vec3d& c
|
||||||
|
|
||||||
void Camera::set_distance(double distance) const
|
void Camera::set_distance(double distance) const
|
||||||
{
|
{
|
||||||
if (m_distance != distance)
|
if (m_distance != distance) {
|
||||||
{
|
const_cast<Transform3d*>(&m_view_matrix)->translate((distance - m_distance) * get_dir_forward());
|
||||||
m_view_matrix.translate((distance - m_distance) * get_dir_forward());
|
*const_cast<double*>(&m_distance) = distance;
|
||||||
m_distance = distance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up)
|
void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up)
|
||||||
{
|
{
|
||||||
Vec3d unit_z = (position - target).normalized();
|
const Vec3d unit_z = (position - target).normalized();
|
||||||
Vec3d unit_x = up.cross(unit_z).normalized();
|
const Vec3d unit_x = up.cross(unit_z).normalized();
|
||||||
Vec3d unit_y = unit_z.cross(unit_x).normalized();
|
const Vec3d unit_y = unit_z.cross(unit_x).normalized();
|
||||||
|
|
||||||
m_target = target;
|
m_target = target;
|
||||||
m_distance = (position - target).norm();
|
m_distance = (position - target).norm();
|
||||||
Vec3d new_position = m_target + m_distance * unit_z;
|
const Vec3d new_position = m_target + m_distance * unit_z;
|
||||||
|
|
||||||
m_view_matrix(0, 0) = unit_x(0);
|
m_view_matrix(0, 0) = unit_x(0);
|
||||||
m_view_matrix(0, 1) = unit_x(1);
|
m_view_matrix(0, 1) = unit_x(1);
|
||||||
|
@ -525,10 +496,10 @@ void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up
|
||||||
void Camera::set_default_orientation()
|
void Camera::set_default_orientation()
|
||||||
{
|
{
|
||||||
m_zenit = 45.0f;
|
m_zenit = 45.0f;
|
||||||
double theta_rad = Geometry::deg2rad(-(double)m_zenit);
|
const double theta_rad = Geometry::deg2rad(-(double)m_zenit);
|
||||||
double phi_rad = Geometry::deg2rad(45.0);
|
const double phi_rad = Geometry::deg2rad(45.0);
|
||||||
double sin_theta = ::sin(theta_rad);
|
const double sin_theta = ::sin(theta_rad);
|
||||||
Vec3d camera_pos = m_target + m_distance * Vec3d(sin_theta * ::sin(phi_rad), sin_theta * ::cos(phi_rad), ::cos(theta_rad));
|
const Vec3d camera_pos = m_target + m_distance * Vec3d(sin_theta * ::sin(phi_rad), sin_theta * ::cos(phi_rad), ::cos(theta_rad));
|
||||||
m_view_rotation = Eigen::AngleAxisd(theta_rad, Vec3d::UnitX()) * Eigen::AngleAxisd(phi_rad, Vec3d::UnitZ());
|
m_view_rotation = Eigen::AngleAxisd(theta_rad, Vec3d::UnitX()) * Eigen::AngleAxisd(phi_rad, Vec3d::UnitZ());
|
||||||
m_view_rotation.normalize();
|
m_view_rotation.normalize();
|
||||||
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (- camera_pos), m_view_rotation, Vec3d(1., 1., 1.));
|
m_view_matrix.fromPositionOrientationScale(m_view_rotation * (- camera_pos), m_view_rotation, Vec3d(1., 1., 1.));
|
||||||
|
@ -543,9 +514,9 @@ Vec3d Camera::validate_target(const Vec3d& target) const
|
||||||
test_box.scale(ScaleFactor);
|
test_box.scale(ScaleFactor);
|
||||||
test_box.translate(m_scene_box.center());
|
test_box.translate(m_scene_box.center());
|
||||||
|
|
||||||
return Vec3d(std::clamp(target(0), test_box.min(0), test_box.max(0)),
|
return { std::clamp(target(0), test_box.min(0), test_box.max(0)),
|
||||||
std::clamp(target(1), test_box.min(1), test_box.max(1)),
|
std::clamp(target(1), test_box.min(1), test_box.max(1)),
|
||||||
std::clamp(target(2), test_box.min(2), test_box.max(2)));
|
std::clamp(target(2), test_box.min(2), test_box.max(2)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::update_zenit()
|
void Camera::update_zenit()
|
||||||
|
|
|
@ -26,7 +26,7 @@ struct Camera
|
||||||
Num_types
|
Num_types
|
||||||
};
|
};
|
||||||
|
|
||||||
bool requires_zoom_to_bed;
|
bool requires_zoom_to_bed{ false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EType m_type{ Perspective };
|
EType m_type{ Perspective };
|
||||||
|
@ -35,26 +35,26 @@ private:
|
||||||
float m_zenit{ 45.0f };
|
float m_zenit{ 45.0f };
|
||||||
double m_zoom{ 1.0 };
|
double m_zoom{ 1.0 };
|
||||||
// Distance between camera position and camera target measured along the camera Z axis
|
// Distance between camera position and camera target measured along the camera Z axis
|
||||||
mutable double m_distance{ DefaultDistance };
|
double m_distance{ DefaultDistance };
|
||||||
mutable double m_gui_scale{ 1.0 };
|
double m_gui_scale{ 1.0 };
|
||||||
|
|
||||||
mutable std::array<int, 4> m_viewport;
|
std::array<int, 4> m_viewport;
|
||||||
mutable Transform3d m_view_matrix{ Transform3d::Identity() };
|
Transform3d m_view_matrix{ Transform3d::Identity() };
|
||||||
// We are calculating the rotation part of the m_view_matrix from m_view_rotation.
|
// We are calculating the rotation part of the m_view_matrix from m_view_rotation.
|
||||||
mutable Eigen::Quaterniond m_view_rotation{ 1.0, 0.0, 0.0, 0.0 };
|
Eigen::Quaterniond m_view_rotation{ 1.0, 0.0, 0.0, 0.0 };
|
||||||
mutable Transform3d m_projection_matrix{ Transform3d::Identity() };
|
Transform3d m_projection_matrix{ Transform3d::Identity() };
|
||||||
mutable std::pair<double, double> m_frustrum_zs;
|
std::pair<double, double> m_frustrum_zs;
|
||||||
|
|
||||||
BoundingBoxf3 m_scene_box;
|
BoundingBoxf3 m_scene_box;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Camera();
|
Camera() { set_default_orientation(); }
|
||||||
|
|
||||||
EType get_type() const { return m_type; }
|
EType get_type() const { return m_type; }
|
||||||
std::string get_type_as_string() const;
|
std::string get_type_as_string() const;
|
||||||
void set_type(EType type);
|
void set_type(EType type);
|
||||||
// valid values for type: "0" -> ortho, "1" -> perspective
|
// valid values for type: "0" -> ortho, "1" -> perspective
|
||||||
void set_type(const std::string& type);
|
void set_type(const std::string& type) { set_type((type == "1") ? Perspective : Ortho); }
|
||||||
void select_next_type();
|
void select_next_type();
|
||||||
|
|
||||||
void enable_update_config_on_type_change(bool enable) { m_update_config_on_type_change_enabled = enable; }
|
void enable_update_config_on_type_change(bool enable) { m_update_config_on_type_change_enabled = enable; }
|
||||||
|
@ -67,7 +67,7 @@ public:
|
||||||
|
|
||||||
double get_zoom() const { return m_zoom; }
|
double get_zoom() const { return m_zoom; }
|
||||||
double get_inv_zoom() const { assert(m_zoom != 0.0); return 1.0 / m_zoom; }
|
double get_inv_zoom() const { assert(m_zoom != 0.0); return 1.0 / m_zoom; }
|
||||||
void update_zoom(double delta_zoom);
|
void update_zoom(double delta_zoom) { set_zoom(m_zoom / (1.0 - std::max(std::min(delta_zoom, 4.0), -4.0) * 0.1)); }
|
||||||
void set_zoom(double zoom);
|
void set_zoom(double zoom);
|
||||||
|
|
||||||
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
|
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
|
||||||
|
@ -119,8 +119,7 @@ public:
|
||||||
bool is_looking_downward() const { return get_dir_forward().dot(Vec3d::UnitZ()) < 0.0; }
|
bool is_looking_downward() const { return get_dir_forward().dot(Vec3d::UnitZ()) < 0.0; }
|
||||||
|
|
||||||
// forces camera right vector to be parallel to XY plane
|
// forces camera right vector to be parallel to XY plane
|
||||||
void recover_from_free_camera()
|
void recover_from_free_camera() {
|
||||||
{
|
|
||||||
if (std::abs(get_dir_right()(2)) > EPSILON)
|
if (std::abs(get_dir_right()(2)) > EPSILON)
|
||||||
look_at(get_position(), m_target, Vec3d::UnitZ());
|
look_at(get_position(), m_target, Vec3d::UnitZ());
|
||||||
}
|
}
|
||||||
|
@ -128,7 +127,7 @@ public:
|
||||||
void look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up);
|
void look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up);
|
||||||
|
|
||||||
double max_zoom() const { return 250.0; }
|
double max_zoom() const { return 250.0; }
|
||||||
double min_zoom() const;
|
double min_zoom() const { return 0.7 * calc_zoom_to_bounding_box_factor(m_scene_box); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// returns tight values for nearZ and farZ plane around the given bounding box
|
// returns tight values for nearZ and farZ plane around the given bounding box
|
||||||
|
|
|
@ -278,6 +278,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||||
bool have_support_material_auto = have_support_material && config->opt_bool("support_material_auto");
|
bool have_support_material_auto = have_support_material && config->opt_bool("support_material_auto");
|
||||||
bool have_support_interface = config->opt_int("support_material_interface_layers") > 0;
|
bool have_support_interface = config->opt_int("support_material_interface_layers") > 0;
|
||||||
bool have_support_soluble = have_support_material && config->opt_float("support_material_contact_distance") == 0;
|
bool have_support_soluble = have_support_material && config->opt_float("support_material_contact_distance") == 0;
|
||||||
|
auto support_material_style = config->opt_enum<SupportMaterialStyle>("support_material_style");
|
||||||
for (auto el : { "support_material_style", "support_material_pattern", "support_material_with_sheath",
|
for (auto el : { "support_material_style", "support_material_pattern", "support_material_with_sheath",
|
||||||
"support_material_spacing", "support_material_angle",
|
"support_material_spacing", "support_material_angle",
|
||||||
"support_material_interface_pattern", "support_material_interface_layers",
|
"support_material_interface_pattern", "support_material_interface_layers",
|
||||||
|
@ -286,6 +287,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||||
toggle_field(el, have_support_material);
|
toggle_field(el, have_support_material);
|
||||||
toggle_field("support_material_threshold", have_support_material_auto);
|
toggle_field("support_material_threshold", have_support_material_auto);
|
||||||
toggle_field("support_material_bottom_contact_distance", have_support_material && ! have_support_soluble);
|
toggle_field("support_material_bottom_contact_distance", have_support_material && ! have_support_soluble);
|
||||||
|
toggle_field("support_material_closing_radius", have_support_material && support_material_style == smsSnug);
|
||||||
|
|
||||||
for (auto el : { "support_material_bottom_interface_layers", "support_material_interface_spacing", "support_material_interface_extruder",
|
for (auto el : { "support_material_bottom_interface_layers", "support_material_interface_spacing", "support_material_interface_extruder",
|
||||||
"support_material_interface_speed", "support_material_interface_contact_loops" })
|
"support_material_interface_speed", "support_material_interface_contact_loops" })
|
||||||
|
|
|
@ -2165,7 +2165,7 @@ static std::string get_custom_code(const std::string& code_in, double height)
|
||||||
if (dlg.ShowModal() != wxID_OK)
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
value = dlg.GetValue().ToStdString();
|
value = into_u8(dlg.GetValue());
|
||||||
valid = GUI::Tab::validate_custom_gcode("Custom G-code", value);
|
valid = GUI::Tab::validate_custom_gcode("Custom G-code", value);
|
||||||
} while (!valid);
|
} while (!valid);
|
||||||
return value;
|
return value;
|
||||||
|
@ -2173,7 +2173,7 @@ static std::string get_custom_code(const std::string& code_in, double height)
|
||||||
if (dlg.ShowModal() != wxID_OK)
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
return dlg.GetValue().ToStdString();
|
return into_u8(dlg.GetValue());
|
||||||
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
|
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -508,6 +508,7 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas)
|
||||||
m_layer_height_profile.clear();
|
m_layer_height_profile.clear();
|
||||||
m_layers_texture.valid = false;
|
m_layers_texture.valid = false;
|
||||||
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
wxGetApp().obj_list()->update_info_items(last_object_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor)
|
void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor)
|
||||||
|
@ -517,6 +518,7 @@ void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas
|
||||||
const_cast<ModelObject*>(m_model_object)->layer_height_profile.set(m_layer_height_profile);
|
const_cast<ModelObject*>(m_model_object)->layer_height_profile.set(m_layer_height_profile);
|
||||||
m_layers_texture.valid = false;
|
m_layers_texture.valid = false;
|
||||||
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
wxGetApp().obj_list()->update_info_items(last_object_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params)
|
void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params)
|
||||||
|
@ -526,6 +528,7 @@ void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas,
|
||||||
const_cast<ModelObject*>(m_model_object)->layer_height_profile.set(m_layer_height_profile);
|
const_cast<ModelObject*>(m_model_object)->layer_height_profile.set(m_layer_height_profile);
|
||||||
m_layers_texture.valid = false;
|
m_layers_texture.valid = false;
|
||||||
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
wxGetApp().obj_list()->update_info_items(last_object_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::LayersEditing::generate_layer_height_texture()
|
void GLCanvas3D::LayersEditing::generate_layer_height_texture()
|
||||||
|
@ -565,6 +568,7 @@ void GLCanvas3D::LayersEditing::accept_changes(GLCanvas3D& canvas)
|
||||||
wxGetApp().plater()->take_snapshot(_(L("Variable layer height - Manual edit")));
|
wxGetApp().plater()->take_snapshot(_(L("Variable layer height - Manual edit")));
|
||||||
const_cast<ModelObject*>(m_model_object)->layer_height_profile.set(m_layer_height_profile);
|
const_cast<ModelObject*>(m_model_object)->layer_height_profile.set(m_layer_height_profile);
|
||||||
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
wxGetApp().obj_list()->update_info_items(last_object_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_layer_height_profile_modified = false;
|
m_layer_height_profile_modified = false;
|
||||||
|
@ -3524,7 +3528,7 @@ Vec2d GLCanvas3D::get_local_mouse_position() const
|
||||||
void GLCanvas3D::set_tooltip(const std::string& tooltip) const
|
void GLCanvas3D::set_tooltip(const std::string& tooltip) const
|
||||||
{
|
{
|
||||||
if (m_canvas != nullptr)
|
if (m_canvas != nullptr)
|
||||||
m_tooltip.set_text(tooltip);
|
const_cast<Tooltip*>(&m_tooltip)->set_text(tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::do_move(const std::string& snapshot_type)
|
void GLCanvas3D::do_move(const std::string& snapshot_type)
|
||||||
|
@ -3541,22 +3545,19 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
||||||
|
|
||||||
Selection::EMode selection_mode = m_selection.get_mode();
|
Selection::EMode selection_mode = m_selection.get_mode();
|
||||||
|
|
||||||
for (const GLVolume* v : m_volumes.volumes)
|
for (const GLVolume* v : m_volumes.volumes) {
|
||||||
{
|
|
||||||
int object_idx = v->object_idx();
|
int object_idx = v->object_idx();
|
||||||
int instance_idx = v->instance_idx();
|
int instance_idx = v->instance_idx();
|
||||||
int volume_idx = v->volume_idx();
|
int volume_idx = v->volume_idx();
|
||||||
|
|
||||||
std::pair<int, int> done_id(object_idx, instance_idx);
|
std::pair<int, int> done_id(object_idx, instance_idx);
|
||||||
|
|
||||||
if ((0 <= object_idx) && (object_idx < (int)m_model->objects.size()))
|
if (0 <= object_idx && object_idx < (int)m_model->objects.size()) {
|
||||||
{
|
|
||||||
done.insert(done_id);
|
done.insert(done_id);
|
||||||
|
|
||||||
// Move instances/volumes
|
// Move instances/volumes
|
||||||
ModelObject* model_object = m_model->objects[object_idx];
|
ModelObject* model_object = m_model->objects[object_idx];
|
||||||
if (model_object != nullptr)
|
if (model_object != nullptr) {
|
||||||
{
|
|
||||||
if (selection_mode == Selection::Instance)
|
if (selection_mode == Selection::Instance)
|
||||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||||
else if (selection_mode == Selection::Volume)
|
else if (selection_mode == Selection::Volume)
|
||||||
|
@ -3572,8 +3573,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixes sinking/flying instances
|
// Fixes sinking/flying instances
|
||||||
for (const std::pair<int, int>& i : done)
|
for (const std::pair<int, int>& i : done) {
|
||||||
{
|
|
||||||
ModelObject* m = m_model->objects[i.first];
|
ModelObject* m = m_model->objects[i.first];
|
||||||
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
|
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
|
||||||
m_selection.translate(i.first, i.second, shift);
|
m_selection.translate(i.first, i.second, shift);
|
||||||
|
@ -3932,13 +3932,13 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) const
|
||||||
em *= m_retina_helper->get_scale_factor();
|
em *= m_retina_helper->get_scale_factor();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (imgui->undo_redo_list(ImVec2(18 * em, 26 * em), is_undo, &string_getter, hovered, selected, m_mouse_wheel))
|
int* mouse_wheel = const_cast<int*>(&m_mouse_wheel);
|
||||||
m_imgui_undo_redo_hovered_pos = hovered;
|
if (imgui->undo_redo_list(ImVec2(18 * em, 26 * em), is_undo, &string_getter, hovered, selected, *mouse_wheel))
|
||||||
|
*const_cast<int*>(&m_imgui_undo_redo_hovered_pos) = hovered;
|
||||||
else
|
else
|
||||||
m_imgui_undo_redo_hovered_pos = -1;
|
*const_cast<int*>(&m_imgui_undo_redo_hovered_pos) = -1;
|
||||||
|
|
||||||
if (selected >= 0)
|
if (selected >= 0) {
|
||||||
{
|
|
||||||
is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected);
|
is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected);
|
||||||
action_taken = true;
|
action_taken = true;
|
||||||
}
|
}
|
||||||
|
@ -3979,9 +3979,10 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
|
||||||
char *s = new char[255];
|
char *s = new char[255];
|
||||||
strcpy(s, search_line.empty() ? _u8L("Enter a search term").c_str() : search_line.c_str());
|
strcpy(s, search_line.empty() ? _u8L("Enter a search term").c_str() : search_line.c_str());
|
||||||
|
|
||||||
|
int* mouse_wheel = const_cast<int*>(&m_mouse_wheel);
|
||||||
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s,
|
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s,
|
||||||
sidebar.get_searcher().view_params,
|
sidebar.get_searcher().view_params,
|
||||||
selected, edited, m_mouse_wheel, wxGetApp().is_localized());
|
selected, edited, *mouse_wheel, wxGetApp().is_localized());
|
||||||
|
|
||||||
search_line = s;
|
search_line = s;
|
||||||
delete [] s;
|
delete [] s;
|
||||||
|
@ -4840,8 +4841,10 @@ void GLCanvas3D::_refresh_if_shown_on_screen()
|
||||||
|
|
||||||
void GLCanvas3D::_picking_pass() const
|
void GLCanvas3D::_picking_pass() const
|
||||||
{
|
{
|
||||||
|
std::vector<int>* hover_volume_idxs = const_cast<std::vector<int>*>(&m_hover_volume_idxs);
|
||||||
|
|
||||||
if (m_picking_enabled && !m_mouse.dragging && m_mouse.position != Vec2d(DBL_MAX, DBL_MAX)) {
|
if (m_picking_enabled && !m_mouse.dragging && m_mouse.position != Vec2d(DBL_MAX, DBL_MAX)) {
|
||||||
m_hover_volume_idxs.clear();
|
hover_volume_idxs->clear();
|
||||||
|
|
||||||
// Render the object for picking.
|
// Render the object for picking.
|
||||||
// FIXME This cannot possibly work in a multi - sampled context as the color gets mangled by the anti - aliasing.
|
// FIXME This cannot possibly work in a multi - sampled context as the color gets mangled by the anti - aliasing.
|
||||||
|
@ -4856,9 +4859,10 @@ void GLCanvas3D::_picking_pass() const
|
||||||
|
|
||||||
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||||
|
|
||||||
m_camera_clipping_plane = m_gizmos.get_clipping_plane();
|
ClippingPlane* camera_clipping_plane = const_cast<ClippingPlane*>(&m_camera_clipping_plane);
|
||||||
if (m_camera_clipping_plane.is_active()) {
|
*camera_clipping_plane = m_gizmos.get_clipping_plane();
|
||||||
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data());
|
if (camera_clipping_plane->is_active()) {
|
||||||
|
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)camera_clipping_plane->get_data());
|
||||||
::glEnable(GL_CLIP_PLANE0);
|
::glEnable(GL_CLIP_PLANE0);
|
||||||
}
|
}
|
||||||
_render_volumes_for_picking();
|
_render_volumes_for_picking();
|
||||||
|
@ -4884,11 +4888,11 @@ void GLCanvas3D::_picking_pass() const
|
||||||
if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size()) {
|
if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size()) {
|
||||||
// do not add the volume id if any gizmo is active and CTRL is pressed
|
// do not add the volume id if any gizmo is active and CTRL is pressed
|
||||||
if (m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined || !wxGetKeyState(WXK_CONTROL))
|
if (m_gizmos.get_current_type() == GLGizmosManager::EType::Undefined || !wxGetKeyState(WXK_CONTROL))
|
||||||
m_hover_volume_idxs.emplace_back(volume_id);
|
hover_volume_idxs->emplace_back(volume_id);
|
||||||
m_gizmos.set_hover_id(-1);
|
const_cast<GLGizmosManager*>(&m_gizmos)->set_hover_id(-1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_gizmos.set_hover_id(inside && (unsigned int)volume_id <= GLGizmoBase::BASE_ID ? ((int)GLGizmoBase::BASE_ID - volume_id) : -1);
|
const_cast<GLGizmosManager*>(&m_gizmos)->set_hover_id(inside && (unsigned int)volume_id <= GLGizmoBase::BASE_ID ? ((int)GLGizmoBase::BASE_ID - volume_id) : -1);
|
||||||
|
|
||||||
_update_volumes_hover_state();
|
_update_volumes_hover_state();
|
||||||
}
|
}
|
||||||
|
@ -4896,12 +4900,11 @@ void GLCanvas3D::_picking_pass() const
|
||||||
|
|
||||||
void GLCanvas3D::_rectangular_selection_picking_pass() const
|
void GLCanvas3D::_rectangular_selection_picking_pass() const
|
||||||
{
|
{
|
||||||
m_gizmos.set_hover_id(-1);
|
const_cast<GLGizmosManager*>(&m_gizmos)->set_hover_id(-1);
|
||||||
|
|
||||||
std::set<int> idxs;
|
std::set<int> idxs;
|
||||||
|
|
||||||
if (m_picking_enabled)
|
if (m_picking_enabled) {
|
||||||
{
|
|
||||||
if (m_multisample_allowed)
|
if (m_multisample_allowed)
|
||||||
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
||||||
glsafe(::glDisable(GL_MULTISAMPLE));
|
glsafe(::glDisable(GL_MULTISAMPLE));
|
||||||
|
@ -4922,8 +4925,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const
|
||||||
|
|
||||||
int left = (int)m_rectangle_selection.get_left();
|
int left = (int)m_rectangle_selection.get_left();
|
||||||
int top = get_canvas_size().get_height() - (int)m_rectangle_selection.get_top();
|
int top = get_canvas_size().get_height() - (int)m_rectangle_selection.get_top();
|
||||||
if ((left >= 0) && (top >= 0))
|
if (left >= 0 && top >= 0) {
|
||||||
{
|
|
||||||
#define USE_PARALLEL 1
|
#define USE_PARALLEL 1
|
||||||
#if USE_PARALLEL
|
#if USE_PARALLEL
|
||||||
struct Pixel
|
struct Pixel
|
||||||
|
@ -4943,7 +4945,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const
|
||||||
for (size_t i = range.begin(); i < range.end(); ++i)
|
for (size_t i = range.begin(); i < range.end(); ++i)
|
||||||
if (frame[i].valid()) {
|
if (frame[i].valid()) {
|
||||||
int volume_id = frame[i].id();
|
int volume_id = frame[i].id();
|
||||||
if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size())) {
|
if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size()) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
idxs.insert(volume_id);
|
idxs.insert(volume_id);
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
@ -4958,14 +4960,14 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const
|
||||||
{
|
{
|
||||||
int px_id = 4 * i;
|
int px_id = 4 * i;
|
||||||
int volume_id = frame[px_id] + (frame[px_id + 1] << 8) + (frame[px_id + 2] << 16);
|
int volume_id = frame[px_id] + (frame[px_id + 1] << 8) + (frame[px_id + 2] << 16);
|
||||||
if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size()))
|
if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size())
|
||||||
idxs.insert(volume_id);
|
idxs.insert(volume_id);
|
||||||
}
|
}
|
||||||
#endif // USE_PARALLEL
|
#endif // USE_PARALLEL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hover_volume_idxs.assign(idxs.begin(), idxs.end());
|
const_cast<std::vector<int>*>(&m_hover_volume_idxs)->assign(idxs.begin(), idxs.end());
|
||||||
_update_volumes_hover_state();
|
_update_volumes_hover_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5059,7 +5061,9 @@ void GLCanvas3D::_render_objects() const
|
||||||
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
m_camera_clipping_plane = m_gizmos.get_clipping_plane();
|
ClippingPlane* camera_clipping_plane = const_cast<ClippingPlane*>(&m_camera_clipping_plane);
|
||||||
|
GLVolumeCollection* volumes = const_cast<GLVolumeCollection*>(&m_volumes);
|
||||||
|
*camera_clipping_plane = m_gizmos.get_clipping_plane();
|
||||||
|
|
||||||
if (m_picking_enabled) {
|
if (m_picking_enabled) {
|
||||||
// Update the layer editing selection to the first object selected, update the current object maximum Z.
|
// Update the layer editing selection to the first object selected, update the current object maximum Z.
|
||||||
|
@ -5067,17 +5071,17 @@ void GLCanvas3D::_render_objects() const
|
||||||
|
|
||||||
if (m_config != nullptr) {
|
if (m_config != nullptr) {
|
||||||
const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false);
|
const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false);
|
||||||
m_volumes.set_print_box((float)bed_bb.min(0) - BedEpsilon, (float)bed_bb.min(1) - BedEpsilon, 0.0f, (float)bed_bb.max(0) + BedEpsilon, (float)bed_bb.max(1) + BedEpsilon, (float)m_config->opt_float("max_print_height"));
|
volumes->set_print_box((float)bed_bb.min(0) - BedEpsilon, (float)bed_bb.min(1) - BedEpsilon, 0.0f, (float)bed_bb.max(0) + BedEpsilon, (float)bed_bb.max(1) + BedEpsilon, (float)m_config->opt_float("max_print_height"));
|
||||||
m_volumes.check_outside_state(m_config, nullptr);
|
volumes->check_outside_state(m_config, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_use_clipping_planes)
|
if (m_use_clipping_planes)
|
||||||
m_volumes.set_z_range(-m_clipping_planes[0].get_data()[3], m_clipping_planes[1].get_data()[3]);
|
volumes->set_z_range(-m_clipping_planes[0].get_data()[3], m_clipping_planes[1].get_data()[3]);
|
||||||
else
|
else
|
||||||
m_volumes.set_z_range(-FLT_MAX, FLT_MAX);
|
volumes->set_z_range(-FLT_MAX, FLT_MAX);
|
||||||
|
|
||||||
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
|
volumes->set_clipping_plane(camera_clipping_plane->get_data());
|
||||||
|
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
||||||
if (shader != nullptr) {
|
if (shader != nullptr) {
|
||||||
|
@ -5085,15 +5089,15 @@ void GLCanvas3D::_render_objects() const
|
||||||
|
|
||||||
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
|
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
|
||||||
int object_id = m_layers_editing.last_object_id;
|
int object_id = m_layers_editing.last_object_id;
|
||||||
m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
|
volumes->render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
|
||||||
// Which volume to paint without the layer height profile shader?
|
// Which volume to paint without the layer height profile shader?
|
||||||
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
||||||
});
|
});
|
||||||
// Let LayersEditing handle rendering of the active object using the layer height profile shader.
|
// Let LayersEditing handle rendering of the active object using the layer height profile shader.
|
||||||
m_layers_editing.render_volumes(*this, this->m_volumes);
|
m_layers_editing.render_volumes(*this, *volumes);
|
||||||
} else {
|
} else {
|
||||||
// do not cull backfaces to show broken geometry, if any
|
// do not cull backfaces to show broken geometry, if any
|
||||||
m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) {
|
volumes->render(GLVolumeCollection::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) {
|
||||||
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
|
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5112,11 +5116,11 @@ void GLCanvas3D::_render_objects() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
|
volumes->render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_camera_clipping_plane = ClippingPlane::ClipsNothing();
|
*camera_clipping_plane = ClippingPlane::ClipsNothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_render_gcode() const
|
void GLCanvas3D::_render_gcode() const
|
||||||
|
@ -5157,13 +5161,13 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() const
|
||||||
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
||||||
#if ENABLE_RETINA_GL
|
#if ENABLE_RETINA_GL
|
||||||
const float sc = m_retina_helper->get_scale_factor() * scale;
|
const float sc = m_retina_helper->get_scale_factor() * scale;
|
||||||
m_main_toolbar.set_scale(sc);
|
const_cast<GLToolbar*>(&m_main_toolbar)->set_scale(sc);
|
||||||
m_undoredo_toolbar.set_scale(sc);
|
const_cast<GLToolbar*>(&m_undoredo_toolbar)->set_scale(sc);
|
||||||
collapse_toolbar.set_scale(sc);
|
collapse_toolbar.set_scale(sc);
|
||||||
size *= m_retina_helper->get_scale_factor();
|
size *= m_retina_helper->get_scale_factor();
|
||||||
#else
|
#else
|
||||||
m_main_toolbar.set_icons_size(size);
|
const_cast<GLToolbar*>(&m_main_toolbar)->set_icons_size(size);
|
||||||
m_undoredo_toolbar.set_icons_size(size);
|
const_cast<GLToolbar*>(&m_undoredo_toolbar)->set_icons_size(size);
|
||||||
collapse_toolbar.set_icons_size(size);
|
collapse_toolbar.set_icons_size(size);
|
||||||
#endif // ENABLE_RETINA_GL
|
#endif // ENABLE_RETINA_GL
|
||||||
|
|
||||||
|
@ -5211,13 +5215,13 @@ void GLCanvas3D::_render_overlays() const
|
||||||
// to correctly place them
|
// to correctly place them
|
||||||
#if ENABLE_RETINA_GL
|
#if ENABLE_RETINA_GL
|
||||||
const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(/*true*/);
|
const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(/*true*/);
|
||||||
m_main_toolbar.set_scale(scale);
|
const_cast<GLToolbar*>(&m_main_toolbar)->set_scale(scale);
|
||||||
m_undoredo_toolbar.set_scale(scale);
|
const_cast<GLToolbar*>(&m_undoredo_toolbar)->set_scale(scale);
|
||||||
wxGetApp().plater()->get_collapse_toolbar().set_scale(scale);
|
wxGetApp().plater()->get_collapse_toolbar().set_scale(scale);
|
||||||
#else
|
#else
|
||||||
const float size = int(GLToolbar::Default_Icons_Size * wxGetApp().toolbar_icon_scale(/*true*/));
|
const float size = int(GLToolbar::Default_Icons_Size * wxGetApp().toolbar_icon_scale(/*true*/));
|
||||||
m_main_toolbar.set_icons_size(size);
|
const_cast<GLToolbar*>(&m_main_toolbar)->set_icons_size(size);
|
||||||
m_undoredo_toolbar.set_icons_size(size);
|
const_cast<GLToolbar*>(&m_undoredo_toolbar)->set_icons_size(size);
|
||||||
wxGetApp().plater()->get_collapse_toolbar().set_icons_size(size);
|
wxGetApp().plater()->get_collapse_toolbar().set_icons_size(size);
|
||||||
#endif // ENABLE_RETINA_GL
|
#endif // ENABLE_RETINA_GL
|
||||||
|
|
||||||
|
@ -5292,12 +5296,12 @@ void GLCanvas3D::_render_gizmos_overlay() const
|
||||||
#if ENABLE_RETINA_GL
|
#if ENABLE_RETINA_GL
|
||||||
// m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor());
|
// m_gizmos.set_overlay_scale(m_retina_helper->get_scale_factor());
|
||||||
const float scale = m_retina_helper->get_scale_factor()*wxGetApp().toolbar_icon_scale();
|
const float scale = m_retina_helper->get_scale_factor()*wxGetApp().toolbar_icon_scale();
|
||||||
m_gizmos.set_overlay_scale(scale); //! #ys_FIXME_experiment
|
const_cast<GLGizmosManager*>(&m_gizmos)->set_overlay_scale(scale); //! #ys_FIXME_experiment
|
||||||
#else
|
#else
|
||||||
// m_gizmos.set_overlay_scale(m_canvas->GetContentScaleFactor());
|
// m_gizmos.set_overlay_scale(m_canvas->GetContentScaleFactor());
|
||||||
// m_gizmos.set_overlay_scale(wxGetApp().em_unit()*0.1f);
|
// m_gizmos.set_overlay_scale(wxGetApp().em_unit()*0.1f);
|
||||||
const float size = int(GLGizmosManager::Default_Icons_Size*wxGetApp().toolbar_icon_scale());
|
const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale());
|
||||||
m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment
|
const_cast<GLGizmosManager*>(&m_gizmos)->set_overlay_icon_size(size); //! #ys_FIXME_experiment
|
||||||
#endif /* __WXMSW__ */
|
#endif /* __WXMSW__ */
|
||||||
|
|
||||||
m_gizmos.render_overlay();
|
m_gizmos.render_overlay();
|
||||||
|
@ -5316,8 +5320,9 @@ void GLCanvas3D::_render_main_toolbar() const
|
||||||
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||||
float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width) * inv_zoom;
|
float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width) * inv_zoom;
|
||||||
|
|
||||||
m_main_toolbar.set_position(top, left);
|
GLToolbar* main_toolbar = const_cast<GLToolbar*>(&m_main_toolbar);
|
||||||
m_main_toolbar.render(*this);
|
main_toolbar->set_position(top, left);
|
||||||
|
main_toolbar->render(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_render_undoredo_toolbar() const
|
void GLCanvas3D::_render_undoredo_toolbar() const
|
||||||
|
@ -5332,8 +5337,10 @@ void GLCanvas3D::_render_undoredo_toolbar() const
|
||||||
const GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
const GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
|
||||||
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
|
||||||
float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width)) * inv_zoom;
|
float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width)) * inv_zoom;
|
||||||
m_undoredo_toolbar.set_position(top, left);
|
|
||||||
m_undoredo_toolbar.render(*this);
|
GLToolbar* undoredo_toolbar = const_cast<GLToolbar*>(&m_undoredo_toolbar);
|
||||||
|
undoredo_toolbar->set_position(top, left);
|
||||||
|
undoredo_toolbar->render(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_render_collapse_toolbar() const
|
void GLCanvas3D::_render_collapse_toolbar() const
|
||||||
|
@ -5424,20 +5431,21 @@ void GLCanvas3D::_render_sla_slices() const
|
||||||
if (!obj->is_step_done(slaposSliceSupports))
|
if (!obj->is_step_done(slaposSliceSupports))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_bottom = m_sla_caps[0].triangles.find(i);
|
SlaCap* sla_caps = const_cast<SlaCap*>(m_sla_caps);
|
||||||
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_top = m_sla_caps[1].triangles.find(i);
|
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_bottom = sla_caps[0].triangles.find(i);
|
||||||
|
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_top = sla_caps[1].triangles.find(i);
|
||||||
{
|
{
|
||||||
if (it_caps_bottom == m_sla_caps[0].triangles.end())
|
if (it_caps_bottom == sla_caps[0].triangles.end())
|
||||||
it_caps_bottom = m_sla_caps[0].triangles.emplace(i, SlaCap::Triangles()).first;
|
it_caps_bottom = sla_caps[0].triangles.emplace(i, SlaCap::Triangles()).first;
|
||||||
if (! m_sla_caps[0].matches(clip_min_z)) {
|
if (!sla_caps[0].matches(clip_min_z)) {
|
||||||
m_sla_caps[0].z = clip_min_z;
|
sla_caps[0].z = clip_min_z;
|
||||||
it_caps_bottom->second.object.clear();
|
it_caps_bottom->second.object.clear();
|
||||||
it_caps_bottom->second.supports.clear();
|
it_caps_bottom->second.supports.clear();
|
||||||
}
|
}
|
||||||
if (it_caps_top == m_sla_caps[1].triangles.end())
|
if (it_caps_top == sla_caps[1].triangles.end())
|
||||||
it_caps_top = m_sla_caps[1].triangles.emplace(i, SlaCap::Triangles()).first;
|
it_caps_top = sla_caps[1].triangles.emplace(i, SlaCap::Triangles()).first;
|
||||||
if (! m_sla_caps[1].matches(clip_max_z)) {
|
if (!sla_caps[1].matches(clip_max_z)) {
|
||||||
m_sla_caps[1].z = clip_max_z;
|
sla_caps[1].z = clip_max_z;
|
||||||
it_caps_top->second.object.clear();
|
it_caps_top->second.object.clear();
|
||||||
it_caps_top->second.supports.clear();
|
it_caps_top->second.supports.clear();
|
||||||
}
|
}
|
||||||
|
@ -5543,7 +5551,7 @@ void GLCanvas3D::_update_volumes_hover_state() const
|
||||||
|
|
||||||
if (alt_pressed && (shift_pressed || ctrl_pressed)) {
|
if (alt_pressed && (shift_pressed || ctrl_pressed)) {
|
||||||
// illegal combinations of keys
|
// illegal combinations of keys
|
||||||
m_hover_volume_idxs.clear();
|
const_cast<std::vector<int>*>(&m_hover_volume_idxs)->clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5567,7 +5575,7 @@ void GLCanvas3D::_update_volumes_hover_state() const
|
||||||
|
|
||||||
if (hover_modifiers_only && !hover_from_single_instance) {
|
if (hover_modifiers_only && !hover_from_single_instance) {
|
||||||
// do not allow to select volumes from different instances
|
// do not allow to select volumes from different instances
|
||||||
m_hover_volume_idxs.clear();
|
const_cast<std::vector<int>*>(&m_hover_volume_idxs)->clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5588,23 +5596,15 @@ void GLCanvas3D::_update_volumes_hover_state() const
|
||||||
(deselect && !m_selection.is_single_full_instance() && (volume.object_idx() == m_selection.get_object_idx()) && (volume.instance_idx() == m_selection.get_instance_idx()))
|
(deselect && !m_selection.is_single_full_instance() && (volume.object_idx() == m_selection.get_object_idx()) && (volume.instance_idx() == m_selection.get_instance_idx()))
|
||||||
);
|
);
|
||||||
|
|
||||||
if (as_volume) {
|
if (as_volume)
|
||||||
if (deselect)
|
volume.hover = deselect ? GLVolume::HS_Deselect : GLVolume::HS_Select;
|
||||||
volume.hover = GLVolume::HS_Deselect;
|
|
||||||
else
|
|
||||||
volume.hover = GLVolume::HS_Select;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
int object_idx = volume.object_idx();
|
int object_idx = volume.object_idx();
|
||||||
int instance_idx = volume.instance_idx();
|
int instance_idx = volume.instance_idx();
|
||||||
|
|
||||||
for (GLVolume* v : m_volumes.volumes) {
|
for (GLVolume* v : m_volumes.volumes) {
|
||||||
if (v->object_idx() == object_idx && v->instance_idx() == instance_idx) {
|
if (v->object_idx() == object_idx && v->instance_idx() == instance_idx)
|
||||||
if (deselect)
|
v->hover = deselect ? GLVolume::HS_Deselect : GLVolume::HS_Select;
|
||||||
v->hover = GLVolume::HS_Deselect;
|
|
||||||
else
|
|
||||||
v->hover = GLVolume::HS_Select;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6311,31 +6311,47 @@ std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& col
|
||||||
#if ENABLE_WARNING_TEXTURE_REMOVAL
|
#if ENABLE_WARNING_TEXTURE_REMOVAL
|
||||||
void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
||||||
{
|
{
|
||||||
|
enum ErrorType{
|
||||||
|
PLATER_WARNING,
|
||||||
|
PLATER_ERROR,
|
||||||
|
SLICING_ERROR
|
||||||
|
};
|
||||||
std::string text;
|
std::string text;
|
||||||
bool error = false;
|
ErrorType error = ErrorType::PLATER_WARNING;
|
||||||
switch (warning) {
|
switch (warning) {
|
||||||
case EWarning::ObjectOutside: text = _u8L("An object outside the print area was detected."); break;
|
case EWarning::ObjectOutside: text = _u8L("An object outside the print area was detected."); break;
|
||||||
case EWarning::ToolpathOutside: text = _u8L("A toolpath outside the print area was detected."); error = true; break;
|
case EWarning::ToolpathOutside: text = _u8L("A toolpath outside the print area was detected."); error = ErrorType::SLICING_ERROR; break;
|
||||||
case EWarning::SlaSupportsOutside: text = _u8L("SLA supports outside the print area were detected."); error = true; break;
|
case EWarning::SlaSupportsOutside: text = _u8L("SLA supports outside the print area were detected."); error = ErrorType::PLATER_ERROR; break;
|
||||||
case EWarning::SomethingNotShown: text = _u8L("Some objects are not visible."); break;
|
case EWarning::SomethingNotShown: text = _u8L("Some objects are not visible."); break;
|
||||||
case EWarning::ObjectClashed:
|
case EWarning::ObjectClashed:
|
||||||
text = _u8L("An object outside the print area was detected.\n"
|
text = _u8L("An object outside the print area was detected.\n"
|
||||||
"Resolve the current problem to continue slicing.");
|
"Resolve the current problem to continue slicing.");
|
||||||
error = true;
|
error = ErrorType::PLATER_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto& notification_manager = *wxGetApp().plater()->get_notification_manager();
|
auto& notification_manager = *wxGetApp().plater()->get_notification_manager();
|
||||||
if (state) {
|
switch (error)
|
||||||
if (error)
|
{
|
||||||
notification_manager.push_plater_error_notification(text);
|
case PLATER_WARNING:
|
||||||
else
|
if (state)
|
||||||
notification_manager.push_plater_warning_notification(text);
|
notification_manager.push_plater_warning_notification(text);
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (error)
|
|
||||||
notification_manager.close_plater_error_notification(text);
|
|
||||||
else
|
else
|
||||||
notification_manager.close_plater_warning_notification(text);
|
notification_manager.close_plater_warning_notification(text);
|
||||||
|
break;
|
||||||
|
case PLATER_ERROR:
|
||||||
|
if (state)
|
||||||
|
notification_manager.push_plater_error_notification(text);
|
||||||
|
else
|
||||||
|
notification_manager.close_plater_error_notification(text);
|
||||||
|
break;
|
||||||
|
case SLICING_ERROR:
|
||||||
|
if (state)
|
||||||
|
notification_manager.push_slicing_error_notification(text);
|
||||||
|
else
|
||||||
|
notification_manager.close_slicing_error_notification(text);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -449,13 +449,13 @@ private:
|
||||||
wxTimer m_timer;
|
wxTimer m_timer;
|
||||||
LayersEditing m_layers_editing;
|
LayersEditing m_layers_editing;
|
||||||
Mouse m_mouse;
|
Mouse m_mouse;
|
||||||
mutable GLGizmosManager m_gizmos;
|
GLGizmosManager m_gizmos;
|
||||||
mutable GLToolbar m_main_toolbar;
|
GLToolbar m_main_toolbar;
|
||||||
mutable GLToolbar m_undoredo_toolbar;
|
GLToolbar m_undoredo_toolbar;
|
||||||
ClippingPlane m_clipping_planes[2];
|
ClippingPlane m_clipping_planes[2];
|
||||||
mutable ClippingPlane m_camera_clipping_plane;
|
ClippingPlane m_camera_clipping_plane;
|
||||||
bool m_use_clipping_planes;
|
bool m_use_clipping_planes;
|
||||||
mutable SlaCap m_sla_caps[2];
|
SlaCap m_sla_caps[2];
|
||||||
std::string m_sidebar_field;
|
std::string m_sidebar_field;
|
||||||
// when true renders an extra frame by not resetting m_dirty to false
|
// when true renders an extra frame by not resetting m_dirty to false
|
||||||
// see request_extra_frame()
|
// see request_extra_frame()
|
||||||
|
@ -463,7 +463,7 @@ private:
|
||||||
int m_extra_frame_requested_delayed { std::numeric_limits<int>::max() };
|
int m_extra_frame_requested_delayed { std::numeric_limits<int>::max() };
|
||||||
bool m_event_handlers_bound{ false };
|
bool m_event_handlers_bound{ false };
|
||||||
|
|
||||||
mutable GLVolumeCollection m_volumes;
|
GLVolumeCollection m_volumes;
|
||||||
GCodeViewer m_gcode_viewer;
|
GCodeViewer m_gcode_viewer;
|
||||||
|
|
||||||
RenderTimer m_render_timer;
|
RenderTimer m_render_timer;
|
||||||
|
@ -478,7 +478,6 @@ private:
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
bool m_apply_zoom_to_volumes_filter;
|
bool m_apply_zoom_to_volumes_filter;
|
||||||
mutable std::vector<int> m_hover_volume_idxs;
|
|
||||||
bool m_picking_enabled;
|
bool m_picking_enabled;
|
||||||
bool m_moving_enabled;
|
bool m_moving_enabled;
|
||||||
bool m_dynamic_background_enabled;
|
bool m_dynamic_background_enabled;
|
||||||
|
@ -487,6 +486,7 @@ private:
|
||||||
bool m_tab_down;
|
bool m_tab_down;
|
||||||
ECursorType m_cursor_type;
|
ECursorType m_cursor_type;
|
||||||
GLSelectionRectangle m_rectangle_selection;
|
GLSelectionRectangle m_rectangle_selection;
|
||||||
|
std::vector<int> m_hover_volume_idxs;
|
||||||
|
|
||||||
// Following variable is obsolete and it should be safe to remove it.
|
// Following variable is obsolete and it should be safe to remove it.
|
||||||
// I just don't want to do it now before a release (Lukas Matena 24.3.2019)
|
// I just don't want to do it now before a release (Lukas Matena 24.3.2019)
|
||||||
|
@ -504,13 +504,13 @@ private:
|
||||||
RenderStats m_render_stats;
|
RenderStats m_render_stats;
|
||||||
#endif // ENABLE_RENDER_STATISTICS
|
#endif // ENABLE_RENDER_STATISTICS
|
||||||
|
|
||||||
mutable int m_imgui_undo_redo_hovered_pos{ -1 };
|
int m_imgui_undo_redo_hovered_pos{ -1 };
|
||||||
mutable int m_mouse_wheel {0};
|
int m_mouse_wheel{ 0 };
|
||||||
int m_selected_extruder;
|
int m_selected_extruder;
|
||||||
|
|
||||||
Labels m_labels;
|
Labels m_labels;
|
||||||
mutable Tooltip m_tooltip;
|
Tooltip m_tooltip;
|
||||||
mutable bool m_tooltip_enabled{ true };
|
bool m_tooltip_enabled{ true };
|
||||||
Slope m_slope;
|
Slope m_slope;
|
||||||
|
|
||||||
ArrangeSettings m_arrange_settings_fff, m_arrange_settings_sla,
|
ArrangeSettings m_arrange_settings_fff, m_arrange_settings_sla,
|
||||||
|
@ -519,8 +519,7 @@ private:
|
||||||
PrinterTechnology current_printer_technology() const;
|
PrinterTechnology current_printer_technology() const;
|
||||||
|
|
||||||
template<class Self>
|
template<class Self>
|
||||||
static auto & get_arrange_settings(Self *self)
|
static auto & get_arrange_settings(Self *self) {
|
||||||
{
|
|
||||||
PrinterTechnology ptech = self->current_printer_technology();
|
PrinterTechnology ptech = self->current_printer_technology();
|
||||||
|
|
||||||
auto *ptr = &self->m_arrange_settings_fff;
|
auto *ptr = &self->m_arrange_settings_fff;
|
||||||
|
@ -529,12 +528,11 @@ private:
|
||||||
ptr = &self->m_arrange_settings_sla;
|
ptr = &self->m_arrange_settings_sla;
|
||||||
} else if (ptech == ptFFF) {
|
} else if (ptech == ptFFF) {
|
||||||
auto co_opt = self->m_config->template option<ConfigOptionBool>("complete_objects");
|
auto co_opt = self->m_config->template option<ConfigOptionBool>("complete_objects");
|
||||||
if (co_opt && co_opt->value) {
|
if (co_opt && co_opt->value)
|
||||||
ptr = &self->m_arrange_settings_fff_seq_print;
|
ptr = &self->m_arrange_settings_fff_seq_print;
|
||||||
} else {
|
else
|
||||||
ptr = &self->m_arrange_settings_fff;
|
ptr = &self->m_arrange_settings_fff;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
@ -715,10 +713,9 @@ public:
|
||||||
double m_rotation = 0.;
|
double m_rotation = 0.;
|
||||||
BoundingBoxf m_bb;
|
BoundingBoxf m_bb;
|
||||||
friend class GLCanvas3D;
|
friend class GLCanvas3D;
|
||||||
public:
|
|
||||||
|
|
||||||
inline operator bool() const
|
public:
|
||||||
{
|
inline operator bool() const {
|
||||||
return !std::isnan(m_pos.x()) && !std::isnan(m_pos.y());
|
return !std::isnan(m_pos.x()) && !std::isnan(m_pos.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,8 +760,7 @@ public:
|
||||||
void use_slope(bool use) { m_slope.use(use); }
|
void use_slope(bool use) { m_slope.use(use); }
|
||||||
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }
|
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }
|
||||||
|
|
||||||
ArrangeSettings get_arrange_settings() const
|
ArrangeSettings get_arrange_settings() const {
|
||||||
{
|
|
||||||
const ArrangeSettings &settings = get_arrange_settings(this);
|
const ArrangeSettings &settings = get_arrange_settings(this);
|
||||||
ArrangeSettings ret = settings;
|
ArrangeSettings ret = settings;
|
||||||
if (&settings == &m_arrange_settings_fff_seq_print) {
|
if (&settings == &m_arrange_settings_fff_seq_print) {
|
||||||
|
|
|
@ -428,8 +428,7 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
||||||
bool processed = false;
|
bool processed = false;
|
||||||
|
|
||||||
// mouse anywhere
|
// mouse anywhere
|
||||||
if (!evt.Dragging() && !evt.Leaving() && !evt.Entering() && (m_mouse_capture.parent != nullptr))
|
if (!evt.Dragging() && !evt.Leaving() && !evt.Entering() && m_mouse_capture.parent != nullptr) {
|
||||||
{
|
|
||||||
if (m_mouse_capture.any() && (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())) {
|
if (m_mouse_capture.any() && (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())) {
|
||||||
// prevents loosing selection into the scene if mouse down was done inside the toolbar and mouse up was down outside it,
|
// prevents loosing selection into the scene if mouse down was done inside the toolbar and mouse up was down outside it,
|
||||||
// as when switching between views
|
// as when switching between views
|
||||||
|
@ -441,38 +440,31 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
||||||
|
|
||||||
if (evt.Moving())
|
if (evt.Moving())
|
||||||
update_hover_state(mouse_pos, parent);
|
update_hover_state(mouse_pos, parent);
|
||||||
else if (evt.LeftUp())
|
else if (evt.LeftUp()) {
|
||||||
{
|
if (m_mouse_capture.left) {
|
||||||
if (m_mouse_capture.left)
|
|
||||||
{
|
|
||||||
processed = true;
|
processed = true;
|
||||||
m_mouse_capture.left = false;
|
m_mouse_capture.left = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (evt.MiddleUp())
|
else if (evt.MiddleUp()) {
|
||||||
{
|
if (m_mouse_capture.middle) {
|
||||||
if (m_mouse_capture.middle)
|
|
||||||
{
|
|
||||||
processed = true;
|
processed = true;
|
||||||
m_mouse_capture.middle = false;
|
m_mouse_capture.middle = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (evt.RightUp())
|
else if (evt.RightUp()) {
|
||||||
{
|
if (m_mouse_capture.right) {
|
||||||
if (m_mouse_capture.right)
|
|
||||||
{
|
|
||||||
processed = true;
|
processed = true;
|
||||||
m_mouse_capture.right = false;
|
m_mouse_capture.right = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (evt.Dragging())
|
else if (evt.Dragging()) {
|
||||||
{
|
|
||||||
if (m_mouse_capture.any())
|
if (m_mouse_capture.any())
|
||||||
// if the button down was done on this toolbar, prevent from dragging into the scene
|
// if the button down was done on this toolbar, prevent from dragging into the scene
|
||||||
processed = true;
|
processed = true;
|
||||||
|
@ -481,35 +473,29 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
int item_id = contains_mouse(mouse_pos, parent);
|
int item_id = contains_mouse(mouse_pos, parent);
|
||||||
if (item_id != -1)
|
if (item_id != -1) {
|
||||||
{
|
|
||||||
// mouse inside toolbar
|
// mouse inside toolbar
|
||||||
if (evt.LeftDown() || evt.LeftDClick())
|
if (evt.LeftDown() || evt.LeftDClick()) {
|
||||||
{
|
|
||||||
m_mouse_capture.left = true;
|
m_mouse_capture.left = true;
|
||||||
m_mouse_capture.parent = &parent;
|
m_mouse_capture.parent = &parent;
|
||||||
processed = true;
|
processed = true;
|
||||||
if ((item_id != -2) && !m_items[item_id]->is_separator() && !m_items[item_id]->is_disabled() &&
|
if (item_id != -2 && !m_items[item_id]->is_separator() && !m_items[item_id]->is_disabled() &&
|
||||||
((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Left)))
|
(m_pressed_toggable_id == -1 || m_items[item_id]->get_last_action_type() == GLToolbarItem::Left)) {
|
||||||
{
|
|
||||||
// mouse is inside an icon
|
// mouse is inside an icon
|
||||||
do_action(GLToolbarItem::Left, item_id, parent, true);
|
do_action(GLToolbarItem::Left, item_id, parent, true);
|
||||||
parent.set_as_dirty();
|
parent.set_as_dirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (evt.MiddleDown())
|
else if (evt.MiddleDown()) {
|
||||||
{
|
|
||||||
m_mouse_capture.middle = true;
|
m_mouse_capture.middle = true;
|
||||||
m_mouse_capture.parent = &parent;
|
m_mouse_capture.parent = &parent;
|
||||||
}
|
}
|
||||||
else if (evt.RightDown())
|
else if (evt.RightDown()) {
|
||||||
{
|
|
||||||
m_mouse_capture.right = true;
|
m_mouse_capture.right = true;
|
||||||
m_mouse_capture.parent = &parent;
|
m_mouse_capture.parent = &parent;
|
||||||
processed = true;
|
processed = true;
|
||||||
if ((item_id != -2) && !m_items[item_id]->is_separator() && !m_items[item_id]->is_disabled() &&
|
if (item_id != -2 && !m_items[item_id]->is_separator() && !m_items[item_id]->is_disabled() &&
|
||||||
((m_pressed_toggable_id == -1) || (m_items[item_id]->get_last_action_type() == GLToolbarItem::Right)))
|
(m_pressed_toggable_id == -1 || m_items[item_id]->get_last_action_type() == GLToolbarItem::Right)) {
|
||||||
{
|
|
||||||
// mouse is inside an icon
|
// mouse is inside an icon
|
||||||
do_action(GLToolbarItem::Right, item_id, parent, true);
|
do_action(GLToolbarItem::Right, item_id, parent, true);
|
||||||
parent.set_as_dirty();
|
parent.set_as_dirty();
|
||||||
|
@ -522,24 +508,26 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
|
||||||
|
|
||||||
void GLToolbar::calc_layout() const
|
void GLToolbar::calc_layout() const
|
||||||
{
|
{
|
||||||
switch (m_layout.type)
|
Layout* layout = const_cast<Layout*>(&m_layout);
|
||||||
|
|
||||||
|
switch (layout->type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case Layout::Horizontal:
|
case Layout::Horizontal:
|
||||||
{
|
{
|
||||||
m_layout.width = get_width_horizontal();
|
layout->width = get_width_horizontal();
|
||||||
m_layout.height = get_height_horizontal();
|
layout->height = get_height_horizontal();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Layout::Vertical:
|
case Layout::Vertical:
|
||||||
{
|
{
|
||||||
m_layout.width = get_width_vertical();
|
layout->width = get_width_vertical();
|
||||||
m_layout.height = get_height_vertical();
|
layout->height = get_height_vertical();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_layout.dirty = false;
|
layout->dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GLToolbar::get_width_horizontal() const
|
float GLToolbar::get_width_horizontal() const
|
||||||
|
@ -1196,19 +1184,17 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const
|
||||||
left += scaled_border;
|
left += scaled_border;
|
||||||
top -= scaled_border;
|
top -= scaled_border;
|
||||||
|
|
||||||
if ((tex_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
if (tex_id == 0 || tex_width <= 0 || tex_height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// renders icons
|
// renders icons
|
||||||
for (const GLToolbarItem* item : m_items)
|
for (const GLToolbarItem* item : m_items) {
|
||||||
{
|
|
||||||
if (!item->is_visible())
|
if (!item->is_visible())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (item->is_separator())
|
if (item->is_separator())
|
||||||
top -= separator_stride;
|
top -= separator_stride;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
|
||||||
top -= icon_stride;
|
top -= icon_stride;
|
||||||
}
|
}
|
||||||
|
@ -1219,16 +1205,14 @@ bool GLToolbar::generate_icons_texture() const
|
||||||
{
|
{
|
||||||
std::string path = resources_dir() + "/icons/";
|
std::string path = resources_dir() + "/icons/";
|
||||||
std::vector<std::string> filenames;
|
std::vector<std::string> filenames;
|
||||||
for (GLToolbarItem* item : m_items)
|
for (GLToolbarItem* item : m_items) {
|
||||||
{
|
|
||||||
const std::string& icon_filename = item->get_icon_filename();
|
const std::string& icon_filename = item->get_icon_filename();
|
||||||
if (!icon_filename.empty())
|
if (!icon_filename.empty())
|
||||||
filenames.push_back(path + icon_filename);
|
filenames.push_back(path + icon_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<int, bool>> states;
|
std::vector<std::pair<int, bool>> states;
|
||||||
if (m_type == Normal)
|
if (m_type == Normal) {
|
||||||
{
|
|
||||||
states.push_back({ 1, false }); // Normal
|
states.push_back({ 1, false }); // Normal
|
||||||
states.push_back({ 0, false }); // Pressed
|
states.push_back({ 0, false }); // Pressed
|
||||||
states.push_back({ 2, false }); // Disabled
|
states.push_back({ 2, false }); // Disabled
|
||||||
|
@ -1236,8 +1220,7 @@ bool GLToolbar::generate_icons_texture() const
|
||||||
states.push_back({ 0, false }); // HoverPressed
|
states.push_back({ 0, false }); // HoverPressed
|
||||||
states.push_back({ 2, false }); // HoverDisabled
|
states.push_back({ 2, false }); // HoverDisabled
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
states.push_back({ 1, false }); // Normal
|
states.push_back({ 1, false }); // Normal
|
||||||
states.push_back({ 1, true }); // Pressed
|
states.push_back({ 1, true }); // Pressed
|
||||||
states.push_back({ 1, false }); // Disabled
|
states.push_back({ 1, false }); // Disabled
|
||||||
|
@ -1251,9 +1234,9 @@ bool GLToolbar::generate_icons_texture() const
|
||||||
// if (sprite_size_px % 2 != 0)
|
// if (sprite_size_px % 2 != 0)
|
||||||
// sprite_size_px += 1;
|
// sprite_size_px += 1;
|
||||||
|
|
||||||
bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, sprite_size_px, false);
|
bool res = const_cast<GLTexture*>(&m_icons_texture)->load_from_svg_files_as_sprites_array(filenames, states, sprite_size_px, false);
|
||||||
if (res)
|
if (res)
|
||||||
m_icons_texture_dirty = false;
|
*const_cast<bool*>(&m_icons_texture_dirty) = false;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1262,8 +1245,7 @@ bool GLToolbar::update_items_visibility()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
for (GLToolbarItem* item : m_items)
|
for (GLToolbarItem* item : m_items) {
|
||||||
{
|
|
||||||
ret |= item->update_visibility();
|
ret |= item->update_visibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1272,12 +1254,10 @@ bool GLToolbar::update_items_visibility()
|
||||||
|
|
||||||
// updates separators visibility to avoid having two of them consecutive
|
// updates separators visibility to avoid having two of them consecutive
|
||||||
bool any_item_visible = false;
|
bool any_item_visible = false;
|
||||||
for (GLToolbarItem* item : m_items)
|
for (GLToolbarItem* item : m_items) {
|
||||||
{
|
|
||||||
if (!item->is_separator())
|
if (!item->is_separator())
|
||||||
any_item_visible |= item->is_visible();
|
any_item_visible |= item->is_visible();
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
item->set_visible(any_item_visible);
|
item->set_visible(any_item_visible);
|
||||||
any_item_visible = false;
|
any_item_visible = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,10 +233,10 @@ private:
|
||||||
EType m_type;
|
EType m_type;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
mutable GLTexture m_icons_texture;
|
GLTexture m_icons_texture;
|
||||||
mutable bool m_icons_texture_dirty;
|
bool m_icons_texture_dirty;
|
||||||
BackgroundTexture m_background_texture;
|
BackgroundTexture m_background_texture;
|
||||||
mutable Layout m_layout;
|
Layout m_layout;
|
||||||
|
|
||||||
ItemsList m_items;
|
ItemsList m_items;
|
||||||
|
|
||||||
|
|
|
@ -1525,14 +1525,20 @@ void ObjectList::del_subobject_item(wxDataViewItem& item)
|
||||||
if (type == itUndef)
|
if (type == itUndef)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wxDataViewItem parent = m_objects_model->GetParent(item);
|
||||||
|
|
||||||
if (type & itSettings)
|
if (type & itSettings)
|
||||||
del_settings_from_config(m_objects_model->GetParent(item));
|
del_settings_from_config(parent);
|
||||||
else if (type & itInstanceRoot && obj_idx != -1)
|
else if (type & itInstanceRoot && obj_idx != -1)
|
||||||
del_instances_from_object(obj_idx);
|
del_instances_from_object(obj_idx);
|
||||||
else if (type & itLayerRoot && obj_idx != -1)
|
else if (type & itLayerRoot && obj_idx != -1)
|
||||||
del_layers_from_object(obj_idx);
|
del_layers_from_object(obj_idx);
|
||||||
else if (type & itLayer && obj_idx != -1)
|
else if (type & itLayer && obj_idx != -1)
|
||||||
del_layer_from_object(obj_idx, m_objects_model->GetLayerRangeByItem(item));
|
del_layer_from_object(obj_idx, m_objects_model->GetLayerRangeByItem(item));
|
||||||
|
else if (type & itInfo && obj_idx != -1) {
|
||||||
|
Unselect(item);
|
||||||
|
Select(parent);
|
||||||
|
}
|
||||||
else if (idx == -1)
|
else if (idx == -1)
|
||||||
return;
|
return;
|
||||||
else if (!del_subobject_from_object(obj_idx, idx, type))
|
else if (!del_subobject_from_object(obj_idx, idx, type))
|
||||||
|
@ -1540,9 +1546,10 @@ void ObjectList::del_subobject_item(wxDataViewItem& item)
|
||||||
|
|
||||||
// If last volume item with warning was deleted, unmark object item
|
// If last volume item with warning was deleted, unmark object item
|
||||||
if (type & itVolume && (*m_objects)[obj_idx]->get_mesh_errors_count() == 0)
|
if (type & itVolume && (*m_objects)[obj_idx]->get_mesh_errors_count() == 0)
|
||||||
m_objects_model->DeleteWarningIcon(m_objects_model->GetParent(item));
|
m_objects_model->DeleteWarningIcon(parent);
|
||||||
|
|
||||||
m_objects_model->Delete(item);
|
m_objects_model->Delete(item);
|
||||||
|
update_info_items(obj_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item)
|
void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item)
|
||||||
|
@ -2118,20 +2125,32 @@ void ObjectList::part_selection_changed()
|
||||||
{
|
{
|
||||||
if (item)
|
if (item)
|
||||||
{
|
{
|
||||||
if (m_objects_model->GetParent(item) == wxDataViewItem(nullptr)) {
|
const ItemType type = m_objects_model->GetItemType(item);
|
||||||
obj_idx = m_objects_model->GetIdByItem(item);
|
const wxDataViewItem parent = m_objects_model->GetParent(item);
|
||||||
|
const ItemType parent_type = m_objects_model->GetItemType(parent);
|
||||||
|
obj_idx = m_objects_model->GetObjectIdByItem(item);
|
||||||
|
|
||||||
|
if (parent == wxDataViewItem(nullptr)
|
||||||
|
|| type == itInfo) {
|
||||||
og_name = _(L("Object manipulation"));
|
og_name = _(L("Object manipulation"));
|
||||||
m_config = &(*m_objects)[obj_idx]->config;
|
m_config = &(*m_objects)[obj_idx]->config;
|
||||||
update_and_show_manipulations = true;
|
update_and_show_manipulations = true;
|
||||||
|
|
||||||
|
if (type == itInfo) {
|
||||||
|
InfoItemType info_type = m_objects_model->GetInfoItemType(item);
|
||||||
|
if (info_type != InfoItemType::VariableLayerHeight) {
|
||||||
|
GLGizmosManager::EType gizmo_type =
|
||||||
|
info_type == InfoItemType::CustomSupports ? GLGizmosManager::EType::FdmSupports
|
||||||
|
: GLGizmosManager::EType::Seam;
|
||||||
|
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->canvas3D()->get_gizmos_manager();
|
||||||
|
if (gizmos_mgr.get_current_type() != gizmo_type)
|
||||||
|
gizmos_mgr.open_gizmo(gizmo_type);
|
||||||
|
} else
|
||||||
|
wxGetApp().plater()->toggle_layers_editing(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
obj_idx = m_objects_model->GetObjectIdByItem(item);
|
|
||||||
|
|
||||||
const ItemType type = m_objects_model->GetItemType(item);
|
|
||||||
if (type & itSettings) {
|
if (type & itSettings) {
|
||||||
const auto parent = m_objects_model->GetParent(item);
|
|
||||||
const ItemType parent_type = m_objects_model->GetItemType(parent);
|
|
||||||
|
|
||||||
if (parent_type & itObject) {
|
if (parent_type & itObject) {
|
||||||
og_name = _(L("Object Settings to modify"));
|
og_name = _(L("Object Settings to modify"));
|
||||||
m_config = &(*m_objects)[obj_idx]->config;
|
m_config = &(*m_objects)[obj_idx]->config;
|
||||||
|
@ -2243,6 +2262,52 @@ wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const D
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ObjectList::update_info_items(size_t obj_idx)
|
||||||
|
{
|
||||||
|
const ModelObject* model_object = (*m_objects)[obj_idx];
|
||||||
|
wxDataViewItem item_obj = m_objects_model->GetItemById(obj_idx);
|
||||||
|
assert(item_obj.IsOk());
|
||||||
|
|
||||||
|
for (InfoItemType type : {InfoItemType::CustomSupports,
|
||||||
|
InfoItemType::CustomSeam,
|
||||||
|
InfoItemType::VariableLayerHeight}) {
|
||||||
|
wxDataViewItem item = m_objects_model->GetInfoItemByType(item_obj, type);
|
||||||
|
bool shows = item.IsOk();
|
||||||
|
bool should_show = false;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case InfoItemType::CustomSupports :
|
||||||
|
case InfoItemType::CustomSeam :
|
||||||
|
should_show = printer_technology() == ptFFF
|
||||||
|
&& std::any_of(model_object->volumes.begin(), model_object->volumes.end(),
|
||||||
|
[type](const ModelVolume* mv) {
|
||||||
|
return ! (type == InfoItemType::CustomSupports
|
||||||
|
? mv->supported_facets.empty()
|
||||||
|
: mv->seam_facets.empty());
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InfoItemType::VariableLayerHeight :
|
||||||
|
should_show = printer_technology() == ptFFF
|
||||||
|
&& ! model_object->layer_height_profile.empty();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! shows && should_show) {
|
||||||
|
m_objects_model->AddInfoChild(item_obj, type);
|
||||||
|
Expand(item_obj);
|
||||||
|
}
|
||||||
|
else if (shows && ! should_show) {
|
||||||
|
Unselect(item);
|
||||||
|
m_objects_model->Delete(item);
|
||||||
|
Select(item_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed)
|
void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed)
|
||||||
{
|
{
|
||||||
auto model_object = (*m_objects)[obj_idx];
|
auto model_object = (*m_objects)[obj_idx];
|
||||||
|
@ -2251,6 +2316,8 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed)
|
||||||
model_object->config.has("extruder") ? model_object->config.extruder() : 0,
|
model_object->config.has("extruder") ? model_object->config.extruder() : 0,
|
||||||
get_mesh_errors_count(obj_idx) > 0);
|
get_mesh_errors_count(obj_idx) > 0);
|
||||||
|
|
||||||
|
update_info_items(obj_idx);
|
||||||
|
|
||||||
// add volumes to the object
|
// add volumes to the object
|
||||||
if (model_object->volumes.size() > 1) {
|
if (model_object->volumes.size() > 1) {
|
||||||
for (const ModelVolume* volume : model_object->volumes) {
|
for (const ModelVolume* volume : model_object->volumes) {
|
||||||
|
@ -3029,7 +3096,7 @@ void ObjectList::update_selections_on_canvas()
|
||||||
|
|
||||||
if (sel_cnt == 1) {
|
if (sel_cnt == 1) {
|
||||||
wxDataViewItem item = GetSelection();
|
wxDataViewItem item = GetSelection();
|
||||||
if (m_objects_model->GetItemType(item) & (itSettings | itInstanceRoot | itLayerRoot | itLayer))
|
if (m_objects_model->GetItemType(item) & (itSettings | itInstanceRoot | itLayerRoot | itLayer | itInfo))
|
||||||
add_to_selection(m_objects_model->GetParent(item), selection, instance_idx, mode);
|
add_to_selection(m_objects_model->GetParent(item), selection, instance_idx, mode);
|
||||||
else
|
else
|
||||||
add_to_selection(item, selection, instance_idx, mode);
|
add_to_selection(item, selection, instance_idx, mode);
|
||||||
|
@ -3442,6 +3509,9 @@ void ObjectList::update_object_list_by_printer_technology()
|
||||||
m_objects_model->GetChildren(wxDataViewItem(nullptr), object_items);
|
m_objects_model->GetChildren(wxDataViewItem(nullptr), object_items);
|
||||||
|
|
||||||
for (auto& object_item : object_items) {
|
for (auto& object_item : object_items) {
|
||||||
|
// update custom supports info
|
||||||
|
update_info_items(m_objects_model->GetObjectIdByItem(object_item));
|
||||||
|
|
||||||
// Update Settings Item for object
|
// Update Settings Item for object
|
||||||
update_settings_item_and_selection(object_item, sel);
|
update_settings_item_and_selection(object_item, sel);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
class wxBoxSizer;
|
class wxBoxSizer;
|
||||||
class wxBitmapComboBox;
|
class wxBitmapComboBox;
|
||||||
class wxMenuItem;
|
class wxMenuItem;
|
||||||
class ObjectDataViewModel;
|
|
||||||
class MenuWithSeparators;
|
class MenuWithSeparators;
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
@ -347,6 +346,7 @@ public:
|
||||||
void update_and_show_object_settings_item();
|
void update_and_show_object_settings_item();
|
||||||
void update_settings_item_and_selection(wxDataViewItem item, wxDataViewItemArray& selections);
|
void update_settings_item_and_selection(wxDataViewItem item, wxDataViewItemArray& selections);
|
||||||
void update_object_list_by_printer_technology();
|
void update_object_list_by_printer_technology();
|
||||||
|
void update_info_items(size_t obj_idx);
|
||||||
|
|
||||||
void instances_to_separated_object(const int obj_idx, const std::set<int>& inst_idx);
|
void instances_to_separated_object(const int obj_idx, const std::set<int>& inst_idx);
|
||||||
void instances_to_separated_objects(const int obj_idx);
|
void instances_to_separated_objects(const int obj_idx);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
@ -316,8 +317,12 @@ void GLGizmoFdmSupports::update_model_object() const
|
||||||
updated |= mv->supported_facets.set(*m_triangle_selectors[idx].get());
|
updated |= mv->supported_facets.set(*m_triangle_selectors[idx].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated)
|
if (updated) {
|
||||||
|
const ModelObjectPtrs& mos = wxGetApp().model().objects;
|
||||||
|
wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin());
|
||||||
|
|
||||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
@ -222,8 +222,12 @@ void GLGizmoSeam::update_model_object() const
|
||||||
updated |= mv->seam_facets.set(*m_triangle_selectors[idx].get());
|
updated |= mv->seam_facets.set(*m_triangle_selectors[idx].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated)
|
if (updated) {
|
||||||
|
const ModelObjectPtrs& mos = wxGetApp().model().objects;
|
||||||
|
wxGetApp().obj_list()->update_info_items(std::find(mos.begin(), mos.end(), mo) - mos.begin());
|
||||||
|
|
||||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,17 @@ void GLGizmosManager::reset_all_states()
|
||||||
m_hover = Undefined;
|
m_hover = Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLGizmosManager::open_gizmo(EType type)
|
||||||
|
{
|
||||||
|
int idx = int(type);
|
||||||
|
if (m_gizmos[idx]->is_selectable() && m_gizmos[idx]->is_activable()) {
|
||||||
|
activate_gizmo(m_current == idx ? Undefined : (EType)idx);
|
||||||
|
update_data();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmosManager::set_hover_id(int id)
|
void GLGizmosManager::set_hover_id(int id)
|
||||||
{
|
{
|
||||||
if (!m_enabled || m_current == Undefined)
|
if (!m_enabled || m_current == Undefined)
|
||||||
|
@ -266,24 +277,21 @@ bool GLGizmosManager::is_running() const
|
||||||
|
|
||||||
bool GLGizmosManager::handle_shortcut(int key)
|
bool GLGizmosManager::handle_shortcut(int key)
|
||||||
{
|
{
|
||||||
if (!m_enabled)
|
if (!m_enabled || m_parent.get_selection().is_empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_parent.get_selection().is_empty())
|
auto it = std::find_if(m_gizmos.begin(), m_gizmos.end(),
|
||||||
|
[key](const std::unique_ptr<GLGizmoBase>& gizmo) {
|
||||||
|
int gizmo_key = gizmo->get_shortcut_key();
|
||||||
|
return gizmo->is_selectable()
|
||||||
|
&& ((gizmo_key == key - 64) || (gizmo_key == key - 96));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it == m_gizmos.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool handled = false;
|
EType gizmo_type = EType(it - m_gizmos.begin());
|
||||||
|
return open_gizmo(gizmo_type);
|
||||||
for (size_t idx : get_selectable_idxs()) {
|
|
||||||
int it_key = m_gizmos[idx]->get_shortcut_key();
|
|
||||||
|
|
||||||
if (m_gizmos[idx]->is_activable() && ((it_key == key - 64) || (it_key == key - 96))) {
|
|
||||||
activate_gizmo(m_current == idx ? Undefined : (EType)idx);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmosManager::is_dragging() const
|
bool GLGizmosManager::is_dragging() const
|
||||||
|
@ -814,11 +822,8 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt)
|
||||||
if (!processed && !evt.HasModifiers())
|
if (!processed && !evt.HasModifiers())
|
||||||
{
|
{
|
||||||
if (handle_shortcut(keyCode))
|
if (handle_shortcut(keyCode))
|
||||||
{
|
|
||||||
update_data();
|
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (processed)
|
if (processed)
|
||||||
m_parent.set_as_dirty();
|
m_parent.set_as_dirty();
|
||||||
|
@ -1156,5 +1161,11 @@ bool GLGizmosManager::is_in_editing_mode(bool error_notification) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GLGizmosManager::get_shortcut_key(GLGizmosManager::EType type) const
|
||||||
|
{
|
||||||
|
return m_gizmos[type]->get_shortcut_key();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -171,6 +171,7 @@ public:
|
||||||
void refresh_on_off_state();
|
void refresh_on_off_state();
|
||||||
void reset_all_states();
|
void reset_all_states();
|
||||||
bool is_serializing() const { return m_serializing; }
|
bool is_serializing() const { return m_serializing; }
|
||||||
|
bool open_gizmo(EType type);
|
||||||
|
|
||||||
void set_hover_id(int id);
|
void set_hover_id(int id);
|
||||||
void enable_grabber(EType type, unsigned int id, bool enable);
|
void enable_grabber(EType type, unsigned int id, bool enable);
|
||||||
|
@ -228,6 +229,7 @@ public:
|
||||||
void update_after_undo_redo(const UndoRedo::Snapshot& snapshot);
|
void update_after_undo_redo(const UndoRedo::Snapshot& snapshot);
|
||||||
|
|
||||||
int get_selectable_icons_cnt() const { return get_selectable_idxs().size(); }
|
int get_selectable_icons_cnt() const { return get_selectable_idxs().size(); }
|
||||||
|
int get_shortcut_key(GLGizmosManager::EType) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void render_background(float left, float top, float right, float bottom, float border) const;
|
void render_background(float left, float top, float right, float bottom, float border) const;
|
||||||
|
|
|
@ -522,8 +522,10 @@ void MainFrame::init_tabpanel()
|
||||||
#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
|
#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
|
||||||
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||||
#endif
|
#endif
|
||||||
|
#if wxCHECK_VERSION(3,1,3)
|
||||||
if (wxSystemSettings::GetAppearance().IsDark())
|
if (wxSystemSettings::GetAppearance().IsDark())
|
||||||
m_tabpanel->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
m_tabpanel->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||||
|
#endif
|
||||||
m_tabpanel->Hide();
|
m_tabpanel->Hide();
|
||||||
m_settings_dialog.set_tabpanel(m_tabpanel);
|
m_settings_dialog.set_tabpanel(m_tabpanel);
|
||||||
|
|
||||||
|
|
|
@ -169,13 +169,16 @@ void NotificationManager::PopNotification::render(GLCanvas3D& canvas, float init
|
||||||
imgui.set_next_window_pos(win_pos.x, win_pos.y, ImGuiCond_Always, 1.0f, 0.0f);
|
imgui.set_next_window_pos(win_pos.x, win_pos.y, ImGuiCond_Always, 1.0f, 0.0f);
|
||||||
imgui.set_next_window_size(m_window_width, m_window_height, ImGuiCond_Always);
|
imgui.set_next_window_size(m_window_width, m_window_height, ImGuiCond_Always);
|
||||||
|
|
||||||
// find if hovered
|
|
||||||
if (m_state == EState::Hovered)
|
// find if hovered FIXME: do it only in update state?
|
||||||
m_state = EState::Shown;
|
if (m_state == EState::Hovered) {
|
||||||
|
m_state = EState::Unknown;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
if (mouse_pos.x < win_pos.x && mouse_pos.x > win_pos.x - m_window_width && mouse_pos.y > win_pos.y && mouse_pos.y < win_pos.y + m_window_height) {
|
if (mouse_pos.x < win_pos.x && mouse_pos.x > win_pos.x - m_window_width && mouse_pos.y > win_pos.y && mouse_pos.y < win_pos.y + m_window_height) {
|
||||||
ImGui::SetNextWindowFocus();
|
ImGui::SetNextWindowFocus();
|
||||||
m_state = EState::Hovered;
|
set_hovered();
|
||||||
}
|
}
|
||||||
|
|
||||||
// color change based on fading out
|
// color change based on fading out
|
||||||
|
@ -185,22 +188,8 @@ void NotificationManager::PopNotification::render(GLCanvas3D& canvas, float init
|
||||||
fading_pop = true;
|
fading_pop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// background color
|
bool bgrnd_color_pop = push_background_color();
|
||||||
if (m_is_gray) {
|
|
||||||
ImVec4 backcolor(0.7f, 0.7f, 0.7f, 0.5f);
|
|
||||||
Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
|
||||||
}
|
|
||||||
else if (m_data.level == NotificationLevel::ErrorNotification) {
|
|
||||||
ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
|
|
||||||
backcolor.x += 0.3f;
|
|
||||||
Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
|
||||||
}
|
|
||||||
else if (m_data.level == NotificationLevel::WarningNotification) {
|
|
||||||
ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
|
|
||||||
backcolor.x += 0.3f;
|
|
||||||
backcolor.y += 0.15f;
|
|
||||||
Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// name of window indentifies window - has to be unique string
|
// name of window indentifies window - has to be unique string
|
||||||
if (m_id == 0)
|
if (m_id == 0)
|
||||||
|
@ -219,13 +208,34 @@ void NotificationManager::PopNotification::render(GLCanvas3D& canvas, float init
|
||||||
}
|
}
|
||||||
imgui.end();
|
imgui.end();
|
||||||
|
|
||||||
if (m_is_gray || m_data.level == NotificationLevel::ErrorNotification || m_data.level == NotificationLevel::WarningNotification)
|
if (bgrnd_color_pop)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
if (fading_pop)
|
if (fading_pop)
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
}
|
}
|
||||||
|
bool NotificationManager::PopNotification::push_background_color()
|
||||||
|
{
|
||||||
|
if (m_is_gray) {
|
||||||
|
ImVec4 backcolor(0.7f, 0.7f, 0.7f, 0.5f);
|
||||||
|
Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (m_data.level == NotificationLevel::ErrorNotification) {
|
||||||
|
ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
|
||||||
|
backcolor.x += 0.3f;
|
||||||
|
Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (m_data.level == NotificationLevel::WarningNotification) {
|
||||||
|
ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
|
||||||
|
backcolor.x += 0.3f;
|
||||||
|
backcolor.y += 0.15f;
|
||||||
|
Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void NotificationManager::PopNotification::count_spaces()
|
void NotificationManager::PopNotification::count_spaces()
|
||||||
{
|
{
|
||||||
//determine line width
|
//determine line width
|
||||||
|
@ -242,19 +252,12 @@ void NotificationManager::PopNotification::count_spaces()
|
||||||
m_window_width = m_line_height * 25;
|
m_window_width = m_line_height * 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::PopNotification::init()
|
void NotificationManager::PopNotification::count_lines()
|
||||||
{
|
{
|
||||||
// Do not init closing notification
|
|
||||||
if (is_finished())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string text = m_text1 + " " + m_hypertext;
|
std::string text = m_text1 + " " + m_hypertext;
|
||||||
size_t last_end = 0;
|
size_t last_end = 0;
|
||||||
m_lines_count = 0;
|
m_lines_count = 0;
|
||||||
|
|
||||||
count_spaces();
|
|
||||||
|
|
||||||
// count lines
|
|
||||||
m_endlines.clear();
|
m_endlines.clear();
|
||||||
while (last_end < text.length() - 1)
|
while (last_end < text.length() - 1)
|
||||||
{
|
{
|
||||||
|
@ -263,7 +266,8 @@ void NotificationManager::PopNotification::init()
|
||||||
//next line is ended by '/n'
|
//next line is ended by '/n'
|
||||||
m_endlines.push_back(next_hard_end);
|
m_endlines.push_back(next_hard_end);
|
||||||
last_end = next_hard_end + 1;
|
last_end = next_hard_end + 1;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// find next suitable endline
|
// find next suitable endline
|
||||||
if (ImGui::CalcTextSize(text.substr(last_end).c_str()).x >= m_window_width - m_window_width_offset) {
|
if (ImGui::CalcTextSize(text.substr(last_end).c_str()).x >= m_window_width - m_window_width_offset) {
|
||||||
// more than one line till end
|
// more than one line till end
|
||||||
|
@ -283,7 +287,8 @@ void NotificationManager::PopNotification::init()
|
||||||
}
|
}
|
||||||
m_endlines.push_back(last_end + letter_count);
|
m_endlines.push_back(last_end + letter_count);
|
||||||
last_end += letter_count;
|
last_end += letter_count;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
m_endlines.push_back(next_space);
|
m_endlines.push_back(next_space);
|
||||||
last_end = next_space + 1;
|
last_end = next_space + 1;
|
||||||
}
|
}
|
||||||
|
@ -297,11 +302,22 @@ void NotificationManager::PopNotification::init()
|
||||||
}
|
}
|
||||||
m_lines_count++;
|
m_lines_count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationManager::PopNotification::init()
|
||||||
|
{
|
||||||
|
// Do not init closing notification
|
||||||
|
if (is_finished())
|
||||||
|
return;
|
||||||
|
|
||||||
|
count_spaces();
|
||||||
|
count_lines();
|
||||||
|
|
||||||
if (m_lines_count == 3)
|
if (m_lines_count == 3)
|
||||||
m_multiline = true;
|
m_multiline = true;
|
||||||
m_notification_start = GLCanvas3D::timestamp_now();
|
m_notification_start = GLCanvas3D::timestamp_now();
|
||||||
//if (m_state != EState::Hidden)
|
if (m_state == EState::Unknown)
|
||||||
// m_state = EState::Shown;
|
m_state = EState::Shown;
|
||||||
}
|
}
|
||||||
void NotificationManager::PopNotification::set_next_window_size(ImGuiWrapper& imgui)
|
void NotificationManager::PopNotification::set_next_window_size(ImGuiWrapper& imgui)
|
||||||
{
|
{
|
||||||
|
@ -324,8 +340,8 @@ void NotificationManager::PopNotification::render_text(ImGuiWrapper& imgui, cons
|
||||||
if (m_multiline) {
|
if (m_multiline) {
|
||||||
|
|
||||||
int last_end = 0;
|
int last_end = 0;
|
||||||
float starting_y = m_line_height/2;//10;
|
float starting_y = m_line_height/2;
|
||||||
float shift_y = m_line_height;// -m_line_height / 20;
|
float shift_y = m_line_height;
|
||||||
for (size_t i = 0; i < m_lines_count; i++) {
|
for (size_t i = 0; i < m_lines_count; i++) {
|
||||||
std::string line = m_text1.substr(last_end , m_endlines[i] - last_end);
|
std::string line = m_text1.substr(last_end , m_endlines[i] - last_end);
|
||||||
if(i < m_lines_count - 1)
|
if(i < m_lines_count - 1)
|
||||||
|
@ -549,7 +565,7 @@ void NotificationManager::PopNotification::update(const NotificationData& n)
|
||||||
m_text2 = n.text2;
|
m_text2 = n.text2;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
bool NotificationManager::PopNotification::compare_text(const std::string& text)
|
bool NotificationManager::PopNotification::compare_text(const std::string& text) const
|
||||||
{
|
{
|
||||||
std::wstring wt1 = boost::nowide::widen(m_text1);
|
std::wstring wt1 = boost::nowide::widen(m_text1);
|
||||||
std::wstring wt2 = boost::nowide::widen(text);
|
std::wstring wt2 = boost::nowide::widen(text);
|
||||||
|
@ -579,9 +595,10 @@ bool NotificationManager::PopNotification::update_state(bool paused, const int64
|
||||||
// reset timers - hovered state is set in render
|
// reset timers - hovered state is set in render
|
||||||
if (m_state == EState::Hovered) {
|
if (m_state == EState::Hovered) {
|
||||||
m_current_fade_opacity = 1.0f;
|
m_current_fade_opacity = 1.0f;
|
||||||
m_notification_start = now;
|
m_state = EState::Unknown;
|
||||||
|
init();
|
||||||
// Timers when not fading
|
// Timers when not fading
|
||||||
} else if (m_state != EState::FadingOut && m_data.duration != 0 && !paused) {
|
} else if (m_state != EState::NotFading && m_state != EState::FadingOut && m_data.duration != 0 && !paused) {
|
||||||
int64_t up_time = now - m_notification_start;
|
int64_t up_time = now - m_notification_start;
|
||||||
if (up_time >= m_data.duration * 1000) {
|
if (up_time >= m_data.duration * 1000) {
|
||||||
m_state = EState::FadingOut;
|
m_state = EState::FadingOut;
|
||||||
|
@ -785,53 +802,154 @@ bool NotificationManager::ExportFinishedNotification::on_text_click()
|
||||||
void NotificationManager::ProgressBarNotification::init()
|
void NotificationManager::ProgressBarNotification::init()
|
||||||
{
|
{
|
||||||
PopNotification::init();
|
PopNotification::init();
|
||||||
m_lines_count++;
|
//m_lines_count++;
|
||||||
|
if(m_lines_count >= 2) {
|
||||||
|
m_lines_count = 3;
|
||||||
|
m_multiline = true;
|
||||||
|
while (m_endlines.size() < 3)
|
||||||
|
m_endlines.push_back(m_endlines.back());
|
||||||
|
} else {
|
||||||
|
m_lines_count = 2;
|
||||||
m_endlines.push_back(m_endlines.back());
|
m_endlines.push_back(m_endlines.back());
|
||||||
}
|
|
||||||
void NotificationManager::ProgressBarNotification::count_spaces()
|
|
||||||
{
|
|
||||||
//determine line width
|
|
||||||
m_line_height = ImGui::CalcTextSize("A").y;
|
|
||||||
|
|
||||||
m_left_indentation = m_line_height;
|
|
||||||
if (m_data.level == NotificationLevel::ErrorNotification || m_data.level == NotificationLevel::WarningNotification) {
|
|
||||||
std::string text;
|
|
||||||
text = (m_data.level == NotificationLevel::ErrorNotification ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
|
||||||
float picture_width = ImGui::CalcTextSize(text.c_str()).x;
|
|
||||||
m_left_indentation = picture_width + m_line_height / 2;
|
|
||||||
}
|
}
|
||||||
m_window_width_offset = m_line_height * (m_has_cancel_button ? 6 : 4);
|
if(m_state == EState::Shown)
|
||||||
m_window_width = m_line_height * 25;
|
m_state = EState::NotFading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NotificationManager::ProgressBarNotification::count_lines()
|
||||||
|
{
|
||||||
|
std::string text = m_text1 + " " + m_hypertext;
|
||||||
|
size_t last_end = 0;
|
||||||
|
m_lines_count = 0;
|
||||||
|
|
||||||
|
m_endlines.clear();
|
||||||
|
while (last_end < text.length() - 1)
|
||||||
|
{
|
||||||
|
size_t next_hard_end = text.find_first_of('\n', last_end);
|
||||||
|
if (next_hard_end != std::string::npos && ImGui::CalcTextSize(text.substr(last_end, next_hard_end - last_end).c_str()).x < m_window_width - m_window_width_offset) {
|
||||||
|
//next line is ended by '/n'
|
||||||
|
m_endlines.push_back(next_hard_end);
|
||||||
|
last_end = next_hard_end + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// find next suitable endline
|
||||||
|
if (ImGui::CalcTextSize(text.substr(last_end).c_str()).x >= m_window_width - m_window_width_offset) {
|
||||||
|
// more than one line till end
|
||||||
|
size_t next_space = text.find_first_of(' ', last_end);
|
||||||
|
if (next_space > 0) {
|
||||||
|
size_t next_space_candidate = text.find_first_of(' ', next_space + 1);
|
||||||
|
while (next_space_candidate > 0 && ImGui::CalcTextSize(text.substr(last_end, next_space_candidate - last_end).c_str()).x < m_window_width - m_window_width_offset) {
|
||||||
|
next_space = next_space_candidate;
|
||||||
|
next_space_candidate = text.find_first_of(' ', next_space + 1);
|
||||||
|
}
|
||||||
|
// when one word longer than line. Or the last space is too early.
|
||||||
|
if (ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x > m_window_width - m_window_width_offset ||
|
||||||
|
ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x < (m_window_width - m_window_width_offset) / 4 * 3
|
||||||
|
) {
|
||||||
|
float width_of_a = ImGui::CalcTextSize("a").x;
|
||||||
|
int letter_count = (int)((m_window_width - m_window_width_offset) / width_of_a);
|
||||||
|
while (last_end + letter_count < text.size() && ImGui::CalcTextSize(text.substr(last_end, letter_count).c_str()).x < m_window_width - m_window_width_offset) {
|
||||||
|
letter_count++;
|
||||||
|
}
|
||||||
|
m_endlines.push_back(last_end + letter_count);
|
||||||
|
last_end += letter_count;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_endlines.push_back(next_space);
|
||||||
|
last_end = next_space + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_endlines.push_back(text.length());
|
||||||
|
last_end = text.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
m_lines_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NotificationManager::ProgressBarNotification::render_text(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
void NotificationManager::ProgressBarNotification::render_text(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||||
{
|
{
|
||||||
// line1 - we do not print any more text than what fits on line 1. Line 2 is bar.
|
// line1 - we do not print any more text than what fits on line 1. Line 2 is bar.
|
||||||
|
if (m_multiline) {
|
||||||
|
// two lines text, one line bar
|
||||||
ImGui::SetCursorPosX(m_left_indentation);
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
ImGui::SetCursorPosY(win_size_y / 2 - win_size_y / 6 - m_line_height / 2);
|
ImGui::SetCursorPosY(m_line_height / 4);
|
||||||
|
imgui.text(m_text1.substr(0, m_endlines[0]).c_str());
|
||||||
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
|
ImGui::SetCursorPosY(m_line_height + m_line_height / 4);
|
||||||
|
std::string line = m_text1.substr(m_endlines[0] + (m_text1[m_endlines[0]] == '\n' || m_text1[m_endlines[0]] == ' ' ? 1 : 0), m_endlines[1] - m_endlines[0] - (m_text1[m_endlines[0]] == '\n' || m_text1[m_endlines[0]] == ' ' ? 1 : 0));
|
||||||
|
imgui.text(line.c_str());
|
||||||
|
if (m_has_cancel_button)
|
||||||
|
render_cancel_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
|
render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
|
} else {
|
||||||
|
//one line text, one line bar
|
||||||
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
|
ImGui::SetCursorPosY(/*win_size_y / 2 - win_size_y / 6 -*/ m_line_height / 4);
|
||||||
imgui.text(m_text1.substr(0, m_endlines[0]).c_str());
|
imgui.text(m_text1.substr(0, m_endlines[0]).c_str());
|
||||||
if (m_has_cancel_button)
|
if (m_has_cancel_button)
|
||||||
render_cancel_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
render_cancel_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void NotificationManager::ProgressBarNotification::render_bar(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
void NotificationManager::ProgressBarNotification::render_bar(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||||
{
|
{
|
||||||
ImVec4 orange_color = ImVec4(.99f, .313f, .0f, 1.0f);
|
ImVec4 orange_color = ImVec4(.99f, .313f, .0f, 1.0f);
|
||||||
ImVec4 gray_color = ImVec4(.34f, .34f, .34f, 1.0f);
|
ImVec4 gray_color = ImVec4(.34f, .34f, .34f, 1.0f);
|
||||||
ImVec2 lineEnd = ImVec2(win_pos_x - m_window_width_offset, win_pos_y + win_size_y / 2 + m_line_height / 4);
|
ImVec2 lineEnd = ImVec2(win_pos_x - m_window_width_offset, win_pos_y + win_size_y / 2 + (m_multiline ? m_line_height / 2 : 0));
|
||||||
ImVec2 lineStart = ImVec2(win_pos_x - win_size_x + m_left_indentation, win_pos_y + win_size_y / 2 + m_line_height / 4);
|
ImVec2 lineStart = ImVec2(win_pos_x - win_size_x + m_left_indentation, win_pos_y + win_size_y / 2 + (m_multiline ? m_line_height / 2 : 0));
|
||||||
ImVec2 midPoint = ImVec2(lineStart.x + (lineEnd.x - lineStart.x) * m_percentage, lineStart.y);
|
ImVec2 midPoint = ImVec2(lineStart.x + (lineEnd.x - lineStart.x) * m_percentage, lineStart.y);
|
||||||
ImGui::GetWindowDrawList()->AddLine(lineStart, lineEnd, IM_COL32((int)(gray_color.x * 255), (int)(gray_color.y * 255), (int)(gray_color.z * 255), (1.0f * 255.f)), m_line_height * 0.2f);
|
ImGui::GetWindowDrawList()->AddLine(lineStart, lineEnd, IM_COL32((int)(gray_color.x * 255), (int)(gray_color.y * 255), (int)(gray_color.z * 255), (1.0f * 255.f)), m_line_height * 0.2f);
|
||||||
ImGui::GetWindowDrawList()->AddLine(lineStart, midPoint, IM_COL32((int)(orange_color.x * 255), (int)(orange_color.y * 255), (int)(orange_color.z * 255), (1.0f * 255.f)), m_line_height * 0.2f);
|
ImGui::GetWindowDrawList()->AddLine(lineStart, midPoint, IM_COL32((int)(orange_color.x * 255), (int)(orange_color.y * 255), (int)(orange_color.z * 255), (1.0f * 255.f)), m_line_height * 0.2f);
|
||||||
}
|
}
|
||||||
//------PrintHostUploadNotification----------------
|
//------PrintHostUploadNotification----------------
|
||||||
|
void NotificationManager::PrintHostUploadNotification::init()
|
||||||
|
{
|
||||||
|
ProgressBarNotification::init();
|
||||||
|
if (m_state == EState::NotFading && m_uj_state == UploadJobState::PB_COMPLETED)
|
||||||
|
m_state = EState::Shown;
|
||||||
|
}
|
||||||
|
void NotificationManager::PrintHostUploadNotification::count_spaces()
|
||||||
|
{
|
||||||
|
//determine line width
|
||||||
|
m_line_height = ImGui::CalcTextSize("A").y;
|
||||||
|
|
||||||
|
m_left_indentation = m_line_height;
|
||||||
|
if (m_uj_state == UploadJobState::PB_ERROR) {
|
||||||
|
std::string text;
|
||||||
|
text = (m_data.level == NotificationLevel::ErrorNotification ? ImGui::ErrorMarker : ImGui::WarningMarker);
|
||||||
|
float picture_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||||
|
m_left_indentation = picture_width + m_line_height / 2;
|
||||||
|
}
|
||||||
|
m_window_width_offset = m_line_height * 6; //(m_has_cancel_button ? 6 : 4);
|
||||||
|
m_window_width = m_line_height * 25;
|
||||||
|
}
|
||||||
|
bool NotificationManager::PrintHostUploadNotification::push_background_color()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (m_uj_state == UploadJobState::PB_ERROR) {
|
||||||
|
ImVec4 backcolor = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg);
|
||||||
|
backcolor.x += 0.3f;
|
||||||
|
Notifications_Internal::push_style_color(ImGuiCol_WindowBg, backcolor, m_state == EState::FadingOut, m_current_fade_opacity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void NotificationManager::PrintHostUploadNotification::set_percentage(float percent)
|
void NotificationManager::PrintHostUploadNotification::set_percentage(float percent)
|
||||||
{
|
{
|
||||||
m_percentage = percent;
|
m_percentage = percent;
|
||||||
if (percent >= 1.0f) {
|
if (percent >= 1.0f) {
|
||||||
m_uj_state = UploadJobState::PB_COMPLETED;
|
m_uj_state = UploadJobState::PB_COMPLETED;
|
||||||
m_has_cancel_button = false;
|
m_has_cancel_button = false;
|
||||||
|
init();
|
||||||
} else if (percent < 0.0f) {
|
} else if (percent < 0.0f) {
|
||||||
error();
|
error();
|
||||||
} else {
|
} else {
|
||||||
|
@ -846,34 +964,44 @@ void NotificationManager::PrintHostUploadNotification::render_bar(ImGuiWrapper&
|
||||||
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_PROGRESS:
|
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_PROGRESS:
|
||||||
{
|
{
|
||||||
ProgressBarNotification::render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
ProgressBarNotification::render_bar(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
float uploaded = m_file_size / 100 * m_percentage;
|
float uploaded = m_file_size * m_percentage;
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << std::fixed << std::setprecision(2) << (int)(m_percentage * 100) << "% - " << uploaded << " of " << m_file_size << "MB uploaded";
|
stream << std::fixed << std::setprecision(2) << (int)(m_percentage * 100) << "% - " << uploaded << " of " << m_file_size << "MB uploaded";
|
||||||
text = stream.str();
|
text = stream.str();
|
||||||
ImGui::SetCursorPosX(m_left_indentation);
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 /*- m_line_height / 4 * 3*/);
|
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? 0 : m_line_height / 4));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_ERROR:
|
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_ERROR:
|
||||||
text = _u8L("ERROR");
|
text = _u8L("ERROR");
|
||||||
ImGui::SetCursorPosX(m_left_indentation);
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - m_line_height / 2);
|
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? m_line_height / 4 : m_line_height / 2));
|
||||||
break;
|
break;
|
||||||
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_CANCELLED:
|
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_CANCELLED:
|
||||||
text = _u8L("CANCELED");
|
text = _u8L("CANCELED");
|
||||||
ImGui::SetCursorPosX(m_left_indentation);
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - m_line_height / 2);
|
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? m_line_height / 4 : m_line_height / 2));
|
||||||
break;
|
break;
|
||||||
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_COMPLETED:
|
case Slic3r::GUI::NotificationManager::PrintHostUploadNotification::UploadJobState::PB_COMPLETED:
|
||||||
text = _u8L("COMPLETED");
|
text = _u8L("COMPLETED");
|
||||||
ImGui::SetCursorPosX(m_left_indentation);
|
ImGui::SetCursorPosX(m_left_indentation);
|
||||||
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - m_line_height / 2);
|
ImGui::SetCursorPosY(win_size_y / 2 + win_size_y / 6 - (m_multiline ? m_line_height / 4 : m_line_height / 2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui.text(text.c_str());
|
imgui.text(text.c_str());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
void NotificationManager::PrintHostUploadNotification::render_left_sign(ImGuiWrapper& imgui)
|
||||||
|
{
|
||||||
|
if (m_uj_state == UploadJobState::PB_ERROR) {
|
||||||
|
std::string text;
|
||||||
|
text = ImGui::ErrorMarker;
|
||||||
|
ImGui::SetCursorPosX(m_line_height / 3);
|
||||||
|
ImGui::SetCursorPosY(m_window_height / 2 - m_line_height);
|
||||||
|
imgui.text(text.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
void NotificationManager::PrintHostUploadNotification::render_cancel_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
void NotificationManager::PrintHostUploadNotification::render_cancel_button(ImGuiWrapper& imgui, const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||||
{
|
{
|
||||||
ImVec2 win_size(win_size_x, win_size_y);
|
ImVec2 win_size(win_size_x, win_size_y);
|
||||||
|
@ -1059,6 +1187,14 @@ void NotificationManager::close_slicing_errors_and_warnings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void NotificationManager::close_slicing_error_notification(const std::string& text)
|
||||||
|
{
|
||||||
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
|
if (notification->get_type() == NotificationType::SlicingError && notification->compare_text(_u8L("ERROR:") + "\n" + text)) {
|
||||||
|
notification->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
void NotificationManager::push_slicing_complete_notification(int timestamp, bool large)
|
void NotificationManager::push_slicing_complete_notification(int timestamp, bool large)
|
||||||
{
|
{
|
||||||
std::string hypertext;
|
std::string hypertext;
|
||||||
|
@ -1122,41 +1258,55 @@ void NotificationManager::push_exporting_finished_notification(const std::string
|
||||||
|
|
||||||
void NotificationManager::push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage)
|
void NotificationManager::push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage)
|
||||||
{
|
{
|
||||||
|
// find if upload with same id was not already in notification
|
||||||
|
// done by compare_jon_id not compare_text thus has to be performed here
|
||||||
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
|
if (notification->get_type() == NotificationType::PrintHostUpload && dynamic_cast<PrintHostUploadNotification*>(notification.get())->compare_job_id(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
|
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
|
||||||
NotificationData data{ NotificationType::PrintHostUpload, NotificationLevel::ProgressBarNotification, 0, text };
|
NotificationData data{ NotificationType::PrintHostUpload, NotificationLevel::ProgressBarNotification, 10, text };
|
||||||
push_notification_data(std::make_unique<NotificationManager::PrintHostUploadNotification>(data, m_id_provider, m_evt_handler, 0, id, filesize), 0);
|
push_notification_data(std::make_unique<NotificationManager::PrintHostUploadNotification>(data, m_id_provider, m_evt_handler, 0, id, filesize), 0);
|
||||||
}
|
}
|
||||||
void NotificationManager::set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage)
|
void NotificationManager::set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage)
|
||||||
{
|
{
|
||||||
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
|
|
||||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
if (notification->get_type() == NotificationType::PrintHostUpload && notification->compare_text(text)) {
|
if (notification->get_type() == NotificationType::PrintHostUpload) {
|
||||||
dynamic_cast<PrintHostUploadNotification*>(notification.get())->set_percentage(percentage);
|
PrintHostUploadNotification* phun = dynamic_cast<PrintHostUploadNotification*>(notification.get());
|
||||||
|
if (phun->compare_job_id(id)) {
|
||||||
|
phun->set_percentage(percentage);
|
||||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void NotificationManager::upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host)
|
void NotificationManager::upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host)
|
||||||
{
|
{
|
||||||
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
|
|
||||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
if (notification->get_type() == NotificationType::PrintHostUpload && notification->compare_text(text)) {
|
if (notification->get_type() == NotificationType::PrintHostUpload) {
|
||||||
dynamic_cast<PrintHostUploadNotification*>(notification.get())->cancel();
|
PrintHostUploadNotification* phun = dynamic_cast<PrintHostUploadNotification*>(notification.get());
|
||||||
|
if (phun->compare_job_id(id)) {
|
||||||
|
phun->cancel();
|
||||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void NotificationManager::upload_job_notification_show_error(int id, const std::string& filename, const std::string& host)
|
void NotificationManager::upload_job_notification_show_error(int id, const std::string& filename, const std::string& host)
|
||||||
{
|
{
|
||||||
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
|
|
||||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
if (notification->get_type() == NotificationType::PrintHostUpload && notification->compare_text(text)) {
|
if (notification->get_type() == NotificationType::PrintHostUpload) {
|
||||||
dynamic_cast<PrintHostUploadNotification*>(notification.get())->error();
|
PrintHostUploadNotification* phun = dynamic_cast<PrintHostUploadNotification*>(notification.get());
|
||||||
|
if(phun->compare_job_id(id)) {
|
||||||
|
phun->error();
|
||||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool NotificationManager::push_notification_data(const NotificationData& notification_data, int timestamp)
|
bool NotificationManager::push_notification_data(const NotificationData& notification_data, int timestamp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -125,6 +125,7 @@ public:
|
||||||
// void set_slicing_warning_gray(const std::string& text, bool g);
|
// void set_slicing_warning_gray(const std::string& text, bool g);
|
||||||
// immediately stops showing slicing errors
|
// immediately stops showing slicing errors
|
||||||
void close_slicing_errors_and_warnings();
|
void close_slicing_errors_and_warnings();
|
||||||
|
void close_slicing_error_notification(const std::string& text);
|
||||||
// Release those slicing warnings, which refer to an ObjectID, which is not in the list.
|
// Release those slicing warnings, which refer to an ObjectID, which is not in the list.
|
||||||
// living_oids is expected to be sorted.
|
// living_oids is expected to be sorted.
|
||||||
void remove_slicing_warnings_of_released_objects(const std::vector<ObjectID>& living_oids);
|
void remove_slicing_warnings_of_released_objects(const std::vector<ObjectID>& living_oids);
|
||||||
|
@ -207,6 +208,7 @@ private:
|
||||||
Unknown, // NOT initialized
|
Unknown, // NOT initialized
|
||||||
Hidden,
|
Hidden,
|
||||||
Shown, // Requesting Render at some time if duration != 0
|
Shown, // Requesting Render at some time if duration != 0
|
||||||
|
NotFading, // Never jumps to state Fading out even if duration says so
|
||||||
FadingOut, // Requesting Render at some time
|
FadingOut, // Requesting Render at some time
|
||||||
ClosePending, // Requesting Render
|
ClosePending, // Requesting Render
|
||||||
Finished, // Requesting Render
|
Finished, // Requesting Render
|
||||||
|
@ -230,18 +232,17 @@ private:
|
||||||
const NotificationData get_data() const { return m_data; }
|
const NotificationData get_data() const { return m_data; }
|
||||||
const bool is_gray() const { return m_is_gray; }
|
const bool is_gray() const { return m_is_gray; }
|
||||||
void set_gray(bool g) { m_is_gray = g; }
|
void set_gray(bool g) { m_is_gray = g; }
|
||||||
bool compare_text(const std::string& text);
|
virtual bool compare_text(const std::string& text) const;
|
||||||
void hide(bool h) { if (is_finished()) return; m_state = h ? EState::Hidden : EState::Unknown; }
|
void hide(bool h) { if (is_finished()) return; m_state = h ? EState::Hidden : EState::Unknown; }
|
||||||
// sets m_next_render with time of next mandatory rendering. Delta is time since last render.
|
// sets m_next_render with time of next mandatory rendering. Delta is time since last render.
|
||||||
bool update_state(bool paused, const int64_t delta);
|
bool update_state(bool paused, const int64_t delta);
|
||||||
int64_t next_render() const { return is_finished() ? 0 : m_next_render; }
|
int64_t next_render() const { return is_finished() ? 0 : m_next_render; }
|
||||||
EState get_state() const { return m_state; }
|
EState get_state() const { return m_state; }
|
||||||
bool is_hovered() const { return m_state == EState::Hovered; }
|
bool is_hovered() const { return m_state == EState::Hovered; }
|
||||||
|
void set_hovered() { if (m_state != EState::Finished && m_state != EState::ClosePending && m_state != EState::Hidden && m_state != EState::Unknown) m_state = EState::Hovered; }
|
||||||
|
protected:
|
||||||
// Call after every size change
|
// Call after every size change
|
||||||
virtual void init();
|
virtual void init();
|
||||||
// Part of init()
|
|
||||||
virtual void count_spaces();
|
|
||||||
// Calculetes correct size but not se it in imgui!
|
// Calculetes correct size but not se it in imgui!
|
||||||
virtual void set_next_window_size(ImGuiWrapper& imgui);
|
virtual void set_next_window_size(ImGuiWrapper& imgui);
|
||||||
virtual void render_text(ImGuiWrapper& imgui,
|
virtual void render_text(ImGuiWrapper& imgui,
|
||||||
|
@ -255,13 +256,20 @@ private:
|
||||||
const std::string text,
|
const std::string text,
|
||||||
bool more = false);
|
bool more = false);
|
||||||
// Left sign could be error or warning sign
|
// Left sign could be error or warning sign
|
||||||
void render_left_sign(ImGuiWrapper& imgui);
|
virtual void render_left_sign(ImGuiWrapper& imgui);
|
||||||
virtual void render_minimize_button(ImGuiWrapper& imgui,
|
virtual void render_minimize_button(ImGuiWrapper& imgui,
|
||||||
const float win_pos_x, const float win_pos_y);
|
const float win_pos_x, const float win_pos_y);
|
||||||
// Hypertext action, returns true if notification should close.
|
// Hypertext action, returns true if notification should close.
|
||||||
// Action is stored in NotificationData::callback as std::function<bool(wxEvtHandler*)>
|
// Action is stored in NotificationData::callback as std::function<bool(wxEvtHandler*)>
|
||||||
virtual bool on_text_click();
|
virtual bool on_text_click();
|
||||||
protected:
|
|
||||||
|
// Part of init(), counts horizontal spacing like left indentation
|
||||||
|
virtual void count_spaces();
|
||||||
|
// Part of init(), counts end lines
|
||||||
|
virtual void count_lines();
|
||||||
|
// returns true if PopStyleColor should be called later to pop this push
|
||||||
|
virtual bool push_background_color();
|
||||||
|
|
||||||
const NotificationData m_data;
|
const NotificationData m_data;
|
||||||
// For reusing ImGUI windows.
|
// For reusing ImGUI windows.
|
||||||
NotificationIDProvider &m_id_provider;
|
NotificationIDProvider &m_id_provider;
|
||||||
|
@ -364,7 +372,8 @@ private:
|
||||||
virtual void set_percentage(float percent) { m_percentage = percent; }
|
virtual void set_percentage(float percent) { m_percentage = percent; }
|
||||||
protected:
|
protected:
|
||||||
virtual void init() override;
|
virtual void init() override;
|
||||||
virtual void count_spaces() override;
|
virtual void count_lines() override;
|
||||||
|
|
||||||
virtual void render_text(ImGuiWrapper& imgui,
|
virtual void render_text(ImGuiWrapper& imgui,
|
||||||
const float win_size_x, const float win_size_y,
|
const float win_size_x, const float win_size_y,
|
||||||
const float win_pos_x, const float win_pos_y) override;
|
const float win_pos_x, const float win_pos_y) override;
|
||||||
|
@ -375,6 +384,8 @@ private:
|
||||||
const float win_size_x, const float win_size_y,
|
const float win_size_x, const float win_size_y,
|
||||||
const float win_pos_x, const float win_pos_y)
|
const float win_pos_x, const float win_pos_y)
|
||||||
{}
|
{}
|
||||||
|
virtual void render_minimize_button(ImGuiWrapper& imgui,
|
||||||
|
const float win_pos_x, const float win_pos_y) override {}
|
||||||
float m_percentage;
|
float m_percentage;
|
||||||
|
|
||||||
bool m_has_cancel_button {false};
|
bool m_has_cancel_button {false};
|
||||||
|
@ -401,17 +412,23 @@ private:
|
||||||
{
|
{
|
||||||
m_has_cancel_button = true;
|
m_has_cancel_button = true;
|
||||||
}
|
}
|
||||||
static std::string get_upload_job_text(int id, const std::string& filename, const std::string& host) { return "[" + std::to_string(id) + "] " + filename + " -> " + host; }
|
static std::string get_upload_job_text(int id, const std::string& filename, const std::string& host) { return /*"[" + std::to_string(id) + "] " + */filename + " -> " + host; }
|
||||||
virtual void set_percentage(float percent) override;
|
virtual void set_percentage(float percent) override;
|
||||||
void cancel() { m_uj_state = UploadJobState::PB_CANCELLED; m_has_cancel_button = false; }
|
void cancel() { m_uj_state = UploadJobState::PB_CANCELLED; m_has_cancel_button = false; }
|
||||||
void error() { m_uj_state = UploadJobState::PB_ERROR; m_has_cancel_button = false; }
|
void error() { m_uj_state = UploadJobState::PB_ERROR; m_has_cancel_button = false; init(); }
|
||||||
|
bool compare_job_id(const int other_id) const { return m_job_id == other_id; }
|
||||||
|
virtual bool compare_text(const std::string& text) const override { return false; }
|
||||||
protected:
|
protected:
|
||||||
|
virtual void init() override;
|
||||||
|
virtual void count_spaces() override;
|
||||||
|
virtual bool push_background_color() override;
|
||||||
virtual void render_bar(ImGuiWrapper& imgui,
|
virtual void render_bar(ImGuiWrapper& imgui,
|
||||||
const float win_size_x, const float win_size_y,
|
const float win_size_x, const float win_size_y,
|
||||||
const float win_pos_x, const float win_pos_y) override;
|
const float win_pos_x, const float win_pos_y) override;
|
||||||
virtual void render_cancel_button(ImGuiWrapper& imgui,
|
virtual void render_cancel_button(ImGuiWrapper& imgui,
|
||||||
const float win_size_x, const float win_size_y,
|
const float win_size_x, const float win_size_y,
|
||||||
const float win_pos_x, const float win_pos_y) override;
|
const float win_pos_x, const float win_pos_y) override;
|
||||||
|
virtual void render_left_sign(ImGuiWrapper& imgui) override;
|
||||||
// Identifies job in cancel callback
|
// Identifies job in cancel callback
|
||||||
int m_job_id;
|
int m_job_id;
|
||||||
// Size of uploaded size to be displayed in MB
|
// Size of uploaded size to be displayed in MB
|
||||||
|
|
|
@ -47,6 +47,19 @@ void ObjectDataViewModelNode::init_container()
|
||||||
static constexpr char LayerRootIcon[] = "edit_layers_all";
|
static constexpr char LayerRootIcon[] = "edit_layers_all";
|
||||||
static constexpr char LayerIcon[] = "edit_layers_some";
|
static constexpr char LayerIcon[] = "edit_layers_some";
|
||||||
static constexpr char WarningIcon[] = "exclamation";
|
static constexpr char WarningIcon[] = "exclamation";
|
||||||
|
static constexpr char InfoIcon[] = "info";
|
||||||
|
|
||||||
|
ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const InfoItemType info_type) :
|
||||||
|
m_parent(parent),
|
||||||
|
m_type(itInfo),
|
||||||
|
m_extruder(wxEmptyString)
|
||||||
|
{
|
||||||
|
m_name = info_type == InfoItemType::CustomSupports ? _L("Paint-on supports")
|
||||||
|
: info_type == InfoItemType::CustomSeam ? _L("Paint-on seam")
|
||||||
|
: _L("Variable layer height");
|
||||||
|
m_info_item_type = info_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type) :
|
ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type) :
|
||||||
m_parent(parent),
|
m_parent(parent),
|
||||||
|
@ -69,6 +82,8 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent
|
||||||
m_bmp = create_scaled_bitmap(LayerRootIcon); // FIXME: pass window ptr
|
m_bmp = create_scaled_bitmap(LayerRootIcon); // FIXME: pass window ptr
|
||||||
m_name = _(L("Layers"));
|
m_name = _(L("Layers"));
|
||||||
}
|
}
|
||||||
|
else if (type == itInfo)
|
||||||
|
assert(false);
|
||||||
|
|
||||||
if (type & (itInstanceRoot | itLayerRoot))
|
if (type & (itInstanceRoot | itLayerRoot))
|
||||||
init_container();
|
init_container();
|
||||||
|
@ -250,6 +265,7 @@ ObjectDataViewModel::ObjectDataViewModel()
|
||||||
|
|
||||||
m_volume_bmps = MenuFactory::get_volume_bitmaps();
|
m_volume_bmps = MenuFactory::get_volume_bitmaps();
|
||||||
m_warning_bmp = create_scaled_bitmap(WarningIcon);
|
m_warning_bmp = create_scaled_bitmap(WarningIcon);
|
||||||
|
m_info_bmp = create_scaled_bitmap(InfoIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectDataViewModel::~ObjectDataViewModel()
|
ObjectDataViewModel::~ObjectDataViewModel()
|
||||||
|
@ -330,12 +346,37 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxDataViewItem ObjectDataViewModel::AddInfoChild(const wxDataViewItem &parent_item, InfoItemType info_type)
|
||||||
|
{
|
||||||
|
ObjectDataViewModelNode *root = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
||||||
|
if (!root) return wxDataViewItem(0);
|
||||||
|
|
||||||
|
const auto node = new ObjectDataViewModelNode(root, info_type);
|
||||||
|
|
||||||
|
// The new item should be added according to its order in InfoItemType.
|
||||||
|
// Find last info item with lower index and append after it.
|
||||||
|
const auto& children = root->GetChildren();
|
||||||
|
int idx = -1;
|
||||||
|
for (int i=0; i<int(children.size()); ++i) {
|
||||||
|
if (children[i]->GetType() == itInfo && int(children[i]->GetInfoItemType()) < int(info_type) )
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
root->Insert(node, idx+1);
|
||||||
|
node->SetBitmap(m_info_bmp);
|
||||||
|
// notify control
|
||||||
|
const wxDataViewItem child((void*)node);
|
||||||
|
ItemAdded(parent_item, child);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
wxDataViewItem ObjectDataViewModel::AddSettingsChild(const wxDataViewItem &parent_item)
|
wxDataViewItem ObjectDataViewModel::AddSettingsChild(const wxDataViewItem &parent_item)
|
||||||
{
|
{
|
||||||
ObjectDataViewModelNode *root = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
ObjectDataViewModelNode *root = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
||||||
if (!root) return wxDataViewItem(0);
|
if (!root) return wxDataViewItem(0);
|
||||||
|
|
||||||
const auto node = new ObjectDataViewModelNode(root, itSettings);
|
const auto node = new ObjectDataViewModelNode(root, itSettings);
|
||||||
|
|
||||||
root->Insert(node, 0);
|
root->Insert(node, 0);
|
||||||
// notify control
|
// notify control
|
||||||
const wxDataViewItem child((void*)node);
|
const wxDataViewItem child((void*)node);
|
||||||
|
@ -1379,6 +1420,14 @@ ItemType ObjectDataViewModel::GetItemType(const wxDataViewItem &item) const
|
||||||
return node->m_type < 0 ? itUndef : node->m_type;
|
return node->m_type < 0 ? itUndef : node->m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InfoItemType ObjectDataViewModel::GetInfoItemType(const wxDataViewItem &item) const
|
||||||
|
{
|
||||||
|
if (!item.IsOk())
|
||||||
|
return InfoItemType::Undef;
|
||||||
|
ObjectDataViewModelNode *node = static_cast<ObjectDataViewModelNode*>(item.GetID());
|
||||||
|
return node->m_info_item_type;
|
||||||
|
}
|
||||||
|
|
||||||
wxDataViewItem ObjectDataViewModel::GetItemByType(const wxDataViewItem &parent_item, ItemType type) const
|
wxDataViewItem ObjectDataViewModel::GetItemByType(const wxDataViewItem &parent_item, ItemType type) const
|
||||||
{
|
{
|
||||||
if (!parent_item.IsOk())
|
if (!parent_item.IsOk())
|
||||||
|
@ -1411,6 +1460,21 @@ wxDataViewItem ObjectDataViewModel::GetLayerRootItem(const wxDataViewItem &item)
|
||||||
return GetItemByType(item, itLayerRoot);
|
return GetItemByType(item, itLayerRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxDataViewItem ObjectDataViewModel::GetInfoItemByType(const wxDataViewItem &parent_item, InfoItemType type) const
|
||||||
|
{
|
||||||
|
if (! parent_item.IsOk())
|
||||||
|
return wxDataViewItem(0);
|
||||||
|
|
||||||
|
ObjectDataViewModelNode *node = static_cast<ObjectDataViewModelNode*>(parent_item.GetID());
|
||||||
|
for (size_t i = 0; i < node->GetChildCount(); i++) {
|
||||||
|
const ObjectDataViewModelNode* child_node = node->GetNthChild(i);
|
||||||
|
if (child_node->m_type == itInfo && child_node->m_info_item_type == type)
|
||||||
|
return wxDataViewItem((void*)child_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxDataViewItem(0); // not found
|
||||||
|
}
|
||||||
|
|
||||||
bool ObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const
|
bool ObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const
|
||||||
{
|
{
|
||||||
if (!item.IsOk())
|
if (!item.IsOk())
|
||||||
|
|
|
@ -27,6 +27,7 @@ enum ItemType {
|
||||||
itSettings = 16,
|
itSettings = 16,
|
||||||
itLayerRoot = 32,
|
itLayerRoot = 32,
|
||||||
itLayer = 64,
|
itLayer = 64,
|
||||||
|
itInfo = 128
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ColumnNumber
|
enum ColumnNumber
|
||||||
|
@ -44,6 +45,14 @@ enum PrintIndicator
|
||||||
piUnprintable , // unprintable
|
piUnprintable , // unprintable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class InfoItemType
|
||||||
|
{
|
||||||
|
Undef,
|
||||||
|
CustomSupports,
|
||||||
|
CustomSeam,
|
||||||
|
VariableLayerHeight
|
||||||
|
};
|
||||||
|
|
||||||
class ObjectDataViewModelNode;
|
class ObjectDataViewModelNode;
|
||||||
WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray);
|
WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray);
|
||||||
|
|
||||||
|
@ -69,6 +78,7 @@ class ObjectDataViewModelNode
|
||||||
|
|
||||||
std::string m_action_icon_name = "";
|
std::string m_action_icon_name = "";
|
||||||
ModelVolumeType m_volume_type;
|
ModelVolumeType m_volume_type;
|
||||||
|
InfoItemType m_info_item_type {InfoItemType::Undef};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectDataViewModelNode(const wxString& name,
|
ObjectDataViewModelNode(const wxString& name,
|
||||||
|
@ -104,6 +114,7 @@ public:
|
||||||
const wxString& extruder = wxEmptyString );
|
const wxString& extruder = wxEmptyString );
|
||||||
|
|
||||||
ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type);
|
ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type);
|
||||||
|
ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const InfoItemType type);
|
||||||
|
|
||||||
~ObjectDataViewModelNode()
|
~ObjectDataViewModelNode()
|
||||||
{
|
{
|
||||||
|
@ -176,6 +187,7 @@ public:
|
||||||
const wxBitmap& GetBitmap() const { return m_bmp; }
|
const wxBitmap& GetBitmap() const { return m_bmp; }
|
||||||
const wxString& GetName() const { return m_name; }
|
const wxString& GetName() const { return m_name; }
|
||||||
ItemType GetType() const { return m_type; }
|
ItemType GetType() const { return m_type; }
|
||||||
|
InfoItemType GetInfoItemType() const { return m_info_item_type; }
|
||||||
void SetIdx(const int& idx);
|
void SetIdx(const int& idx);
|
||||||
int GetIdx() const { return m_idx; }
|
int GetIdx() const { return m_idx; }
|
||||||
ModelVolumeType GetVolumeType() { return m_volume_type; }
|
ModelVolumeType GetVolumeType() { return m_volume_type; }
|
||||||
|
@ -244,6 +256,7 @@ class ObjectDataViewModel :public wxDataViewModel
|
||||||
std::vector<ObjectDataViewModelNode*> m_objects;
|
std::vector<ObjectDataViewModelNode*> m_objects;
|
||||||
std::vector<wxBitmap> m_volume_bmps;
|
std::vector<wxBitmap> m_volume_bmps;
|
||||||
wxBitmap m_warning_bmp;
|
wxBitmap m_warning_bmp;
|
||||||
|
wxBitmap m_info_bmp;
|
||||||
|
|
||||||
wxDataViewCtrl* m_ctrl { nullptr };
|
wxDataViewCtrl* m_ctrl { nullptr };
|
||||||
|
|
||||||
|
@ -261,6 +274,7 @@ public:
|
||||||
const int extruder = 0,
|
const int extruder = 0,
|
||||||
const bool create_frst_child = true);
|
const bool create_frst_child = true);
|
||||||
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
|
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
|
||||||
|
wxDataViewItem AddInfoChild(const wxDataViewItem &parent_item, InfoItemType info_type);
|
||||||
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num);
|
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num);
|
||||||
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, const std::vector<bool>& print_indicator);
|
wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, const std::vector<bool>& print_indicator);
|
||||||
wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item);
|
wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item);
|
||||||
|
@ -335,12 +349,15 @@ public:
|
||||||
// In our case it is an item with all columns
|
// In our case it is an item with all columns
|
||||||
bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
|
bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
|
||||||
|
|
||||||
ItemType GetItemType(const wxDataViewItem &item) const ;
|
ItemType GetItemType(const wxDataViewItem &item) const;
|
||||||
|
InfoItemType GetInfoItemType(const wxDataViewItem &item) const;
|
||||||
wxDataViewItem GetItemByType( const wxDataViewItem &parent_item,
|
wxDataViewItem GetItemByType( const wxDataViewItem &parent_item,
|
||||||
ItemType type) const;
|
ItemType type) const;
|
||||||
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
|
wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const;
|
||||||
wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const;
|
wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const;
|
||||||
wxDataViewItem GetLayerRootItem(const wxDataViewItem &item) const;
|
wxDataViewItem GetLayerRootItem(const wxDataViewItem &item) const;
|
||||||
|
wxDataViewItem GetInfoItemByType(const wxDataViewItem &parent_item, InfoItemType type) const;
|
||||||
|
|
||||||
bool IsSettingsItem(const wxDataViewItem &item) const;
|
bool IsSettingsItem(const wxDataViewItem &item) const;
|
||||||
void UpdateSettingsDigest( const wxDataViewItem &item,
|
void UpdateSettingsDigest( const wxDataViewItem &item,
|
||||||
const std::vector<std::string>& categories);
|
const std::vector<std::string>& categories);
|
||||||
|
|
|
@ -90,22 +90,24 @@ float OpenGLManager::GLInfo::get_max_anisotropy() const
|
||||||
|
|
||||||
void OpenGLManager::GLInfo::detect() const
|
void OpenGLManager::GLInfo::detect() const
|
||||||
{
|
{
|
||||||
m_version = gl_get_string_safe(GL_VERSION, "N/A");
|
*const_cast<std::string*>(&m_version) = gl_get_string_safe(GL_VERSION, "N/A");
|
||||||
m_glsl_version = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A");
|
*const_cast<std::string*>(&m_glsl_version) = gl_get_string_safe(GL_SHADING_LANGUAGE_VERSION, "N/A");
|
||||||
m_vendor = gl_get_string_safe(GL_VENDOR, "N/A");
|
*const_cast<std::string*>(&m_vendor) = gl_get_string_safe(GL_VENDOR, "N/A");
|
||||||
m_renderer = gl_get_string_safe(GL_RENDERER, "N/A");
|
*const_cast<std::string*>(&m_renderer) = gl_get_string_safe(GL_RENDERER, "N/A");
|
||||||
|
|
||||||
glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_tex_size));
|
int* max_tex_size = const_cast<int*>(&m_max_tex_size);
|
||||||
|
glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, max_tex_size));
|
||||||
|
|
||||||
m_max_tex_size /= 2;
|
*max_tex_size /= 2;
|
||||||
|
|
||||||
if (Slic3r::total_physical_memory() / (1024 * 1024 * 1024) < 6)
|
if (Slic3r::total_physical_memory() / (1024 * 1024 * 1024) < 6)
|
||||||
m_max_tex_size /= 2;
|
*max_tex_size /= 2;
|
||||||
|
|
||||||
if (GLEW_EXT_texture_filter_anisotropic)
|
if (GLEW_EXT_texture_filter_anisotropic) {
|
||||||
glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &m_max_anisotropy));
|
float* max_anisotropy = const_cast<float*>(&m_max_anisotropy);
|
||||||
|
glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy));
|
||||||
m_detected = true;
|
}
|
||||||
|
*const_cast<bool*>(&m_detected) = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool version_greater_or_equal_to(const std::string& version, unsigned int major, unsigned int minor)
|
static bool version_greater_or_equal_to(const std::string& version, unsigned int major, unsigned int minor)
|
||||||
|
@ -174,19 +176,16 @@ std::string OpenGLManager::GLInfo::to_string(bool format_as_html, bool extension
|
||||||
out << b_start << "Renderer: " << b_end << m_renderer << line_end;
|
out << b_start << "Renderer: " << b_end << m_renderer << line_end;
|
||||||
out << b_start << "GLSL version: " << b_end << m_glsl_version << line_end;
|
out << b_start << "GLSL version: " << b_end << m_glsl_version << line_end;
|
||||||
|
|
||||||
if (extensions)
|
if (extensions) {
|
||||||
{
|
|
||||||
std::vector<std::string> extensions_list;
|
std::vector<std::string> extensions_list;
|
||||||
std::string extensions_str = gl_get_string_safe(GL_EXTENSIONS, "");
|
std::string extensions_str = gl_get_string_safe(GL_EXTENSIONS, "");
|
||||||
boost::split(extensions_list, extensions_str, boost::is_any_of(" "), boost::token_compress_off);
|
boost::split(extensions_list, extensions_str, boost::is_any_of(" "), boost::token_compress_off);
|
||||||
|
|
||||||
if (!extensions_list.empty())
|
if (!extensions_list.empty()) {
|
||||||
{
|
|
||||||
out << h2_start << "Installed extensions:" << h2_end << line_end;
|
out << h2_start << "Installed extensions:" << h2_end << line_end;
|
||||||
|
|
||||||
std::sort(extensions_list.begin(), extensions_list.end());
|
std::sort(extensions_list.begin(), extensions_list.end());
|
||||||
for (const std::string& ext : extensions_list)
|
for (const std::string& ext : extensions_list) {
|
||||||
{
|
|
||||||
out << ext << line_end;
|
out << ext << line_end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,7 +251,7 @@ bool OpenGLManager::init_gl()
|
||||||
message += _L("You may need to update your graphics card driver.");
|
message += _L("You may need to update your graphics card driver.");
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
message += "\n";
|
message += "\n";
|
||||||
message += _L("As a workaround, you may run PrusaSlicer with a software rendered 3D graphics by running prusa-slicer.exe with the --sw_renderer parameter.");
|
message += _L("As a workaround, you may run PrusaSlicer with a software rendered 3D graphics by running prusa-slicer.exe with the --sw-renderer parameter.");
|
||||||
#endif
|
#endif
|
||||||
wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Unsupported OpenGL version"), wxOK | wxICON_ERROR);
|
wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Unsupported OpenGL version"), wxOK | wxICON_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -304,8 +303,7 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent)
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (s_multisample == EMultisampleState::Unknown)
|
if (s_multisample == EMultisampleState::Unknown) {
|
||||||
{
|
|
||||||
detect_multisample(attribList);
|
detect_multisample(attribList);
|
||||||
// // debug output
|
// // debug output
|
||||||
// std::cout << "Multisample " << (can_multisample() ? "enabled" : "disabled") << std::endl;
|
// std::cout << "Multisample " << (can_multisample() ? "enabled" : "disabled") << std::endl;
|
||||||
|
|
|
@ -22,14 +22,14 @@ public:
|
||||||
|
|
||||||
class GLInfo
|
class GLInfo
|
||||||
{
|
{
|
||||||
mutable bool m_detected{ false };
|
bool m_detected{ false };
|
||||||
mutable int m_max_tex_size{ 0 };
|
int m_max_tex_size{ 0 };
|
||||||
mutable float m_max_anisotropy{ 0.0f };
|
float m_max_anisotropy{ 0.0f };
|
||||||
|
|
||||||
mutable std::string m_version;
|
std::string m_version;
|
||||||
mutable std::string m_glsl_version;
|
std::string m_glsl_version;
|
||||||
mutable std::string m_vendor;
|
std::string m_vendor;
|
||||||
mutable std::string m_renderer;
|
std::string m_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLInfo() = default;
|
GLInfo() = default;
|
||||||
|
|
|
@ -2407,6 +2407,29 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
||||||
#endif /* AUTOPLACEMENT_ON_LOAD */
|
#endif /* AUTOPLACEMENT_ON_LOAD */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_MODIFIED_DOWNSCALE_ON_LOAD_OBJECTS_TOO_BIG
|
||||||
|
for (size_t i = 0; i < object->instances.size(); ++i) {
|
||||||
|
ModelInstance* instance = object->instances[i];
|
||||||
|
const Vec3d size = object->instance_bounding_box(i).size();
|
||||||
|
const Vec3d ratio = size.cwiseQuotient(bed_size);
|
||||||
|
const double max_ratio = std::max(ratio(0), ratio(1));
|
||||||
|
if (max_ratio > 10000) {
|
||||||
|
// the size of the object is too big -> this could lead to overflow when moving to clipper coordinates,
|
||||||
|
// so scale down the mesh
|
||||||
|
double inv = 1. / max_ratio;
|
||||||
|
object->scale_mesh_after_creation(inv * Vec3d::Ones());
|
||||||
|
object->origin_translation = Vec3d::Zero();
|
||||||
|
object->center_around_origin();
|
||||||
|
scaled_down = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (max_ratio > 5) {
|
||||||
|
const Vec3d inverse = 1.0 / max_ratio * Vec3d::Ones();
|
||||||
|
instance->set_scaling_factor(inverse.cwiseProduct(instance->get_scaling_factor()));
|
||||||
|
scaled_down = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
const Vec3d size = object->bounding_box().size();
|
const Vec3d size = object->bounding_box().size();
|
||||||
const Vec3d ratio = size.cwiseQuotient(bed_size);
|
const Vec3d ratio = size.cwiseQuotient(bed_size);
|
||||||
const double max_ratio = std::max(ratio(0), ratio(1));
|
const double max_ratio = std::max(ratio(0), ratio(1));
|
||||||
|
@ -2425,6 +2448,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
|
||||||
}
|
}
|
||||||
scaled_down = true;
|
scaled_down = true;
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_MODIFIED_DOWNSCALE_ON_LOAD_OBJECTS_TOO_BIG
|
||||||
|
|
||||||
object->ensure_on_bed();
|
object->ensure_on_bed();
|
||||||
}
|
}
|
||||||
|
@ -4943,6 +4967,12 @@ void Plater::convert_unit(ConversionType conv_type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plater::toggle_layers_editing(bool enable)
|
||||||
|
{
|
||||||
|
if (canvas3D()->is_layers_editing_enabled() != enable)
|
||||||
|
wxPostEvent(canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING));
|
||||||
|
}
|
||||||
|
|
||||||
void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower)
|
void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower)
|
||||||
{
|
{
|
||||||
wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds");
|
wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds");
|
||||||
|
|
|
@ -191,6 +191,7 @@ public:
|
||||||
bool is_selection_empty() const;
|
bool is_selection_empty() const;
|
||||||
void scale_selection_to_fit_print_volume();
|
void scale_selection_to_fit_print_volume();
|
||||||
void convert_unit(ConversionType conv_type);
|
void convert_unit(ConversionType conv_type);
|
||||||
|
void toggle_layers_editing(bool enable);
|
||||||
|
|
||||||
void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false);
|
void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/wupdlock.h>
|
#include <wx/wupdlock.h>
|
||||||
#include <wx/debug.h>
|
#include <wx/debug.h>
|
||||||
|
#include <wx/msgdlg.h>
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
@ -68,7 +69,9 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
|
||||||
combo_groups->SetValue(recent_group);
|
combo_groups->SetValue(recent_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
btn_sizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL));
|
auto* szr = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||||
|
auto* btn_ok = szr->GetAffirmativeButton();
|
||||||
|
btn_sizer->Add(szr);
|
||||||
|
|
||||||
wxString recent_path = from_u8(app_config->get("recent", CONFIG_KEY_PATH));
|
wxString recent_path = from_u8(app_config->get("recent", CONFIG_KEY_PATH));
|
||||||
if (recent_path.Length() > 0 && recent_path[recent_path.Length() - 1] != '/') {
|
if (recent_path.Length() > 0 && recent_path[recent_path.Length() - 1] != '/') {
|
||||||
|
@ -82,6 +85,20 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
|
||||||
txt_filename->SetValue(recent_path);
|
txt_filename->SetValue(recent_path);
|
||||||
txt_filename->SetFocus();
|
txt_filename->SetFocus();
|
||||||
|
|
||||||
|
wxString suffix = recent_path.substr(recent_path.find_last_of('.'));
|
||||||
|
|
||||||
|
btn_ok->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) {
|
||||||
|
wxString path = txt_filename->GetValue();
|
||||||
|
// .gcode suffix control
|
||||||
|
if (!path.Lower().EndsWith(suffix.Lower()))
|
||||||
|
{
|
||||||
|
wxMessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
|
||||||
|
if (msg_wingow.ShowModal() == wxID_NO)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EndDialog(wxID_OK);
|
||||||
|
});
|
||||||
|
|
||||||
Fit();
|
Fit();
|
||||||
CenterOnParent();
|
CenterOnParent();
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,9 @@ static void unmount_callback(DADiskRef disk, DADissenterRef dissenter, void *con
|
||||||
NSLog(@"-%@",(CFStringRef)deviceModelKey);
|
NSLog(@"-%@",(CFStringRef)deviceModelKey);
|
||||||
*/
|
*/
|
||||||
if (mediaEjectableKey != nullptr) {
|
if (mediaEjectableKey != nullptr) {
|
||||||
BOOL op = ejectable && (CFEqual(deviceProtocolName, CFSTR("USB")) || CFEqual(deviceModelKey, CFSTR("SD Card Reader")) || CFEqual(deviceProtocolName, CFSTR("Secure Digital")));
|
BOOL op = ejectable &&
|
||||||
|
( (deviceProtocolName != nullptr && (CFEqual(deviceProtocolName, CFSTR("USB")) || CFEqual(deviceProtocolName, CFSTR("Secure Digital")))) ||
|
||||||
|
(deviceModelKey != nullptr && CFEqual(deviceModelKey, CFSTR("SD Card Reader"))) );
|
||||||
//!CFEqual(deviceModelKey, CFSTR("Disk Image"));
|
//!CFEqual(deviceModelKey, CFSTR("Disk Image"));
|
||||||
if (op)
|
if (op)
|
||||||
[result addObject:volURL.path];
|
[result addObject:volURL.path];
|
||||||
|
|
|
@ -1102,39 +1102,32 @@ void Selection::erase()
|
||||||
|
|
||||||
if (is_single_full_object())
|
if (is_single_full_object())
|
||||||
wxGetApp().obj_list()->delete_from_model_and_list(ItemType::itObject, get_object_idx(), 0);
|
wxGetApp().obj_list()->delete_from_model_and_list(ItemType::itObject, get_object_idx(), 0);
|
||||||
else if (is_multiple_full_object())
|
else if (is_multiple_full_object()) {
|
||||||
{
|
|
||||||
std::vector<ItemForDelete> items;
|
std::vector<ItemForDelete> items;
|
||||||
items.reserve(m_cache.content.size());
|
items.reserve(m_cache.content.size());
|
||||||
for (ObjectIdxsToInstanceIdxsMap::iterator it = m_cache.content.begin(); it != m_cache.content.end(); ++it)
|
for (ObjectIdxsToInstanceIdxsMap::iterator it = m_cache.content.begin(); it != m_cache.content.end(); ++it) {
|
||||||
{
|
|
||||||
items.emplace_back(ItemType::itObject, it->first, 0);
|
items.emplace_back(ItemType::itObject, it->first, 0);
|
||||||
}
|
}
|
||||||
wxGetApp().obj_list()->delete_from_model_and_list(items);
|
wxGetApp().obj_list()->delete_from_model_and_list(items);
|
||||||
}
|
}
|
||||||
else if (is_multiple_full_instance())
|
else if (is_multiple_full_instance()) {
|
||||||
{
|
|
||||||
std::set<std::pair<int, int>> instances_idxs;
|
std::set<std::pair<int, int>> instances_idxs;
|
||||||
for (ObjectIdxsToInstanceIdxsMap::iterator obj_it = m_cache.content.begin(); obj_it != m_cache.content.end(); ++obj_it)
|
for (ObjectIdxsToInstanceIdxsMap::iterator obj_it = m_cache.content.begin(); obj_it != m_cache.content.end(); ++obj_it) {
|
||||||
{
|
for (InstanceIdxsList::reverse_iterator inst_it = obj_it->second.rbegin(); inst_it != obj_it->second.rend(); ++inst_it) {
|
||||||
for (InstanceIdxsList::reverse_iterator inst_it = obj_it->second.rbegin(); inst_it != obj_it->second.rend(); ++inst_it)
|
|
||||||
{
|
|
||||||
instances_idxs.insert(std::make_pair(obj_it->first, *inst_it));
|
instances_idxs.insert(std::make_pair(obj_it->first, *inst_it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ItemForDelete> items;
|
std::vector<ItemForDelete> items;
|
||||||
items.reserve(instances_idxs.size());
|
items.reserve(instances_idxs.size());
|
||||||
for (const std::pair<int, int>& i : instances_idxs)
|
for (const std::pair<int, int>& i : instances_idxs) {
|
||||||
{
|
|
||||||
items.emplace_back(ItemType::itInstance, i.first, i.second);
|
items.emplace_back(ItemType::itInstance, i.first, i.second);
|
||||||
}
|
}
|
||||||
wxGetApp().obj_list()->delete_from_model_and_list(items);
|
wxGetApp().obj_list()->delete_from_model_and_list(items);
|
||||||
}
|
}
|
||||||
else if (is_single_full_instance())
|
else if (is_single_full_instance())
|
||||||
wxGetApp().obj_list()->delete_from_model_and_list(ItemType::itInstance, get_object_idx(), get_instance_idx());
|
wxGetApp().obj_list()->delete_from_model_and_list(ItemType::itInstance, get_object_idx(), get_instance_idx());
|
||||||
else if (is_mixed())
|
else if (is_mixed()) {
|
||||||
{
|
|
||||||
std::set<ItemForDelete> items_set;
|
std::set<ItemForDelete> items_set;
|
||||||
std::map<int, int> volumes_in_obj;
|
std::map<int, int> volumes_in_obj;
|
||||||
|
|
||||||
|
@ -1186,11 +1179,9 @@ void Selection::erase()
|
||||||
|
|
||||||
wxGetApp().obj_list()->delete_from_model_and_list(items);
|
wxGetApp().obj_list()->delete_from_model_and_list(items);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
std::set<std::pair<int, int>> volumes_idxs;
|
std::set<std::pair<int, int>> volumes_idxs;
|
||||||
for (unsigned int i : m_list)
|
for (unsigned int i : m_list) {
|
||||||
{
|
|
||||||
const GLVolume* v = (*m_volumes)[i];
|
const GLVolume* v = (*m_volumes)[i];
|
||||||
// Only remove volumes associated with ModelVolumes from the object list.
|
// Only remove volumes associated with ModelVolumes from the object list.
|
||||||
// Temporary meshes (SLA supports or pads) are not managed by the object list.
|
// Temporary meshes (SLA supports or pads) are not managed by the object list.
|
||||||
|
@ -1200,8 +1191,7 @@ void Selection::erase()
|
||||||
|
|
||||||
std::vector<ItemForDelete> items;
|
std::vector<ItemForDelete> items;
|
||||||
items.reserve(volumes_idxs.size());
|
items.reserve(volumes_idxs.size());
|
||||||
for (const std::pair<int, int>& v : volumes_idxs)
|
for (const std::pair<int, int>& v : volumes_idxs) {
|
||||||
{
|
|
||||||
items.emplace_back(ItemType::itVolume, v.first, v.second);
|
items.emplace_back(ItemType::itVolume, v.first, v.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1214,7 +1204,7 @@ void Selection::render(float scale_factor) const
|
||||||
if (!m_valid || is_empty())
|
if (!m_valid || is_empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_scale_factor = scale_factor;
|
*const_cast<float*>(&m_scale_factor) = scale_factor;
|
||||||
|
|
||||||
// render cumulative bounding box of selected volumes
|
// render cumulative bounding box of selected volumes
|
||||||
render_selected_volumes();
|
render_selected_volumes();
|
||||||
|
@ -1224,7 +1214,7 @@ void Selection::render(float scale_factor) const
|
||||||
#if ENABLE_RENDER_SELECTION_CENTER
|
#if ENABLE_RENDER_SELECTION_CENTER
|
||||||
void Selection::render_center(bool gizmo_is_dragging) const
|
void Selection::render_center(bool gizmo_is_dragging) const
|
||||||
{
|
{
|
||||||
if (!m_valid || is_empty() || (m_quadric == nullptr))
|
if (!m_valid || is_empty() || m_quadric == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center();
|
Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center();
|
||||||
|
@ -1250,8 +1240,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const
|
||||||
|
|
||||||
GLShaderProgram* shader = nullptr;
|
GLShaderProgram* shader = nullptr;
|
||||||
|
|
||||||
if (!boost::starts_with(sidebar_field, "layer"))
|
if (!boost::starts_with(sidebar_field, "layer")) {
|
||||||
{
|
|
||||||
shader = wxGetApp().get_shader("gouraud_light");
|
shader = wxGetApp().get_shader("gouraud_light");
|
||||||
if (shader == nullptr)
|
if (shader == nullptr)
|
||||||
return;
|
return;
|
||||||
|
@ -1735,18 +1724,16 @@ void Selection::do_remove_volume(unsigned int volume_idx)
|
||||||
|
|
||||||
void Selection::do_remove_instance(unsigned int object_idx, unsigned int instance_idx)
|
void Selection::do_remove_instance(unsigned int object_idx, unsigned int instance_idx)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
|
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
|
||||||
{
|
|
||||||
GLVolume* v = (*m_volumes)[i];
|
GLVolume* v = (*m_volumes)[i];
|
||||||
if ((v->object_idx() == (int)object_idx) && (v->instance_idx() == (int)instance_idx))
|
if (v->object_idx() == (int)object_idx && v->instance_idx() == (int)instance_idx)
|
||||||
do_remove_volume(i);
|
do_remove_volume(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::do_remove_object(unsigned int object_idx)
|
void Selection::do_remove_object(unsigned int object_idx)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
|
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
|
||||||
{
|
|
||||||
GLVolume* v = (*m_volumes)[i];
|
GLVolume* v = (*m_volumes)[i];
|
||||||
if (v->object_idx() == (int)object_idx)
|
if (v->object_idx() == (int)object_idx)
|
||||||
do_remove_volume(i);
|
do_remove_volume(i);
|
||||||
|
@ -1755,47 +1742,48 @@ void Selection::do_remove_object(unsigned int object_idx)
|
||||||
|
|
||||||
void Selection::calc_bounding_box() const
|
void Selection::calc_bounding_box() const
|
||||||
{
|
{
|
||||||
m_bounding_box = BoundingBoxf3();
|
BoundingBoxf3* bounding_box = const_cast<BoundingBoxf3*>(&m_bounding_box);
|
||||||
if (m_valid)
|
*bounding_box = BoundingBoxf3();
|
||||||
{
|
if (m_valid) {
|
||||||
for (unsigned int i : m_list)
|
for (unsigned int i : m_list) {
|
||||||
{
|
bounding_box->merge((*m_volumes)[i]->transformed_convex_hull_bounding_box());
|
||||||
m_bounding_box.merge((*m_volumes)[i]->transformed_convex_hull_bounding_box());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_bounding_box_dirty = false;
|
*const_cast<bool*>(&m_bounding_box_dirty) = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::calc_unscaled_instance_bounding_box() const
|
void Selection::calc_unscaled_instance_bounding_box() const
|
||||||
{
|
{
|
||||||
m_unscaled_instance_bounding_box = BoundingBoxf3();
|
BoundingBoxf3* unscaled_instance_bounding_box = const_cast<BoundingBoxf3*>(&m_unscaled_instance_bounding_box);
|
||||||
|
*unscaled_instance_bounding_box = BoundingBoxf3();
|
||||||
if (m_valid) {
|
if (m_valid) {
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
const GLVolume &volume = *(*m_volumes)[i];
|
const GLVolume& volume = *(*m_volumes)[i];
|
||||||
if (volume.is_modifier)
|
if (volume.is_modifier)
|
||||||
continue;
|
continue;
|
||||||
Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, true, false) * volume.get_volume_transformation().get_matrix();
|
Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, true, false) * volume.get_volume_transformation().get_matrix();
|
||||||
trafo.translation()(2) += volume.get_sla_shift_z();
|
trafo.translation()(2) += volume.get_sla_shift_z();
|
||||||
m_unscaled_instance_bounding_box.merge(volume.transformed_convex_hull_bounding_box(trafo));
|
unscaled_instance_bounding_box->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_unscaled_instance_bounding_box_dirty = false;
|
*const_cast<bool*>(&m_unscaled_instance_bounding_box_dirty) = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::calc_scaled_instance_bounding_box() const
|
void Selection::calc_scaled_instance_bounding_box() const
|
||||||
{
|
{
|
||||||
m_scaled_instance_bounding_box = BoundingBoxf3();
|
BoundingBoxf3* scaled_instance_bounding_box = const_cast<BoundingBoxf3*>(&m_scaled_instance_bounding_box);
|
||||||
|
*scaled_instance_bounding_box = BoundingBoxf3();
|
||||||
if (m_valid) {
|
if (m_valid) {
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
const GLVolume &volume = *(*m_volumes)[i];
|
const GLVolume& volume = *(*m_volumes)[i];
|
||||||
if (volume.is_modifier)
|
if (volume.is_modifier)
|
||||||
continue;
|
continue;
|
||||||
Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, false, false) * volume.get_volume_transformation().get_matrix();
|
Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, false, false) * volume.get_volume_transformation().get_matrix();
|
||||||
trafo.translation()(2) += volume.get_sla_shift_z();
|
trafo.translation()(2) += volume.get_sla_shift_z();
|
||||||
m_scaled_instance_bounding_box.merge(volume.transformed_convex_hull_bounding_box(trafo));
|
scaled_instance_bounding_box->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_scaled_instance_bounding_box_dirty = false;
|
*const_cast<bool*>(&m_scaled_instance_bounding_box_dirty) = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::render_selected_volumes() const
|
void Selection::render_selected_volumes() const
|
||||||
|
|
|
@ -206,14 +206,14 @@ private:
|
||||||
IndicesList m_list;
|
IndicesList m_list;
|
||||||
Cache m_cache;
|
Cache m_cache;
|
||||||
Clipboard m_clipboard;
|
Clipboard m_clipboard;
|
||||||
mutable BoundingBoxf3 m_bounding_box;
|
BoundingBoxf3 m_bounding_box;
|
||||||
mutable bool m_bounding_box_dirty;
|
bool m_bounding_box_dirty;
|
||||||
// Bounding box of a selection, with no instance scaling applied. This bounding box
|
// Bounding box of a selection, with no instance scaling applied. This bounding box
|
||||||
// is useful for absolute scaling of tilted objects in world coordinate space.
|
// is useful for absolute scaling of tilted objects in world coordinate space.
|
||||||
mutable BoundingBoxf3 m_unscaled_instance_bounding_box;
|
BoundingBoxf3 m_unscaled_instance_bounding_box;
|
||||||
mutable bool m_unscaled_instance_bounding_box_dirty;
|
bool m_unscaled_instance_bounding_box_dirty;
|
||||||
mutable BoundingBoxf3 m_scaled_instance_bounding_box;
|
BoundingBoxf3 m_scaled_instance_bounding_box;
|
||||||
mutable bool m_scaled_instance_bounding_box_dirty;
|
bool m_scaled_instance_bounding_box_dirty;
|
||||||
|
|
||||||
#if ENABLE_RENDER_SELECTION_CENTER
|
#if ENABLE_RENDER_SELECTION_CENTER
|
||||||
GLUquadricObj* m_quadric;
|
GLUquadricObj* m_quadric;
|
||||||
|
@ -222,7 +222,7 @@ private:
|
||||||
GLModel m_arrow;
|
GLModel m_arrow;
|
||||||
GLModel m_curved_arrow;
|
GLModel m_curved_arrow;
|
||||||
|
|
||||||
mutable float m_scale_factor;
|
float m_scale_factor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Selection();
|
Selection();
|
||||||
|
|
|
@ -1515,6 +1515,7 @@ void TabPrint::build()
|
||||||
optgroup->append_single_option_line("support_material_with_sheath", category_path + "with-sheath-around-the-support");
|
optgroup->append_single_option_line("support_material_with_sheath", category_path + "with-sheath-around-the-support");
|
||||||
optgroup->append_single_option_line("support_material_spacing", category_path + "pattern-spacing-0-inf");
|
optgroup->append_single_option_line("support_material_spacing", category_path + "pattern-spacing-0-inf");
|
||||||
optgroup->append_single_option_line("support_material_angle", category_path + "pattern-angle");
|
optgroup->append_single_option_line("support_material_angle", category_path + "pattern-angle");
|
||||||
|
optgroup->append_single_option_line("support_material_closing_radius", category_path + "pattern-angle");
|
||||||
optgroup->append_single_option_line("support_material_interface_layers", category_path + "interface-layers");
|
optgroup->append_single_option_line("support_material_interface_layers", category_path + "interface-layers");
|
||||||
optgroup->append_single_option_line("support_material_bottom_interface_layers", category_path + "interface-layers");
|
optgroup->append_single_option_line("support_material_bottom_interface_layers", category_path + "interface-layers");
|
||||||
optgroup->append_single_option_line("support_material_interface_pattern", category_path + "interface-pattern");
|
optgroup->append_single_option_line("support_material_interface_pattern", category_path + "interface-pattern");
|
||||||
|
|
|
@ -1171,7 +1171,7 @@ TEST_CASE("Test for biggest bounding box area", "[Nesting], [NestKernels]")
|
||||||
|
|
||||||
pconfig.object_function = [&pile_box](const Item &item) -> double {
|
pconfig.object_function = [&pile_box](const Item &item) -> double {
|
||||||
Box b = sl::boundingBox(item.boundingBox(), pile_box);
|
Box b = sl::boundingBox(item.boundingBox(), pile_box);
|
||||||
double area = b.area<double>() / (W * W);
|
double area = b.area<double>() / (double(W) * W);
|
||||||
return -area;
|
return -area;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1187,5 +1187,5 @@ TEST_CASE("Test for biggest bounding box area", "[Nesting], [NestKernels]")
|
||||||
|
|
||||||
// Here the result shall be a stairway of boxes
|
// Here the result shall be a stairway of boxes
|
||||||
REQUIRE(pile.size() == N);
|
REQUIRE(pile.size() == N);
|
||||||
REQUIRE(bb.area() == N * N * W * W);
|
REQUIRE(bb.area() == double(N) * N * W * W);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue