Merge branch 'dev'
@ -33,6 +33,7 @@ option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
|
|||||||
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
|
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
|
||||||
option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and integration tests" 0)
|
option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and integration tests" 0)
|
||||||
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
|
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
|
||||||
|
option(SLIC3R_UBSAN "Enable UBSan on Clang and GCC" 0)
|
||||||
# If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, othrewise variable.
|
# If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, othrewise variable.
|
||||||
CMAKE_DEPENDENT_OPTION(SLIC3R_DESKTOP_INTEGRATION "Allow perfoming desktop integration during runtime" 1 "NOT SLIC3R_FHS" 0)
|
CMAKE_DEPENDENT_OPTION(SLIC3R_DESKTOP_INTEGRATION "Allow perfoming desktop integration during runtime" 1 "NOT SLIC3R_FHS" 0)
|
||||||
|
|
||||||
@ -239,6 +240,11 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP
|
|||||||
add_compile_options(-Wno-deprecated-declarations)
|
add_compile_options(-Wno-deprecated-declarations)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Clang reports misleading indentation for some IF blocks because of mixing tabs with spaces.
|
||||||
|
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||||
|
add_compile_options(-Wno-misleading-indentation)
|
||||||
|
endif()
|
||||||
|
|
||||||
#GCC generates loads of -Wunknown-pragmas when compiling igl. The fix is not easy due to a bug in gcc, see
|
#GCC generates loads of -Wunknown-pragmas when compiling igl. The fix is not easy due to a bug in gcc, see
|
||||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66943 or
|
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66943 or
|
||||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
|
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
|
||||||
@ -266,6 +272,32 @@ if (SLIC3R_ASAN)
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (SLIC3R_UBSAN)
|
||||||
|
# Stacktrace for every report is enabled by default. It can be disabled by running PrusaSlicer with "UBSAN_OPTIONS=print_stacktrace=0".
|
||||||
|
|
||||||
|
# Define macro SLIC3R_UBSAN to allow detection in the source code if this sanitizer is enabled.
|
||||||
|
add_compile_definitions(SLIC3R_UBSAN)
|
||||||
|
|
||||||
|
# Clang supports much more useful checks than GCC, so when Clang is detected, another checks will be enabled.
|
||||||
|
# List of what GCC is checking: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
|
||||||
|
# List of what Clang is checking: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set(_ubsan_flags "-fsanitize=undefined,integer")
|
||||||
|
else ()
|
||||||
|
set(_ubsan_flags "-fsanitize=undefined")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_compile_options(${_ubsan_flags} -fno-omit-frame-pointer)
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_ubsan_flags}")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_ubsan_flags}")
|
||||||
|
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${_ubsan_flags}")
|
||||||
|
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lubsan")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
|
||||||
|
9
deps/Boost/Boost.cmake
vendored
@ -28,6 +28,9 @@ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|||||||
elseif (MSVC_VERSION LESS 1930)
|
elseif (MSVC_VERSION LESS 1930)
|
||||||
# 1920-1929 = VS 16.0 (v142 toolset)
|
# 1920-1929 = VS 16.0 (v142 toolset)
|
||||||
set(_boost_toolset "msvc-14.2")
|
set(_boost_toolset "msvc-14.2")
|
||||||
|
elseif (MSVC_VERSION LESS 1940)
|
||||||
|
# 1930-1939 = VS 17.0 (v143 toolset)
|
||||||
|
set(_boost_toolset "msvc-14.3")
|
||||||
else ()
|
else ()
|
||||||
message(FATAL_ERROR "Unsupported MSVC version")
|
message(FATAL_ERROR "Unsupported MSVC version")
|
||||||
endif ()
|
endif ()
|
||||||
@ -117,6 +120,12 @@ set(_build_cmd ${_build_cmd}
|
|||||||
|
|
||||||
set(_install_cmd ${_build_cmd} --prefix=${_prefix} install)
|
set(_install_cmd ${_build_cmd} --prefix=${_prefix} install)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
# When Clang is used with enabled UndefinedBehaviorSanitizer, it produces "undefined reference to '__muloti4'" when __int128 is used.
|
||||||
|
# Because of that, UndefinedBehaviorSanitizer is disabled for those functions that use __int128.
|
||||||
|
list(APPEND _patch_command COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/Boost.patch)
|
||||||
|
endif ()
|
||||||
|
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
dep_Boost
|
dep_Boost
|
||||||
URL "https://boostorg.jfrog.io/artifactory/main/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"
|
||||||
|
23
deps/Boost/Boost.patch
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
diff -u ../boost_1_75_0-orig/boost/rational.hpp ./boost/rational.hpp
|
||||||
|
--- ../boost_1_75_0-orig/boost/rational.hpp 2020-12-03 06:02:19.000000000 +0100
|
||||||
|
+++ ./boost/rational.hpp 2022-01-27 16:02:27.993848905 +0100
|
||||||
|
@@ -302,6 +302,9 @@
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
+ #if defined(__clang__)
|
||||||
|
+ __attribute__((no_sanitize("undefined")))
|
||||||
|
+ #endif
|
||||||
|
BOOST_CXX14_CONSTEXPR typename boost::enable_if_c<rational_detail::is_compatible_integer<T, IntType>::value, rational&>::type operator*= (const T& i)
|
||||||
|
{
|
||||||
|
// Avoid overflow and preserve normalization
|
||||||
|
@@ -311,6 +314,9 @@
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
+ #if defined(__clang__)
|
||||||
|
+ __attribute__((no_sanitize("undefined")))
|
||||||
|
+ #endif
|
||||||
|
BOOST_CXX14_CONSTEXPR typename boost::enable_if_c<rational_detail::is_compatible_integer<T, IntType>::value, rational&>::type operator/= (const T& i)
|
||||||
|
{
|
||||||
|
// Avoid repeated construction
|
4
deps/deps-windows.cmake
vendored
@ -15,6 +15,10 @@ elseif (MSVC_VERSION LESS 1930)
|
|||||||
# 1920-1929 = VS 16.0 (v142 toolset)
|
# 1920-1929 = VS 16.0 (v142 toolset)
|
||||||
set(DEP_VS_VER "16")
|
set(DEP_VS_VER "16")
|
||||||
set(DEP_BOOST_TOOLSET "msvc-14.2")
|
set(DEP_BOOST_TOOLSET "msvc-14.2")
|
||||||
|
elseif (MSVC_VERSION LESS 1940)
|
||||||
|
# 1930-1939 = VS 17.0 (v143 toolset)
|
||||||
|
set(DEP_VS_VER "17")
|
||||||
|
set(DEP_BOOST_TOOLSET "msvc-14.3")
|
||||||
else ()
|
else ()
|
||||||
message(FATAL_ERROR "Unsupported MSVC version")
|
message(FATAL_ERROR "Unsupported MSVC version")
|
||||||
endif ()
|
endif ()
|
||||||
|
4
deps/wxWidgets/wxWidgets.cmake
vendored
@ -12,8 +12,8 @@ endif()
|
|||||||
prusaslicer_add_cmake_project(wxWidgets
|
prusaslicer_add_cmake_project(wxWidgets
|
||||||
# GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
# GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
|
||||||
# GIT_TAG tm_cross_compile #${_wx_git_tag}
|
# GIT_TAG tm_cross_compile #${_wx_git_tag}
|
||||||
URL https://github.com/prusa3d/wxWidgets/archive/refs/heads/v3.1.4-patched.zip
|
URL https://github.com/prusa3d/wxWidgets/archive/73f029adfcc82fb3aa4b01220a013f716e57d110.zip
|
||||||
URL_HASH SHA256=69dec874981d2fc3d90345660c27f3450d8430c483e8446edcc87b6ed18bff8f
|
URL_HASH SHA256=c35fe0187db497b6a3f477e24ed5e307028657ff0c2554385810b6e7961ad2e4
|
||||||
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG
|
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG
|
||||||
CMAKE_ARGS
|
CMAKE_ARGS
|
||||||
-DwxBUILD_PRECOMP=ON
|
-DwxBUILD_PRECOMP=ON
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#
|
#
|
||||||
# Open preferences (might add item to highlight)
|
# Open preferences (might add item to highlight)
|
||||||
# hypertext_type = preferences
|
# hypertext_type = preferences
|
||||||
# hypertext_preferences_page = 2 (values 0-2 according to prefernces tab to be opened)
|
# hypertext_preferences_page = name of the prefernces tab
|
||||||
# hypertext_preferences_item = show_collapse_button (name of variable saved in prusaslicer.ini connected to the setting in preferences)
|
# hypertext_preferences_item = show_collapse_button (name of variable saved in prusaslicer.ini connected to the setting in preferences)
|
||||||
#
|
#
|
||||||
# Open gallery (no aditional var)
|
# Open gallery (no aditional var)
|
||||||
@ -97,7 +97,7 @@ documentation_link = https://help.prusa3d.com/en/article/reload-from-disk_120427
|
|||||||
[hint:Hiding sidebar]
|
[hint:Hiding sidebar]
|
||||||
text = Hiding sidebar\nDid you know that you can hide the right sidebar using the shortcut <b>Shift+Tab</b>? You can also enable the icon for this from the<a>Preferences</a>.
|
text = Hiding sidebar\nDid you know that you can hide the right sidebar using the shortcut <b>Shift+Tab</b>? You can also enable the icon for this from the<a>Preferences</a>.
|
||||||
hypertext_type = preferences
|
hypertext_type = preferences
|
||||||
hypertext_preferences_page = 2
|
hypertext_preferences_page = GUI
|
||||||
hypertext_preferences_item = show_collapse_button
|
hypertext_preferences_item = show_collapse_button
|
||||||
|
|
||||||
[hint:Perspective camera]
|
[hint:Perspective camera]
|
||||||
@ -214,7 +214,7 @@ disabled_tags = SLA
|
|||||||
[hint:Settings in non-modal window]
|
[hint:Settings in non-modal window]
|
||||||
text = Settings in non-modal window\nDid you know that you can open the Settings in a new non-modal window? This means you can have settings open on one screen and the G-code Preview on the other. Go to the<a>Preferences</a>and select Settings in non-modal window.
|
text = Settings in non-modal window\nDid you know that you can open the Settings in a new non-modal window? This means you can have settings open on one screen and the G-code Preview on the other. Go to the<a>Preferences</a>and select Settings in non-modal window.
|
||||||
hypertext_type = preferences
|
hypertext_type = preferences
|
||||||
hypertext_preferences_page = 2
|
hypertext_preferences_page = GUI
|
||||||
hypertext_preferences_item = dlg_settings_layout_mode
|
hypertext_preferences_item = dlg_settings_layout_mode
|
||||||
|
|
||||||
[hint:Adaptive infills]
|
[hint:Adaptive infills]
|
||||||
|
91
resources/icons/edit_button_pressed.svg
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="Capa_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 348.882 348.882"
|
||||||
|
style="enable-background:new 0 0 348.882 348.882;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="edit_button - Copy.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs209">
|
||||||
|
|
||||||
|
|
||||||
|
</defs><sodipodi:namedview
|
||||||
|
id="namedview207"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.3274346"
|
||||||
|
inkscape:cx="89.583613"
|
||||||
|
inkscape:cy="139.85355"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="3191"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Capa_1" />
|
||||||
|
<path
|
||||||
|
d="m 333.988,11.758 -0.42,-0.383 C 325.538,4.04 315.129,0 304.258,0 292.071,0 280.37,5.159 272.154,14.153 L 116.803,184.231 c -1.416,1.55 -2.49,3.379 -3.154,5.37 l -18.267,54.762 c -2.112,6.331 -1.052,13.333 2.835,18.729 3.918,5.438 10.23,8.685 16.886,8.685 0,0 0.001,0 0.001,0 2.879,0 5.693,-0.592 8.362,-1.76 l 52.89,-23.138 c 1.923,-0.841 3.648,-2.076 5.063,-3.626 L 336.771,73.176 C 352.937,55.479 351.69,27.929 333.988,11.758 Z m -203.607,222.489 10.719,-32.134 0.904,-0.99 20.316,18.556 -0.904,0.99 z M 314.621,52.943 182.553,197.53 162.237,178.974 294.305,34.386 c 2.583,-2.828 6.118,-4.386 9.954,-4.386 3.365,0 6.588,1.252 9.082,3.53 l 0.419,0.383 c 5.484,5.009 5.87,13.546 0.861,19.03 z"
|
||||||
|
id="path170"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1" /><path
|
||||||
|
d="m 303.85,138.388 c -8.284,0 -15,6.716 -15,15 v 127.347 c 0,21.034 -17.113,38.147 -38.147,38.147 H 68.904 c -21.035,0 -38.147,-17.113 -38.147,-38.147 V 100.413 c 0,-21.034 17.113,-38.147 38.147,-38.147 h 131.587 c 8.284,0 15,-6.716 15,-15 0,-8.284 -6.716,-15 -15,-15 H 68.904 c -37.577,0 -68.147,30.571 -68.147,68.147 v 180.321 c 0,37.576 30.571,68.147 68.147,68.147 h 181.798 c 37.576,0 68.147,-30.571 68.147,-68.147 V 153.388 c 0.001,-8.284 -6.715,-15 -14.999,-15 z"
|
||||||
|
id="path172"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1" />
|
||||||
|
<g
|
||||||
|
id="g176">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g178">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g180">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g182">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g184">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g186">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g188">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g190">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g192">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g194">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g196">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g198">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g200">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g202">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g204">
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
157
resources/icons/legend_colorchanges.svg
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="Capa_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 348.882 348.882"
|
||||||
|
style="enable-background:new 0 0 348.882 348.882;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="legend_colorchange.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs209">
|
||||||
|
|
||||||
|
|
||||||
|
</defs><sodipodi:namedview
|
||||||
|
id="namedview207"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.8228724"
|
||||||
|
inkscape:cx="159.80606"
|
||||||
|
inkscape:cy="209.63153"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="-9"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Capa_1" />
|
||||||
|
|
||||||
|
<g
|
||||||
|
id="g176">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g178">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g180">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g182">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g184">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g186">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g188">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g190">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g192">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g194">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g196">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g198">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g200">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g202">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g204">
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
style="fill:#da948b;fill-opacity:1"
|
||||||
|
id="rect4805"
|
||||||
|
width="280.72397"
|
||||||
|
height="36.457657"
|
||||||
|
x="34.634773"
|
||||||
|
y="295.91464" /><g
|
||||||
|
id="g5796"
|
||||||
|
transform="matrix(0.5,0,0,0.5,48.819638,25.122266)"><path
|
||||||
|
style="fill:#ffce47"
|
||||||
|
d="m 433.479,205.747 c 75.09,43.351 100.812,139.37 57.461,214.46 -43.351,75.09 -139.37,100.812 -214.46,57.461 -7.304,-4.21 -14.135,-8.93 -20.48,-14.074 l 31.824,-170.903 123.221,-97.645 c 7.632,2.924 15.13,6.491 22.434,10.701 z"
|
||||||
|
id="path4126" /><path
|
||||||
|
style="fill:#ff4181"
|
||||||
|
d="m 78.521,205.747 c -75.09,43.351 -100.812,139.37 -57.461,214.46 43.351,75.09 139.37,100.812 214.46,57.461 7.304,-4.21 14.135,-8.93 20.48,-14.074 L 224.176,292.691 100.955,195.046 c -7.632,2.924 -15.13,6.491 -22.434,10.701 z"
|
||||||
|
id="path4128" /><path
|
||||||
|
style="fill:#4eb9ff"
|
||||||
|
d="m 412.999,170.271 c 0,8.432 -0.667,16.707 -1.953,24.775 L 256,256.196 100.954,195.046 c -1.286,-8.068 -1.953,-16.343 -1.953,-24.775 0,-86.713 70.298,-156.999 156.999,-156.999 86.701,0 156.999,70.285 156.999,156.999 z"
|
||||||
|
id="path4130" /><path
|
||||||
|
style="fill:#ff755c"
|
||||||
|
d="M 312.09,316.957 H 199.91 c -8.7,54.525 12.023,110.943 56.09,146.637 44.066,-35.694 64.789,-92.112 56.09,-146.637 z"
|
||||||
|
id="path4132" /><path
|
||||||
|
style="fill:#85c250"
|
||||||
|
d="m 256,219.797 56.09,97.16 c 51.577,-19.74 90.086,-65.906 98.955,-121.911 C 358.098,174.724 298.865,185 256,219.797 Z"
|
||||||
|
id="path4134" /><path
|
||||||
|
style="fill:#3b8bc0"
|
||||||
|
d="m 100.954,195.046 c 8.869,56.005 47.379,102.171 98.955,121.911 l 56.09,-97.16 C 213.134,185 153.902,174.724 100.954,195.046 Z"
|
||||||
|
id="path4136" /><path
|
||||||
|
style="fill:#174461"
|
||||||
|
d="m 292.981,263.208 c 9.876,17.119 16.173,35.331 19.109,53.748 -17.423,6.661 -36.326,10.313 -56.09,10.313 -19.764,0 -38.667,-3.652 -56.09,-10.313 2.936,-18.418 9.233,-36.629 19.109,-53.749 9.876,-17.107 22.494,-31.667 36.981,-43.411 14.486,11.746 27.105,26.305 36.981,43.412 z"
|
||||||
|
id="path4138" /><use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path4126"
|
||||||
|
id="use4251"
|
||||||
|
width="100%"
|
||||||
|
height="100%" /><use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path4128"
|
||||||
|
id="use4253"
|
||||||
|
width="100%"
|
||||||
|
height="100%" /><use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path4130"
|
||||||
|
id="use4255"
|
||||||
|
width="100%"
|
||||||
|
height="100%" /><use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path4132"
|
||||||
|
id="use4257"
|
||||||
|
width="100%"
|
||||||
|
height="100%" /><use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path4134"
|
||||||
|
id="use4259"
|
||||||
|
width="100%"
|
||||||
|
height="100%" /><use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path4136"
|
||||||
|
id="use4261"
|
||||||
|
width="100%"
|
||||||
|
height="100%" /><use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path4138"
|
||||||
|
id="use4263"
|
||||||
|
width="100%"
|
||||||
|
height="100%" /></g></svg>
|
After Width: | Height: | Size: 4.2 KiB |
9
resources/icons/legend_customgcodes.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
|
||||||
|
<rect id="rect4805" x="11.7" y="81.8" width="73.6" height="9.56" style="fill: #e2d243"/>
|
||||||
|
<g>
|
||||||
|
<path d="M38.1,25c-5.6,5.6-3.5,15.9,3.9,18.7.8.3.9.5-.7,1.9C26.6,58.2,29.4,62,21.5,51.7c-2.5-3.3,4-4.8,3-7.1a17,17,0,0,1-1.8-4.4c-.1-.4-.2-.5-.7-.5-2.6-.1-6.5,1.1-6.6-2.9a45.7,45.7,0,0,0,0-7.4c-.1-1.8.8-3.5,2.8-3.3s4.3,1,4.8-1.2a14,14,0,0,1,1.6-3.8,1,1,0,0,0-.3-1.4c-1.4-1.6-4.9-3.6-2.5-5.9l6.1-6.1a2.1,2.1,0,0,1,3.3,0c4.8,5.1,2.6,2.3,8.1,1.1,1.4-.3,1.3-.9,1.2-1.9a18.6,18.6,0,0,1-.4-3.4c.6-2.8,3.8-1.9,5.9-2h5.3c1.7,0,2.4.7,2.5,2.5s-.8,3.7,1.8,5,3.5,2.6,4.9.8S63.9,5.5,66,7.6l6.3,6.3c.5.4.4.8-.1,1.2L59,28.3c-.7.7-.9.2-1.2-.3C55,20.8,44.2,18.6,39,24.1" style="fill: #ed6b21"/>
|
||||||
|
<path d="M78.9,18.8c1.7.1,8.5,7.4,10.1,9.2a1.7,1.7,0,0,1,0,2.4c-1.6,1.7-3.4,3.4-5.1,5.1a.7.7,0,0,1-1.1,0L72.5,25.2c-.4-.5-.3-.7.3-1.3s2.8-2.8,4.1-4.1A2.8,2.8,0,0,1,78.9,18.8Z" style="fill: #fff"/>
|
||||||
|
<path d="M45.7,73.7h0c-1.6,1.2-3.5,1.2-5.3,1.7l-5.6,1.3c-2.1.4-2.9.3-3.7-1.4a1.3,1.3,0,0,1-.1-.6c.8-3.6,1.5-7.2,2.4-10.8.5-1.8,2.2-2.7,3.4-4s.6,0,.9.2L47.8,70.3a.8.8,0,0,1,.4.9" style="fill: #fff"/>
|
||||||
|
<path d="M78.2,39.4a1.1,1.1,0,0,1,0,1.5c-7.9,8.5-16.6,16.5-24.7,24.9-.6.6-1,.7-1.6,0l-9.8-9.7a1.2,1.2,0,0,1,0-1.6c8.4-8.3,16.7-16.7,25-25,.4-.4.7-.5,1.2,0C71.5,32.8,74.9,36,78.2,39.4Z" style="fill: #fff"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
107
resources/icons/legend_deretract.svg
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="Capa_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 348.882 348.882"
|
||||||
|
style="enable-background:new 0 0 348.882 348.882;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="legend_deretract.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs209">
|
||||||
|
|
||||||
|
|
||||||
|
</defs><sodipodi:namedview
|
||||||
|
id="namedview207"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.6457448"
|
||||||
|
inkscape:cx="174.08531"
|
||||||
|
inkscape:cy="175.30057"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="-9"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Capa_1" />
|
||||||
|
|
||||||
|
<g
|
||||||
|
id="g176">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g178">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g180">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g182">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g184">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g186">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g188">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g190">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g192">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g194">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g196">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g198">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g200">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g202">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g204">
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
d="m 168.35743,271.22732 a 7.3770678,7.3770678 0 0 0 2.35439,5.49356 7.5340268,7.5340268 0 0 0 10.98712,0 l 92.13487,-91.82095 a 7.5340268,7.5340268 0 0 0 0,-10.98712 7.5340268,7.5340268 0 0 0 -10.98712,0 l -92.13487,91.82095 a 7.3770678,7.3770678 0 0 0 -2.35439,5.49356 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3790"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><path
|
||||||
|
d="m 76.222558,179.09246 a 7.3770678,7.3770678 0 0 0 2.354394,5.80747 l 92.134868,91.82095 a 7.5340268,7.5340268 0 0 0 10.98712,0 7.5340268,7.5340268 0 0 0 0,-10.98712 L 89.564071,173.59889 a 7.5340268,7.5340268 0 0 0 -10.987119,0 7.3770678,7.3770678 0 0 0 -2.354394,5.49357 z m 92.134872,18.20723 a 8.0049033,8.0049033 0 0 0 2.35439,5.65052 7.8479445,7.8479445 0 0 0 10.98712,0 l 92.13487,-92.29183 a 7.5340268,7.5340268 0 0 0 0,-10.987123 7.5340268,7.5340268 0 0 0 -10.98712,0 l -92.13487,92.134873 a 7.6909855,7.6909855 0 0 0 -2.35439,5.49356 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3792"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><path
|
||||||
|
d="m 76.222558,105.16482 a 7.3770678,7.3770678 0 0 0 2.354394,5.49356 l 92.134868,92.29183 a 7.8479445,7.8479445 0 0 0 10.98712,0 7.8479445,7.8479445 0 0 0 0,-11.14408 L 89.564071,99.671257 a 7.8479445,7.8479445 0 0 0 -13.341513,5.493563 z m 92.134872,18.20723 a 8.0049033,8.0049033 0 0 0 2.35439,5.65052 7.8479445,7.8479445 0 0 0 10.98712,0 l 92.13487,-92.134866 a 7.8479445,7.8479445 0 0 0 0,-11.144082 7.8479445,7.8479445 0 0 0 -10.98712,0 l -92.13487,92.134868 a 7.8479445,7.8479445 0 0 0 -2.35439,5.49356 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3794"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><path
|
||||||
|
d="m 76.222558,31.237177 a 8.0049033,8.0049033 0 0 0 2.354394,5.650527 l 92.134868,92.134866 a 7.8479445,7.8479445 0 0 0 10.98712,0 7.8479445,7.8479445 0 0 0 0,-11.14408 L 89.564071,25.743622 a 7.8479445,7.8479445 0 0 0 -13.341513,5.493555 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3796"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><rect
|
||||||
|
style="fill:#49adcf;fill-opacity:1"
|
||||||
|
id="rect4805"
|
||||||
|
width="280.72397"
|
||||||
|
height="36.457657"
|
||||||
|
x="34.634773"
|
||||||
|
y="295.91464" /></svg>
|
After Width: | Height: | Size: 3.8 KiB |
76
resources/icons/legend_pauseprints.svg
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
id="Layer_1"
|
||||||
|
style="enable-background:new 0 0 96 96;"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 96 96"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="legend_pauseprints.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs7016"><linearGradient
|
||||||
|
id="linearGradient7403"
|
||||||
|
inkscape:swatch="solid"><stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop7401" /></linearGradient></defs><sodipodi:namedview
|
||||||
|
id="namedview7014"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="4.2291667"
|
||||||
|
inkscape:cx="6.2660098"
|
||||||
|
inkscape:cy="41.73399"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="-9"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Layer_1" /><style
|
||||||
|
type="text/css"
|
||||||
|
id="style6991">
|
||||||
|
.st0{fill:none;stroke:#010000;stroke-width:4;stroke-linecap:round;stroke-miterlimit:10;}
|
||||||
|
.st1{fill:none;stroke:#010000;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st2{fill:none;stroke:#010000;stroke-width:4;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st3{fill:none;stroke:#010000;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st4{fill:#010000;}
|
||||||
|
.st5{fill:none;stroke:#010000;stroke-width:3.8974;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st6{fill:none;stroke:#010000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st7{fill:#010000;stroke:#010000;stroke-width:2;stroke-miterlimit:10;}
|
||||||
|
.st8{opacity:0.75;}
|
||||||
|
.st9{fill:none;stroke:#010000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st10{fill:none;stroke:#010000;stroke-width:6;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st11{fill:none;stroke:#010000;stroke-width:3;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st12{fill:none;stroke:#010000;stroke-width:3.9497;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st13{fill:none;stroke:#010000;stroke-width:1.9008;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st14{fill:none;stroke:#010000;stroke-width:1.9935;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st15{fill:none;stroke:#010000;stroke-width:4;stroke-miterlimit:10;}
|
||||||
|
.st16{fill:none;stroke:#010000;stroke-width:1.9048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st17{fill:none;stroke:#010000;stroke-width:1.934;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st18{fill:none;stroke:#010000;stroke-width:1.9684;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
.st19{fill:none;stroke:#010000;stroke-width:1.9343;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||||
|
</style><rect
|
||||||
|
style="fill:#52f083;fill-opacity:1;stroke-width:0.262144"
|
||||||
|
id="rect4805"
|
||||||
|
width="73.590103"
|
||||||
|
height="9.5571566"
|
||||||
|
x="11.677858"
|
||||||
|
y="81.76329" /><g
|
||||||
|
id="g7865"
|
||||||
|
transform="matrix(0.13421773,0,0,0.13421773,16.48933,9.3957966)"><path
|
||||||
|
d="m 355.507,181.955 c 8.793,-6.139 29.39,-20.519 29.39,-55.351 v -71.77 h 9.814 c 4.49,0 8.17,-3.679 8.17,-8.169 V 8.165 C 402.881,3.675 399.2,0 394.711,0 H 78.351 c -4.495,0 -8.165,3.675 -8.165,8.165 v 38.5 c 0,4.491 3.67,8.169 8.165,8.169 h 9.82 v 73.071 c 0,34.499 10.502,42.576 29.074,53.89 l 80.745,49.203 v 20.984 c -20.346,12.23 -73.465,44.242 -80.434,49.107 -8.793,6.135 -29.384,20.51 -29.384,55.352 v 61.793 h -9.82 c -4.495,0 -8.165,3.676 -8.165,8.166 v 38.498 c 0,4.49 3.67,8.17 8.165,8.17 h 316.361 c 4.49,0 8.17,-3.68 8.17,-8.17 V 426.4 c 0,-4.49 -3.681,-8.166 -8.17,-8.166 h -9.814 V 355.13 c 0,-34.493 -10.508,-42.572 -29.069,-53.885 l -80.745,-49.202 v -20.987 c 20.332,-12.225 73.452,-44.234 80.422,-49.101 z m -102.781,90.904 87.802,53.5 c 6.734,4.109 10.333,6.373 12.001,9.002 1.991,3.164 2.963,9.627 2.963,19.768 v 63.104 H 117.574 V 356.44 c 0,-19.507 9.718,-26.289 16.81,-31.242 5.551,-3.865 54.402,-33.389 85.878,-52.289 4.428,-2.658 7.135,-7.441 7.135,-12.611 v -37.563 c 0,-5.123 -2.671,-9.883 -7.053,-12.55 l -87.54,-53.339 -0.265,-0.165 c -6.741,-4.105 -10.336,-6.369 -11.998,-9.009 -1.992,-3.156 -2.968,-9.626 -2.968,-19.767 v -73.07 h 237.918 v 71.77 c 0,19.5 -9.718,26.288 -16.814,31.235 -5.546,3.872 -54.391,33.395 -85.869,52.295 -4.427,2.658 -7.134,7.442 -7.134,12.601 v 37.563 c 0.001,5.132 2.672,9.889 7.052,12.56 z"
|
||||||
|
id="path7859"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" /><path
|
||||||
|
d="m 331.065,154.234 c 0,0 5.291,-4.619 -2.801,-3.299 -19.178,3.115 -53.079,15.133 -92.079,15.133 -39,0 -57,-11 -82.507,-11.303 -5.569,-0.066 -5.456,3.629 0.937,7.391 6.386,3.758 63.772,35.681 71.671,40.08 7.896,4.389 12.417,4.05 20.786,0 12.174,-5.902 83.993,-48.002 83.993,-48.002 z"
|
||||||
|
id="path7861"
|
||||||
|
style="stroke:#ed6b21;stroke-opacity:1;fill:#ed6b21;fill-opacity:1" /><path
|
||||||
|
d="m 154.311,397.564 c -6.748,6.209 -9.978,10.713 5.536,10.713 12.656,0 139.332,0 155.442,0 16.099,0 9.856,-5.453 2.311,-12.643 -14.576,-13.883 -45.416,-23.566 -82.414,-23.566 -38.754,0 -65.844,11.655 -80.875,25.496 z"
|
||||||
|
id="path7863"
|
||||||
|
style="stroke:#ed6b21;stroke-opacity:1;fill:#ed6b21;fill-opacity:1" /></g></svg>
|
After Width: | Height: | Size: 5.4 KiB |
110
resources/icons/legend_retract.svg
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="Capa_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 348.882 348.882"
|
||||||
|
style="enable-background:new 0 0 348.882 348.882;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="legend_retract.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs209">
|
||||||
|
|
||||||
|
|
||||||
|
</defs><sodipodi:namedview
|
||||||
|
id="namedview207"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.6457448"
|
||||||
|
inkscape:cx="174.08531"
|
||||||
|
inkscape:cy="175.30057"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="-9"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Capa_1" />
|
||||||
|
|
||||||
|
<g
|
||||||
|
id="g176">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g178">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g180">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g182">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g184">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g186">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g188">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g190">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g192">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g194">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g196">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g198">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g200">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g202">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g204">
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g5653"
|
||||||
|
transform="matrix(1,0,0,-1,0,302.59856)"
|
||||||
|
style="stroke:#ed6b21;stroke-opacity:1;fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none"><path
|
||||||
|
d="m 168.35743,271.22732 a 7.3770678,7.3770678 0 0 0 2.35439,5.49356 7.5340268,7.5340268 0 0 0 10.98712,0 l 92.13487,-91.82095 a 7.5340268,7.5340268 0 0 0 0,-10.98712 7.5340268,7.5340268 0 0 0 -10.98712,0 l -92.13487,91.82095 a 7.3770678,7.3770678 0 0 0 -2.35439,5.49356 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3790"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><path
|
||||||
|
d="m 76.222558,179.09246 a 7.3770678,7.3770678 0 0 0 2.354394,5.80747 l 92.134868,91.82095 a 7.5340268,7.5340268 0 0 0 10.98712,0 7.5340268,7.5340268 0 0 0 0,-10.98712 L 89.564071,173.59889 a 7.5340268,7.5340268 0 0 0 -10.987119,0 7.3770678,7.3770678 0 0 0 -2.354394,5.49357 z m 92.134872,18.20723 a 8.0049033,8.0049033 0 0 0 2.35439,5.65052 7.8479445,7.8479445 0 0 0 10.98712,0 l 92.13487,-92.29183 a 7.5340268,7.5340268 0 0 0 0,-10.987123 7.5340268,7.5340268 0 0 0 -10.98712,0 l -92.13487,92.134873 a 7.6909855,7.6909855 0 0 0 -2.35439,5.49356 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3792"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><path
|
||||||
|
d="m 76.222558,105.16482 a 7.3770678,7.3770678 0 0 0 2.354394,5.49356 l 92.134868,92.29183 a 7.8479445,7.8479445 0 0 0 10.98712,0 7.8479445,7.8479445 0 0 0 0,-11.14408 L 89.564071,99.671257 a 7.8479445,7.8479445 0 0 0 -13.341513,5.493563 z m 92.134872,18.20723 a 8.0049033,8.0049033 0 0 0 2.35439,5.65052 7.8479445,7.8479445 0 0 0 10.98712,0 l 92.13487,-92.134866 a 7.8479445,7.8479445 0 0 0 0,-11.144082 7.8479445,7.8479445 0 0 0 -10.98712,0 l -92.13487,92.134868 a 7.8479445,7.8479445 0 0 0 -2.35439,5.49356 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3794"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><path
|
||||||
|
d="m 76.222558,31.237177 a 8.0049033,8.0049033 0 0 0 2.354394,5.650527 l 92.134868,92.134866 a 7.8479445,7.8479445 0 0 0 10.98712,0 7.8479445,7.8479445 0 0 0 0,-11.14408 L 89.564071,25.743622 a 7.8479445,7.8479445 0 0 0 -13.341513,5.493555 z"
|
||||||
|
fill="#333333"
|
||||||
|
id="path3796"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke-width:4;stroke:#ed6b21;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /></g><rect
|
||||||
|
style="fill:#cd22d6;fill-opacity:1"
|
||||||
|
id="rect4805"
|
||||||
|
width="280.72397"
|
||||||
|
height="36.457657"
|
||||||
|
x="34.634773"
|
||||||
|
y="295.91464" /></svg>
|
After Width: | Height: | Size: 4.0 KiB |
45
resources/icons/legend_seams.svg
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
class="svg-icon"
|
||||||
|
style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;"
|
||||||
|
viewBox="0 0 1024 1024"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1878"
|
||||||
|
sodipodi:docname="legend_seams.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs1882" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1880"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.39648438"
|
||||||
|
inkscape:cx="361.93103"
|
||||||
|
inkscape:cy="596.49261"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="-9"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1878" />
|
||||||
|
<path
|
||||||
|
d="m 257.84285,390.79005 a 34.420553,34.420553 0 0 0 8.87467,-68.26667 l -60.07467,-15.01866 a 34.133334,34.133334 0 1 0 -17.74933,65.87733 l 60.07466,16.04267 a 26.624,26.624 0 0 0 8.87467,1.36533 z M 389.59752,199.98472 a 34.133334,34.133334 0 0 0 34.13333,25.25866 27.989334,27.989334 0 0 0 8.87467,0 34.133334,34.133334 0 0 0 23.89333,-41.64266 l -16.04267,-60.07467 a 34.133334,34.133334 0 1 0 -65.87733,17.74933 z m 164.864,341.33333 a 34.133334,34.133334 0 0 0 -49.49334,0 L 385.50152,662.83272 a 75.434666,75.434666 0 0 1 -104.448,0 73.386666,73.386666 0 0 1 0,-104.448 L 402.56818,438.91805 a 34.133334,34.133334 0 1 0 -48.128,-48.128 L 231.90152,509.91538 A 142.8846,142.8846 0 1 0 433.97085,711.98472 L 554.46152,591.49405 a 34.133334,34.133334 0 0 0 0,-50.176 z M 272.17885,254.25672 a 34.133334,34.133334 0 0 0 23.89333,9.89866 34.133334,34.133334 0 0 0 24.23467,-9.89866 34.133334,34.133334 0 0 0 0,-48.128 l -44.032,-44.032 a 34.133334,34.133334 0 0 0 -48.128,48.128 z m 548.864,250.19733 -60.07467,-16.04267 a 34.133334,34.133334 0 1 0 -17.06666,65.87734 l 60.07466,16.04266 h 8.87467 a 34.420552,34.420552 0 0 0 8.87467,-68.26666 z m -200.704,173.39733 a 34.133334,34.133334 0 0 0 -41.984,-23.89333 34.133334,34.133334 0 0 0 -23.89333,41.64267 l 16.04266,60.07466 a 34.133334,34.133334 0 0 0 34.13334,25.25867 39.253334,39.253334 0 0 0 8.87466,0 34.133334,34.133334 0 0 0 24.23467,-41.984 z m 117.41867,-53.58933 a 34.133334,34.133334 0 0 0 -48.128,48.128 l 44.032,44.032 a 34.133334,34.133334 0 0 0 48.128,0 34.133334,34.133334 0 0 0 0,-48.128 z m 81.23733,-356.01067 a 141.99467,141.99467 0 0 0 -243.02933,-102.4 L 455.47485,287.36605 a 34.876601,34.876601 0 1 0 49.49333,49.152 L 624.43485,215.00338 a 75.434666,75.434666 0 0 1 104.448,0 73.386666,73.386666 0 0 1 0,104.448 L 607.36818,438.91805 a 34.133334,34.133334 0 0 0 0,48.128 34.133334,34.133334 0 0 0 48.128,0 L 778.03485,367.92072 a 143.01867,143.01867 0 0 0 40.96,-99.66934 z"
|
||||||
|
id="path1876"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke-width:0.8" />
|
||||||
|
<rect
|
||||||
|
style="fill:#e6e6e6;fill-opacity:1;stroke-width:2.86654"
|
||||||
|
id="rect4805"
|
||||||
|
width="804.70764"
|
||||||
|
height="104.50751"
|
||||||
|
x="104.60175"
|
||||||
|
y="855.72644" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
77
resources/icons/legend_shells.svg
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 457.478 457.478"
|
||||||
|
enable-background="new 0 0 457.478 457.478"
|
||||||
|
id="svg24"
|
||||||
|
sodipodi:docname="legend_shell.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs28" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview26"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.88747438"
|
||||||
|
inkscape:cx="-16.3385"
|
||||||
|
inkscape:cy="218.03446"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="-9"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg24" />
|
||||||
|
<g
|
||||||
|
id="g22"
|
||||||
|
style="fill:#ffffff;fill-opacity:1">
|
||||||
|
<path
|
||||||
|
d="m423.173,110.709l-189.434-109.369c-3.094-1.786-6.906-1.786-10-3.33067e-15l-189.433,109.369c-3.094,1.786-5,5.087-5,8.66v218.739c0,3.573 1.906,6.874 5,8.66l189.434,109.37c1.547,0.893 3.273,1.34 5,1.34s3.453-0.447 5-1.34l189.434-109.37c3.094-1.786 5-5.087 5-8.66v-218.739c-0.001-3.572-1.908-6.874-5.001-8.66zm-15,206.884l-6.459-3.729c-4.781-2.762-10.898-1.123-13.66,3.66-2.762,4.783-1.123,10.899 3.66,13.661l9.226,5.327-162.201,93.647v-188.638c0.128,0.005 0.255,0.024 0.383,0.024 3.456,0 6.817-1.793 8.67-5.001 1.421-2.46 1.669-5.271 0.932-7.799l159.449-92.058v180.906zm-338.747-.069c-2.761-4.782-8.874-6.422-13.66-3.66l-6.46,3.729v-180.905l159.449,92.058c-0.737,2.527-0.488,5.338 0.932,7.798 1.853,3.208 5.213,5.001 8.67,5.001 0.127,0 0.255-0.02 0.383-0.024v188.637l-162.202-93.647 9.227-5.327c4.784-2.761 6.422-8.877 3.661-13.66zm159.314-275.941c5.522,2.84217e-14 10-4.477 10-10v-4.263l159.431,92.048-159.634,92.165c-0.931-4.559-4.964-7.989-9.797-7.989-4.834,0-8.867,3.43-9.798,7.99l-159.635-92.166 159.433-92.048v4.264c0,5.522 4.478,9.999 10,9.999z"
|
||||||
|
id="path2"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m304.003,280.544l17.839,10.3c1.575,0.909 3.294,1.341 4.99,1.341 3.456,0 6.817-1.793 8.67-5.001 2.762-4.783 1.123-10.898-3.66-13.66l-17.839-10.3c-4.784-2.761-10.898-1.123-13.66,3.66s-1.123,10.898 3.66,13.66z"
|
||||||
|
id="path4"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m260.147,255.224l17.84,10.299c1.575,0.91 3.294,1.341 4.99,1.341 3.456,0 6.818-1.793 8.67-5.001 2.762-4.783 1.123-10.899-3.66-13.66l-17.84-10.299c-4.784-2.763-10.899-1.123-13.66,3.66-2.762,4.783-1.123,10.899 3.66,13.66z"
|
||||||
|
id="path6"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m347.857,305.864l17.84,10.3c1.575,0.909 3.294,1.341 4.99,1.341 3.456,0 6.818-1.793 8.67-5.001 2.762-4.783 1.123-10.899-3.66-13.66l-17.84-10.3c-4.784-2.762-10.9-1.123-13.66,3.66-2.762,4.783-1.123,10.899 3.66,13.66z"
|
||||||
|
id="path8"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m174.501,266.865c1.696,0 3.416-0.432 4.99-1.341l17.84-10.3c4.783-2.761 6.422-8.877 3.66-13.66-2.761-4.783-8.877-6.421-13.66-3.66l-17.84,10.3c-4.783,2.761-6.422,8.877-3.66,13.66 1.852,3.209 5.213,5.001 8.67,5.001z"
|
||||||
|
id="path10"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m86.791,317.505c1.696,0 3.415-0.432 4.99-1.341l17.84-10.299c4.783-2.761 6.422-8.877 3.66-13.66-2.76-4.782-8.874-6.421-13.66-3.66l-17.84,10.299c-4.783,2.761-6.422,8.877-3.66,13.66 1.852,3.208 5.213,5.001 8.67,5.001z"
|
||||||
|
id="path12"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m130.646,292.185c1.696,0 3.416-0.432 4.99-1.341l17.839-10.3c4.783-2.762 6.422-8.877 3.66-13.66-2.761-4.783-8.877-6.421-13.66-3.66l-17.839,10.3c-4.783,2.762-6.422,8.877-3.66,13.66 1.853,3.208 5.213,5.001 8.67,5.001z"
|
||||||
|
id="path14"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="M218.74,82.223c0,5.523,4.478,10,10,10s10-4.477,10-10V61.624c0-5.523-4.478-10-10-10s-10,4.477-10,10V82.223z"
|
||||||
|
id="path16"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m228.74,102.264c-5.522,0-10,4.477-10,10v20.599c0,5.523 4.478,10 10,10s10-4.477 10-10v-20.599c0-5.523-4.477-10-10-10z"
|
||||||
|
id="path18"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
d="m228.74,152.904c-5.522,0-10,4.477-10,10v20.599c0,5.523 4.478,10 10,10s10-4.477 10-10v-20.599c0-5.523-4.477-10-10-10z"
|
||||||
|
id="path20"
|
||||||
|
style="fill:#ffffff;fill-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
10
resources/icons/legend_toolchanges.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
|
||||||
|
<rect id="rect4805" x="11.7" y="81.8" width="73.6" height="9.6" style="fill: #c1be63"/>
|
||||||
|
<polyline points="29.9 53.6 34.5 44.8 43.9 44.7 43.9 33.1 38.9 33.1 38.9 6.2 17 6.2 17 33.2 11.6 33.2 11.6 44.7 21 44.7 25.6 53.6" style="fill: #fff"/>
|
||||||
|
<polyline points="68 73.2 73.3 63.3 84 63.2 84 50 78.3 50 78.3 19.7 53.3 19.7 53.3 50.2 47.1 50.2 47.1 63.2 57.9 63.2 63.1 73.2" style="fill: #ed6b21"/>
|
||||||
|
<g>
|
||||||
|
<path d="M32.3,62.6c4.5,5.9,10.4,7.8,18.5,8.4" style="fill: none;stroke: #fff;stroke-miterlimit: 10;stroke-width: 2.8346456692913384px"/>
|
||||||
|
<polygon points="28.9 66.3 28.8 56.4 37.4 61.2 28.9 66.3" style="fill: #fff"/>
|
||||||
|
<polygon points="49.2 75.8 57.9 71.2 49.6 65.9 49.2 75.8" style="fill: #fff"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 844 B |
3
resources/icons/legend_toolmarker.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
|
||||||
|
<polyline points="50.6 92.4 57.8 78.8 72.7 78.7 72.7 60.6 64.7 60.6 64.7 2.2 30.3 2.2 30.3 60.7 21.8 60.7 21.8 78.7 36.6 78.7 43.9 92.4" style="fill: #fff"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 251 B |
163
resources/icons/legend_travel.svg
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 24.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
id="Layer_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
style="enable-background:new 0 0 512 512;"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:docname="legend_travel.svg"
|
||||||
|
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs960" /><sodipodi:namedview
|
||||||
|
id="namedview958"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.5292969"
|
||||||
|
inkscape:cx="256"
|
||||||
|
inkscape:cy="256"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="-9"
|
||||||
|
inkscape:window-y="-9"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g955" />
|
||||||
|
<g
|
||||||
|
id="g955">
|
||||||
|
<path
|
||||||
|
d="M113.5,451c2.3,0,4.4-1,5.8-2.8c3.2-3.9,76.7-96.1,76.7-139.7c0-45.6-36.9-82.5-82.5-82.5S31,262.9,31,308.5 c0,43.6,73.5,135.8,76.7,139.7C109.1,450,111.2,451,113.5,451z M113.5,241c37.3,0,67.5,30.2,67.5,67.5c0,29.1-44.3,92.7-67.5,122.8 C90.3,401.2,46,337.6,46,308.5C46,271.2,76.2,241,113.5,241z"
|
||||||
|
id="path893"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke:#ed6b21;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M143.5,301c0-16.6-13.4-30-30-30s-30,13.4-30,30s13.4,30,30,30S143.5,317.6,143.5,301z M98.5,301c0-8.3,6.7-15,15-15 s15,6.7,15,15s-6.7,15-15,15S98.5,309.3,98.5,301z"
|
||||||
|
id="path895"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke:#ed6b21;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M421,188.5c2.2,0,4.3-1,5.7-2.6c5.6-6.5,54.3-64,54.3-94.9c0-33.1-26.9-60-60-60s-60,26.9-60,60 c0,30.9,48.8,88.4,54.3,94.9C416.7,187.5,418.8,188.5,421,188.5z M421,46c24.8,0,45,20.2,45,45c0,19-28.6,58.2-45,78.3 c-16.4-20.1-45-59.2-45-78.3C376,66.2,396.2,46,421,46z"
|
||||||
|
id="path897"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke:#ed6b21;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M443.5,83.5c0-12.4-10.1-22.5-22.5-22.5s-22.5,10.1-22.5,22.5S408.6,106,421,106S443.5,95.9,443.5,83.5z M413.5,83.5 c0-4.1,3.4-7.5,7.5-7.5s7.5,3.4,7.5,7.5S425.1,91,421,91S413.5,87.6,413.5,83.5z"
|
||||||
|
id="path899"
|
||||||
|
style="fill:#ed6b21;fill-opacity:1;stroke:#ed6b21;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M413.5,218.5h7.5c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-7.5c-4.1,0-7.5,3.4-7.5,7.5S409.4,218.5,413.5,218.5z"
|
||||||
|
id="path901"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M316,263.5h15.2c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-15.3c-2,0-3.9,0.8-5.3,2.2s-2.2,3.3-2.2,5.3 C308.5,260.2,311.8,263.5,316,263.5z"
|
||||||
|
id="path903"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M400.1,256c0,4.1,3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-15.3C403.4,248.5,400.1,251.9,400.1,256z"
|
||||||
|
id="path905"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M367.7,218.5h15.3c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-15.3c-4.1,0-7.5,3.4-7.5,7.5S363.5,218.5,367.7,218.5z"
|
||||||
|
id="path907"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M167.6,466h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5S171.8,466,167.6,466z"
|
||||||
|
id="path909"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M294,245.7c0.5,0,1-0.1,1.6-0.2c4.1-0.9,6.6-4.8,5.8-8.9c-0.2-1-0.3-2.1-0.3-3.1c0-2.4,0.6-4.7,1.6-6.8 c1.9-3.7,0.4-8.2-3.3-10.1c-3.7-1.9-8.2-0.4-10.1,3.3c-3.1,6.1-4,13.1-2.6,19.8C287.4,243.1,290.4,245.6,294,245.7z"
|
||||||
|
id="path911"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M361.8,263.5H377c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-15.3c-4.1,0-7.5,3.4-7.5,7.5S357.6,263.5,361.8,263.5z"
|
||||||
|
id="path913"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M321.8,218.5h15.3c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-15.3c-4.1,0-7.5,3.4-7.5,7.5S317.7,218.5,321.8,218.5z"
|
||||||
|
id="path915"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M247.7,348.8c0.6,0.2,1.2,0.2,1.8,0.2c3.4,0,6.4-2.4,7.3-5.7c1-3.9,2.8-7.4,5.3-10.5c1.8-2,2.4-4.9,1.4-7.5 c-0.9-2.6-3.1-4.4-5.8-4.9c-2.7-0.5-5.4,0.6-7.1,2.7c-4,4.8-6.9,10.4-8.4,16.5c-0.5,1.9-0.2,4,0.8,5.7 C244.1,347.1,245.8,348.3,247.7,348.8z"
|
||||||
|
id="path917"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M395.9,465.7c-1.6,0.2-3.2,0.3-4.9,0.3h-9.4c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h9.4c2.3,0,4.5-0.1,6.7-0.4 c4.1-0.5,7-4.3,6.5-8.4C403.7,468.1,399.9,465.2,395.9,465.7L395.9,465.7z"
|
||||||
|
id="path919"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M406.3,378.2c-5-1.5-10.1-2.3-15.3-2.2h-2c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h2c3.7,0,7.4,0.5,10.9,1.6 c0.7,0.2,1.4,0.3,2.2,0.3c3.7,0,6.9-2.7,7.4-6.4C412.1,382.9,409.9,379.4,406.3,378.2L406.3,378.2z"
|
||||||
|
id="path921"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M390.3,323.5c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5H375c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5H390.3z"
|
||||||
|
id="path923"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M435.1,440.1c-3.8-1.7-8.2,0-9.9,3.8c-1.7,3.9-4.1,7.4-7.1,10.5c-1.9,1.9-2.7,4.7-1.9,7.3c0.7,2.6,2.8,4.6,5.5,5.3 c2.6,0.6,5.4-0.2,7.3-2.2c4.1-4.3,7.5-9.3,9.9-14.7C440.6,446.3,438.9,441.8,435.1,440.1z"
|
||||||
|
id="path925"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M474.4,287.3c-1.9-0.6-4-0.3-5.7,0.6c-1.7,1-3,2.6-3.6,4.5c-1.1,3.7-3.1,7-5.9,9.7c-3,2.9-3,7.7-0.1,10.6s7.7,3,10.6,0.1 c4.6-4.5,7.9-10,9.7-16.2c0.6-1.9,0.3-4-0.6-5.7C477.9,289.2,476.3,287.9,474.4,287.3z"
|
||||||
|
id="path927"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M465.8,273.5c3,0,5.6-1.7,6.9-4.4c1.2-2.7,0.7-5.9-1.3-8.1c-4.3-4.8-9.7-8.4-15.8-10.4c-3.9-1.3-8.2,0.7-9.5,4.7 s0.7,8.2,4.7,9.5c3.6,1.2,6.9,3.4,9.4,6.3C461.7,272.6,463.7,273.5,465.8,273.5z"
|
||||||
|
id="path929"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M358.5,376h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5S362.6,376,358.5,376z"
|
||||||
|
id="path931"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M436.2,308.5h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5S440.3,308.5,436.2,308.5z"
|
||||||
|
id="path933"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M213.5,466h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5S217.6,466,213.5,466z"
|
||||||
|
id="path935"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M434.4,399c-2.3-3.4-7-4.3-10.4-2c-3.4,2.3-4.3,7-2,10.4c2.4,3.5,4.2,7.4,5.2,11.5c0.6,2.7,2.6,4.8,5.2,5.6 c2.6,0.8,5.5,0,7.4-1.9c1.9-1.9,2.6-4.8,1.9-7.4C440.3,409.5,437.8,404,434.4,399z"
|
||||||
|
id="path937"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M270.6,373.3c-3.6-1.8-6.7-4.3-9.1-7.5c-2.5-3.3-7.3-3.9-10.5-1.3c-3.3,2.5-3.9,7.3-1.3,10.5c3.8,4.9,8.7,8.9,14.3,11.7 c3.7,1.7,8.1,0.2,9.9-3.5C275.7,379.6,274.3,375.2,270.6,373.3z"
|
||||||
|
id="path939"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M259.3,466H244c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5S263.4,466,259.3,466z"
|
||||||
|
id="path941"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M351,466h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5H351c4.1,0,7.5-3.4,7.5-7.5S355.1,466,351,466z"
|
||||||
|
id="path943"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M298.6,323.5c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5H298.6z"
|
||||||
|
id="path945"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M344.5,323.5c4.1,0,7.5-3.4,7.5-7.5s-3.4-7.5-7.5-7.5h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5H344.5z"
|
||||||
|
id="path947"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M312.6,376h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5S316.8,376,312.6,376z"
|
||||||
|
id="path949"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M305.2,466h-15.3c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h15.3c4.1,0,7.5-3.4,7.5-7.5S309.3,466,305.2,466z"
|
||||||
|
id="path951"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M121,466h-7.5c-4.1,0-7.5,3.4-7.5,7.5s3.4,7.5,7.5,7.5h7.5c4.1,0,7.5-3.4,7.5-7.5S125.1,466,121,466z"
|
||||||
|
id="path953"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 10 KiB |
16
resources/icons/legend_wipe.svg
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg enable-background="new 0 0 1000 1000" version="1.1" viewBox="0 0 1e3 1e3" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect id="path6995" width="1e3" height="1e3" style="display:none;stroke:#FFFFFF;stroke-miterlimit:10"/>
|
||||||
|
|
||||||
|
<g transform="translate(1.7416 41.799)">
|
||||||
|
<path id="path6997"
|
||||||
|
d="m969.8 495.7c-10.7 22.2-16.2 30.3-35.8 53-47.1 54.8-64.5 95.5-83.8 195.8-12.6 65.9-21.5 86.8-45.2 103.8-1.8 1.3-4 1.9-6.2 1.9l-172.4-3.4c-6.6-0.1-11.4-6.4-9.7-12.8 21.1-79.3 66.6-153.2 57.1-240.5 0-0.3-0.1-0.6-0.1-0.9l-0.7-66.3c0-0.7-0.1-1.3-0.2-2-16.4-78.2 46.5-267.9-73-265.6-4.2 0.1-8-2.3-9.6-6.1-16.3-37.2-32.6-71.2-82.7-62.5-3.4 0.6-6.8-0.5-9.2-3-34.4-36.2-88.1-55.1-121.6-1.8-1.5 2.5-7.1 4.6-9.9 3.8-121.5-16.5-81.4 135.5-86.4 221.7-0.5 8.5-10.5 12.7-16.9 7.1-51.8-45.3-132.7-6.5-100.3 71.4l0.5 1.3c0.1 0.3 0.3 0.9 0.2 0.9 42.3 94.2 69.4 198.2 143.9 274.4 0.3 0.3 0.7 0.7 1.1 0.9 6.5 5 11.8 10.6 16.1 16.5 17.3 24-0.4 57.4-29.9 56.9l-190.5-3.7c-20.4-0.4-40-8.7-54.3-23.2-9.6-9.7-18.1-20.1-22-27.5-13.5-25.5-18.6-58.7-14.4-92.5 3.2-27.3 9.9-53 26.7-104.2 18.2-55.6 21.2-69.8 21.4-98.9 0-30.2-4-49-20.6-100.3-30.8-93.9-37.9-147.9-25.8-195.6 6.3-24.7 14.4-39.3 31.4-56.3 25.1-24.9 56-37 107-41.5 28.5-2.6 55-1.4 99.9 4.3 36.6 4.7 63.5 4.2 89.2-2 22.2-5.5 27.5-7.5 77.9-32 45.3-22 61.5-27.7 90-31.2 63.7-7.9 129.5 6.3 163.8 35.6 5.1 4.3 17.8 20 28.1 34.4 43.7 61.5 80.7 86.4 149.5 100.7 36.2 7.5 52.8 16.2 76.9 40.5 25.9 26.1 42.1 55 52.4 93.2 14.4 53.8 10 110-11.9 155.7z"
|
||||||
|
style="fill:#FFFFFF" />
|
||||||
|
|
||||||
|
<path id="path6999"
|
||||||
|
d="m233.1 455.1c-87.3-66.3 66.2 239.8 88.3 256.3 31.3 39.1 55.6 123.7 81.2 151.8s123.2 38.4 158.4 6.5 76.5-180 66.4-269.3c-0.4-90.4-5-180.8-1.4-271.3 2.4-33.2-42.1-34-40.7-0.7-0.5 33.3-0.9 66.7-1.5 100-0.3 16.5-9.6 26.6-23.6 26.2-60.5-8.5 17.7-210.7-40-219.9-56.8 10 14.9 211.2-46 218.1-62.2-6.3 18.3-243.8-39.2-255.1-60.1 9.3 16 247.1-47.7 253.9-14-0.4-22.4-11.1-22.2-28.6-8.9-41.8 25.5-179.1-17.6-190.7-47.3 20-11.8 217.8-24.3 275.7-16.5 80.6-69.8-29.1-90.1-52.9z"
|
||||||
|
style="fill:#ED6B21" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
11
resources/shaders/background.fs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#version 110
|
||||||
|
|
||||||
|
uniform vec4 top_color;
|
||||||
|
uniform vec4 bottom_color;
|
||||||
|
|
||||||
|
varying vec2 tex_coord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = mix(bottom_color, top_color, tex_coord.y);
|
||||||
|
}
|
9
resources/shaders/background.vs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#version 110
|
||||||
|
|
||||||
|
varying vec2 tex_coord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = gl_Vertex;
|
||||||
|
tex_coord = gl_MultiTexCoord0.xy;
|
||||||
|
}
|
8
resources/shaders/flat.fs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#version 110
|
||||||
|
|
||||||
|
uniform vec4 uniform_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = uniform_color;
|
||||||
|
}
|
6
resources/shaders/flat.vs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#version 110
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
10
resources/shaders/flat_texture.fs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#version 110
|
||||||
|
|
||||||
|
uniform sampler2D uniform_texture;
|
||||||
|
|
||||||
|
varying vec2 tex_coord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = texture2D(uniform_texture, tex_coord);
|
||||||
|
}
|
9
resources/shaders/flat_texture.vs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#version 110
|
||||||
|
|
||||||
|
varying vec2 tex_coord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = ftransform();
|
||||||
|
tex_coord = gl_MultiTexCoord0.xy;
|
||||||
|
}
|
@ -823,6 +823,35 @@ std::string CLI::output_filepath(const Model &model, IO::ExportFormat format) co
|
|||||||
return proposed_path.string();
|
return proposed_path.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// __has_feature() is used later for Clang, this is for compatibility with other compilers (such as GCC and MSVC)
|
||||||
|
#ifndef __has_feature
|
||||||
|
# define __has_feature(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
extern "C" {
|
||||||
|
// Based on https://github.com/google/skia/blob/main/tools/LsanSuppressions.cpp
|
||||||
|
const char *__lsan_default_suppressions() {
|
||||||
|
return "leak:libfontconfig\n" // FontConfig looks like it leaks, but it doesn't.
|
||||||
|
"leak:libfreetype\n" // Unsure, appeared upgrading Debian 9->10.
|
||||||
|
"leak:libGLX_nvidia.so\n" // For NVidia driver.
|
||||||
|
"leak:libnvidia-glcore.so\n" // For NVidia driver.
|
||||||
|
"leak:libnvidia-tls.so\n" // For NVidia driver.
|
||||||
|
"leak:terminator_CreateDevice\n" // For Intel Vulkan drivers.
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SLIC3R_UBSAN)
|
||||||
|
extern "C" {
|
||||||
|
// Enable printing stacktrace by default. It can be disabled by running PrusaSlicer with "UBSAN_OPTIONS=print_stacktrace=0".
|
||||||
|
const char *__ubsan_default_options() {
|
||||||
|
return "print_stacktrace=1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
__declspec(dllexport) int __stdcall slic3r_main(int argc, wchar_t **argv)
|
__declspec(dllexport) int __stdcall slic3r_main(int argc, wchar_t **argv)
|
||||||
|
@ -155,6 +155,18 @@ namespace ImGui
|
|||||||
const wchar_t ClippyMarker = 0x2602;
|
const wchar_t ClippyMarker = 0x2602;
|
||||||
const wchar_t InfoMarker = 0x2603;
|
const wchar_t InfoMarker = 0x2603;
|
||||||
const wchar_t SliderFloatEditBtnIcon = 0x2604;
|
const wchar_t SliderFloatEditBtnIcon = 0x2604;
|
||||||
|
const wchar_t SliderFloatEditBtnPressedIcon = 0x2605;
|
||||||
|
const wchar_t LegendTravel = 0x2606;
|
||||||
|
const wchar_t LegendWipe = 0x2607;
|
||||||
|
const wchar_t LegendRetract = 0x2608;
|
||||||
|
const wchar_t LegendDeretract = 0x2609;
|
||||||
|
const wchar_t LegendSeams = 0x2610;
|
||||||
|
const wchar_t LegendToolChanges = 0x2611;
|
||||||
|
const wchar_t LegendColorChanges = 0x2612;
|
||||||
|
const wchar_t LegendPausePrints = 0x2613;
|
||||||
|
const wchar_t LegendCustomGCodes = 0x2614;
|
||||||
|
const wchar_t LegendShells = 0x2615;
|
||||||
|
const wchar_t LegendToolMarker = 0x2616;
|
||||||
|
|
||||||
// void MyFunction(const char* name, const MyMatrix44& v);
|
// void MyFunction(const char* name, const MyMatrix44& v);
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,11 @@ void AppConfig::set_defaults()
|
|||||||
if (get("order_volumes").empty())
|
if (get("order_volumes").empty())
|
||||||
set("order_volumes", "1");
|
set("order_volumes", "1");
|
||||||
|
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
if (get("non_manifold_edges").empty())
|
||||||
|
set("non_manifold_edges", "1");
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
if (get("clear_undo_redo_stack_on_new_project").empty())
|
if (get("clear_undo_redo_stack_on_new_project").empty())
|
||||||
set("clear_undo_redo_stack_on_new_project", "1");
|
set("clear_undo_redo_stack_on_new_project", "1");
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ if (TARGET OpenVDB::openvdb)
|
|||||||
set(OpenVDBUtils_SOURCES OpenVDBUtils.cpp OpenVDBUtils.hpp)
|
set(OpenVDBUtils_SOURCES OpenVDBUtils.cpp OpenVDBUtils.hpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(libslic3r STATIC
|
set(SLIC3R_SOURCES
|
||||||
pchheader.cpp
|
pchheader.cpp
|
||||||
pchheader.hpp
|
pchheader.hpp
|
||||||
BoundingBox.cpp
|
BoundingBox.cpp
|
||||||
@ -29,6 +29,8 @@ add_library(libslic3r STATIC
|
|||||||
clipper.hpp
|
clipper.hpp
|
||||||
ClipperUtils.cpp
|
ClipperUtils.cpp
|
||||||
ClipperUtils.hpp
|
ClipperUtils.hpp
|
||||||
|
Color.cpp
|
||||||
|
Color.hpp
|
||||||
Config.cpp
|
Config.cpp
|
||||||
Config.hpp
|
Config.hpp
|
||||||
EdgeGrid.cpp
|
EdgeGrid.cpp
|
||||||
@ -293,6 +295,14 @@ add_library(libslic3r STATIC
|
|||||||
SLA/ReprojectPointsOnMesh.hpp
|
SLA/ReprojectPointsOnMesh.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_library(libslic3r STATIC ${SLIC3R_SOURCES})
|
||||||
|
|
||||||
|
foreach(_source IN ITEMS ${SLIC3R_SOURCES})
|
||||||
|
get_filename_component(_source_path "${_source}" PATH)
|
||||||
|
string(REPLACE "/" "\\" _group_path "${_source_path}")
|
||||||
|
source_group("${_group_path}" FILES "${_source}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
if (SLIC3R_STATIC)
|
if (SLIC3R_STATIC)
|
||||||
set(CGAL_Boost_USE_STATIC_LIBS ON CACHE BOOL "" FORCE)
|
set(CGAL_Boost_USE_STATIC_LIBS ON CACHE BOOL "" FORCE)
|
||||||
endif ()
|
endif ()
|
||||||
|
400
src/libslic3r/Color.cpp
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
#include "libslic3r.h"
|
||||||
|
#include "Color.hpp"
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
static const float INV_255 = 1.0f / 255.0f;
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Conversion from RGB to HSV color space
|
||||||
|
// The input RGB values are in the range [0, 1]
|
||||||
|
// The output HSV values are in the ranges h = [0, 360], and s, v = [0, 1]
|
||||||
|
static void RGBtoHSV(float r, float g, float b, float& h, float& s, float& v)
|
||||||
|
{
|
||||||
|
assert(0.0f <= r && r <= 1.0f);
|
||||||
|
assert(0.0f <= g && g <= 1.0f);
|
||||||
|
assert(0.0f <= b && b <= 1.0f);
|
||||||
|
|
||||||
|
const float max_comp = std::max(std::max(r, g), b);
|
||||||
|
const float min_comp = std::min(std::min(r, g), b);
|
||||||
|
const float delta = max_comp - min_comp;
|
||||||
|
|
||||||
|
if (delta > 0.0f) {
|
||||||
|
if (max_comp == r)
|
||||||
|
h = 60.0f * (std::fmod(((g - b) / delta), 6.0f));
|
||||||
|
else if (max_comp == g)
|
||||||
|
h = 60.0f * (((b - r) / delta) + 2.0f);
|
||||||
|
else if (max_comp == b)
|
||||||
|
h = 60.0f * (((r - g) / delta) + 4.0f);
|
||||||
|
|
||||||
|
s = (max_comp > 0.0f) ? delta / max_comp : 0.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
h = 0.0f;
|
||||||
|
s = 0.0f;
|
||||||
|
}
|
||||||
|
v = max_comp;
|
||||||
|
|
||||||
|
while (h < 0.0f) { h += 360.0f; }
|
||||||
|
while (h > 360.0f) { h -= 360.0f; }
|
||||||
|
|
||||||
|
assert(0.0f <= s && s <= 1.0f);
|
||||||
|
assert(0.0f <= v && v <= 1.0f);
|
||||||
|
assert(0.0f <= h && h <= 360.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conversion from HSV to RGB color space
|
||||||
|
// The input HSV values are in the ranges h = [0, 360], and s, v = [0, 1]
|
||||||
|
// The output RGB values are in the range [0, 1]
|
||||||
|
static void HSVtoRGB(float h, float s, float v, float& r, float& g, float& b)
|
||||||
|
{
|
||||||
|
assert(0.0f <= s && s <= 1.0f);
|
||||||
|
assert(0.0f <= v && v <= 1.0f);
|
||||||
|
assert(0.0f <= h && h <= 360.0f);
|
||||||
|
|
||||||
|
const float chroma = v * s;
|
||||||
|
const float h_prime = std::fmod(h / 60.0f, 6.0f);
|
||||||
|
const float x = chroma * (1.0f - std::abs(std::fmod(h_prime, 2.0f) - 1.0f));
|
||||||
|
const float m = v - chroma;
|
||||||
|
|
||||||
|
if (0.0f <= h_prime && h_prime < 1.0f) {
|
||||||
|
r = chroma;
|
||||||
|
g = x;
|
||||||
|
b = 0.0f;
|
||||||
|
}
|
||||||
|
else if (1.0f <= h_prime && h_prime < 2.0f) {
|
||||||
|
r = x;
|
||||||
|
g = chroma;
|
||||||
|
b = 0.0f;
|
||||||
|
}
|
||||||
|
else if (2.0f <= h_prime && h_prime < 3.0f) {
|
||||||
|
r = 0.0f;
|
||||||
|
g = chroma;
|
||||||
|
b = x;
|
||||||
|
}
|
||||||
|
else if (3.0f <= h_prime && h_prime < 4.0f) {
|
||||||
|
r = 0.0f;
|
||||||
|
g = x;
|
||||||
|
b = chroma;
|
||||||
|
}
|
||||||
|
else if (4.0f <= h_prime && h_prime < 5.0f) {
|
||||||
|
r = x;
|
||||||
|
g = 0.0f;
|
||||||
|
b = chroma;
|
||||||
|
}
|
||||||
|
else if (5.0f <= h_prime && h_prime < 6.0f) {
|
||||||
|
r = chroma;
|
||||||
|
g = 0.0f;
|
||||||
|
b = x;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = 0.0f;
|
||||||
|
g = 0.0f;
|
||||||
|
b = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
r += m;
|
||||||
|
g += m;
|
||||||
|
b += m;
|
||||||
|
|
||||||
|
assert(0.0f <= r && r <= 1.0f);
|
||||||
|
assert(0.0f <= g && g <= 1.0f);
|
||||||
|
assert(0.0f <= b && b <= 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Randomizer
|
||||||
|
{
|
||||||
|
std::random_device m_rd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
float random_float(float min, float max) {
|
||||||
|
std::mt19937 rand_generator(m_rd());
|
||||||
|
std::uniform_real_distribution<float> distrib(min, max);
|
||||||
|
return distrib(rand_generator);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ColorRGB::ColorRGB(float r, float g, float b)
|
||||||
|
: m_data({ std::clamp(r, 0.0f, 1.0f), std::clamp(g, 0.0f, 1.0f), std::clamp(b, 0.0f, 1.0f) })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB::ColorRGB(unsigned char r, unsigned char g, unsigned char b)
|
||||||
|
: m_data({ std::clamp(r * INV_255, 0.0f, 1.0f), std::clamp(g * INV_255, 0.0f, 1.0f), std::clamp(b * INV_255, 0.0f, 1.0f) })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ColorRGB::operator < (const ColorRGB& other) const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
if (m_data[i] < other.m_data[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ColorRGB::operator > (const ColorRGB& other) const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
if (m_data[i] > other.m_data[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB ColorRGB::operator + (const ColorRGB& other) const
|
||||||
|
{
|
||||||
|
ColorRGB ret;
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
ret.m_data[i] = std::clamp(m_data[i] + other.m_data[i], 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB ColorRGB::operator * (float value) const
|
||||||
|
{
|
||||||
|
assert(value >= 0.0f);
|
||||||
|
ColorRGB ret;
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
ret.m_data[i] = std::clamp(value * m_data[i], 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA::ColorRGBA(float r, float g, float b, float a)
|
||||||
|
: m_data({ std::clamp(r, 0.0f, 1.0f), std::clamp(g, 0.0f, 1.0f), std::clamp(b, 0.0f, 1.0f), std::clamp(a, 0.0f, 1.0f) })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA::ColorRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
|
||||||
|
: m_data({ std::clamp(r * INV_255, 0.0f, 1.0f), std::clamp(g * INV_255, 0.0f, 1.0f), std::clamp(b * INV_255, 0.0f, 1.0f), std::clamp(a * INV_255, 0.0f, 1.0f) })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ColorRGBA::operator < (const ColorRGBA& other) const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
if (m_data[i] < other.m_data[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ColorRGBA::operator > (const ColorRGBA& other) const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
if (m_data[i] > other.m_data[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA ColorRGBA::operator + (const ColorRGBA& other) const
|
||||||
|
{
|
||||||
|
ColorRGBA ret;
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
ret.m_data[i] = std::clamp(m_data[i] + other.m_data[i], 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA ColorRGBA::operator * (float value) const
|
||||||
|
{
|
||||||
|
assert(value >= 0.0f);
|
||||||
|
ColorRGBA ret;
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
ret.m_data[i] = std::clamp(value * m_data[i], 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
ret.m_data[3] = this->m_data[3];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB operator * (float value, const ColorRGB& other) { return other * value; }
|
||||||
|
ColorRGBA operator * (float value, const ColorRGBA& other) { return other * value; }
|
||||||
|
|
||||||
|
ColorRGB lerp(const ColorRGB& a, const ColorRGB& b, float t)
|
||||||
|
{
|
||||||
|
assert(0.0f <= t && t <= 1.0f);
|
||||||
|
return (1.0f - t) * a + t * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA lerp(const ColorRGBA& a, const ColorRGBA& b, float t)
|
||||||
|
{
|
||||||
|
assert(0.0f <= t && t <= 1.0f);
|
||||||
|
return (1.0f - t) * a + t * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB complementary(const ColorRGB& color)
|
||||||
|
{
|
||||||
|
return { 1.0f - color.r(), 1.0f - color.g(), 1.0f - color.b() };
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA complementary(const ColorRGBA& color)
|
||||||
|
{
|
||||||
|
return { 1.0f - color.r(), 1.0f - color.g(), 1.0f - color.b(), color.a() };
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB saturate(const ColorRGB& color, float factor)
|
||||||
|
{
|
||||||
|
float h, s, v;
|
||||||
|
RGBtoHSV(color.r(), color.g(), color.b(), h, s, v);
|
||||||
|
s = std::clamp(s * factor, 0.0f, 1.0f);
|
||||||
|
float r, g, b;
|
||||||
|
HSVtoRGB(h, s, v, r, g, b);
|
||||||
|
return { r, g, b };
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA saturate(const ColorRGBA& color, float factor)
|
||||||
|
{
|
||||||
|
return to_rgba(saturate(to_rgb(color), factor), color.a());
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB opposite(const ColorRGB& color)
|
||||||
|
{
|
||||||
|
float h, s, v;
|
||||||
|
RGBtoHSV(color.r(), color.g(), color.b(), h, s, v);
|
||||||
|
|
||||||
|
h += 65.0f; // 65 instead 60 to avoid circle values
|
||||||
|
if (h > 360.0f)
|
||||||
|
h -= 360.0f;
|
||||||
|
|
||||||
|
Randomizer rnd;
|
||||||
|
s = rnd.random_float(0.65f, 1.0f);
|
||||||
|
v = rnd.random_float(0.65f, 1.0f);
|
||||||
|
|
||||||
|
float r, g, b;
|
||||||
|
HSVtoRGB(h, s, v, r, g, b);
|
||||||
|
return { r, g, b };
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB opposite(const ColorRGB& a, const ColorRGB& b)
|
||||||
|
{
|
||||||
|
float ha, sa, va;
|
||||||
|
RGBtoHSV(a.r(), a.g(), a.b(), ha, sa, va);
|
||||||
|
float hb, sb, vb;
|
||||||
|
RGBtoHSV(b.r(), b.g(), b.b(), hb, sb, vb);
|
||||||
|
|
||||||
|
float delta_h = std::abs(ha - hb);
|
||||||
|
float start_h = (delta_h > 180.0f) ? std::min(ha, hb) : std::max(ha, hb);
|
||||||
|
|
||||||
|
start_h += 5.0f; // to avoid circle change of colors for 120 deg
|
||||||
|
if (delta_h < 180.0f)
|
||||||
|
delta_h = 360.0f - delta_h;
|
||||||
|
|
||||||
|
Randomizer rnd;
|
||||||
|
float out_h = start_h + 0.5f * delta_h;
|
||||||
|
if (out_h > 360.0f)
|
||||||
|
out_h -= 360.0f;
|
||||||
|
float out_s = rnd.random_float(0.65f, 1.0f);
|
||||||
|
float out_v = rnd.random_float(0.65f, 1.0f);
|
||||||
|
|
||||||
|
float out_r, out_g, out_b;
|
||||||
|
HSVtoRGB(out_h, out_s, out_v, out_r, out_g, out_b);
|
||||||
|
return { out_r, out_g, out_b };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool can_decode_color(const std::string& color) { return color.size() == 7 && color.front() == '#'; }
|
||||||
|
|
||||||
|
bool decode_color(const std::string& color_in, ColorRGB& color_out)
|
||||||
|
{
|
||||||
|
auto hex_digit_to_int = [](const char c) {
|
||||||
|
return
|
||||||
|
(c >= '0' && c <= '9') ? int(c - '0') :
|
||||||
|
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
|
||||||
|
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
color_out = ColorRGB::BLACK();
|
||||||
|
if (can_decode_color(color_in)) {
|
||||||
|
const char* c = color_in.data() + 1;
|
||||||
|
for (unsigned int i = 0; i < 3; ++i) {
|
||||||
|
const int digit1 = hex_digit_to_int(*c++);
|
||||||
|
const int digit2 = hex_digit_to_int(*c++);
|
||||||
|
if (digit1 != -1 && digit2 != -1)
|
||||||
|
color_out.set(i, float(digit1 * 16 + digit2) * INV_255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
assert(0.0f <= color_out.r() && color_out.r() <= 1.0f);
|
||||||
|
assert(0.0f <= color_out.g() && color_out.g() <= 1.0f);
|
||||||
|
assert(0.0f <= color_out.b() && color_out.b() <= 1.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool decode_color(const std::string& color_in, ColorRGBA& color_out)
|
||||||
|
{
|
||||||
|
ColorRGB rgb;
|
||||||
|
if (!decode_color(color_in, rgb))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
color_out = to_rgba(rgb, color_out.a());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGB>& colors_out)
|
||||||
|
{
|
||||||
|
colors_out = std::vector<ColorRGB>(colors_in.size(), ColorRGB::BLACK());
|
||||||
|
for (size_t i = 0; i < colors_in.size(); ++i) {
|
||||||
|
if (!decode_color(colors_in[i], colors_out[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGBA>& colors_out)
|
||||||
|
{
|
||||||
|
colors_out = std::vector<ColorRGBA>(colors_in.size(), ColorRGBA::BLACK());
|
||||||
|
for (size_t i = 0; i < colors_in.size(); ++i) {
|
||||||
|
if (!decode_color(colors_in[i], colors_out[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string encode_color(const ColorRGB& color)
|
||||||
|
{
|
||||||
|
char buffer[64];
|
||||||
|
::sprintf(buffer, "#%02X%02X%02X", color.r_uchar(), color.g_uchar(), color.b_uchar());
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string encode_color(const ColorRGBA& color) { return encode_color(to_rgb(color)); }
|
||||||
|
|
||||||
|
ColorRGB to_rgb(const ColorRGBA& other_rgba) { return { other_rgba.r(), other_rgba.g(), other_rgba.b() }; }
|
||||||
|
ColorRGBA to_rgba(const ColorRGB& other_rgb) { return { other_rgb.r(), other_rgb.g(), other_rgb.b(), 1.0f }; }
|
||||||
|
ColorRGBA to_rgba(const ColorRGB& other_rgb, float alpha) { return { other_rgb.r(), other_rgb.g(), other_rgb.b(), alpha }; }
|
||||||
|
|
||||||
|
ColorRGBA picking_decode(unsigned int id)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
float((id >> 0) & 0xff) * INV_255, // red
|
||||||
|
float((id >> 8) & 0xff) * INV_255, // green
|
||||||
|
float((id >> 16) & 0xff) * INV_255, // blue
|
||||||
|
float(picking_checksum_alpha_channel(id & 0xff, (id >> 8) & 0xff, (id >> 16) & 0xff)) * INV_255 // checksum for validating against unwanted alpha blending and multi sampling
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int picking_encode(unsigned char r, unsigned char g, unsigned char b) { return r + (g << 8) + (b << 16); }
|
||||||
|
|
||||||
|
unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue)
|
||||||
|
{
|
||||||
|
// 8 bit hash for the color
|
||||||
|
unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff;
|
||||||
|
// Increase enthropy by a bit reversal
|
||||||
|
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||||
|
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||||
|
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||||
|
// Flip every second bit to increase the enthropy even more.
|
||||||
|
b ^= 0x55;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
174
src/libslic3r/Color.hpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
#ifndef slic3r_Color_hpp_
|
||||||
|
#define slic3r_Color_hpp_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class ColorRGB
|
||||||
|
{
|
||||||
|
std::array<float, 3> m_data{1.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ColorRGB() = default;
|
||||||
|
ColorRGB(float r, float g, float b);
|
||||||
|
ColorRGB(unsigned char r, unsigned char g, unsigned char b);
|
||||||
|
ColorRGB(const ColorRGB& other) = default;
|
||||||
|
|
||||||
|
ColorRGB& operator = (const ColorRGB& other) { m_data = other.m_data; return *this; }
|
||||||
|
|
||||||
|
bool operator == (const ColorRGB& other) const { return m_data == other.m_data; }
|
||||||
|
bool operator != (const ColorRGB& other) const { return !operator==(other); }
|
||||||
|
bool operator < (const ColorRGB& other) const;
|
||||||
|
bool operator > (const ColorRGB& other) const;
|
||||||
|
|
||||||
|
ColorRGB operator + (const ColorRGB& other) const;
|
||||||
|
ColorRGB operator * (float value) const;
|
||||||
|
|
||||||
|
const float* const data() const { return m_data.data(); }
|
||||||
|
|
||||||
|
float r() const { return m_data[0]; }
|
||||||
|
float g() const { return m_data[1]; }
|
||||||
|
float b() const { return m_data[2]; }
|
||||||
|
|
||||||
|
void r(float r) { m_data[0] = std::clamp(r, 0.0f, 1.0f); }
|
||||||
|
void g(float g) { m_data[1] = std::clamp(g, 0.0f, 1.0f); }
|
||||||
|
void b(float b) { m_data[2] = std::clamp(b, 0.0f, 1.0f); }
|
||||||
|
|
||||||
|
void set(unsigned int comp, float value) {
|
||||||
|
assert(0 <= comp && comp <= 2);
|
||||||
|
m_data[comp] = std::clamp(value, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char r_uchar() const { return static_cast<unsigned char>(m_data[0] * 255.0f); }
|
||||||
|
unsigned char g_uchar() const { return static_cast<unsigned char>(m_data[1] * 255.0f); }
|
||||||
|
unsigned char b_uchar() const { return static_cast<unsigned char>(m_data[2] * 255.0f); }
|
||||||
|
|
||||||
|
static const ColorRGB BLACK() { return { 0.0f, 0.0f, 0.0f }; }
|
||||||
|
static const ColorRGB BLUE() { return { 0.0f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGB BLUEISH() { return { 0.5f, 0.5f, 1.0f }; }
|
||||||
|
static const ColorRGB CYAN() { return { 0.0f, 1.0f, 1.0f }; }
|
||||||
|
static const ColorRGB DARK_GRAY() { return { 0.25f, 0.25f, 0.25f }; }
|
||||||
|
static const ColorRGB DARK_YELLOW() { return { 0.5f, 0.5f, 0.0f }; }
|
||||||
|
static const ColorRGB GRAY() { return { 0.5f, 0.5f, 0.5f }; }
|
||||||
|
static const ColorRGB GREEN() { return { 0.0f, 1.0f, 0.0f }; }
|
||||||
|
static const ColorRGB GREENISH() { return { 0.5f, 1.0f, 0.5f }; }
|
||||||
|
static const ColorRGB LIGHT_GRAY() { return { 0.75f, 0.75f, 0.75f }; }
|
||||||
|
static const ColorRGB MAGENTA() { return { 1.0f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGB ORANGE() { return { 0.92f, 0.50f, 0.26f }; }
|
||||||
|
static const ColorRGB RED() { return { 1.0f, 0.0f, 0.0f }; }
|
||||||
|
static const ColorRGB REDISH() { return { 1.0f, 0.5f, 0.5f }; }
|
||||||
|
static const ColorRGB YELLOW() { return { 1.0f, 1.0f, 0.0f }; }
|
||||||
|
static const ColorRGB WHITE() { return { 1.0f, 1.0f, 1.0f }; }
|
||||||
|
|
||||||
|
static const ColorRGB X() { return { 0.75f, 0.0f, 0.0f }; }
|
||||||
|
static const ColorRGB Y() { return { 0.0f, 0.75f, 0.0f }; }
|
||||||
|
static const ColorRGB Z() { return { 0.0f, 0.0f, 0.75f }; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ColorRGBA
|
||||||
|
{
|
||||||
|
std::array<float, 4> m_data{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
|
||||||
|
public:
|
||||||
|
ColorRGBA() = default;
|
||||||
|
ColorRGBA(float r, float g, float b, float a);
|
||||||
|
ColorRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
|
||||||
|
ColorRGBA(const ColorRGBA& other) = default;
|
||||||
|
|
||||||
|
ColorRGBA& operator = (const ColorRGBA& other) { m_data = other.m_data; return *this; }
|
||||||
|
|
||||||
|
bool operator == (const ColorRGBA& other) const { return m_data == other.m_data; }
|
||||||
|
bool operator != (const ColorRGBA& other) const { return !operator==(other); }
|
||||||
|
bool operator < (const ColorRGBA& other) const;
|
||||||
|
bool operator > (const ColorRGBA& other) const;
|
||||||
|
|
||||||
|
ColorRGBA operator + (const ColorRGBA& other) const;
|
||||||
|
ColorRGBA operator * (float value) const;
|
||||||
|
|
||||||
|
const float* const data() const { return m_data.data(); }
|
||||||
|
|
||||||
|
float r() const { return m_data[0]; }
|
||||||
|
float g() const { return m_data[1]; }
|
||||||
|
float b() const { return m_data[2]; }
|
||||||
|
float a() const { return m_data[3]; }
|
||||||
|
|
||||||
|
void r(float r) { m_data[0] = std::clamp(r, 0.0f, 1.0f); }
|
||||||
|
void g(float g) { m_data[1] = std::clamp(g, 0.0f, 1.0f); }
|
||||||
|
void b(float b) { m_data[2] = std::clamp(b, 0.0f, 1.0f); }
|
||||||
|
void a(float a) { m_data[3] = std::clamp(a, 0.0f, 1.0f); }
|
||||||
|
|
||||||
|
void set(unsigned int comp, float value) {
|
||||||
|
assert(0 <= comp && comp <= 3);
|
||||||
|
m_data[comp] = std::clamp(value, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char r_uchar() const { return static_cast<unsigned char>(m_data[0] * 255.0f); }
|
||||||
|
unsigned char g_uchar() const { return static_cast<unsigned char>(m_data[1] * 255.0f); }
|
||||||
|
unsigned char b_uchar() const { return static_cast<unsigned char>(m_data[2] * 255.0f); }
|
||||||
|
unsigned char a_uchar() const { return static_cast<unsigned char>(m_data[3] * 255.0f); }
|
||||||
|
|
||||||
|
bool is_transparent() const { return m_data[3] < 1.0f; }
|
||||||
|
|
||||||
|
static const ColorRGBA BLACK() { return { 0.0f, 0.0f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA BLUE() { return { 0.0f, 0.0f, 1.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA BLUEISH() { return { 0.5f, 0.5f, 1.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA CYAN() { return { 0.0f, 1.0f, 1.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA DARK_GRAY() { return { 0.25f, 0.25f, 0.25f, 1.0f }; }
|
||||||
|
static const ColorRGBA DARK_YELLOW() { return { 0.5f, 0.5f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA GRAY() { return { 0.5f, 0.5f, 0.5f, 1.0f }; }
|
||||||
|
static const ColorRGBA GREEN() { return { 0.0f, 1.0f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA GREENISH() { return { 0.5f, 1.0f, 0.5f, 1.0f }; }
|
||||||
|
static const ColorRGBA LIGHT_GRAY() { return { 0.75f, 0.75f, 0.75f, 1.0f }; }
|
||||||
|
static const ColorRGBA MAGENTA() { return { 1.0f, 0.0f, 1.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA ORANGE() { return { 0.923f, 0.504f, 0.264f, 1.0f }; }
|
||||||
|
static const ColorRGBA RED() { return { 1.0f, 0.0f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA REDISH() { return { 1.0f, 0.5f, 0.5f, 1.0f }; }
|
||||||
|
static const ColorRGBA YELLOW() { return { 1.0f, 1.0f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA WHITE() { return { 1.0f, 1.0f, 1.0f, 1.0f }; }
|
||||||
|
|
||||||
|
static const ColorRGBA X() { return { 0.75f, 0.0f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA Y() { return { 0.0f, 0.75f, 0.0f, 1.0f }; }
|
||||||
|
static const ColorRGBA Z() { return { 0.0f, 0.0f, 0.75f, 1.0f }; }
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ColorRGB operator * (float value, const ColorRGB& other);
|
||||||
|
extern ColorRGBA operator * (float value, const ColorRGBA& other);
|
||||||
|
|
||||||
|
extern ColorRGB lerp(const ColorRGB& a, const ColorRGB& b, float t);
|
||||||
|
extern ColorRGBA lerp(const ColorRGBA& a, const ColorRGBA& b, float t);
|
||||||
|
|
||||||
|
extern ColorRGB complementary(const ColorRGB& color);
|
||||||
|
extern ColorRGBA complementary(const ColorRGBA& color);
|
||||||
|
|
||||||
|
extern ColorRGB saturate(const ColorRGB& color, float factor);
|
||||||
|
extern ColorRGBA saturate(const ColorRGBA& color, float factor);
|
||||||
|
|
||||||
|
extern ColorRGB opposite(const ColorRGB& color);
|
||||||
|
extern ColorRGB opposite(const ColorRGB& a, const ColorRGB& b);
|
||||||
|
|
||||||
|
extern bool can_decode_color(const std::string& color);
|
||||||
|
|
||||||
|
extern bool decode_color(const std::string& color_in, ColorRGB& color_out);
|
||||||
|
extern bool decode_color(const std::string& color_in, ColorRGBA& color_out);
|
||||||
|
|
||||||
|
extern bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGB>& colors_out);
|
||||||
|
extern bool decode_colors(const std::vector<std::string>& colors_in, std::vector<ColorRGBA>& colors_out);
|
||||||
|
|
||||||
|
extern std::string encode_color(const ColorRGB& color);
|
||||||
|
extern std::string encode_color(const ColorRGBA& color);
|
||||||
|
|
||||||
|
extern ColorRGB to_rgb(const ColorRGBA& other_rgba);
|
||||||
|
extern ColorRGBA to_rgba(const ColorRGB& other_rgb);
|
||||||
|
extern ColorRGBA to_rgba(const ColorRGB& other_rgb, float alpha);
|
||||||
|
|
||||||
|
extern ColorRGBA picking_decode(unsigned int id);
|
||||||
|
extern unsigned int picking_encode(unsigned char r, unsigned char g, unsigned char b);
|
||||||
|
// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components
|
||||||
|
// were not interpolated by alpha blending or multi sampling.
|
||||||
|
extern unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue);
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif /* slic3r_Color_hpp_ */
|
@ -58,10 +58,7 @@ ExtrusionEntityCollection::operator ExtrusionPaths() const
|
|||||||
|
|
||||||
ExtrusionEntity *ExtrusionEntityCollection::clone() const
|
ExtrusionEntity *ExtrusionEntityCollection::clone() const
|
||||||
{
|
{
|
||||||
ExtrusionEntityCollection* coll = new ExtrusionEntityCollection(*this);
|
return new ExtrusionEntityCollection(*this);
|
||||||
for (size_t i = 0; i < coll->entities.size(); ++i)
|
|
||||||
coll->entities[i] = this->entities[i]->clone();
|
|
||||||
return coll;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtrusionEntityCollection::reverse()
|
void ExtrusionEntityCollection::reverse()
|
||||||
|
@ -2391,7 +2391,7 @@ static std::vector<MonotonicRegionLink> chain_monotonic_regions(
|
|||||||
|
|
||||||
// Probability (unnormalized) of traversing a link between two monotonic regions.
|
// Probability (unnormalized) of traversing a link between two monotonic regions.
|
||||||
auto path_probability = [
|
auto path_probability = [
|
||||||
#ifndef __APPLE__
|
#if !defined(__APPLE__) && !defined(__clang__)
|
||||||
// clang complains when capturing constexpr constants.
|
// clang complains when capturing constexpr constants.
|
||||||
pheromone_alpha, pheromone_beta
|
pheromone_alpha, pheromone_beta
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
@ -283,25 +283,28 @@ void AMFParserContext::startElement(const char *name, const char **atts)
|
|||||||
m_value[0] = type;
|
m_value[0] = type;
|
||||||
node_type_new = NODE_TYPE_METADATA;
|
node_type_new = NODE_TYPE_METADATA;
|
||||||
}
|
}
|
||||||
} else if (strcmp(name, "material") == 0) {
|
}
|
||||||
|
else if (strcmp(name, "material") == 0) {
|
||||||
const char *material_id = get_attribute(atts, "id");
|
const char *material_id = get_attribute(atts, "id");
|
||||||
m_material = m_model.add_material((material_id == nullptr) ? "_" : material_id);
|
m_material = m_model.add_material((material_id == nullptr) ? "_" : material_id);
|
||||||
node_type_new = NODE_TYPE_MATERIAL;
|
node_type_new = NODE_TYPE_MATERIAL;
|
||||||
} else if (strcmp(name, "object") == 0) {
|
}
|
||||||
|
else if (strcmp(name, "object") == 0) {
|
||||||
const char *object_id = get_attribute(atts, "id");
|
const char *object_id = get_attribute(atts, "id");
|
||||||
if (object_id == nullptr)
|
if (object_id == nullptr)
|
||||||
this->stop();
|
this->stop();
|
||||||
else {
|
else {
|
||||||
assert(m_object_vertices.empty());
|
assert(m_object_vertices.empty());
|
||||||
m_object = m_model.add_object();
|
m_object = m_model.add_object();
|
||||||
|
m_object->name = std::string(object_id);
|
||||||
m_object_instances_map[object_id].idx = int(m_model.objects.size())-1;
|
m_object_instances_map[object_id].idx = int(m_model.objects.size())-1;
|
||||||
node_type_new = NODE_TYPE_OBJECT;
|
node_type_new = NODE_TYPE_OBJECT;
|
||||||
}
|
}
|
||||||
} else if (strcmp(name, "constellation") == 0) {
|
|
||||||
node_type_new = NODE_TYPE_CONSTELLATION;
|
|
||||||
} else if (strcmp(name, "custom_gcodes_per_height") == 0) {
|
|
||||||
node_type_new = NODE_TYPE_CUSTOM_GCODE;
|
|
||||||
}
|
}
|
||||||
|
else if (strcmp(name, "constellation") == 0)
|
||||||
|
node_type_new = NODE_TYPE_CONSTELLATION;
|
||||||
|
else if (strcmp(name, "custom_gcodes_per_height") == 0)
|
||||||
|
node_type_new = NODE_TYPE_CUSTOM_GCODE;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (strcmp(name, "metadata") == 0) {
|
if (strcmp(name, "metadata") == 0) {
|
||||||
@ -309,12 +312,14 @@ void AMFParserContext::startElement(const char *name, const char **atts)
|
|||||||
m_value[0] = get_attribute(atts, "type");
|
m_value[0] = get_attribute(atts, "type");
|
||||||
node_type_new = NODE_TYPE_METADATA;
|
node_type_new = NODE_TYPE_METADATA;
|
||||||
}
|
}
|
||||||
} else if (strcmp(name, "layer_config_ranges") == 0 && m_path[1] == NODE_TYPE_OBJECT)
|
}
|
||||||
|
else if (strcmp(name, "layer_config_ranges") == 0 && m_path[1] == NODE_TYPE_OBJECT)
|
||||||
node_type_new = NODE_TYPE_LAYER_CONFIG;
|
node_type_new = NODE_TYPE_LAYER_CONFIG;
|
||||||
else if (strcmp(name, "mesh") == 0) {
|
else if (strcmp(name, "mesh") == 0) {
|
||||||
if (m_path[1] == NODE_TYPE_OBJECT)
|
if (m_path[1] == NODE_TYPE_OBJECT)
|
||||||
node_type_new = NODE_TYPE_MESH;
|
node_type_new = NODE_TYPE_MESH;
|
||||||
} else if (strcmp(name, "instance") == 0) {
|
}
|
||||||
|
else if (strcmp(name, "instance") == 0) {
|
||||||
if (m_path[1] == NODE_TYPE_CONSTELLATION) {
|
if (m_path[1] == NODE_TYPE_CONSTELLATION) {
|
||||||
const char *object_id = get_attribute(atts, "objectid");
|
const char *object_id = get_attribute(atts, "objectid");
|
||||||
if (object_id == nullptr)
|
if (object_id == nullptr)
|
||||||
@ -910,12 +915,17 @@ bool load_amf_file(const char *path, DynamicPrintConfig *config, ConfigSubstitut
|
|||||||
if (result)
|
if (result)
|
||||||
ctx.endDocument();
|
ctx.endDocument();
|
||||||
|
|
||||||
for (ModelObject* o : model->objects)
|
for (ModelObject* o : model->objects) {
|
||||||
{
|
unsigned int counter = 0;
|
||||||
for (ModelVolume* v : o->volumes)
|
for (ModelVolume* v : o->volumes) {
|
||||||
{
|
++counter;
|
||||||
if (v->source.input_file.empty() && (v->type() == ModelVolumeType::MODEL_PART))
|
if (v->source.input_file.empty() && v->type() == ModelVolumeType::MODEL_PART)
|
||||||
v->source.input_file = path;
|
v->source.input_file = path;
|
||||||
|
if (v->name.empty()) {
|
||||||
|
v->name = o->name;
|
||||||
|
if (o->volumes.size() > 1)
|
||||||
|
v->name += "_" + std::to_string(counter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,6 +189,9 @@ void GCodeProcessor::TimeMachine::reset()
|
|||||||
max_travel_acceleration = 0.0f;
|
max_travel_acceleration = 0.0f;
|
||||||
extrude_factor_override_percentage = 1.0f;
|
extrude_factor_override_percentage = 1.0f;
|
||||||
time = 0.0f;
|
time = 0.0f;
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
travel_time = 0.0f;
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
stop_times = std::vector<StopTime>();
|
stop_times = std::vector<StopTime>();
|
||||||
curr.reset();
|
curr.reset();
|
||||||
prev.reset();
|
prev.reset();
|
||||||
@ -304,9 +307,17 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, floa
|
|||||||
block_time += additional_time;
|
block_time += additional_time;
|
||||||
|
|
||||||
time += block_time;
|
time += block_time;
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
if (block.move_type == EMoveType::Travel)
|
||||||
|
travel_time += block_time;
|
||||||
|
else
|
||||||
|
roles_time[static_cast<size_t>(block.role)] += block_time;
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
gcode_time.cache += block_time;
|
gcode_time.cache += block_time;
|
||||||
moves_time[static_cast<size_t>(block.move_type)] += block_time;
|
moves_time[static_cast<size_t>(block.move_type)] += block_time;
|
||||||
|
#if !ENABLE_TRAVEL_TIME
|
||||||
roles_time[static_cast<size_t>(block.role)] += block_time;
|
roles_time[static_cast<size_t>(block.role)] += block_time;
|
||||||
|
#endif // !ENABLE_TRAVEL_TIME
|
||||||
if (block.layer_id >= layers_time.size()) {
|
if (block.layer_id >= layers_time.size()) {
|
||||||
const size_t curr_size = layers_time.size();
|
const size_t curr_size = layers_time.size();
|
||||||
layers_time.resize(block.layer_id);
|
layers_time.resize(block.layer_id);
|
||||||
@ -1177,6 +1188,7 @@ void GCodeProcessor::reset()
|
|||||||
|
|
||||||
m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f };
|
m_start_position = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
m_end_position = { 0.0f, 0.0f, 0.0f, 0.0f };
|
m_end_position = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
m_saved_position = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
m_origin = { 0.0f, 0.0f, 0.0f, 0.0f };
|
m_origin = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
m_cached_position.reset();
|
m_cached_position.reset();
|
||||||
m_wiping = false;
|
m_wiping = false;
|
||||||
@ -1378,6 +1390,18 @@ std::string GCodeProcessor::get_time_dhm(PrintEstimatedStatistics::ETimeMode mod
|
|||||||
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast<size_t>(mode)].time)) : std::string("N/A");
|
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast<size_t>(mode)].time)) : std::string("N/A");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
float GCodeProcessor::get_travel_time(PrintEstimatedStatistics::ETimeMode mode) const
|
||||||
|
{
|
||||||
|
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast<size_t>(mode)].travel_time : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GCodeProcessor::get_travel_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const
|
||||||
|
{
|
||||||
|
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast<size_t>(mode)].travel_time)) : std::string("N/A");
|
||||||
|
}
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
|
|
||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> GCodeProcessor::get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> GCodeProcessor::get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const
|
||||||
{
|
{
|
||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> ret;
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> ret;
|
||||||
@ -1593,6 +1617,13 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '6':
|
||||||
|
switch (cmd[2]) {
|
||||||
|
case '0': { process_G60(line); break; } // Save Current Position
|
||||||
|
case '1': { process_G61(line); break; } // Return to Saved Position
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case '9':
|
case '9':
|
||||||
switch (cmd[2]) {
|
switch (cmd[2]) {
|
||||||
case '0': { process_G90(line); break; } // Set to Absolute Positioning
|
case '0': { process_G90(line); break; } // Set to Absolute Positioning
|
||||||
@ -2805,6 +2836,43 @@ void GCodeProcessor::process_G28(const GCodeReader::GCodeLine& line)
|
|||||||
process_G1(new_gline);
|
process_G1(new_gline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GCodeProcessor::process_G60(const GCodeReader::GCodeLine& line)
|
||||||
|
{
|
||||||
|
if (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware)
|
||||||
|
m_saved_position = m_end_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeProcessor::process_G61(const GCodeReader::GCodeLine& line)
|
||||||
|
{
|
||||||
|
if (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware) {
|
||||||
|
bool modified = false;
|
||||||
|
if (line.has_x()) {
|
||||||
|
m_end_position[X] = m_saved_position[X];
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
if (line.has_y()) {
|
||||||
|
m_end_position[Y] = m_saved_position[Y];
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
if (line.has_z()) {
|
||||||
|
m_end_position[Z] = m_saved_position[Z];
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
if (line.has_e()) {
|
||||||
|
m_end_position[E] = m_saved_position[E];
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
if (line.has_f())
|
||||||
|
m_feedrate = line.f();
|
||||||
|
|
||||||
|
if (!modified)
|
||||||
|
m_end_position = m_saved_position;
|
||||||
|
|
||||||
|
|
||||||
|
store_move_vertex(EMoveType::Travel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GCodeProcessor::process_G90(const GCodeReader::GCodeLine& line)
|
void GCodeProcessor::process_G90(const GCodeReader::GCodeLine& line)
|
||||||
{
|
{
|
||||||
m_global_positioning_type = EPositioningType::Absolute;
|
m_global_positioning_type = EPositioningType::Absolute;
|
||||||
@ -3395,6 +3463,9 @@ void GCodeProcessor::update_estimated_times_stats()
|
|||||||
auto update_mode = [this](PrintEstimatedStatistics::ETimeMode mode) {
|
auto update_mode = [this](PrintEstimatedStatistics::ETimeMode mode) {
|
||||||
PrintEstimatedStatistics::Mode& data = m_result.print_statistics.modes[static_cast<size_t>(mode)];
|
PrintEstimatedStatistics::Mode& data = m_result.print_statistics.modes[static_cast<size_t>(mode)];
|
||||||
data.time = get_time(mode);
|
data.time = get_time(mode);
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
data.travel_time = get_travel_time(mode);
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
data.custom_gcode_times = get_custom_gcode_times(mode, true);
|
data.custom_gcode_times = get_custom_gcode_times(mode, true);
|
||||||
data.moves_times = get_moves_time(mode);
|
data.moves_times = get_moves_time(mode);
|
||||||
data.roles_times = get_roles_time(mode);
|
data.roles_times = get_roles_time(mode);
|
||||||
|
@ -44,6 +44,9 @@ namespace Slic3r {
|
|||||||
struct Mode
|
struct Mode
|
||||||
{
|
{
|
||||||
float time;
|
float time;
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
float travel_time;
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> custom_gcode_times;
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> custom_gcode_times;
|
||||||
std::vector<std::pair<EMoveType, float>> moves_times;
|
std::vector<std::pair<EMoveType, float>> moves_times;
|
||||||
std::vector<std::pair<ExtrusionRole, float>> roles_times;
|
std::vector<std::pair<ExtrusionRole, float>> roles_times;
|
||||||
@ -51,6 +54,9 @@ namespace Slic3r {
|
|||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
time = 0.0f;
|
time = 0.0f;
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
travel_time = 0.0f;
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
custom_gcode_times.clear();
|
custom_gcode_times.clear();
|
||||||
moves_times.clear();
|
moves_times.clear();
|
||||||
roles_times.clear();
|
roles_times.clear();
|
||||||
@ -290,6 +296,9 @@ namespace Slic3r {
|
|||||||
float max_travel_acceleration; // mm/s^2
|
float max_travel_acceleration; // mm/s^2
|
||||||
float extrude_factor_override_percentage;
|
float extrude_factor_override_percentage;
|
||||||
float time; // s
|
float time; // s
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
float travel_time; // s
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
struct StopTime
|
struct StopTime
|
||||||
{
|
{
|
||||||
unsigned int g1_line_id;
|
unsigned int g1_line_id;
|
||||||
@ -508,6 +517,7 @@ namespace Slic3r {
|
|||||||
|
|
||||||
AxisCoords m_start_position; // mm
|
AxisCoords m_start_position; // mm
|
||||||
AxisCoords m_end_position; // mm
|
AxisCoords m_end_position; // mm
|
||||||
|
AxisCoords m_saved_position; // mm
|
||||||
AxisCoords m_origin; // mm
|
AxisCoords m_origin; // mm
|
||||||
CachedPosition m_cached_position;
|
CachedPosition m_cached_position;
|
||||||
bool m_wiping;
|
bool m_wiping;
|
||||||
@ -599,6 +609,10 @@ namespace Slic3r {
|
|||||||
|
|
||||||
float get_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
float get_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
|
#if ENABLE_TRAVEL_TIME
|
||||||
|
float get_travel_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
|
std::string get_travel_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
|
#endif // ENABLE_TRAVEL_TIME
|
||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
|
||||||
|
|
||||||
std::vector<std::pair<EMoveType, float>> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::vector<std::pair<EMoveType, float>> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
@ -648,6 +662,12 @@ namespace Slic3r {
|
|||||||
// Move to origin
|
// Move to origin
|
||||||
void process_G28(const GCodeReader::GCodeLine& line);
|
void process_G28(const GCodeReader::GCodeLine& line);
|
||||||
|
|
||||||
|
// Save Current Position
|
||||||
|
void process_G60(const GCodeReader::GCodeLine& line);
|
||||||
|
|
||||||
|
// Return to Saved Position
|
||||||
|
void process_G61(const GCodeReader::GCodeLine& line);
|
||||||
|
|
||||||
// Set to Absolute Positioning
|
// Set to Absolute Positioning
|
||||||
void process_G90(const GCodeReader::GCodeLine& line);
|
void process_G90(const GCodeReader::GCodeLine& line);
|
||||||
|
|
||||||
|
@ -325,40 +325,36 @@ Vec3d extract_euler_angles(const Eigen::Matrix<double, 3, 3, Eigen::DontAlign>&
|
|||||||
// reference: http://www.gregslabaugh.net/publications/euler.pdf
|
// reference: http://www.gregslabaugh.net/publications/euler.pdf
|
||||||
Vec3d angles1 = Vec3d::Zero();
|
Vec3d angles1 = Vec3d::Zero();
|
||||||
Vec3d angles2 = Vec3d::Zero();
|
Vec3d angles2 = Vec3d::Zero();
|
||||||
if (std::abs(std::abs(rotation_matrix(2, 0)) - 1.0) < 1e-5)
|
if (std::abs(std::abs(rotation_matrix(2, 0)) - 1.0) < 1e-5) {
|
||||||
{
|
angles1.z() = 0.0;
|
||||||
angles1(2) = 0.0;
|
if (rotation_matrix(2, 0) < 0.0) { // == -1.0
|
||||||
if (rotation_matrix(2, 0) < 0.0) // == -1.0
|
angles1.y() = 0.5 * double(PI);
|
||||||
{
|
angles1.x() = angles1.z() + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2));
|
||||||
angles1(1) = 0.5 * (double)PI;
|
|
||||||
angles1(0) = angles1(2) + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2));
|
|
||||||
}
|
}
|
||||||
else // == 1.0
|
else { // == 1.0
|
||||||
{
|
angles1.y() = - 0.5 * double(PI);
|
||||||
angles1(1) = - 0.5 * (double)PI;
|
angles1.x() = - angles1.y() + ::atan2(- rotation_matrix(0, 1), - rotation_matrix(0, 2));
|
||||||
angles1(0) = - angles1(2) + ::atan2(- rotation_matrix(0, 1), - rotation_matrix(0, 2));
|
|
||||||
}
|
}
|
||||||
angles2 = angles1;
|
angles2 = angles1;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
angles1.y() = -::asin(rotation_matrix(2, 0));
|
||||||
angles1(1) = -::asin(rotation_matrix(2, 0));
|
const double inv_cos1 = 1.0 / ::cos(angles1.y());
|
||||||
double inv_cos1 = 1.0 / ::cos(angles1(1));
|
angles1.x() = ::atan2(rotation_matrix(2, 1) * inv_cos1, rotation_matrix(2, 2) * inv_cos1);
|
||||||
angles1(0) = ::atan2(rotation_matrix(2, 1) * inv_cos1, rotation_matrix(2, 2) * inv_cos1);
|
angles1.z() = ::atan2(rotation_matrix(1, 0) * inv_cos1, rotation_matrix(0, 0) * inv_cos1);
|
||||||
angles1(2) = ::atan2(rotation_matrix(1, 0) * inv_cos1, rotation_matrix(0, 0) * inv_cos1);
|
|
||||||
|
|
||||||
angles2(1) = (double)PI - angles1(1);
|
angles2.y() = double(PI) - angles1.y();
|
||||||
double inv_cos2 = 1.0 / ::cos(angles2(1));
|
const double inv_cos2 = 1.0 / ::cos(angles2.y());
|
||||||
angles2(0) = ::atan2(rotation_matrix(2, 1) * inv_cos2, rotation_matrix(2, 2) * inv_cos2);
|
angles2.x() = ::atan2(rotation_matrix(2, 1) * inv_cos2, rotation_matrix(2, 2) * inv_cos2);
|
||||||
angles2(2) = ::atan2(rotation_matrix(1, 0) * inv_cos2, rotation_matrix(0, 0) * inv_cos2);
|
angles2.z() = ::atan2(rotation_matrix(1, 0) * inv_cos2, rotation_matrix(0, 0) * inv_cos2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following euristic is the best found up to now (in the sense that it works fine with the greatest number of edge use-cases)
|
// The following euristic is the best found up to now (in the sense that it works fine with the greatest number of edge use-cases)
|
||||||
// but there are other use-cases were it does not
|
// but there are other use-cases were it does not
|
||||||
// We need to improve it
|
// We need to improve it
|
||||||
double min_1 = angles1.cwiseAbs().minCoeff();
|
const double min_1 = angles1.cwiseAbs().minCoeff();
|
||||||
double min_2 = angles2.cwiseAbs().minCoeff();
|
const double min_2 = angles2.cwiseAbs().minCoeff();
|
||||||
bool use_1 = (min_1 < min_2) || (is_approx(min_1, min_2) && (angles1.norm() <= angles2.norm()));
|
const bool use_1 = (min_1 < min_2) || (is_approx(min_1, min_2) && (angles1.norm() <= angles2.norm()));
|
||||||
|
|
||||||
return use_1 ? angles1 : angles2;
|
return use_1 ? angles1 : angles2;
|
||||||
}
|
}
|
||||||
@ -374,14 +370,6 @@ Vec3d extract_euler_angles(const Transform3d& transform)
|
|||||||
return extract_euler_angles(m);
|
return extract_euler_angles(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transformation::Flags::Flags()
|
|
||||||
: dont_translate(true)
|
|
||||||
, dont_rotate(true)
|
|
||||||
, dont_scale(true)
|
|
||||||
, dont_mirror(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
||||||
{
|
{
|
||||||
return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror);
|
return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror);
|
||||||
@ -407,15 +395,14 @@ Transformation::Transformation(const Transform3d& transform)
|
|||||||
|
|
||||||
void Transformation::set_offset(const Vec3d& offset)
|
void Transformation::set_offset(const Vec3d& offset)
|
||||||
{
|
{
|
||||||
set_offset(X, offset(0));
|
set_offset(X, offset.x());
|
||||||
set_offset(Y, offset(1));
|
set_offset(Y, offset.y());
|
||||||
set_offset(Z, offset(2));
|
set_offset(Z, offset.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_offset(Axis axis, double offset)
|
void Transformation::set_offset(Axis axis, double offset)
|
||||||
{
|
{
|
||||||
if (m_offset(axis) != offset)
|
if (m_offset(axis) != offset) {
|
||||||
{
|
|
||||||
m_offset(axis) = offset;
|
m_offset(axis) = offset;
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -423,19 +410,18 @@ void Transformation::set_offset(Axis axis, double offset)
|
|||||||
|
|
||||||
void Transformation::set_rotation(const Vec3d& rotation)
|
void Transformation::set_rotation(const Vec3d& rotation)
|
||||||
{
|
{
|
||||||
set_rotation(X, rotation(0));
|
set_rotation(X, rotation.x());
|
||||||
set_rotation(Y, rotation(1));
|
set_rotation(Y, rotation.y());
|
||||||
set_rotation(Z, rotation(2));
|
set_rotation(Z, rotation.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_rotation(Axis axis, double rotation)
|
void Transformation::set_rotation(Axis axis, double rotation)
|
||||||
{
|
{
|
||||||
rotation = angle_to_0_2PI(rotation);
|
rotation = angle_to_0_2PI(rotation);
|
||||||
if (is_approx(std::abs(rotation), 2.0 * (double)PI))
|
if (is_approx(std::abs(rotation), 2.0 * double(PI)))
|
||||||
rotation = 0.0;
|
rotation = 0.0;
|
||||||
|
|
||||||
if (m_rotation(axis) != rotation)
|
if (m_rotation(axis) != rotation) {
|
||||||
{
|
|
||||||
m_rotation(axis) = rotation;
|
m_rotation(axis) = rotation;
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -443,15 +429,14 @@ void Transformation::set_rotation(Axis axis, double rotation)
|
|||||||
|
|
||||||
void Transformation::set_scaling_factor(const Vec3d& scaling_factor)
|
void Transformation::set_scaling_factor(const Vec3d& scaling_factor)
|
||||||
{
|
{
|
||||||
set_scaling_factor(X, scaling_factor(0));
|
set_scaling_factor(X, scaling_factor.x());
|
||||||
set_scaling_factor(Y, scaling_factor(1));
|
set_scaling_factor(Y, scaling_factor.y());
|
||||||
set_scaling_factor(Z, scaling_factor(2));
|
set_scaling_factor(Z, scaling_factor.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
||||||
{
|
{
|
||||||
if (m_scaling_factor(axis) != std::abs(scaling_factor))
|
if (m_scaling_factor(axis) != std::abs(scaling_factor)) {
|
||||||
{
|
|
||||||
m_scaling_factor(axis) = std::abs(scaling_factor);
|
m_scaling_factor(axis) = std::abs(scaling_factor);
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -459,9 +444,9 @@ void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
|||||||
|
|
||||||
void Transformation::set_mirror(const Vec3d& mirror)
|
void Transformation::set_mirror(const Vec3d& mirror)
|
||||||
{
|
{
|
||||||
set_mirror(X, mirror(0));
|
set_mirror(X, mirror.x());
|
||||||
set_mirror(Y, mirror(1));
|
set_mirror(Y, mirror.y());
|
||||||
set_mirror(Z, mirror(2));
|
set_mirror(Z, mirror.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transformation::set_mirror(Axis axis, double mirror)
|
void Transformation::set_mirror(Axis axis, double mirror)
|
||||||
@ -472,8 +457,7 @@ void Transformation::set_mirror(Axis axis, double mirror)
|
|||||||
else if (abs_mirror != 1.0)
|
else if (abs_mirror != 1.0)
|
||||||
mirror /= abs_mirror;
|
mirror /= abs_mirror;
|
||||||
|
|
||||||
if (m_mirror(axis) != mirror)
|
if (m_mirror(axis) != mirror) {
|
||||||
{
|
|
||||||
m_mirror(axis) = mirror;
|
m_mirror(axis) = mirror;
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
@ -491,9 +475,8 @@ void Transformation::set_from_transform(const Transform3d& transform)
|
|||||||
// we can only detect if the matrix contains a left handed reference system
|
// we can only detect if the matrix contains a left handed reference system
|
||||||
// in which case we reorient it back to right handed by mirroring the x axis
|
// in which case we reorient it back to right handed by mirroring the x axis
|
||||||
Vec3d mirror = Vec3d::Ones();
|
Vec3d mirror = Vec3d::Ones();
|
||||||
if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0)
|
if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0) {
|
||||||
{
|
mirror.x() = -1.0;
|
||||||
mirror(0) = -1.0;
|
|
||||||
// remove mirror
|
// remove mirror
|
||||||
m3x3.col(0) *= -1.0;
|
m3x3.col(0) *= -1.0;
|
||||||
}
|
}
|
||||||
@ -530,8 +513,7 @@ void Transformation::reset()
|
|||||||
|
|
||||||
const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
|
||||||
{
|
{
|
||||||
if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror))
|
if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror)) {
|
||||||
{
|
|
||||||
m_matrix = Geometry::assemble_transform(
|
m_matrix = Geometry::assemble_transform(
|
||||||
dont_translate ? Vec3d::Zero() : m_offset,
|
dont_translate ? Vec3d::Zero() : m_offset,
|
||||||
dont_rotate ? Vec3d::Zero() : m_rotation,
|
dont_rotate ? Vec3d::Zero() : m_rotation,
|
||||||
@ -560,8 +542,7 @@ Transformation Transformation::volume_to_bed_transformation(const Transformation
|
|||||||
// Just set the inverse.
|
// Just set the inverse.
|
||||||
out.set_from_transform(instance_transformation.get_matrix(true).inverse());
|
out.set_from_transform(instance_transformation.get_matrix(true).inverse());
|
||||||
}
|
}
|
||||||
else if (is_rotation_ninety_degrees(instance_transformation.get_rotation()))
|
else if (is_rotation_ninety_degrees(instance_transformation.get_rotation())) {
|
||||||
{
|
|
||||||
// Anisotropic scaling, rotation by multiples of ninety degrees.
|
// Anisotropic scaling, rotation by multiples of ninety degrees.
|
||||||
Eigen::Matrix3d instance_rotation_trafo =
|
Eigen::Matrix3d instance_rotation_trafo =
|
||||||
(Eigen::AngleAxisd(instance_transformation.get_rotation().z(), Vec3d::UnitZ()) *
|
(Eigen::AngleAxisd(instance_transformation.get_rotation().z(), Vec3d::UnitZ()) *
|
||||||
@ -594,8 +575,8 @@ Transformation Transformation::volume_to_bed_transformation(const Transformation
|
|||||||
scale(i) = pts.col(i).dot(qs.col(i)) / pts.col(i).dot(pts.col(i));
|
scale(i) = pts.col(i).dot(qs.col(i)) / pts.col(i).dot(pts.col(i));
|
||||||
|
|
||||||
out.set_rotation(Geometry::extract_euler_angles(volume_rotation_trafo));
|
out.set_rotation(Geometry::extract_euler_angles(volume_rotation_trafo));
|
||||||
out.set_scaling_factor(Vec3d(std::abs(scale(0)), std::abs(scale(1)), std::abs(scale(2))));
|
out.set_scaling_factor(Vec3d(std::abs(scale.x()), std::abs(scale.y()), std::abs(scale.z())));
|
||||||
out.set_mirror(Vec3d(scale(0) > 0 ? 1. : -1, scale(1) > 0 ? 1. : -1, scale(2) > 0 ? 1. : -1));
|
out.set_mirror(Vec3d(scale.x() > 0 ? 1. : -1, scale.y() > 0 ? 1. : -1, scale.z() > 0 ? 1. : -1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -614,19 +595,15 @@ Transform3d transform3d_from_string(const std::string& transform_str)
|
|||||||
assert(is_decimal_separator_point()); // for atof
|
assert(is_decimal_separator_point()); // for atof
|
||||||
Transform3d transform = Transform3d::Identity();
|
Transform3d transform = Transform3d::Identity();
|
||||||
|
|
||||||
if (!transform_str.empty())
|
if (!transform_str.empty()) {
|
||||||
{
|
|
||||||
std::vector<std::string> mat_elements_str;
|
std::vector<std::string> mat_elements_str;
|
||||||
boost::split(mat_elements_str, transform_str, boost::is_any_of(" "), boost::token_compress_on);
|
boost::split(mat_elements_str, transform_str, boost::is_any_of(" "), boost::token_compress_on);
|
||||||
|
|
||||||
unsigned int size = (unsigned int)mat_elements_str.size();
|
const unsigned int size = (unsigned int)mat_elements_str.size();
|
||||||
if (size == 16)
|
if (size == 16) {
|
||||||
{
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (unsigned int r = 0; r < 4; ++r)
|
for (unsigned int r = 0; r < 4; ++r) {
|
||||||
{
|
for (unsigned int c = 0; c < 4; ++c) {
|
||||||
for (unsigned int c = 0; c < 4; ++c)
|
|
||||||
{
|
|
||||||
transform(r, c) = ::atof(mat_elements_str[i++].c_str());
|
transform(r, c) = ::atof(mat_elements_str[i++].c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,17 +617,17 @@ Eigen::Quaterniond rotation_xyz_diff(const Vec3d &rot_xyz_from, const Vec3d &rot
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
// From the current coordinate system to world.
|
// From the current coordinate system to world.
|
||||||
Eigen::AngleAxisd(rot_xyz_to(2), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to(1), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to(0), Vec3d::UnitX()) *
|
Eigen::AngleAxisd(rot_xyz_to.z(), Vec3d::UnitZ()) * Eigen::AngleAxisd(rot_xyz_to.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(rot_xyz_to.x(), Vec3d::UnitX()) *
|
||||||
// From world to the initial coordinate system.
|
// From world to the initial coordinate system.
|
||||||
Eigen::AngleAxisd(-rot_xyz_from(0), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from(1), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from(2), Vec3d::UnitZ());
|
Eigen::AngleAxisd(-rot_xyz_from.x(), Vec3d::UnitX()) * Eigen::AngleAxisd(-rot_xyz_from.y(), Vec3d::UnitY()) * Eigen::AngleAxisd(-rot_xyz_from.z(), Vec3d::UnitZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis.
|
// This should only be called if it is known, that the two rotations only differ in rotation around the Z axis.
|
||||||
double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
|
||||||
{
|
{
|
||||||
Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
const Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
|
||||||
Vec3d axis = angle_axis.axis();
|
const Vec3d axis = angle_axis.axis();
|
||||||
double angle = angle_axis.angle();
|
const double angle = angle_axis.angle();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (std::abs(angle) > 1e-8) {
|
if (std::abs(angle) > 1e-8) {
|
||||||
assert(std::abs(axis.x()) < 1e-8);
|
assert(std::abs(axis.x()) < 1e-8);
|
||||||
|
@ -347,25 +347,23 @@ class Transformation
|
|||||||
{
|
{
|
||||||
struct Flags
|
struct Flags
|
||||||
{
|
{
|
||||||
bool dont_translate;
|
bool dont_translate{ true };
|
||||||
bool dont_rotate;
|
bool dont_rotate{ true };
|
||||||
bool dont_scale;
|
bool dont_scale{ true };
|
||||||
bool dont_mirror;
|
bool dont_mirror{ true };
|
||||||
|
|
||||||
Flags();
|
|
||||||
|
|
||||||
bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const;
|
bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const;
|
||||||
void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror);
|
void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror);
|
||||||
};
|
};
|
||||||
|
|
||||||
Vec3d m_offset; // In unscaled coordinates
|
Vec3d m_offset{ Vec3d::Zero() }; // In unscaled coordinates
|
||||||
Vec3d m_rotation; // Rotation around the three axes, in radians around mesh center point
|
Vec3d m_rotation{ Vec3d::Zero() }; // Rotation around the three axes, in radians around mesh center point
|
||||||
Vec3d m_scaling_factor; // Scaling factors along the three axes
|
Vec3d m_scaling_factor{ Vec3d::Ones() }; // Scaling factors along the three axes
|
||||||
Vec3d m_mirror; // Mirroring along the three axes
|
Vec3d m_mirror{ Vec3d::Ones() }; // Mirroring along the three axes
|
||||||
|
|
||||||
mutable Transform3d m_matrix;
|
mutable Transform3d m_matrix{ Transform3d::Identity() };
|
||||||
mutable Flags m_flags;
|
mutable Flags m_flags;
|
||||||
mutable bool m_dirty;
|
mutable bool m_dirty{ false };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Transformation();
|
Transformation();
|
||||||
@ -435,7 +433,7 @@ extern double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to
|
|||||||
// Is the angle close to a multiple of 90 degrees?
|
// Is the angle close to a multiple of 90 degrees?
|
||||||
inline bool is_rotation_ninety_degrees(double a)
|
inline bool is_rotation_ninety_degrees(double a)
|
||||||
{
|
{
|
||||||
a = fmod(std::abs(a), 0.5 * M_PI);
|
a = fmod(std::abs(a), 0.5 * PI);
|
||||||
if (a > 0.25 * PI)
|
if (a > 0.25 * PI)
|
||||||
a = 0.5 * PI - a;
|
a = 0.5 * PI - a;
|
||||||
return a < 0.001;
|
return a < 0.001;
|
||||||
|
@ -105,6 +105,11 @@ public:
|
|||||||
|
|
||||||
static inline Int128 multiply(int64_t lhs, int64_t rhs) { return Int128(__int128(lhs) * __int128(rhs)); }
|
static inline Int128 multiply(int64_t lhs, int64_t rhs) { return Int128(__int128(lhs) * __int128(rhs)); }
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
// When Clang is used with enabled UndefinedBehaviorSanitizer, it produces "undefined reference to '__muloti4'" when __int128 is used.
|
||||||
|
// Because of that, UndefinedBehaviorSanitizer is disabled for this function.
|
||||||
|
__attribute__((no_sanitize("undefined")))
|
||||||
|
#endif
|
||||||
// Evaluate signum of a 2x2 determinant.
|
// Evaluate signum of a 2x2 determinant.
|
||||||
static int sign_determinant_2x2(int64_t a11, int64_t a12, int64_t a21, int64_t a22)
|
static int sign_determinant_2x2(int64_t a11, int64_t a12, int64_t a21, int64_t a22)
|
||||||
{
|
{
|
||||||
|
@ -2264,7 +2264,7 @@ void check_model_ids_validity(const Model &model)
|
|||||||
for (const ModelInstance *model_instance : model_object->instances)
|
for (const ModelInstance *model_instance : model_object->instances)
|
||||||
check(model_instance->id());
|
check(model_instance->id());
|
||||||
}
|
}
|
||||||
for (const auto mm : model.materials) {
|
for (const auto &mm : model.materials) {
|
||||||
check(mm.second->id());
|
check(mm.second->id());
|
||||||
check(mm.second->config.id());
|
check(mm.second->config.id());
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ class MultiPoint
|
|||||||
public:
|
public:
|
||||||
Points points;
|
Points points;
|
||||||
|
|
||||||
MultiPoint() {}
|
MultiPoint() = default;
|
||||||
|
virtual ~MultiPoint() = default;
|
||||||
MultiPoint(const MultiPoint &other) : points(other.points) {}
|
MultiPoint(const MultiPoint &other) : points(other.points) {}
|
||||||
MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
|
MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
|
||||||
MultiPoint(std::initializer_list<Point> list) : points(list) {}
|
MultiPoint(std::initializer_list<Point> list) : points(list) {}
|
||||||
|
@ -501,6 +501,7 @@ namespace client
|
|||||||
boost::throw_exception(qi::expectation_failure<Iterator>(
|
boost::throw_exception(qi::expectation_failure<Iterator>(
|
||||||
lhs.it_range.begin(), rhs.it_range.end(), spirit::info("*Cannot compare the types.")));
|
lhs.it_range.begin(), rhs.it_range.end(), spirit::info("*Cannot compare the types.")));
|
||||||
}
|
}
|
||||||
|
lhs.reset();
|
||||||
lhs.type = TYPE_BOOL;
|
lhs.type = TYPE_BOOL;
|
||||||
lhs.data.b = invert ? ! value : value;
|
lhs.data.b = invert ? ! value : value;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class Polygon : public MultiPoint
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Polygon() = default;
|
Polygon() = default;
|
||||||
virtual ~Polygon() = default;
|
~Polygon() override = default;
|
||||||
explicit Polygon(const Points &points) : MultiPoint(points) {}
|
explicit Polygon(const Points &points) : MultiPoint(points) {}
|
||||||
Polygon(std::initializer_list<Point> points) : MultiPoint(points) {}
|
Polygon(std::initializer_list<Point> points) : MultiPoint(points) {}
|
||||||
Polygon(const Polygon &other) : MultiPoint(other.points) {}
|
Polygon(const Polygon &other) : MultiPoint(other.points) {}
|
||||||
|
@ -16,7 +16,8 @@ typedef std::vector<ThickPolyline> ThickPolylines;
|
|||||||
|
|
||||||
class Polyline : public MultiPoint {
|
class Polyline : public MultiPoint {
|
||||||
public:
|
public:
|
||||||
Polyline() {};
|
Polyline() = default;
|
||||||
|
~Polyline() override = default;
|
||||||
Polyline(const Polyline &other) : MultiPoint(other.points) {}
|
Polyline(const Polyline &other) : MultiPoint(other.points) {}
|
||||||
Polyline(Polyline &&other) : MultiPoint(std::move(other.points)) {}
|
Polyline(Polyline &&other) : MultiPoint(std::move(other.points)) {}
|
||||||
Polyline(std::initializer_list<Point> list) : MultiPoint(list) {}
|
Polyline(std::initializer_list<Point> list) : MultiPoint(list) {}
|
||||||
|
@ -116,6 +116,8 @@ public:
|
|||||||
// This type is here to support PresetConfigSubstitutions for physical printers, however it does not belong to the Preset class,
|
// This type is here to support PresetConfigSubstitutions for physical printers, however it does not belong to the Preset class,
|
||||||
// PhysicalPrinter class is used instead.
|
// PhysicalPrinter class is used instead.
|
||||||
TYPE_PHYSICAL_PRINTER,
|
TYPE_PHYSICAL_PRINTER,
|
||||||
|
// This type is here to support search through the Preferences
|
||||||
|
TYPE_PREFERENCES,
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type = TYPE_INVALID;
|
Type type = TYPE_INVALID;
|
||||||
|
@ -346,7 +346,11 @@ private:
|
|||||||
friend class Print;
|
friend class Print;
|
||||||
|
|
||||||
PrintObject(Print* print, ModelObject* model_object, const Transform3d& trafo, PrintInstances&& instances);
|
PrintObject(Print* print, ModelObject* model_object, const Transform3d& trafo, PrintInstances&& instances);
|
||||||
~PrintObject() { if (m_shared_regions && -- m_shared_regions->m_ref_cnt == 0) delete m_shared_regions; }
|
~PrintObject() {
|
||||||
|
if (m_shared_regions && --m_shared_regions->m_ref_cnt == 0)
|
||||||
|
delete m_shared_regions;
|
||||||
|
clear_layers();
|
||||||
|
}
|
||||||
|
|
||||||
void config_apply(const ConfigBase &other, bool ignore_nonexistent = false) { m_config.apply(other, ignore_nonexistent); }
|
void config_apply(const ConfigBase &other, bool ignore_nonexistent = false) { m_config.apply(other, ignore_nonexistent); }
|
||||||
void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) { m_config.apply_only(other, keys, ignore_nonexistent); }
|
void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) { m_config.apply_only(other, keys, ignore_nonexistent); }
|
||||||
|
@ -2759,7 +2759,8 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->label = L("Synchronize with object layers");
|
def->label = L("Synchronize with object layers");
|
||||||
def->category = L("Support material");
|
def->category = L("Support material");
|
||||||
def->tooltip = L("Synchronize support layers with the object print layers. This is useful "
|
def->tooltip = L("Synchronize support layers with the object print layers. This is useful "
|
||||||
"with multi-material printers, where the extruder switch is expensive.");
|
"with multi-material printers, where the extruder switch is expensive. "
|
||||||
|
"This option is only available when top contact Z distance is set to zero.");
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->set_default_value(new ConfigOptionBool(false));
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <libslic3r/SLA/RasterBase.hpp>
|
#include <libslic3r/SLA/RasterBase.hpp>
|
||||||
#include "libslic3r/ExPolygon.hpp"
|
#include "libslic3r/ExPolygon.hpp"
|
||||||
#include "libslic3r/MTUtils.hpp"
|
|
||||||
|
|
||||||
// For rasterizing
|
// For rasterizing
|
||||||
#include <agg/agg_basics.h>
|
#include <agg/agg_basics.h>
|
||||||
|
@ -77,6 +77,8 @@ std::unique_ptr<RasterBase> create_raster_grayscale_aa(
|
|||||||
|
|
||||||
if (gamma > 0)
|
if (gamma > 0)
|
||||||
rst = std::make_unique<RasterGrayscaleAAGammaPower>(res, pxdim, tr, gamma);
|
rst = std::make_unique<RasterGrayscaleAAGammaPower>(res, pxdim, tr, gamma);
|
||||||
|
else if (std::abs(gamma - 1.) < 1e-6)
|
||||||
|
rst = std::make_unique<RasterGrayscaleAA>(res, pxdim, tr, agg::gamma_none());
|
||||||
else
|
else
|
||||||
rst = std::make_unique<RasterGrayscaleAA>(res, pxdim, tr, agg::gamma_threshold(.5));
|
rst = std::make_unique<RasterGrayscaleAA>(res, pxdim, tr, agg::gamma_threshold(.5));
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <libslic3r/ExPolygon.hpp>
|
#include <libslic3r/ExPolygon.hpp>
|
||||||
#include <libslic3r/SLA/Concurrency.hpp>
|
//#include <libslic3r/SLA/Concurrency.hpp>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "MTUtils.hpp"
|
#include "MTUtils.hpp"
|
||||||
#include "Zipper.hpp"
|
#include "Zipper.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/Execution/ExecutionTBB.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
enum SLAPrintStep : unsigned int {
|
enum SLAPrintStep : unsigned int {
|
||||||
|
@ -110,10 +110,30 @@ public:
|
|||||||
void set_maj(int maj) { ver.major = maj; }
|
void set_maj(int maj) { ver.major = maj; }
|
||||||
void set_min(int min) { ver.minor = min; }
|
void set_min(int min) { ver.minor = min; }
|
||||||
void set_patch(int patch) { ver.patch = patch; }
|
void set_patch(int patch) { ver.patch = patch; }
|
||||||
void set_metadata(boost::optional<const std::string&> meta) { ver.metadata = meta ? strdup(*meta) : nullptr; }
|
void set_metadata(boost::optional<const std::string &> meta)
|
||||||
void set_metadata(const char *meta) { ver.metadata = meta ? strdup(meta) : nullptr; }
|
{
|
||||||
void set_prerelease(boost::optional<const std::string&> pre) { ver.prerelease = pre ? strdup(*pre) : nullptr; }
|
if (ver.metadata)
|
||||||
void set_prerelease(const char *pre) { ver.prerelease = pre ? strdup(pre) : nullptr; }
|
free(ver.metadata);
|
||||||
|
ver.metadata = meta ? strdup(*meta) : nullptr;
|
||||||
|
}
|
||||||
|
void set_metadata(const char *meta)
|
||||||
|
{
|
||||||
|
if (ver.metadata)
|
||||||
|
free(ver.metadata);
|
||||||
|
ver.metadata = meta ? strdup(meta) : nullptr;
|
||||||
|
}
|
||||||
|
void set_prerelease(boost::optional<const std::string &> pre)
|
||||||
|
{
|
||||||
|
if (ver.prerelease)
|
||||||
|
free(ver.prerelease);
|
||||||
|
ver.prerelease = pre ? strdup(*pre) : nullptr;
|
||||||
|
}
|
||||||
|
void set_prerelease(const char *pre)
|
||||||
|
{
|
||||||
|
if (ver.prerelease)
|
||||||
|
free(ver.prerelease);
|
||||||
|
ver.prerelease = pre ? strdup(pre) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Comparison
|
// Comparison
|
||||||
bool operator<(const Semver &b) const { return ::semver_compare(ver, b.ver) == -1; }
|
bool operator<(const Semver &b) const { return ::semver_compare(ver, b.ver) == -1; }
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#define ENABLE_GCODE_VIEWER_DATA_CHECKING 0
|
#define ENABLE_GCODE_VIEWER_DATA_CHECKING 0
|
||||||
// Enable project dirty state manager debug window
|
// Enable project dirty state manager debug window
|
||||||
#define ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW 0
|
#define ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW 0
|
||||||
|
// Disable using instanced models to render options in gcode preview
|
||||||
|
#define DISABLE_GCODEVIEWER_INSTANCED_MODELS 1
|
||||||
|
|
||||||
|
|
||||||
// Enable rendering of objects using environment map
|
// Enable rendering of objects using environment map
|
||||||
@ -47,4 +49,27 @@
|
|||||||
#define ENABLE_Z_OFFSET_CORRECTION (1 && ENABLE_2_4_1_RC)
|
#define ENABLE_Z_OFFSET_CORRECTION (1 && ENABLE_2_4_1_RC)
|
||||||
|
|
||||||
|
|
||||||
|
//====================
|
||||||
|
// 2.5.0.alpha1 techs
|
||||||
|
//====================
|
||||||
|
#define ENABLE_2_5_0_ALPHA1 1
|
||||||
|
|
||||||
|
// Enable changes in preview layout
|
||||||
|
#define ENABLE_PREVIEW_LAYOUT (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
|
// Enable drawing the items in legend toolbar using icons
|
||||||
|
#define ENABLE_LEGEND_TOOLBAR_ICONS (1 && ENABLE_PREVIEW_LAYOUT)
|
||||||
|
// Enable coloring of toolpaths in preview by layer time
|
||||||
|
#define ENABLE_PREVIEW_LAYER_TIME (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
|
// Enable showing time estimate for travel moves in legend
|
||||||
|
#define ENABLE_TRAVEL_TIME (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
|
// Enable not killing focus in object manipulator fields when hovering over 3D scene
|
||||||
|
#define ENABLE_OBJECT_MANIPULATOR_FOCUS (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
|
// Enable removal of wipe tower magic object_id equal to 1000
|
||||||
|
#define ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
|
// Enable removal of old OpenGL render calls
|
||||||
|
#define ENABLE_GLBEGIN_GLEND_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
|
// Enable show non-manifold edges
|
||||||
|
#define ENABLE_SHOW_NON_MANIFOLD_EDGES (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
|
|
||||||
|
|
||||||
#endif // _prusaslicer_technologies_h_
|
#endif // _prusaslicer_technologies_h_
|
||||||
|
@ -1239,13 +1239,30 @@ bool its_is_splittable(const indexed_triangle_set &its, const std::vector<Vec3i>
|
|||||||
size_t its_num_open_edges(const std::vector<Vec3i> &face_neighbors)
|
size_t its_num_open_edges(const std::vector<Vec3i> &face_neighbors)
|
||||||
{
|
{
|
||||||
size_t num_open_edges = 0;
|
size_t num_open_edges = 0;
|
||||||
for (Vec3i neighbors : face_neighbors)
|
for (const Vec3i& neighbors : face_neighbors)
|
||||||
for (int n : neighbors)
|
for (int n : neighbors)
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
++ num_open_edges;
|
++ num_open_edges;
|
||||||
return num_open_edges;
|
return num_open_edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
std::vector<std::pair<int, int>> its_get_open_edges(const indexed_triangle_set& its)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<int, int>> ret;
|
||||||
|
std::vector<Vec3i> face_neighbors = its_face_neighbors(its);
|
||||||
|
for (size_t i = 0; i < face_neighbors.size(); ++i) {
|
||||||
|
for (size_t j = 0; j < 3; ++j) {
|
||||||
|
if (face_neighbors[i][j] < 0) {
|
||||||
|
const Vec2i edge_indices = its_triangle_edge(its.indices[i], j);
|
||||||
|
ret.emplace_back(edge_indices[0], edge_indices[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
size_t its_num_open_edges(const indexed_triangle_set &its)
|
size_t its_num_open_edges(const indexed_triangle_set &its)
|
||||||
{
|
{
|
||||||
return its_num_open_edges(its_face_neighbors(its));
|
return its_num_open_edges(its_face_neighbors(its));
|
||||||
|
@ -227,6 +227,12 @@ bool its_is_splittable(const indexed_triangle_set &its, const std::vector<Vec3i>
|
|||||||
size_t its_num_open_edges(const indexed_triangle_set &its);
|
size_t its_num_open_edges(const indexed_triangle_set &its);
|
||||||
size_t its_num_open_edges(const std::vector<Vec3i> &face_neighbors);
|
size_t its_num_open_edges(const std::vector<Vec3i> &face_neighbors);
|
||||||
|
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
// Calculate and returns the list of unconnected face edges.
|
||||||
|
// Each edge is represented by the indices of the two endpoint vertices
|
||||||
|
std::vector<std::pair<int, int>> its_get_open_edges(const indexed_triangle_set& its);
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
// Shrink the vectors of its.vertices and its.faces to a minimum size by reallocating the two vectors.
|
// Shrink the vectors of its.vertices and its.faces to a minimum size by reallocating the two vectors.
|
||||||
void its_shrink_to_fit(indexed_triangle_set &its);
|
void its_shrink_to_fit(indexed_triangle_set &its);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
@ -361,7 +362,7 @@ inline std::string get_time_dhms(float time_in_secs)
|
|||||||
else if (minutes > 0)
|
else if (minutes > 0)
|
||||||
::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs);
|
::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs);
|
||||||
else
|
else
|
||||||
::sprintf(buffer, "%ds", (int)time_in_secs);
|
::sprintf(buffer, "%ds", (int)std::round(time_in_secs));
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -169,9 +169,11 @@ set(SLIC3R_GUI_SOURCES
|
|||||||
GUI/PrintHostDialogs.cpp
|
GUI/PrintHostDialogs.cpp
|
||||||
GUI/PrintHostDialogs.hpp
|
GUI/PrintHostDialogs.hpp
|
||||||
GUI/Jobs/Job.hpp
|
GUI/Jobs/Job.hpp
|
||||||
GUI/Jobs/Job.cpp
|
GUI/Jobs/Worker.hpp
|
||||||
GUI/Jobs/PlaterJob.hpp
|
GUI/Jobs/BoostThreadWorker.hpp
|
||||||
GUI/Jobs/PlaterJob.cpp
|
GUI/Jobs/BoostThreadWorker.cpp
|
||||||
|
GUI/Jobs/BusyCursorJob.hpp
|
||||||
|
GUI/Jobs/PlaterWorker.hpp
|
||||||
GUI/Jobs/ArrangeJob.hpp
|
GUI/Jobs/ArrangeJob.hpp
|
||||||
GUI/Jobs/ArrangeJob.cpp
|
GUI/Jobs/ArrangeJob.cpp
|
||||||
GUI/Jobs/RotoptimizeJob.hpp
|
GUI/Jobs/RotoptimizeJob.hpp
|
||||||
@ -183,6 +185,8 @@ set(SLIC3R_GUI_SOURCES
|
|||||||
GUI/Jobs/ProgressIndicator.hpp
|
GUI/Jobs/ProgressIndicator.hpp
|
||||||
GUI/Jobs/NotificationProgressIndicator.hpp
|
GUI/Jobs/NotificationProgressIndicator.hpp
|
||||||
GUI/Jobs/NotificationProgressIndicator.cpp
|
GUI/Jobs/NotificationProgressIndicator.cpp
|
||||||
|
GUI/Jobs/ThreadSafeQueue.hpp
|
||||||
|
GUI/Jobs/SLAImportDialog.hpp
|
||||||
GUI/ProgressStatusBar.hpp
|
GUI/ProgressStatusBar.hpp
|
||||||
GUI/ProgressStatusBar.cpp
|
GUI/ProgressStatusBar.cpp
|
||||||
GUI/Mouse3DController.cpp
|
GUI/Mouse3DController.cpp
|
||||||
@ -258,6 +262,12 @@ endif ()
|
|||||||
|
|
||||||
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
||||||
|
|
||||||
|
foreach(_source IN ITEMS ${SLIC3R_GUI_SOURCES})
|
||||||
|
get_filename_component(_source_path "${_source}" PATH)
|
||||||
|
string(REPLACE "/" "\\" _group_path "${_source_path}")
|
||||||
|
source_group("${_group_path}" FILES "${_source}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
encoding_check(libslic3r_gui)
|
encoding_check(libslic3r_gui)
|
||||||
|
|
||||||
target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL hidapi libcurl ${wxWidgets_LIBRARIES})
|
target_link_libraries(libslic3r_gui libslic3r avrdude cereal imgui GLEW::GLEW OpenGL::GL hidapi libcurl ${wxWidgets_LIBRARIES})
|
||||||
|
@ -19,8 +19,10 @@
|
|||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
static const float GROUND_Z = -0.02f;
|
static const float GROUND_Z = -0.02f;
|
||||||
static const std::array<float, 4> DEFAULT_MODEL_COLOR = { 0.235f, 0.235f, 0.235f, 1.0f };
|
static const Slic3r::ColorRGBA DEFAULT_MODEL_COLOR = Slic3r::ColorRGBA::DARK_GRAY();
|
||||||
static const std::array<float, 4> PICKING_MODEL_COLOR = { 0.0f, 0.0f, 0.0f, 1.0f };
|
static const Slic3r::ColorRGBA PICKING_MODEL_COLOR = Slic3r::ColorRGBA::BLACK();
|
||||||
|
static const Slic3r::ColorRGBA DEFAULT_SOLID_GRID_COLOR = { 0.9f, 0.9f, 0.9f, 1.0f };
|
||||||
|
static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0.9f, 0.6f };
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
@ -99,7 +101,7 @@ const float Bed3D::Axes::DefaultStemLength = 25.0f;
|
|||||||
const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius;
|
const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius;
|
||||||
const float Bed3D::Axes::DefaultTipLength = 5.0f;
|
const float Bed3D::Axes::DefaultTipLength = 5.0f;
|
||||||
|
|
||||||
void Bed3D::Axes::render() const
|
void Bed3D::Axes::render()
|
||||||
{
|
{
|
||||||
auto render_axis = [this](const Transform3f& transform) {
|
auto render_axis = [this](const Transform3f& transform) {
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
@ -109,7 +111,7 @@ void Bed3D::Axes::render() const
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!m_arrow.is_initialized())
|
if (!m_arrow.is_initialized())
|
||||||
const_cast<GLModel*>(&m_arrow)->init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
|
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)
|
||||||
@ -121,15 +123,27 @@ void Bed3D::Axes::render() const
|
|||||||
shader->set_uniform("emission_factor", 0.0f);
|
shader->set_uniform("emission_factor", 0.0f);
|
||||||
|
|
||||||
// x axis
|
// x axis
|
||||||
const_cast<GLModel*>(&m_arrow)->set_color(-1, { 0.75f, 0.0f, 0.0f, 1.0f });
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
m_arrow.set_color(ColorRGBA::X());
|
||||||
|
#else
|
||||||
|
m_arrow.set_color(-1, ColorRGBA::X());
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast<float>());
|
render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast<float>());
|
||||||
|
|
||||||
// y axis
|
// y axis
|
||||||
const_cast<GLModel*>(&m_arrow)->set_color(-1, { 0.0f, 0.75f, 0.0f, 1.0f });
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
m_arrow.set_color(ColorRGBA::Y());
|
||||||
|
#else
|
||||||
|
m_arrow.set_color(-1, ColorRGBA::Y());
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast<float>());
|
render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast<float>());
|
||||||
|
|
||||||
// z axis
|
// z axis
|
||||||
const_cast<GLModel*>(&m_arrow)->set_color(-1, { 0.0f, 0.0f, 0.75f, 1.0f });
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
m_arrow.set_color(ColorRGBA::Z());
|
||||||
|
#else
|
||||||
|
m_arrow.set_color(-1, ColorRGBA::Z());
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
render_axis(Geometry::assemble_transform(m_origin).cast<float>());
|
render_axis(Geometry::assemble_transform(m_origin).cast<float>());
|
||||||
|
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
@ -228,15 +242,18 @@ void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_fact
|
|||||||
void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||||
bool show_axes, bool show_texture, bool picking)
|
bool show_axes, bool show_texture, bool picking)
|
||||||
{
|
{
|
||||||
float* factor = const_cast<float*>(&m_scale_factor);
|
m_scale_factor = scale_factor;
|
||||||
*factor = scale_factor;
|
|
||||||
|
|
||||||
if (show_axes)
|
if (show_axes)
|
||||||
render_axes();
|
render_axes();
|
||||||
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
m_model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
|
||||||
|
#else
|
||||||
m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
|
m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
@ -328,13 +345,13 @@ std::tuple<Bed3D::Type, std::string, std::string> Bed3D::detect_type(const Point
|
|||||||
return { Type::Custom, {}, {} };
|
return { Type::Custom, {}, {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::render_axes() const
|
void Bed3D::render_axes()
|
||||||
{
|
{
|
||||||
if (m_build_volume.valid())
|
if (m_build_volume.valid())
|
||||||
m_axes.render();
|
m_axes.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) const
|
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
|
||||||
{
|
{
|
||||||
if (!bottom)
|
if (!bottom)
|
||||||
render_model();
|
render_model();
|
||||||
@ -343,26 +360,23 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) co
|
|||||||
render_texture(bottom, canvas);
|
render_texture(bottom, canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
|
||||||
{
|
{
|
||||||
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()) {
|
||||||
texture->reset();
|
m_texture.reset();
|
||||||
render_default(bottom, false);
|
render_default(bottom, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture->get_id() == 0 || texture->get_source() != m_texture_filename) {
|
if (m_texture.get_id() == 0 || m_texture.get_source() != m_texture_filename) {
|
||||||
texture->reset();
|
m_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 (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
|
if (m_temp_texture.get_id() == 0 || m_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 (!temp_texture->load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
|
if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
|
||||||
render_default(bottom, false);
|
render_default(bottom, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -370,15 +384,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 (!texture->load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
|
if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
|
||||||
render_default(bottom, false);
|
render_default(bottom, false);
|
||||||
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 (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
|
if (m_temp_texture.get_id() == 0 || m_temp_texture.get_source() != m_texture_filename) {
|
||||||
if (!temp_texture->load_from_file(m_texture_filename, false, GLTexture::None, false)) {
|
if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) {
|
||||||
render_default(bottom, false);
|
render_default(bottom, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -386,7 +400,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 (!texture->load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
|
if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
|
||||||
render_default(bottom, false);
|
render_default(bottom, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -396,13 +410,13 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (texture->unsent_compressed_data_available()) {
|
else if (m_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
|
||||||
texture->send_compressed_data_to_gpu();
|
m_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 (temp_texture->get_id() != 0)
|
if (m_temp_texture.get_id() != 0)
|
||||||
temp_texture->reset();
|
m_temp_texture.reset();
|
||||||
|
|
||||||
canvas.request_extra_frame();
|
canvas.request_extra_frame();
|
||||||
}
|
}
|
||||||
@ -414,11 +428,9 @@ 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"));
|
||||||
|
|
||||||
unsigned int* vbo_id = const_cast<unsigned int*>(&m_vbo_id);
|
if (m_vbo_id == 0) {
|
||||||
|
glsafe(::glGenBuffers(1, &m_vbo_id));
|
||||||
if (*vbo_id == 0) {
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
||||||
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));
|
||||||
}
|
}
|
||||||
@ -439,12 +451,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)temp_texture->get_id();
|
GLuint tex_id = (GLuint)m_temp_texture.get_id();
|
||||||
if (tex_id == 0)
|
if (tex_id == 0)
|
||||||
tex_id = (GLuint)texture->get_id();
|
tex_id = (GLuint)m_texture.get_id();
|
||||||
|
|
||||||
glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id));
|
glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id));
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, *vbo_id));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
|
||||||
|
|
||||||
if (position_id != -1) {
|
if (position_id != -1) {
|
||||||
glsafe(::glEnableVertexAttribArray(position_id));
|
glsafe(::glEnableVertexAttribArray(position_id));
|
||||||
@ -478,38 +490,40 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::render_model() const
|
void Bed3D::render_model()
|
||||||
{
|
{
|
||||||
if (m_model_filename.empty())
|
if (m_model_filename.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GLModel* model = const_cast<GLModel*>(&m_model);
|
if (m_model.get_filename() != m_model_filename && m_model.init_from_file(m_model_filename)) {
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
if (model->get_filename() != m_model_filename && model->init_from_file(m_model_filename)) {
|
m_model.set_color(DEFAULT_MODEL_COLOR);
|
||||||
model->set_color(-1, DEFAULT_MODEL_COLOR);
|
#else
|
||||||
|
m_model.set_color(-1, DEFAULT_MODEL_COLOR);
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
// 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
|
||||||
*const_cast<Vec3d*>(&m_model_offset) = to_3d(m_build_volume.bounding_volume2d().center(), -0.03);
|
m_model_offset = to_3d(m_build_volume.bounding_volume2d().center(), -0.03);
|
||||||
|
|
||||||
// update extended bounding box
|
// update extended bounding box
|
||||||
const_cast<BoundingBoxf3&>(m_extended_bounding_box) = this->calc_extended_bounding_box();
|
m_extended_bounding_box = this->calc_extended_bounding_box();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!model->get_filename().empty()) {
|
if (!m_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("emission_factor", 0.0f);
|
shader->set_uniform("emission_factor", 0.0f);
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z()));
|
glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z()));
|
||||||
model->render();
|
m_model.render();
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) const
|
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking)
|
||||||
{
|
{
|
||||||
if (m_texture_filename.empty() && m_model_filename.empty()) {
|
if (m_texture_filename.empty() && m_model_filename.empty()) {
|
||||||
render_default(bottom, picking);
|
render_default(bottom, picking);
|
||||||
@ -523,13 +537,13 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo
|
|||||||
render_texture(bottom, canvas);
|
render_texture(bottom, canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed3D::render_default(bool bottom, bool picking) const
|
void Bed3D::render_default(bool bottom, bool picking)
|
||||||
{
|
{
|
||||||
const_cast<GLTexture*>(&m_texture)->reset();
|
m_texture.reset();
|
||||||
|
|
||||||
unsigned int triangles_vcount = m_triangles.get_vertices_count();
|
const unsigned int triangles_vcount = m_triangles.get_vertices_count();
|
||||||
if (triangles_vcount > 0) {
|
if (triangles_vcount > 0) {
|
||||||
bool has_model = !m_model.get_filename().empty();
|
const bool has_model = !m_model.get_filename().empty();
|
||||||
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
glsafe(::glEnable(GL_BLEND));
|
glsafe(::glEnable(GL_BLEND));
|
||||||
@ -550,10 +564,7 @@ void Bed3D::render_default(bool bottom, bool picking) const
|
|||||||
if (!picking) {
|
if (!picking) {
|
||||||
// draw grid
|
// draw grid
|
||||||
glsafe(::glLineWidth(1.5f * m_scale_factor));
|
glsafe(::glLineWidth(1.5f * m_scale_factor));
|
||||||
if (has_model && !bottom)
|
glsafe(::glColor4fv(has_model && !bottom ? DEFAULT_SOLID_GRID_COLOR.data() : DEFAULT_TRANSPARENT_GRID_COLOR.data()));
|
||||||
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f));
|
|
||||||
else
|
|
||||||
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f));
|
|
||||||
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
|
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
|
||||||
glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count()));
|
glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count()));
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ class Bed3D
|
|||||||
m_arrow.reset();
|
m_arrow.reset();
|
||||||
}
|
}
|
||||||
float get_total_length() const { return m_stem_length + DefaultTipLength; }
|
float get_total_length() const { return m_stem_length + DefaultTipLength; }
|
||||||
void render() const;
|
void render();
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -130,12 +130,12 @@ private:
|
|||||||
static std::tuple<Type, std::string, std::string> detect_type(const Pointfs& shape);
|
static std::tuple<Type, std::string, std::string> detect_type(const Pointfs& shape);
|
||||||
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||||
bool show_axes, bool show_texture, bool picking);
|
bool show_axes, bool show_texture, bool picking);
|
||||||
void render_axes() const;
|
void render_axes();
|
||||||
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) const;
|
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture);
|
||||||
void render_texture(bool bottom, GLCanvas3D& canvas) const;
|
void render_texture(bool bottom, GLCanvas3D& canvas);
|
||||||
void render_model() const;
|
void render_model();
|
||||||
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) const;
|
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking);
|
||||||
void render_default(bool bottom, bool picking) const;
|
void render_default(bool bottom, bool picking);
|
||||||
void release_VBOs();
|
void release_VBOs();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,10 +302,10 @@ void GLVolume::SinkingContours::render()
|
|||||||
|
|
||||||
void GLVolume::SinkingContours::update()
|
void GLVolume::SinkingContours::update()
|
||||||
{
|
{
|
||||||
int object_idx = m_parent.object_idx();
|
const int object_idx = m_parent.object_idx();
|
||||||
Model& model = GUI::wxGetApp().plater()->model();
|
const Model& model = GUI::wxGetApp().plater()->model();
|
||||||
|
|
||||||
if (0 <= object_idx && object_idx < (int)model.objects.size() && m_parent.is_sinking() && !m_parent.is_below_printbed()) {
|
if (0 <= object_idx && object_idx < int(model.objects.size()) && m_parent.is_sinking() && !m_parent.is_below_printbed()) {
|
||||||
const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box();
|
const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box();
|
||||||
if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) {
|
if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) {
|
||||||
m_old_box = box;
|
m_old_box = box;
|
||||||
@ -314,16 +314,37 @@ void GLVolume::SinkingContours::update()
|
|||||||
const TriangleMesh& mesh = model.objects[object_idx]->volumes[m_parent.volume_idx()]->mesh();
|
const TriangleMesh& mesh = model.objects[object_idx]->volumes[m_parent.volume_idx()]->mesh();
|
||||||
|
|
||||||
m_model.reset();
|
m_model.reset();
|
||||||
GUI::GLModel::InitializationData init_data;
|
GUI::GLModel::Geometry init_data;
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::EIndexType::UINT };
|
||||||
|
init_data.color = ColorRGBA::WHITE();
|
||||||
|
unsigned int vertices_counter = 0;
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
MeshSlicingParams slicing_params;
|
MeshSlicingParams slicing_params;
|
||||||
slicing_params.trafo = m_parent.world_matrix();
|
slicing_params.trafo = m_parent.world_matrix();
|
||||||
Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params));
|
const Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params));
|
||||||
for (ExPolygon &expoly : diff_ex(expand(polygons, float(scale_(HalfWidth))), shrink(polygons, float(scale_(HalfWidth))))) {
|
for (const ExPolygon& expoly : diff_ex(expand(polygons, float(scale_(HalfWidth))), shrink(polygons, float(scale_(HalfWidth))))) {
|
||||||
GUI::GLModel::InitializationData::Entity entity;
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
entity.type = GUI::GLModel::PrimitiveType::Triangles;
|
|
||||||
const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(expoly);
|
const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(expoly);
|
||||||
|
init_data.vertices.reserve(init_data.vertices.size() + triangulation.size() * GUI::GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
|
init_data.indices.reserve(init_data.indices.size() + triangulation.size() * GUI::GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
for (const Vec3d& v : triangulation) {
|
for (const Vec3d& v : triangulation) {
|
||||||
entity.positions.emplace_back(v.cast<float>() + Vec3f(0.0f, 0.0f, 0.015f)); // add a small positive z to avoid z-fighting
|
init_data.add_vertex((Vec3f)(v.cast<float>() + 0.015f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting
|
||||||
|
++vertices_counter;
|
||||||
|
if (vertices_counter % 3 == 0)
|
||||||
|
init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_model.init_from(std::move(init_data));
|
||||||
|
#else
|
||||||
|
GUI::GLModel::Geometry::Entity entity;
|
||||||
|
entity.type = GUI::GLModel::EPrimitiveType::Triangles;
|
||||||
|
const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(expoly);
|
||||||
|
entity.positions.reserve(entity.positions.size() + triangulation.size());
|
||||||
|
entity.normals.reserve(entity.normals.size() + triangulation.size());
|
||||||
|
entity.indices.reserve(entity.indices.size() + triangulation.size() / 3);
|
||||||
|
for (const Vec3d& v : triangulation) {
|
||||||
|
entity.positions.emplace_back(v.cast<float>() + 0.015f * Vec3f::UnitZ()); // add a small positive z to avoid z-fighting
|
||||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||||
const size_t positions_count = entity.positions.size();
|
const size_t positions_count = entity.positions.size();
|
||||||
if (positions_count % 3 == 0) {
|
if (positions_count % 3 == 0) {
|
||||||
@ -334,8 +355,8 @@ void GLVolume::SinkingContours::update()
|
|||||||
}
|
}
|
||||||
init_data.entities.emplace_back(entity);
|
init_data.entities.emplace_back(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_model.init_from(init_data);
|
m_model.init_from(init_data);
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_shift = box.center() - m_old_box.center();
|
m_shift = box.center() - m_old_box.center();
|
||||||
@ -344,25 +365,103 @@ void GLVolume::SinkingContours::update()
|
|||||||
m_model.reset();
|
m_model.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::array<float, 4> GLVolume::SELECTED_COLOR = { 0.0f, 1.0f, 0.0f, 1.0f };
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
const std::array<float, 4> GLVolume::HOVER_SELECT_COLOR = { 0.4f, 0.9f, 0.1f, 1.0f };
|
void GLVolume::NonManifoldEdges::render()
|
||||||
const std::array<float, 4> GLVolume::HOVER_DESELECT_COLOR = { 1.0f, 0.75f, 0.75f, 1.0f };
|
{
|
||||||
const std::array<float, 4> GLVolume::OUTSIDE_COLOR = { 0.0f, 0.38f, 0.8f, 1.0f };
|
update();
|
||||||
const std::array<float, 4> GLVolume::SELECTED_OUTSIDE_COLOR = { 0.19f, 0.58f, 1.0f, 1.0f };
|
|
||||||
const std::array<float, 4> GLVolume::DISABLED_COLOR = { 0.25f, 0.25f, 0.25f, 1.0f };
|
glsafe(::glLineWidth(2.0f));
|
||||||
const std::array<float, 4> GLVolume::SLA_SUPPORT_COLOR = { 0.75f, 0.75f, 0.75f, 1.0f };
|
glsafe(::glPushMatrix());
|
||||||
const std::array<float, 4> GLVolume::SLA_PAD_COLOR = { 0.0f, 0.2f, 0.0f, 1.0f };
|
glsafe(::glMultMatrixd(m_parent.world_matrix().data()));
|
||||||
const std::array<float, 4> GLVolume::NEUTRAL_COLOR = { 0.9f, 0.9f, 0.9f, 1.0f };
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
const std::array<std::array<float, 4>, 4> GLVolume::MODEL_COLOR = { {
|
m_model.set_color(complementary(m_parent.render_color));
|
||||||
{ 1.0f, 1.0f, 0.0f, 1.f },
|
#else
|
||||||
{ 1.0f, 0.5f, 0.5f, 1.f },
|
m_model.set_color(-1, complementary(m_parent.render_color));
|
||||||
{ 0.5f, 1.0f, 0.5f, 1.f },
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
{ 0.5f, 0.5f, 1.0f, 1.f }
|
m_model.render();
|
||||||
|
glsafe(::glPopMatrix());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLVolume::NonManifoldEdges::update()
|
||||||
|
{
|
||||||
|
if (!m_update_needed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_model.reset();
|
||||||
|
const int object_idx = m_parent.object_idx();
|
||||||
|
const Model& model = GUI::wxGetApp().plater()->model();
|
||||||
|
if (0 <= object_idx && object_idx < int(model.objects.size())) {
|
||||||
|
const ModelObject* model_object = model.objects[object_idx];
|
||||||
|
const int volume_idx = m_parent.volume_idx();
|
||||||
|
if (0 <= volume_idx && volume_idx < int(model_object->volumes.size())) {
|
||||||
|
const ModelVolume* model_volume = model_object->volumes[volume_idx];
|
||||||
|
const TriangleMesh& mesh = model_volume->mesh();
|
||||||
|
const std::vector<std::pair<int, int>> edges = its_get_open_edges(mesh.its);
|
||||||
|
if (!edges.empty()) {
|
||||||
|
GUI::GLModel::Geometry init_data;
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Lines, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::EIndexType::UINT };
|
||||||
|
init_data.vertices.reserve(2 * edges.size() * GUI::GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
|
init_data.indices.reserve(2 * edges.size() * GUI::GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
|
// vertices + indices
|
||||||
|
unsigned int vertices_count = 0;
|
||||||
|
for (const std::pair<int, int>& edge : edges) {
|
||||||
|
init_data.add_vertex((Vec3f)mesh.its.vertices[edge.first].cast<float>());
|
||||||
|
init_data.add_vertex((Vec3f)mesh.its.vertices[edge.second].cast<float>());
|
||||||
|
vertices_count += 2;
|
||||||
|
init_data.add_uint_line(vertices_count - 2, vertices_count - 1);
|
||||||
|
}
|
||||||
|
m_model.init_from(std::move(init_data));
|
||||||
|
#else
|
||||||
|
GUI::GLModel::Geometry::Entity entity;
|
||||||
|
entity.type = GUI::GLModel::EPrimitiveType::Lines;
|
||||||
|
|
||||||
|
entity.positions.reserve(2 * edges.size());
|
||||||
|
entity.normals.reserve(2 * edges.size());
|
||||||
|
entity.indices.reserve(2 * edges.size());
|
||||||
|
for (const std::pair<int, int>& edge : edges) {
|
||||||
|
entity.positions.emplace_back(mesh.its.vertices[edge.first].cast<float>());
|
||||||
|
entity.positions.emplace_back(mesh.its.vertices[edge.second].cast<float>());
|
||||||
|
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||||
|
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||||
|
entity.indices.emplace_back(entity.positions.size() - 2);
|
||||||
|
entity.indices.emplace_back(entity.positions.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
init_data.entities.emplace_back(entity);
|
||||||
|
m_model.init_from(init_data);
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_update_needed = false;
|
||||||
|
}
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
|
const ColorRGBA GLVolume::SELECTED_COLOR = ColorRGBA::GREEN();
|
||||||
|
const ColorRGBA GLVolume::HOVER_SELECT_COLOR = { 0.4f, 0.9f, 0.1f, 1.0f };
|
||||||
|
const ColorRGBA GLVolume::HOVER_DESELECT_COLOR = { 1.0f, 0.75f, 0.75f, 1.0f };
|
||||||
|
const ColorRGBA GLVolume::OUTSIDE_COLOR = { 0.0f, 0.38f, 0.8f, 1.0f };
|
||||||
|
const ColorRGBA GLVolume::SELECTED_OUTSIDE_COLOR = { 0.19f, 0.58f, 1.0f, 1.0f };
|
||||||
|
const ColorRGBA GLVolume::DISABLED_COLOR = ColorRGBA::DARK_GRAY();
|
||||||
|
const ColorRGBA GLVolume::SLA_SUPPORT_COLOR = ColorRGBA::LIGHT_GRAY();
|
||||||
|
const ColorRGBA GLVolume::SLA_PAD_COLOR = { 0.0f, 0.2f, 0.0f, 1.0f };
|
||||||
|
const ColorRGBA GLVolume::NEUTRAL_COLOR = { 0.9f, 0.9f, 0.9f, 1.0f };
|
||||||
|
const std::array<ColorRGBA, 4> GLVolume::MODEL_COLOR = { {
|
||||||
|
ColorRGBA::YELLOW(),
|
||||||
|
{ 1.0f, 0.5f, 0.5f, 1.0f },
|
||||||
|
{ 0.5f, 1.0f, 0.5f, 1.0f },
|
||||||
|
{ 0.5f, 0.5f, 1.0f, 1.0f }
|
||||||
} };
|
} };
|
||||||
|
|
||||||
GLVolume::GLVolume(float r, float g, float b, float a)
|
GLVolume::GLVolume(float r, float g, float b, float a)
|
||||||
: m_sla_shift_z(0.0)
|
: m_sla_shift_z(0.0)
|
||||||
, m_sinking_contours(*this)
|
, m_sinking_contours(*this)
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
, m_non_manifold_edges(*this)
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
// geometry_id == 0 -> invalid
|
// geometry_id == 0 -> invalid
|
||||||
, geometry_id(std::pair<size_t, size_t>(0, 0))
|
, geometry_id(std::pair<size_t, size_t>(0, 0))
|
||||||
, extruder_id(0)
|
, extruder_id(0)
|
||||||
@ -377,7 +476,6 @@ GLVolume::GLVolume(float r, float g, float b, float a)
|
|||||||
, is_modifier(false)
|
, is_modifier(false)
|
||||||
, is_wipe_tower(false)
|
, is_wipe_tower(false)
|
||||||
, is_extrusion_path(false)
|
, is_extrusion_path(false)
|
||||||
, force_transparent(false)
|
|
||||||
, force_native_color(false)
|
, force_native_color(false)
|
||||||
, force_neutral_color(false)
|
, force_neutral_color(false)
|
||||||
, force_sinking_contours(false)
|
, force_sinking_contours(false)
|
||||||
@ -388,22 +486,7 @@ GLVolume::GLVolume(float r, float g, float b, float a)
|
|||||||
set_render_color(color);
|
set_render_color(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVolume::set_color(const std::array<float, 4>& rgba)
|
void GLVolume::set_render_color(bool force_transparent)
|
||||||
{
|
|
||||||
color = rgba;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLVolume::set_render_color(float r, float g, float b, float a)
|
|
||||||
{
|
|
||||||
render_color = { r, g, b, a };
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLVolume::set_render_color(const std::array<float, 4>& rgba)
|
|
||||||
{
|
|
||||||
render_color = rgba;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLVolume::set_render_color()
|
|
||||||
{
|
{
|
||||||
bool outside = is_outside || is_below_printbed();
|
bool outside = is_outside || is_below_printbed();
|
||||||
|
|
||||||
@ -432,40 +515,28 @@ void GLVolume::set_render_color()
|
|||||||
set_render_color(color);
|
set_render_color(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!printable) {
|
if (!printable)
|
||||||
render_color[0] /= 4;
|
render_color = saturate(render_color, 0.25f);
|
||||||
render_color[1] /= 4;
|
|
||||||
render_color[2] /= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (force_transparent)
|
if (force_transparent)
|
||||||
render_color[3] = color[3];
|
render_color.a(color.a());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<float, 4> color_from_model_volume(const ModelVolume& model_volume)
|
ColorRGBA color_from_model_volume(const ModelVolume& model_volume)
|
||||||
{
|
{
|
||||||
std::array<float, 4> color;
|
ColorRGBA color;
|
||||||
if (model_volume.is_negative_volume()) {
|
if (model_volume.is_negative_volume())
|
||||||
color[0] = 0.2f;
|
color = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||||
color[1] = 0.2f;
|
else if (model_volume.is_modifier())
|
||||||
color[2] = 0.2f;
|
color = { 1.0, 1.0f, 0.2f, 1.0f };
|
||||||
}
|
else if (model_volume.is_support_blocker())
|
||||||
else if (model_volume.is_modifier()) {
|
color = { 1.0f, 0.2f, 0.2f, 1.0f };
|
||||||
color[0] = 1.0f;
|
else if (model_volume.is_support_enforcer())
|
||||||
color[1] = 1.0f;
|
color = { 0.2f, 0.2f, 1.0f, 1.0f };
|
||||||
color[2] = 0.2f;
|
|
||||||
}
|
if (!model_volume.is_model_part())
|
||||||
else if (model_volume.is_support_blocker()) {
|
color.a(0.5f);
|
||||||
color[0] = 1.0f;
|
|
||||||
color[1] = 0.2f;
|
|
||||||
color[2] = 0.2f;
|
|
||||||
}
|
|
||||||
else if (model_volume.is_support_enforcer()) {
|
|
||||||
color[0] = 0.2f;
|
|
||||||
color[1] = 0.2f;
|
|
||||||
color[2] = 1.0f;
|
|
||||||
}
|
|
||||||
color[3] = model_volume.is_model_part() ? 1.f : 0.5f;
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,6 +670,13 @@ void GLVolume::render_sinking_contours()
|
|||||||
m_sinking_contours.render();
|
m_sinking_contours.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
void GLVolume::render_non_manifold_edges()
|
||||||
|
{
|
||||||
|
m_non_manifold_edges.render();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
std::vector<int> GLVolumeCollection::load_object(
|
std::vector<int> GLVolumeCollection::load_object(
|
||||||
const ModelObject *model_object,
|
const ModelObject *model_object,
|
||||||
int obj_idx,
|
int obj_idx,
|
||||||
@ -625,8 +703,8 @@ int GLVolumeCollection::load_object_volume(
|
|||||||
const int extruder_id = model_volume->extruder_id();
|
const int extruder_id = model_volume->extruder_id();
|
||||||
const ModelInstance *instance = model_object->instances[instance_idx];
|
const ModelInstance *instance = model_object->instances[instance_idx];
|
||||||
const TriangleMesh &mesh = model_volume->mesh();
|
const TriangleMesh &mesh = model_volume->mesh();
|
||||||
std::array<float, 4> color = GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4];
|
ColorRGBA color = GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4];
|
||||||
color[3] = model_volume->is_model_part() ? 1.f : 0.5f;
|
color.a(model_volume->is_model_part() ? 1.0f : 0.5f);
|
||||||
this->volumes.emplace_back(new GLVolume(color));
|
this->volumes.emplace_back(new GLVolume(color));
|
||||||
GLVolume& v = *this->volumes.back();
|
GLVolume& v = *this->volumes.back();
|
||||||
v.set_color(color_from_model_volume(*model_volume));
|
v.set_color(color_from_model_volume(*model_volume));
|
||||||
@ -697,9 +775,15 @@ void GLVolumeCollection::load_object_auxiliary(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
|
int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
|
float pos_x, float pos_y, float width, float depth, float height,
|
||||||
|
float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized)
|
||||||
|
#else
|
||||||
int GLVolumeCollection::load_wipe_tower_preview(
|
int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height,
|
int obj_idx, float pos_x, float pos_y, float width, float depth, float height,
|
||||||
float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized)
|
float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized)
|
||||||
|
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
{
|
{
|
||||||
if (depth < 0.01f)
|
if (depth < 0.01f)
|
||||||
return int(this->volumes.size() - 1);
|
return int(this->volumes.size() - 1);
|
||||||
@ -707,13 +791,13 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||||||
height = 0.1f;
|
height = 0.1f;
|
||||||
|
|
||||||
TriangleMesh mesh;
|
TriangleMesh mesh;
|
||||||
std::array<float, 4> color = { 0.5f, 0.5f, 0.0f, 1.0f };
|
ColorRGBA color = ColorRGBA::DARK_YELLOW();
|
||||||
|
|
||||||
// In case we don't know precise dimensions of the wipe tower yet, we'll draw
|
// In case we don't know precise dimensions of the wipe tower yet, we'll draw
|
||||||
// the box with different color with one side jagged:
|
// the box with different color with one side jagged:
|
||||||
if (size_unknown) {
|
if (size_unknown) {
|
||||||
color[0] = 0.9f;
|
color.r(0.9f);
|
||||||
color[1] = 0.6f;
|
color.g(0.6f);
|
||||||
|
|
||||||
// Too narrow tower would interfere with the teeth. The estimate is not precise anyway.
|
// Too narrow tower would interfere with the teeth. The estimate is not precise anyway.
|
||||||
depth = std::max(depth, 10.f);
|
depth = std::max(depth, 10.f);
|
||||||
@ -761,7 +845,11 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||||||
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
|
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
|
||||||
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
|
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
|
||||||
v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle));
|
v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle));
|
||||||
|
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
|
v.composite_id = GLVolume::CompositeID(INT_MAX, 0, 0);
|
||||||
|
#else
|
||||||
v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0);
|
v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0);
|
||||||
|
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
v.geometry_id.first = 0;
|
v.geometry_id.first = 0;
|
||||||
v.geometry_id.second = wipe_tower_instance_id().id;
|
v.geometry_id.second = wipe_tower_instance_id().id;
|
||||||
v.is_wipe_tower = true;
|
v.is_wipe_tower = true;
|
||||||
@ -769,14 +857,14 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||||||
return int(volumes.size() - 1);
|
return int(volumes.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLVolume* GLVolumeCollection::new_toolpath_volume(const std::array<float, 4>& rgba, size_t reserve_vbo_floats)
|
GLVolume* GLVolumeCollection::new_toolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats)
|
||||||
{
|
{
|
||||||
GLVolume *out = new_nontoolpath_volume(rgba, reserve_vbo_floats);
|
GLVolume *out = new_nontoolpath_volume(rgba, reserve_vbo_floats);
|
||||||
out->is_extrusion_path = true;
|
out->is_extrusion_path = true;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLVolume* GLVolumeCollection::new_nontoolpath_volume(const std::array<float, 4>& rgba, size_t reserve_vbo_floats)
|
GLVolume* GLVolumeCollection::new_nontoolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats)
|
||||||
{
|
{
|
||||||
GLVolume *out = new GLVolume(rgba);
|
GLVolume *out = new GLVolume(rgba);
|
||||||
out->is_extrusion_path = false;
|
out->is_extrusion_path = false;
|
||||||
@ -793,7 +881,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
|
|||||||
|
|
||||||
for (unsigned int i = 0; i < (unsigned int)volumes.size(); ++i) {
|
for (unsigned int i = 0; i < (unsigned int)volumes.size(); ++i) {
|
||||||
GLVolume* volume = volumes[i];
|
GLVolume* volume = volumes[i];
|
||||||
bool is_transparent = (volume->render_color[3] < 1.0f);
|
bool is_transparent = volume->render_color.is_transparent();
|
||||||
if (((type == GLVolumeCollection::ERenderType::Opaque && !is_transparent) ||
|
if (((type == GLVolumeCollection::ERenderType::Opaque && !is_transparent) ||
|
||||||
(type == GLVolumeCollection::ERenderType::Transparent && is_transparent) ||
|
(type == GLVolumeCollection::ERenderType::Transparent && is_transparent) ||
|
||||||
type == GLVolumeCollection::ERenderType::All) &&
|
type == GLVolumeCollection::ERenderType::All) &&
|
||||||
@ -829,6 +917,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||||||
if (shader == nullptr)
|
if (shader == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat");
|
||||||
|
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat");
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
if (type == ERenderType::Transparent) {
|
if (type == ERenderType::Transparent) {
|
||||||
glsafe(::glEnable(GL_BLEND));
|
glsafe(::glEnable(GL_BLEND));
|
||||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
@ -839,20 +932,31 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||||||
glsafe(::glDisable(GL_CULL_FACE));
|
glsafe(::glDisable(GL_CULL_FACE));
|
||||||
|
|
||||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||||
if (type == ERenderType::Transparent)
|
volume.first->set_render_color(true);
|
||||||
volume.first->force_transparent = true;
|
|
||||||
volume.first->set_render_color();
|
|
||||||
if (type == ERenderType::Transparent)
|
|
||||||
volume.first->force_transparent = false;
|
|
||||||
|
|
||||||
// render sinking contours of non-hovered volumes
|
// render sinking contours of non-hovered volumes
|
||||||
if (m_show_sinking_contours)
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
shader->stop_using();
|
||||||
|
if (sink_shader != nullptr) {
|
||||||
|
sink_shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
if (m_show_sinking_contours) {
|
||||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
||||||
volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) {
|
volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) {
|
||||||
|
#if !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
|
#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
volume.first->render_sinking_contours();
|
volume.first->render_sinking_contours();
|
||||||
|
#if !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
|
#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
sink_shader->stop_using();
|
||||||
|
}
|
||||||
|
shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||||
@ -892,18 +996,50 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_show_sinking_contours) {
|
if (m_show_sinking_contours) {
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
shader->stop_using();
|
||||||
|
if (sink_shader != nullptr) {
|
||||||
|
sink_shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||||
// render sinking contours of hovered/displaced volumes
|
// render sinking contours of hovered/displaced volumes
|
||||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
||||||
(volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) {
|
(volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) {
|
||||||
|
#if !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
|
#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
glsafe(::glDepthFunc(GL_ALWAYS));
|
glsafe(::glDepthFunc(GL_ALWAYS));
|
||||||
volume.first->render_sinking_contours();
|
volume.first->render_sinking_contours();
|
||||||
glsafe(::glDepthFunc(GL_LESS));
|
glsafe(::glDepthFunc(GL_LESS));
|
||||||
|
#if !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
|
#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
sink_shader->start_using();
|
||||||
}
|
}
|
||||||
|
shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
shader->stop_using();
|
||||||
|
if (edges_shader != nullptr) {
|
||||||
|
edges_shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get("non_manifold_edges") == "1") {
|
||||||
|
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||||
|
volume.first->render_non_manifold_edges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
edges_shader->stop_using();
|
||||||
|
}
|
||||||
|
shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
if (disable_cullface)
|
if (disable_cullface)
|
||||||
glsafe(::glEnable(GL_CULL_FACE));
|
glsafe(::glEnable(GL_CULL_FACE));
|
||||||
@ -972,8 +1108,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
|
|||||||
|
|
||||||
void GLVolumeCollection::reset_outside_state()
|
void GLVolumeCollection::reset_outside_state()
|
||||||
{
|
{
|
||||||
for (GLVolume* volume : this->volumes)
|
for (GLVolume* volume : this->volumes) {
|
||||||
{
|
|
||||||
if (volume != nullptr)
|
if (volume != nullptr)
|
||||||
volume->is_outside = false;
|
volume->is_outside = false;
|
||||||
}
|
}
|
||||||
@ -981,46 +1116,18 @@ void GLVolumeCollection::reset_outside_state()
|
|||||||
|
|
||||||
void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig* config)
|
void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig* config)
|
||||||
{
|
{
|
||||||
static const float inv_255 = 1.0f / 255.0f;
|
using ColorItem = std::pair<std::string, ColorRGB>;
|
||||||
|
std::vector<ColorItem> colors;
|
||||||
|
|
||||||
struct Color
|
if (static_cast<PrinterTechnology>(config->opt_int("printer_technology")) == ptSLA) {
|
||||||
{
|
|
||||||
std::string text;
|
|
||||||
unsigned char rgb[3];
|
|
||||||
|
|
||||||
Color()
|
|
||||||
: text("")
|
|
||||||
{
|
|
||||||
rgb[0] = 255;
|
|
||||||
rgb[1] = 255;
|
|
||||||
rgb[2] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(const std::string& text, unsigned char* rgb)
|
|
||||||
{
|
|
||||||
this->text = text;
|
|
||||||
::memcpy((void*)this->rgb, (const void*)rgb, 3 * sizeof(unsigned char));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (config == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
unsigned char rgb[3];
|
|
||||||
std::vector<Color> colors;
|
|
||||||
|
|
||||||
if (static_cast<PrinterTechnology>(config->opt_int("printer_technology")) == ptSLA)
|
|
||||||
{
|
|
||||||
const std::string& txt_color = config->opt_string("material_colour").empty() ?
|
const std::string& txt_color = config->opt_string("material_colour").empty() ?
|
||||||
print_config_def.get("material_colour")->get_default_value<ConfigOptionString>()->value :
|
print_config_def.get("material_colour")->get_default_value<ConfigOptionString>()->value :
|
||||||
config->opt_string("material_colour");
|
config->opt_string("material_colour");
|
||||||
if (Slic3r::GUI::BitmapCache::parse_color(txt_color, rgb)) {
|
ColorRGB rgb;
|
||||||
colors.resize(1);
|
if (decode_color(txt_color, rgb))
|
||||||
colors[0].set(txt_color, rgb);
|
colors.push_back({ txt_color, rgb });
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else
|
|
||||||
{
|
|
||||||
const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(config->option("extruder_colour"));
|
const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(config->option("extruder_colour"));
|
||||||
if (extruders_opt == nullptr)
|
if (extruders_opt == nullptr)
|
||||||
return;
|
return;
|
||||||
@ -1029,37 +1136,35 @@ void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig* con
|
|||||||
if (filamemts_opt == nullptr)
|
if (filamemts_opt == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned int colors_count = std::max((unsigned int)extruders_opt->values.size(), (unsigned int)filamemts_opt->values.size());
|
size_t colors_count = std::max(extruders_opt->values.size(), filamemts_opt->values.size());
|
||||||
if (colors_count == 0)
|
if (colors_count == 0)
|
||||||
return;
|
return;
|
||||||
colors.resize(colors_count);
|
colors.resize(colors_count);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < colors_count; ++i) {
|
for (unsigned int i = 0; i < colors_count; ++i) {
|
||||||
const std::string& txt_color = config->opt_string("extruder_colour", i);
|
const std::string& ext_color = config->opt_string("extruder_colour", i);
|
||||||
if (Slic3r::GUI::BitmapCache::parse_color(txt_color, rgb))
|
ColorRGB rgb;
|
||||||
colors[i].set(txt_color, rgb);
|
if (decode_color(ext_color, rgb))
|
||||||
|
colors[i] = { ext_color, rgb };
|
||||||
else {
|
else {
|
||||||
const std::string& txt_color = config->opt_string("filament_colour", i);
|
const std::string& fil_color = config->opt_string("filament_colour", i);
|
||||||
if (Slic3r::GUI::BitmapCache::parse_color(txt_color, rgb))
|
if (decode_color(fil_color, rgb))
|
||||||
colors[i].set(txt_color, rgb);
|
colors[i] = { fil_color, rgb };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GLVolume* volume : volumes) {
|
for (GLVolume* volume : volumes) {
|
||||||
if (volume == nullptr || volume->is_modifier || volume->is_wipe_tower || (volume->volume_idx() < 0))
|
if (volume == nullptr || volume->is_modifier || volume->is_wipe_tower || volume->volume_idx() < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int extruder_id = volume->extruder_id - 1;
|
int extruder_id = volume->extruder_id - 1;
|
||||||
if (extruder_id < 0 || (int)colors.size() <= extruder_id)
|
if (extruder_id < 0 || (int)colors.size() <= extruder_id)
|
||||||
extruder_id = 0;
|
extruder_id = 0;
|
||||||
|
|
||||||
const Color& color = colors[extruder_id];
|
const ColorItem& color = colors[extruder_id];
|
||||||
if (!color.text.empty()) {
|
if (!color.first.empty())
|
||||||
for (int i = 0; i < 3; ++i) {
|
volume->color = to_rgba(color.second, volume->color.a());
|
||||||
volume->color[i] = (float)color.rgb[i] * inv_255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "libslic3r/TriangleMesh.hpp"
|
#include "libslic3r/TriangleMesh.hpp"
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "libslic3r/Geometry.hpp"
|
#include "libslic3r/Geometry.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
|
|
||||||
#include "GLModel.hpp"
|
#include "GLModel.hpp"
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ class ModelVolume;
|
|||||||
enum ModelInstanceEPrintVolumeState : unsigned char;
|
enum ModelInstanceEPrintVolumeState : unsigned char;
|
||||||
|
|
||||||
// Return appropriate color based on the ModelVolume.
|
// Return appropriate color based on the ModelVolume.
|
||||||
std::array<float, 4> color_from_model_volume(const ModelVolume& model_volume);
|
extern ColorRGBA color_from_model_volume(const ModelVolume& model_volume);
|
||||||
|
|
||||||
// A container for interleaved arrays of 3D vertices and normals,
|
// A container for interleaved arrays of 3D vertices and normals,
|
||||||
// possibly indexed by triangles and / or quads.
|
// possibly indexed by triangles and / or quads.
|
||||||
@ -248,16 +249,16 @@ private:
|
|||||||
|
|
||||||
class GLVolume {
|
class GLVolume {
|
||||||
public:
|
public:
|
||||||
static const std::array<float, 4> SELECTED_COLOR;
|
static const ColorRGBA SELECTED_COLOR;
|
||||||
static const std::array<float, 4> HOVER_SELECT_COLOR;
|
static const ColorRGBA HOVER_SELECT_COLOR;
|
||||||
static const std::array<float, 4> HOVER_DESELECT_COLOR;
|
static const ColorRGBA HOVER_DESELECT_COLOR;
|
||||||
static const std::array<float, 4> OUTSIDE_COLOR;
|
static const ColorRGBA OUTSIDE_COLOR;
|
||||||
static const std::array<float, 4> SELECTED_OUTSIDE_COLOR;
|
static const ColorRGBA SELECTED_OUTSIDE_COLOR;
|
||||||
static const std::array<float, 4> DISABLED_COLOR;
|
static const ColorRGBA DISABLED_COLOR;
|
||||||
static const std::array<float, 4> SLA_SUPPORT_COLOR;
|
static const ColorRGBA SLA_SUPPORT_COLOR;
|
||||||
static const std::array<float, 4> SLA_PAD_COLOR;
|
static const ColorRGBA SLA_PAD_COLOR;
|
||||||
static const std::array<float, 4> NEUTRAL_COLOR;
|
static const ColorRGBA NEUTRAL_COLOR;
|
||||||
static const std::array<std::array<float, 4>, 4> MODEL_COLOR;
|
static const std::array<ColorRGBA, 4> MODEL_COLOR;
|
||||||
|
|
||||||
enum EHoverState : unsigned char
|
enum EHoverState : unsigned char
|
||||||
{
|
{
|
||||||
@ -267,8 +268,8 @@ public:
|
|||||||
HS_Deselect
|
HS_Deselect
|
||||||
};
|
};
|
||||||
|
|
||||||
GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f);
|
GLVolume(float r = 1.0f, float g = 1.0f, float b = 1.0f, float a = 1.0f);
|
||||||
GLVolume(const std::array<float, 4>& rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
|
GLVolume(const ColorRGBA& color) : GLVolume(color.r(), color.g(), color.b(), color.a()) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Geometry::Transformation m_instance_transformation;
|
Geometry::Transformation m_instance_transformation;
|
||||||
@ -303,11 +304,30 @@ private:
|
|||||||
|
|
||||||
SinkingContours m_sinking_contours;
|
SinkingContours m_sinking_contours;
|
||||||
|
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
class NonManifoldEdges
|
||||||
|
{
|
||||||
|
GLVolume& m_parent;
|
||||||
|
GUI::GLModel m_model;
|
||||||
|
bool m_update_needed{ true };
|
||||||
|
|
||||||
|
public:
|
||||||
|
NonManifoldEdges(GLVolume& volume) : m_parent(volume) {}
|
||||||
|
void render();
|
||||||
|
void set_as_dirty() { m_update_needed = true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update();
|
||||||
|
};
|
||||||
|
|
||||||
|
NonManifoldEdges m_non_manifold_edges;
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Color of the triangles / quads held by this volume.
|
// Color of the triangles / quads held by this volume.
|
||||||
std::array<float, 4> color;
|
ColorRGBA color;
|
||||||
// Color used to render this volume.
|
// Color used to render this volume.
|
||||||
std::array<float, 4> render_color;
|
ColorRGBA render_color;
|
||||||
|
|
||||||
struct CompositeID {
|
struct CompositeID {
|
||||||
CompositeID(int object_id, int volume_id, int instance_id) : object_id(object_id), volume_id(volume_id), instance_id(instance_id) {}
|
CompositeID(int object_id, int volume_id, int instance_id) : object_id(object_id), volume_id(volume_id), instance_id(instance_id) {}
|
||||||
@ -357,8 +377,6 @@ public:
|
|||||||
bool is_wipe_tower : 1;
|
bool is_wipe_tower : 1;
|
||||||
// Wheter or not this volume has been generated from an extrusion path
|
// Wheter or not this volume has been generated from an extrusion path
|
||||||
bool is_extrusion_path : 1;
|
bool is_extrusion_path : 1;
|
||||||
// Wheter or not to always render this volume using its own alpha
|
|
||||||
bool force_transparent : 1;
|
|
||||||
// Whether or not always use the volume's own color (not using SELECTED/HOVER/DISABLED/OUTSIDE)
|
// Whether or not always use the volume's own color (not using SELECTED/HOVER/DISABLED/OUTSIDE)
|
||||||
bool force_native_color : 1;
|
bool force_native_color : 1;
|
||||||
// Whether or not render this volume in neutral
|
// Whether or not render this volume in neutral
|
||||||
@ -393,11 +411,10 @@ public:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_color(const std::array<float, 4>& rgba);
|
void set_color(const ColorRGBA& rgba) { color = rgba; }
|
||||||
void set_render_color(float r, float g, float b, float a);
|
void set_render_color(const ColorRGBA& rgba) { render_color = rgba; }
|
||||||
void set_render_color(const std::array<float, 4>& rgba);
|
|
||||||
// Sets render color in dependence of current state
|
// Sets render color in dependence of current state
|
||||||
void set_render_color();
|
void set_render_color(bool force_transparent);
|
||||||
// set color according to model volume
|
// set color according to model volume
|
||||||
void set_color_from_model_volume(const ModelVolume& model_volume);
|
void set_color_from_model_volume(const ModelVolume& model_volume);
|
||||||
|
|
||||||
@ -502,6 +519,9 @@ public:
|
|||||||
bool is_sinking() const;
|
bool is_sinking() const;
|
||||||
bool is_below_printbed() const;
|
bool is_below_printbed() const;
|
||||||
void render_sinking_contours();
|
void render_sinking_contours();
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
void render_non_manifold_edges();
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
// Return an estimate of the memory consumed by this class.
|
// Return an estimate of the memory consumed by this class.
|
||||||
size_t cpu_memory_used() const {
|
size_t cpu_memory_used() const {
|
||||||
@ -558,7 +578,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Slope m_slope;
|
Slope m_slope;
|
||||||
bool m_show_sinking_contours = false;
|
bool m_show_sinking_contours{ false };
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
bool m_show_non_manifold_edges{ true };
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLVolumePtrs volumes;
|
GLVolumePtrs volumes;
|
||||||
@ -592,11 +615,16 @@ public:
|
|||||||
size_t timestamp,
|
size_t timestamp,
|
||||||
bool opengl_initialized);
|
bool opengl_initialized);
|
||||||
|
|
||||||
|
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
|
int load_wipe_tower_preview(
|
||||||
|
float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
|
||||||
|
#else
|
||||||
int load_wipe_tower_preview(
|
int load_wipe_tower_preview(
|
||||||
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
|
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
|
||||||
|
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
|
|
||||||
GLVolume* new_toolpath_volume(const std::array<float, 4>& rgba, size_t reserve_vbo_floats = 0);
|
GLVolume* new_toolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0);
|
||||||
GLVolume* new_nontoolpath_volume(const std::array<float, 4>& rgba, size_t reserve_vbo_floats = 0);
|
GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0);
|
||||||
|
|
||||||
// Render the volumes by OpenGL.
|
// Render the volumes by OpenGL.
|
||||||
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
|
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
|
||||||
@ -626,6 +654,9 @@ public:
|
|||||||
void set_slope_normal_z(float normal_z) { m_slope.normal_z = normal_z; }
|
void set_slope_normal_z(float normal_z) { m_slope.normal_z = normal_z; }
|
||||||
void set_default_slope_normal_z() { m_slope.normal_z = -::cos(Geometry::deg2rad(90.0f - 45.0f)); }
|
void set_default_slope_normal_z() { m_slope.normal_z = -::cos(Geometry::deg2rad(90.0f - 45.0f)); }
|
||||||
void set_show_sinking_contours(bool show) { m_show_sinking_contours = show; }
|
void set_show_sinking_contours(bool show) { m_show_sinking_contours = show; }
|
||||||
|
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
void set_show_non_manifold_edges(bool show) { m_show_non_manifold_edges = show; }
|
||||||
|
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "I18N.hpp"
|
#include "I18N.hpp"
|
||||||
|
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
@ -133,12 +134,12 @@ wxString CopyrightsDialog::get_html_text()
|
|||||||
wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||||
|
|
||||||
const auto text_clr = wxGetApp().get_label_clr_default();
|
const auto text_clr = wxGetApp().get_label_clr_default();
|
||||||
const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
|
const auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue()));
|
||||||
const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
|
const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()));
|
||||||
|
|
||||||
const wxString copyright_str = _(L("Copyright")) + "© ";
|
const wxString copyright_str = _L("Copyright") + "© ";
|
||||||
// TRN "Slic3r _is licensed under the_ License"
|
// TRN "Slic3r _is licensed under the_ License"
|
||||||
const wxString header_str = _(L("License agreements of all following programs (libraries) are part of application license agreement"));
|
const wxString header_str = _L("License agreements of all following programs (libraries) are part of application license agreement");
|
||||||
|
|
||||||
wxString text = wxString::Format(
|
wxString text = wxString::Format(
|
||||||
"<html>"
|
"<html>"
|
||||||
@ -257,8 +258,8 @@ AboutDialog::AboutDialog()
|
|||||||
m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
|
m_html->SetMinSize(wxSize(-1, 16 * wxGetApp().em_unit()));
|
||||||
wxFont font = get_default_font(this);
|
wxFont font = get_default_font(this);
|
||||||
const auto text_clr = wxGetApp().get_label_clr_default();
|
const auto text_clr = wxGetApp().get_label_clr_default();
|
||||||
auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
|
const auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue()));
|
||||||
auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
|
const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()));
|
||||||
|
|
||||||
const int fs = font.GetPointSize()-1;
|
const int fs = font.GetPointSize()-1;
|
||||||
int size[] = {fs,fs,fs,fs,fs,fs,fs};
|
int size[] = {fs,fs,fs,fs,fs,fs,fs};
|
||||||
|
@ -18,6 +18,7 @@ namespace GUI {
|
|||||||
class ConfigOptionsGroup;
|
class ConfigOptionsGroup;
|
||||||
|
|
||||||
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
|
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
|
||||||
|
using ConfigOptionsGroupWkp = std::weak_ptr<ConfigOptionsGroup>;
|
||||||
|
|
||||||
struct BedShape
|
struct BedShape
|
||||||
{
|
{
|
||||||
|
@ -395,21 +395,5 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi
|
|||||||
return wxImage_to_wxBitmap_with_alpha(std::move(image), scale);
|
return wxImage_to_wxBitmap_with_alpha(std::move(image), scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitmapCache::parse_color(const std::string& scolor, unsigned char* rgb_out)
|
|
||||||
{
|
|
||||||
rgb_out[0] = rgb_out[1] = rgb_out[2] = 0;
|
|
||||||
if (scolor.size() != 7 || scolor.front() != '#')
|
|
||||||
return false;
|
|
||||||
const char* c = scolor.data() + 1;
|
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
|
||||||
int digit1 = hex_digit_to_int(*c++);
|
|
||||||
int digit2 = hex_digit_to_int(*c++);
|
|
||||||
if (digit1 == -1 || digit2 == -1)
|
|
||||||
return false;
|
|
||||||
rgb_out[i] = (unsigned char)(digit1 * 16 + digit2);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
|
|
||||||
struct NSVGimage;
|
struct NSVGimage;
|
||||||
|
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r {
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
class BitmapCache
|
class BitmapCache
|
||||||
{
|
{
|
||||||
@ -43,11 +46,9 @@ public:
|
|||||||
wxBitmap* load_svg(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, const bool grayscale = false, const bool dark_mode = false, const std::string& new_color = "");
|
wxBitmap* load_svg(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, const bool grayscale = false, const bool dark_mode = false, const std::string& new_color = "");
|
||||||
|
|
||||||
wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false);
|
wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false);
|
||||||
wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3], bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); }
|
wxBitmap mksolid(size_t width, size_t height, const ColorRGB& rgb, bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false) { return mksolid(width, height, rgb.r_uchar(), rgb.g_uchar(), rgb.b_uchar(), wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); }
|
||||||
wxBitmap mkclear(size_t width, size_t height) { return mksolid(width, height, 0, 0, 0, wxALPHA_TRANSPARENT); }
|
wxBitmap mkclear(size_t width, size_t height) { return mksolid(width, height, 0, 0, 0, wxALPHA_TRANSPARENT); }
|
||||||
|
|
||||||
static bool parse_color(const std::string& scolor, unsigned char* rgb_out);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, wxBitmap*> m_map;
|
std::map<std::string, wxBitmap*> m_map;
|
||||||
double m_gs = 0.2; // value, used for image.ConvertToGreyscale(m_gs, m_gs, m_gs)
|
double m_gs = 0.2; // value, used for image.ConvertToGreyscale(m_gs, m_gs, m_gs)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "libslic3r/Time.hpp"
|
#include "libslic3r/Time.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
#include "wxExtensions.hpp"
|
#include "wxExtensions.hpp"
|
||||||
@ -31,11 +32,9 @@ static wxString format_reason(const Config::Snapshot::Reason reason)
|
|||||||
|
|
||||||
static std::string get_color(wxColour colour)
|
static std::string get_color(wxColour colour)
|
||||||
{
|
{
|
||||||
wxString clr_str = wxString::Format(wxT("#%02X%02X%02X"), colour.Red(), colour.Green(), colour.Blue());
|
return encode_color(ColorRGB(colour.Red(), colour.Green(), colour.Blue()));
|
||||||
return clr_str.ToStdString();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_even, bool snapshot_active, bool dark_mode)
|
static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_even, bool snapshot_active, bool dark_mode)
|
||||||
{
|
{
|
||||||
// Start by declaring a row with an alternating background color.
|
// Start by declaring a row with an alternating background color.
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "libslic3r/Config.hpp"
|
#include "libslic3r/Config.hpp"
|
||||||
#include "libslic3r/libslic3r.h"
|
#include "libslic3r/libslic3r.h"
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "GUI_Utils.hpp"
|
#include "GUI_Utils.hpp"
|
||||||
@ -746,9 +747,9 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
|
|||||||
wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
|
wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
|
|
||||||
const auto text_clr = wxGetApp().get_label_clr_default();
|
const auto text_clr = wxGetApp().get_label_clr_default();
|
||||||
const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
|
const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()));
|
||||||
|
const auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue()));
|
||||||
wxString first_line = format_wxstr(_L("%1% marked with <b>*</b> are <b>not</b> compatible with some installed printers."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials"));
|
wxString first_line = format_wxstr(_L("%1% marked with <b>*</b> are <b>not</b> compatible with some installed printers."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials"));
|
||||||
wxString text;
|
wxString text;
|
||||||
if (all_printers) {
|
if (all_printers) {
|
||||||
@ -2522,24 +2523,34 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
|||||||
{
|
{
|
||||||
wxString header, caption = _L("Configuration is edited in ConfigWizard");
|
wxString header, caption = _L("Configuration is edited in ConfigWizard");
|
||||||
const auto enabled_vendors = appconfig_new.vendors();
|
const auto enabled_vendors = appconfig_new.vendors();
|
||||||
|
const auto enabled_vendors_old = app_config->vendors();
|
||||||
|
|
||||||
bool suppress_sla_printer = model_has_multi_part_objects(wxGetApp().model());
|
bool suppress_sla_printer = model_has_multi_part_objects(wxGetApp().model());
|
||||||
PrinterTechnology preferred_pt = ptAny;
|
PrinterTechnology preferred_pt = ptAny;
|
||||||
auto get_preferred_printer_technology = [enabled_vendors, suppress_sla_printer](const std::string& bundle_name, const Bundle& bundle) {
|
auto get_preferred_printer_technology = [enabled_vendors, enabled_vendors_old, suppress_sla_printer](const std::string& bundle_name, const Bundle& bundle) {
|
||||||
const auto config = enabled_vendors.find(bundle_name);
|
const auto config = enabled_vendors.find(bundle_name);
|
||||||
PrinterTechnology pt = ptAny;
|
PrinterTechnology pt = ptAny;
|
||||||
if (config != enabled_vendors.end()) {
|
if (config != enabled_vendors.end()) {
|
||||||
for (const auto& model : bundle.vendor_profile->models) {
|
for (const auto& model : bundle.vendor_profile->models) {
|
||||||
if (const auto model_it = config->second.find(model.id);
|
if (const auto model_it = config->second.find(model.id);
|
||||||
model_it != config->second.end() && model_it->second.size() > 0) {
|
model_it != config->second.end() && model_it->second.size() > 0) {
|
||||||
if (pt == ptAny)
|
|
||||||
pt = model.technology;
|
pt = model.technology;
|
||||||
// if preferred printer model has SLA printer technology it's important to check the model for multypart state
|
const auto config_old = enabled_vendors_old.find(bundle_name);
|
||||||
|
if (config_old == enabled_vendors_old.end() || config_old->second.find(model.id) == config_old->second.end()) {
|
||||||
|
// if preferred printer model has SLA printer technology it's important to check the model for multi-part state
|
||||||
if (pt == ptSLA && suppress_sla_printer)
|
if (pt == ptSLA && suppress_sla_printer)
|
||||||
continue;
|
continue;
|
||||||
else
|
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const auto model_it_old = config_old->second.find(model.id);
|
||||||
|
model_it_old == config_old->second.end() || model_it_old->second != model_it->second) {
|
||||||
|
// if preferred printer model has SLA printer technology it's important to check the model for multi-part state
|
||||||
|
if (pt == ptSLA && suppress_sla_printer)
|
||||||
|
continue;
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pt;
|
return pt;
|
||||||
@ -2645,7 +2656,6 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
|||||||
|
|
||||||
std::string preferred_model;
|
std::string preferred_model;
|
||||||
std::string preferred_variant;
|
std::string preferred_variant;
|
||||||
const auto enabled_vendors_old = app_config->vendors();
|
|
||||||
auto get_preferred_printer_model = [enabled_vendors, enabled_vendors_old, preferred_pt](const std::string& bundle_name, const Bundle& bundle, std::string& variant) {
|
auto get_preferred_printer_model = [enabled_vendors, enabled_vendors_old, preferred_pt](const std::string& bundle_name, const Bundle& bundle, std::string& variant) {
|
||||||
const auto config = enabled_vendors.find(bundle_name);
|
const auto config = enabled_vendors.find(bundle_name);
|
||||||
if (config == enabled_vendors.end())
|
if (config == enabled_vendors.end())
|
||||||
|
@ -2557,36 +2557,46 @@ bool Control::check_ticks_changed_event(Type type)
|
|||||||
|
|
||||||
std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int extruder)
|
std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int extruder)
|
||||||
{
|
{
|
||||||
|
auto opposite_one_color = [](const std::string& color) {
|
||||||
|
ColorRGB rgb;
|
||||||
|
decode_color(color, rgb);
|
||||||
|
return encode_color(opposite(rgb));
|
||||||
|
};
|
||||||
|
auto opposite_two_colors = [](const std::string& a, const std::string& b) {
|
||||||
|
ColorRGB rgb1; decode_color(a, rgb1);
|
||||||
|
ColorRGB rgb2; decode_color(b, rgb2);
|
||||||
|
return encode_color(opposite(rgb1, rgb2));
|
||||||
|
};
|
||||||
|
|
||||||
if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) {
|
if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) {
|
||||||
#if 1
|
#if 1
|
||||||
if (ticks.empty())
|
if (ticks.empty())
|
||||||
return color_generator.get_opposite_color((*m_colors)[0]);
|
return opposite_one_color((*m_colors)[0]);
|
||||||
|
|
||||||
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick);
|
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick);
|
||||||
if (before_tick_it == ticks.end())
|
if (before_tick_it == ticks.end()) {
|
||||||
{
|
|
||||||
while (before_tick_it != ticks.begin())
|
while (before_tick_it != ticks.begin())
|
||||||
if (--before_tick_it; before_tick_it->type == ColorChange)
|
if (--before_tick_it; before_tick_it->type == ColorChange)
|
||||||
break;
|
break;
|
||||||
if (before_tick_it->type == ColorChange)
|
if (before_tick_it->type == ColorChange)
|
||||||
return color_generator.get_opposite_color(before_tick_it->color);
|
return opposite_one_color(before_tick_it->color);
|
||||||
return color_generator.get_opposite_color((*m_colors)[0]);
|
|
||||||
|
return opposite_one_color((*m_colors)[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (before_tick_it == ticks.begin())
|
if (before_tick_it == ticks.begin()) {
|
||||||
{
|
|
||||||
const std::string& frst_color = (*m_colors)[0];
|
const std::string& frst_color = (*m_colors)[0];
|
||||||
if (before_tick_it->type == ColorChange)
|
if (before_tick_it->type == ColorChange)
|
||||||
return color_generator.get_opposite_color(frst_color, before_tick_it->color);
|
return opposite_two_colors(frst_color, before_tick_it->color);
|
||||||
|
|
||||||
auto next_tick_it = before_tick_it;
|
auto next_tick_it = before_tick_it;
|
||||||
while (next_tick_it != ticks.end())
|
while (next_tick_it != ticks.end())
|
||||||
if (++next_tick_it; next_tick_it->type == ColorChange)
|
if (++next_tick_it; next_tick_it->type == ColorChange)
|
||||||
break;
|
break;
|
||||||
if (next_tick_it->type == ColorChange)
|
if (next_tick_it->type == ColorChange)
|
||||||
return color_generator.get_opposite_color(frst_color, next_tick_it->color);
|
return opposite_two_colors(frst_color, next_tick_it->color);
|
||||||
|
|
||||||
return color_generator.get_opposite_color(frst_color);
|
return opposite_one_color(frst_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string frst_color = "";
|
std::string frst_color = "";
|
||||||
@ -2607,13 +2617,15 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int
|
|||||||
|
|
||||||
if (before_tick_it->type == ColorChange) {
|
if (before_tick_it->type == ColorChange) {
|
||||||
if (frst_color.empty())
|
if (frst_color.empty())
|
||||||
return color_generator.get_opposite_color(before_tick_it->color);
|
return opposite_one_color(before_tick_it->color);
|
||||||
return color_generator.get_opposite_color(before_tick_it->color, frst_color);
|
|
||||||
|
return opposite_two_colors(before_tick_it->color, frst_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frst_color.empty())
|
if (frst_color.empty())
|
||||||
return color_generator.get_opposite_color((*m_colors)[0]);
|
return opposite_one_color((*m_colors)[0]);
|
||||||
return color_generator.get_opposite_color((*m_colors)[0], frst_color);
|
|
||||||
|
return opposite_two_colors((*m_colors)[0], frst_color);
|
||||||
#else
|
#else
|
||||||
const std::vector<std::string>& colors = ColorPrintColors::get();
|
const std::vector<std::string>& colors = ColorPrintColors::get();
|
||||||
if (ticks.empty())
|
if (ticks.empty())
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "libslic3r/CustomGCode.hpp"
|
#include "libslic3r/CustomGCode.hpp"
|
||||||
#include "wxExtensions.hpp"
|
#include "wxExtensions.hpp"
|
||||||
#include "DoubleSlider_Utils.hpp"
|
|
||||||
|
|
||||||
#include <wx/window.h>
|
#include <wx/window.h>
|
||||||
#include <wx/control.h>
|
#include <wx/control.h>
|
||||||
@ -119,7 +118,6 @@ class TickCodeInfo
|
|||||||
// int m_default_color_idx = 0;
|
// int m_default_color_idx = 0;
|
||||||
|
|
||||||
std::vector<std::string>* m_colors {nullptr};
|
std::vector<std::string>* m_colors {nullptr};
|
||||||
ColorGenerator color_generator;
|
|
||||||
|
|
||||||
std::string get_color_for_tick(TickCode tick, Type type, const int extruder);
|
std::string get_color_for_tick(TickCode tick, Type type, const int extruder);
|
||||||
|
|
||||||
|
@ -1,191 +1,8 @@
|
|||||||
|
#ifndef slic3r_GUI_DoubleSlider_Utils_hpp_
|
||||||
|
#define slic3r_GUI_DoubleSlider_Utils_hpp_
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include "wx/colour.h"
|
|
||||||
|
|
||||||
class ColorGenerator
|
#endif // slic3r_GUI_DoubleSlider_Utils_hpp_
|
||||||
{
|
|
||||||
// Some of next code is borrowed from https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
|
|
||||||
typedef struct {
|
|
||||||
double r; // a fraction between 0 and 1
|
|
||||||
double g; // a fraction between 0 and 1
|
|
||||||
double b; // a fraction between 0 and 1
|
|
||||||
} rgb;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
double h; // angle in degrees
|
|
||||||
double s; // a fraction between 0 and 1
|
|
||||||
double v; // a fraction between 0 and 1
|
|
||||||
} hsv;
|
|
||||||
|
|
||||||
//static hsv rgb2hsv(rgb in);
|
|
||||||
//static rgb hsv2rgb(hsv in);
|
|
||||||
|
|
||||||
hsv rgb2hsv(rgb in)
|
|
||||||
{
|
|
||||||
hsv out;
|
|
||||||
double min, max, delta;
|
|
||||||
|
|
||||||
min = in.r < in.g ? in.r : in.g;
|
|
||||||
min = min < in.b ? min : in.b;
|
|
||||||
|
|
||||||
max = in.r > in.g ? in.r : in.g;
|
|
||||||
max = max > in.b ? max : in.b;
|
|
||||||
|
|
||||||
out.v = max; // v
|
|
||||||
delta = max - min;
|
|
||||||
if (delta < 0.00001)
|
|
||||||
{
|
|
||||||
out.s = 0;
|
|
||||||
out.h = 0; // undefined, maybe nan?
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
if (max > 0.0) { // NOTE: if Max is == 0, this divide would cause a crash
|
|
||||||
out.s = (delta / max); // s
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// if max is 0, then r = g = b = 0
|
|
||||||
// s = 0, h is undefined
|
|
||||||
out.s = 0.0;
|
|
||||||
out.h = NAN; // its now undefined
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
if (in.r >= max) // > is bogus, just keeps compilor happy
|
|
||||||
out.h = (in.g - in.b) / delta; // between yellow & magenta
|
|
||||||
else
|
|
||||||
if (in.g >= max)
|
|
||||||
out.h = 2.0 + (in.b - in.r) / delta; // between cyan & yellow
|
|
||||||
else
|
|
||||||
out.h = 4.0 + (in.r - in.g) / delta; // between magenta & cyan
|
|
||||||
|
|
||||||
out.h *= 60.0; // degrees
|
|
||||||
|
|
||||||
if (out.h < 0.0)
|
|
||||||
out.h += 360.0;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
hsv rgb2hsv(const std::string& str_clr_in)
|
|
||||||
{
|
|
||||||
wxColour clr(str_clr_in);
|
|
||||||
rgb in = { clr.Red() / 255.0, clr.Green() / 255.0, clr.Blue() / 255.0 };
|
|
||||||
return rgb2hsv(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rgb hsv2rgb(hsv in)
|
|
||||||
{
|
|
||||||
double hh, p, q, t, ff;
|
|
||||||
long i;
|
|
||||||
rgb out;
|
|
||||||
|
|
||||||
if (in.s <= 0.0) { // < is bogus, just shuts up warnings
|
|
||||||
out.r = in.v;
|
|
||||||
out.g = in.v;
|
|
||||||
out.b = in.v;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
hh = in.h;
|
|
||||||
if (hh >= 360.0) hh -= 360.0;//hh = 0.0;
|
|
||||||
hh /= 60.0;
|
|
||||||
i = (long)hh;
|
|
||||||
ff = hh - i;
|
|
||||||
p = in.v * (1.0 - in.s);
|
|
||||||
q = in.v * (1.0 - (in.s * ff));
|
|
||||||
t = in.v * (1.0 - (in.s * (1.0 - ff)));
|
|
||||||
|
|
||||||
switch (i) {
|
|
||||||
case 0:
|
|
||||||
out.r = in.v;
|
|
||||||
out.g = t;
|
|
||||||
out.b = p;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
out.r = q;
|
|
||||||
out.g = in.v;
|
|
||||||
out.b = p;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
out.r = p;
|
|
||||||
out.g = in.v;
|
|
||||||
out.b = t;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
out.r = p;
|
|
||||||
out.g = q;
|
|
||||||
out.b = in.v;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
out.r = t;
|
|
||||||
out.g = p;
|
|
||||||
out.b = in.v;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
default:
|
|
||||||
out.r = in.v;
|
|
||||||
out.g = p;
|
|
||||||
out.b = q;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::random_device rd;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
ColorGenerator() {}
|
|
||||||
~ColorGenerator() {}
|
|
||||||
|
|
||||||
double rand_val()
|
|
||||||
{
|
|
||||||
std::mt19937 rand_generator(rd());
|
|
||||||
|
|
||||||
// this value will be used for Saturation and Value
|
|
||||||
// to avoid extremely light/dark colors, take this value from range [0.65; 1.0]
|
|
||||||
std::uniform_real_distribution<double> distrib(0.65, 1.0);
|
|
||||||
return distrib(rand_generator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string get_opposite_color(const std::string& color)
|
|
||||||
{
|
|
||||||
std::string opp_color = "";
|
|
||||||
|
|
||||||
hsv hsv_clr = rgb2hsv(color);
|
|
||||||
hsv_clr.h += 65; // 65 instead 60 to avoid circle values
|
|
||||||
hsv_clr.s = rand_val();
|
|
||||||
hsv_clr.v = rand_val();
|
|
||||||
|
|
||||||
rgb rgb_opp_color = hsv2rgb(hsv_clr);
|
|
||||||
|
|
||||||
wxString clr_str = wxString::Format(wxT("#%02X%02X%02X"), (unsigned char)(rgb_opp_color.r * 255), (unsigned char)(rgb_opp_color.g * 255), (unsigned char)(rgb_opp_color.b * 255));
|
|
||||||
opp_color = clr_str.ToStdString();
|
|
||||||
|
|
||||||
return opp_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string get_opposite_color(const std::string& color_frst, const std::string& color_scnd)
|
|
||||||
{
|
|
||||||
std::string opp_color = "";
|
|
||||||
|
|
||||||
hsv hsv_frst = rgb2hsv(color_frst);
|
|
||||||
hsv hsv_scnd = rgb2hsv(color_scnd);
|
|
||||||
|
|
||||||
double delta_h = fabs(hsv_frst.h - hsv_scnd.h);
|
|
||||||
double start_h = delta_h > 180 ? std::min<double>(hsv_scnd.h, hsv_frst.h) : std::max<double>(hsv_scnd.h, hsv_frst.h);
|
|
||||||
start_h += 5; // to avoid circle change of colors for 120 deg
|
|
||||||
if (delta_h < 180)
|
|
||||||
delta_h = 360 - delta_h;
|
|
||||||
|
|
||||||
hsv hsv_opp = hsv{ start_h + 0.5 * delta_h, rand_val(), rand_val() };
|
|
||||||
rgb rgb_opp_color = hsv2rgb(hsv_opp);
|
|
||||||
|
|
||||||
wxString clr_str = wxString::Format(wxT("#%02X%02X%02X"), (unsigned char)(rgb_opp_color.r * 255), (unsigned char)(rgb_opp_color.g * 255), (unsigned char)(rgb_opp_color.b * 255));
|
|
||||||
opp_color = clr_str.ToStdString();
|
|
||||||
|
|
||||||
return opp_color;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
@ -1386,12 +1386,7 @@ void ColourPicker::set_value(const boost::any& value, bool change_event)
|
|||||||
boost::any& ColourPicker::get_value()
|
boost::any& ColourPicker::get_value()
|
||||||
{
|
{
|
||||||
auto colour = static_cast<wxColourPickerCtrl*>(window)->GetColour();
|
auto colour = static_cast<wxColourPickerCtrl*>(window)->GetColour();
|
||||||
if (colour == wxTransparentColour)
|
m_value = (colour == wxTransparentColour) ? std::string("") : encode_color(ColorRGB(colour.Red(), colour.Green(), colour.Blue()));
|
||||||
m_value = std::string("");
|
|
||||||
else {
|
|
||||||
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), colour.Red(), colour.Green(), colour.Blue());
|
|
||||||
m_value = clr_str.ToStdString();
|
|
||||||
}
|
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,86 @@ using t_back_to_init = std::function<void(const std::string&)>;
|
|||||||
wxString double_to_string(double const value, const int max_precision = 4);
|
wxString double_to_string(double const value, const int max_precision = 4);
|
||||||
wxString get_thumbnails_string(const std::vector<Vec2d>& values);
|
wxString get_thumbnails_string(const std::vector<Vec2d>& values);
|
||||||
|
|
||||||
class Field {
|
class UndoValueUIManager
|
||||||
|
{
|
||||||
|
struct UndoValueUI {
|
||||||
|
// Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
|
||||||
|
const ScalableBitmap* undo_bitmap{ nullptr };
|
||||||
|
const wxString* undo_tooltip{ nullptr };
|
||||||
|
// Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
|
||||||
|
const ScalableBitmap* undo_to_sys_bitmap{ nullptr };
|
||||||
|
const wxString* undo_to_sys_tooltip{ nullptr };
|
||||||
|
// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
|
||||||
|
const wxColour* label_color{ nullptr };
|
||||||
|
// State of the blinker icon
|
||||||
|
bool blink{ false };
|
||||||
|
|
||||||
|
bool set_undo_bitmap(const ScalableBitmap* bmp) {
|
||||||
|
if (undo_bitmap != bmp) {
|
||||||
|
undo_bitmap = bmp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_undo_to_sys_bitmap(const ScalableBitmap* bmp) {
|
||||||
|
if (undo_to_sys_bitmap != bmp) {
|
||||||
|
undo_to_sys_bitmap = bmp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_label_colour(const wxColour* clr) {
|
||||||
|
if (label_color != clr) {
|
||||||
|
label_color = clr;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_undo_tooltip(const wxString* tip) {
|
||||||
|
if (undo_tooltip != tip) {
|
||||||
|
undo_tooltip = tip;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_undo_to_sys_tooltip(const wxString* tip) {
|
||||||
|
if (undo_to_sys_tooltip != tip) {
|
||||||
|
undo_to_sys_tooltip = tip;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UndoValueUI m_undo_ui;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UndoValueUIManager() {}
|
||||||
|
~UndoValueUIManager() {}
|
||||||
|
|
||||||
|
bool set_undo_bitmap(const ScalableBitmap* bmp) { return m_undo_ui.set_undo_bitmap(bmp); }
|
||||||
|
bool set_undo_to_sys_bitmap(const ScalableBitmap* bmp) { return m_undo_ui.set_undo_to_sys_bitmap(bmp); }
|
||||||
|
bool set_label_colour(const wxColour* clr) { return m_undo_ui.set_label_colour(clr); }
|
||||||
|
bool set_undo_tooltip(const wxString* tip) { return m_undo_ui.set_undo_tooltip(tip); }
|
||||||
|
bool set_undo_to_sys_tooltip(const wxString* tip) { return m_undo_ui.set_undo_to_sys_tooltip(tip); }
|
||||||
|
|
||||||
|
// ui items used for revert line value
|
||||||
|
bool has_undo_ui() const { return m_undo_ui.undo_bitmap != nullptr; }
|
||||||
|
const wxBitmap& undo_bitmap() const { return m_undo_ui.undo_bitmap->bmp(); }
|
||||||
|
const wxString* undo_tooltip() const { return m_undo_ui.undo_tooltip; }
|
||||||
|
const wxBitmap& undo_to_sys_bitmap() const { return m_undo_ui.undo_to_sys_bitmap->bmp(); }
|
||||||
|
const wxString* undo_to_sys_tooltip() const { return m_undo_ui.undo_to_sys_tooltip; }
|
||||||
|
const wxColour* label_color() const { return m_undo_ui.label_color; }
|
||||||
|
const bool blink() const { return m_undo_ui.blink; }
|
||||||
|
bool* get_blink_ptr() { return &m_undo_ui.blink; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Field : public UndoValueUIManager
|
||||||
|
{
|
||||||
protected:
|
protected:
|
||||||
// factory function to defer and enforce creation of derived type.
|
// factory function to defer and enforce creation of derived type.
|
||||||
virtual void PostInitialize();
|
virtual void PostInitialize();
|
||||||
@ -137,49 +216,6 @@ public:
|
|||||||
return std::move(p); //!p;
|
return std::move(p); //!p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_undo_bitmap(const ScalableBitmap *bmp) {
|
|
||||||
if (m_undo_bitmap != bmp) {
|
|
||||||
m_undo_bitmap = bmp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set_undo_to_sys_bitmap(const ScalableBitmap *bmp) {
|
|
||||||
if (m_undo_to_sys_bitmap != bmp) {
|
|
||||||
m_undo_to_sys_bitmap = bmp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set_label_colour(const wxColour *clr) {
|
|
||||||
if (m_label_color != clr) {
|
|
||||||
m_label_color = clr;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set_undo_tooltip(const wxString *tip) {
|
|
||||||
if (m_undo_tooltip != tip) {
|
|
||||||
m_undo_tooltip = tip;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set_undo_to_sys_tooltip(const wxString *tip) {
|
|
||||||
if (m_undo_to_sys_tooltip != tip) {
|
|
||||||
m_undo_to_sys_tooltip = tip;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool* get_blink_ptr() {
|
|
||||||
return &m_blink;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void msw_rescale();
|
virtual void msw_rescale();
|
||||||
virtual void sys_color_changed();
|
virtual void sys_color_changed();
|
||||||
|
|
||||||
@ -191,26 +227,7 @@ public:
|
|||||||
static int def_width_wider() ;
|
static int def_width_wider() ;
|
||||||
static int def_width_thinner() ;
|
static int def_width_thinner() ;
|
||||||
|
|
||||||
const ScalableBitmap* undo_bitmap() { return m_undo_bitmap; }
|
|
||||||
const wxString* undo_tooltip() { return m_undo_tooltip; }
|
|
||||||
const ScalableBitmap* undo_to_sys_bitmap() { return m_undo_to_sys_bitmap; }
|
|
||||||
const wxString* undo_to_sys_tooltip() { return m_undo_to_sys_tooltip; }
|
|
||||||
const wxColour* label_color() { return m_label_color; }
|
|
||||||
const bool blink() { return m_blink; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
|
|
||||||
const ScalableBitmap* m_undo_bitmap = nullptr;
|
|
||||||
const wxString* m_undo_tooltip = nullptr;
|
|
||||||
// Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
|
|
||||||
const ScalableBitmap* m_undo_to_sys_bitmap = nullptr;
|
|
||||||
const wxString* m_undo_to_sys_tooltip = nullptr;
|
|
||||||
|
|
||||||
bool m_blink{ false };
|
|
||||||
|
|
||||||
// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
|
|
||||||
const wxColour* m_label_color = nullptr;
|
|
||||||
|
|
||||||
// current value
|
// current value
|
||||||
boost::any m_value;
|
boost::any m_value;
|
||||||
// last maeningful value
|
// last maeningful value
|
||||||
|
@ -654,7 +654,7 @@ void FirmwareDialog::priv::perform_upload()
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on_message([
|
.on_message([
|
||||||
#ifndef __APPLE__
|
#if !defined(__APPLE__) && !defined(__clang__)
|
||||||
// clang complains when capturing constants.
|
// clang complains when capturing constants.
|
||||||
extra_verbose,
|
extra_verbose,
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
@ -22,7 +22,6 @@ namespace GUI {
|
|||||||
class GCodeViewer
|
class GCodeViewer
|
||||||
{
|
{
|
||||||
using IBufferType = unsigned short;
|
using IBufferType = unsigned short;
|
||||||
using Color = std::array<float, 4>;
|
|
||||||
using VertexBuffer = std::vector<float>;
|
using VertexBuffer = std::vector<float>;
|
||||||
using MultiVertexBuffer = std::vector<VertexBuffer>;
|
using MultiVertexBuffer = std::vector<VertexBuffer>;
|
||||||
using IndexBuffer = std::vector<IBufferType>;
|
using IndexBuffer = std::vector<IBufferType>;
|
||||||
@ -31,12 +30,12 @@ class GCodeViewer
|
|||||||
using InstanceIdBuffer = std::vector<size_t>;
|
using InstanceIdBuffer = std::vector<size_t>;
|
||||||
using InstancesOffsets = std::vector<Vec3f>;
|
using InstancesOffsets = std::vector<Vec3f>;
|
||||||
|
|
||||||
static const std::vector<Color> Extrusion_Role_Colors;
|
static const std::vector<ColorRGBA> Extrusion_Role_Colors;
|
||||||
static const std::vector<Color> Options_Colors;
|
static const std::vector<ColorRGBA> Options_Colors;
|
||||||
static const std::vector<Color> Travel_Colors;
|
static const std::vector<ColorRGBA> Travel_Colors;
|
||||||
static const std::vector<Color> Range_Colors;
|
static const std::vector<ColorRGBA> Range_Colors;
|
||||||
static const Color Wipe_Color;
|
static const ColorRGBA Wipe_Color;
|
||||||
static const Color Neutral_Color;
|
static const ColorRGBA Neutral_Color;
|
||||||
|
|
||||||
enum class EOptionsColors : unsigned char
|
enum class EOptionsColors : unsigned char
|
||||||
{
|
{
|
||||||
@ -121,7 +120,7 @@ class GCodeViewer
|
|||||||
// vbo id
|
// vbo id
|
||||||
unsigned int vbo{ 0 };
|
unsigned int vbo{ 0 };
|
||||||
// Color to apply to the instances
|
// Color to apply to the instances
|
||||||
Color color;
|
ColorRGBA color;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Range> ranges;
|
std::vector<Range> ranges;
|
||||||
@ -243,7 +242,7 @@ class GCodeViewer
|
|||||||
// Index of the parent tbuffer
|
// Index of the parent tbuffer
|
||||||
unsigned char tbuffer_id;
|
unsigned char tbuffer_id;
|
||||||
// Render path property
|
// Render path property
|
||||||
Color color;
|
ColorRGBA color;
|
||||||
// Index of the buffer in TBuffer::indices
|
// Index of the buffer in TBuffer::indices
|
||||||
unsigned int ibuffer_id;
|
unsigned int ibuffer_id;
|
||||||
// Render path content
|
// Render path content
|
||||||
@ -263,12 +262,10 @@ class GCodeViewer
|
|||||||
bool operator() (const RenderPath &l, const RenderPath &r) const {
|
bool operator() (const RenderPath &l, const RenderPath &r) const {
|
||||||
if (l.tbuffer_id < r.tbuffer_id)
|
if (l.tbuffer_id < r.tbuffer_id)
|
||||||
return true;
|
return true;
|
||||||
for (int i = 0; i < 3; ++i) {
|
if (l.color < r.color)
|
||||||
if (l.color[i] < r.color[i])
|
|
||||||
return true;
|
return true;
|
||||||
else if (l.color[i] > r.color[i])
|
else if (l.color > r.color)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return l.ibuffer_id < r.ibuffer_id;
|
return l.ibuffer_id < r.ibuffer_id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -299,9 +296,9 @@ class GCodeViewer
|
|||||||
struct Model
|
struct Model
|
||||||
{
|
{
|
||||||
GLModel model;
|
GLModel model;
|
||||||
Color color;
|
ColorRGBA color;
|
||||||
InstanceVBuffer instances;
|
InstanceVBuffer instances;
|
||||||
GLModel::InitializationData data;
|
GLModel::Geometry data;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
@ -364,7 +361,11 @@ class GCodeViewer
|
|||||||
}
|
}
|
||||||
case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); }
|
case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); }
|
||||||
case ERenderPrimitiveType::BatchedModel: {
|
case ERenderPrimitiveType::BatchedModel: {
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
return !model.data.vertices.empty() && !model.data.indices.empty() &&
|
||||||
|
#else
|
||||||
return model.data.vertices_count() > 0 && model.data.indices_count() &&
|
return model.data.vertices_count() > 0 && model.data.indices_count() &&
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
!vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
|
!vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
|
||||||
}
|
}
|
||||||
default: { return false; }
|
default: { return false; }
|
||||||
@ -384,6 +385,14 @@ class GCodeViewer
|
|||||||
{
|
{
|
||||||
struct Range
|
struct Range
|
||||||
{
|
{
|
||||||
|
#if ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
enum class EType : unsigned char
|
||||||
|
{
|
||||||
|
Linear,
|
||||||
|
Logarithmic
|
||||||
|
};
|
||||||
|
#endif // ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
|
||||||
float min;
|
float min;
|
||||||
float max;
|
float max;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
@ -398,8 +407,13 @@ class GCodeViewer
|
|||||||
}
|
}
|
||||||
void reset() { min = FLT_MAX; max = -FLT_MAX; count = 0; }
|
void reset() { min = FLT_MAX; max = -FLT_MAX; count = 0; }
|
||||||
|
|
||||||
|
#if ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
float step_size(EType type = EType::Linear) const;
|
||||||
|
ColorRGBA get_color_at(float value, EType type = EType::Linear) const;
|
||||||
|
#else
|
||||||
float step_size() const { return (max - min) / (static_cast<float>(Range_Colors.size()) - 1.0f); }
|
float step_size() const { return (max - min) / (static_cast<float>(Range_Colors.size()) - 1.0f); }
|
||||||
Color get_color_at(float value) const;
|
ColorRGBA get_color_at(float value) const;
|
||||||
|
#endif // ENABLE_PREVIEW_LAYER_TIME
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ranges
|
struct Ranges
|
||||||
@ -416,6 +430,10 @@ class GCodeViewer
|
|||||||
Range volumetric_rate;
|
Range volumetric_rate;
|
||||||
// Color mapping by extrusion temperature.
|
// Color mapping by extrusion temperature.
|
||||||
Range temperature;
|
Range temperature;
|
||||||
|
#if ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
// Color mapping by layer time.
|
||||||
|
std::array<Range, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> layer_time;
|
||||||
|
#endif // ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
height.reset();
|
height.reset();
|
||||||
@ -424,6 +442,11 @@ class GCodeViewer
|
|||||||
fan_speed.reset();
|
fan_speed.reset();
|
||||||
volumetric_rate.reset();
|
volumetric_rate.reset();
|
||||||
temperature.reset();
|
temperature.reset();
|
||||||
|
#if ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
for (auto& range : layer_time) {
|
||||||
|
range.reset();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_PREVIEW_LAYER_TIME
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -443,42 +466,43 @@ class GCodeViewer
|
|||||||
class Layers
|
class Layers
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct Endpoints
|
struct Range
|
||||||
{
|
{
|
||||||
size_t first{ 0 };
|
size_t first{ 0 };
|
||||||
size_t last{ 0 };
|
size_t last{ 0 };
|
||||||
|
|
||||||
bool operator == (const Endpoints& other) const { return first == other.first && last == other.last; }
|
bool operator == (const Range& other) const { return first == other.first && last == other.last; }
|
||||||
bool operator != (const Endpoints& other) const { return !operator==(other); }
|
bool operator != (const Range& other) const { return !operator==(other); }
|
||||||
|
bool contains(size_t id) const { return first <= id && id <= last; }
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<double> m_zs;
|
std::vector<double> m_zs;
|
||||||
std::vector<Endpoints> m_endpoints;
|
std::vector<Range> m_ranges;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void append(double z, Endpoints endpoints) {
|
void append(double z, const Range& range) {
|
||||||
m_zs.emplace_back(z);
|
m_zs.emplace_back(z);
|
||||||
m_endpoints.emplace_back(endpoints);
|
m_ranges.emplace_back(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
m_zs = std::vector<double>();
|
m_zs = std::vector<double>();
|
||||||
m_endpoints = std::vector<Endpoints>();
|
m_ranges = std::vector<Range>();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const { return m_zs.size(); }
|
size_t size() const { return m_zs.size(); }
|
||||||
bool empty() const { return m_zs.empty(); }
|
bool empty() const { return m_zs.empty(); }
|
||||||
const std::vector<double>& get_zs() const { return m_zs; }
|
const std::vector<double>& get_zs() const { return m_zs; }
|
||||||
const std::vector<Endpoints>& get_endpoints() const { return m_endpoints; }
|
const std::vector<Range>& get_ranges() const { return m_ranges; }
|
||||||
std::vector<Endpoints>& get_endpoints() { return m_endpoints; }
|
std::vector<Range>& get_ranges() { return m_ranges; }
|
||||||
double get_z_at(unsigned int id) const { return (id < m_zs.size()) ? m_zs[id] : 0.0; }
|
double get_z_at(unsigned int id) const { return (id < m_zs.size()) ? m_zs[id] : 0.0; }
|
||||||
Endpoints get_endpoints_at(unsigned int id) const { return (id < m_endpoints.size()) ? m_endpoints[id] : Endpoints(); }
|
Range get_range_at(unsigned int id) const { return (id < m_ranges.size()) ? m_ranges[id] : Range(); }
|
||||||
|
|
||||||
bool operator != (const Layers& other) const {
|
bool operator != (const Layers& other) const {
|
||||||
if (m_zs != other.m_zs)
|
if (m_zs != other.m_zs)
|
||||||
return true;
|
return true;
|
||||||
if (m_endpoints != other.m_endpoints)
|
if (m_ranges != other.m_ranges)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -491,7 +515,7 @@ class GCodeViewer
|
|||||||
TBuffer* buffer{ nullptr };
|
TBuffer* buffer{ nullptr };
|
||||||
unsigned int ibo{ 0 };
|
unsigned int ibo{ 0 };
|
||||||
unsigned int vbo{ 0 };
|
unsigned int vbo{ 0 };
|
||||||
Color color;
|
ColorRGBA color;
|
||||||
|
|
||||||
~SequentialRangeCap();
|
~SequentialRangeCap();
|
||||||
bool is_renderable() const { return buffer != nullptr; }
|
bool is_renderable() const { return buffer != nullptr; }
|
||||||
@ -612,7 +636,7 @@ public:
|
|||||||
bool is_visible() const { return m_visible; }
|
bool is_visible() const { return m_visible; }
|
||||||
void set_visible(bool visible) { m_visible = visible; }
|
void set_visible(bool visible) { m_visible = visible; }
|
||||||
|
|
||||||
void render() const;
|
void render();
|
||||||
};
|
};
|
||||||
|
|
||||||
class GCodeWindow
|
class GCodeWindow
|
||||||
@ -668,7 +692,7 @@ public:
|
|||||||
GCodeWindow gcode_window;
|
GCodeWindow gcode_window;
|
||||||
std::vector<unsigned int> gcode_ids;
|
std::vector<unsigned int> gcode_ids;
|
||||||
|
|
||||||
void render(float legend_height) const;
|
void render(float legend_height);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EViewType : unsigned char
|
enum class EViewType : unsigned char
|
||||||
@ -680,6 +704,10 @@ public:
|
|||||||
FanSpeed,
|
FanSpeed,
|
||||||
Temperature,
|
Temperature,
|
||||||
VolumetricRate,
|
VolumetricRate,
|
||||||
|
#if ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
LayerTimeLinear,
|
||||||
|
LayerTimeLogarithmic,
|
||||||
|
#endif // ENABLE_PREVIEW_LAYER_TIME
|
||||||
Tool,
|
Tool,
|
||||||
ColorPrint,
|
ColorPrint,
|
||||||
Count
|
Count
|
||||||
@ -695,7 +723,7 @@ private:
|
|||||||
// bounding box of toolpaths + marker tools
|
// bounding box of toolpaths + marker tools
|
||||||
BoundingBoxf3 m_max_bounding_box;
|
BoundingBoxf3 m_max_bounding_box;
|
||||||
float m_max_print_height{ 0.0f };
|
float m_max_print_height{ 0.0f };
|
||||||
std::vector<Color> m_tool_colors;
|
std::vector<ColorRGBA> m_tool_colors;
|
||||||
Layers m_layers;
|
Layers m_layers;
|
||||||
std::array<unsigned int, 2> m_layers_z_range;
|
std::array<unsigned int, 2> m_layers_z_range;
|
||||||
std::vector<ExtrusionRole> m_roles;
|
std::vector<ExtrusionRole> m_roles;
|
||||||
@ -708,6 +736,14 @@ private:
|
|||||||
Shells m_shells;
|
Shells m_shells;
|
||||||
EViewType m_view_type{ EViewType::FeatureType };
|
EViewType m_view_type{ EViewType::FeatureType };
|
||||||
bool m_legend_enabled{ true };
|
bool m_legend_enabled{ true };
|
||||||
|
#if ENABLE_PREVIEW_LAYOUT
|
||||||
|
struct LegendResizer
|
||||||
|
{
|
||||||
|
bool dirty{ true };
|
||||||
|
void reset() { dirty = true; }
|
||||||
|
};
|
||||||
|
LegendResizer m_legend_resizer;
|
||||||
|
#endif // ENABLE_PREVIEW_LAYOUT
|
||||||
PrintEstimatedStatistics m_print_statistics;
|
PrintEstimatedStatistics m_print_statistics;
|
||||||
PrintEstimatedStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedStatistics::ETimeMode::Normal };
|
PrintEstimatedStatistics::ETimeMode m_time_estimate_mode{ PrintEstimatedStatistics::ETimeMode::Normal };
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
@ -716,6 +752,9 @@ private:
|
|||||||
std::array<float, 2> m_detected_point_sizes = { 0.0f, 0.0f };
|
std::array<float, 2> m_detected_point_sizes = { 0.0f, 0.0f };
|
||||||
GCodeProcessorResult::SettingsIds m_settings_ids;
|
GCodeProcessorResult::SettingsIds m_settings_ids;
|
||||||
std::array<SequentialRangeCap, 2> m_sequential_range_caps;
|
std::array<SequentialRangeCap, 2> m_sequential_range_caps;
|
||||||
|
#if ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
std::array<std::vector<float>, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> m_layers_times;
|
||||||
|
#endif // ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
|
||||||
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
|
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
|
||||||
|
|
||||||
@ -731,7 +770,11 @@ public:
|
|||||||
void load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized);
|
void load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized);
|
||||||
// recalculate ranges in dependence of what is visible and sets tool/print colors
|
// recalculate ranges in dependence of what is visible and sets tool/print colors
|
||||||
void refresh(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
|
void refresh(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
|
||||||
|
#if ENABLE_PREVIEW_LAYOUT
|
||||||
|
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
|
||||||
|
#else
|
||||||
void refresh_render_paths();
|
void refresh_render_paths();
|
||||||
|
#endif // ENABLE_PREVIEW_LAYOUT
|
||||||
void update_shells_color_by_extruder(const DynamicPrintConfig* config);
|
void update_shells_color_by_extruder(const DynamicPrintConfig* config);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@ -775,10 +818,16 @@ public:
|
|||||||
std::vector<CustomGCode::Item>& get_custom_gcode_per_print_z() { return m_custom_gcode_per_print_z; }
|
std::vector<CustomGCode::Item>& get_custom_gcode_per_print_z() { return m_custom_gcode_per_print_z; }
|
||||||
size_t get_extruders_count() { return m_extruders_count; }
|
size_t get_extruders_count() { return m_extruders_count; }
|
||||||
|
|
||||||
|
#if ENABLE_PREVIEW_LAYOUT
|
||||||
|
void invalidate_legend() { m_legend_resizer.reset(); }
|
||||||
|
#endif // ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load_toolpaths(const GCodeProcessorResult& gcode_result);
|
void load_toolpaths(const GCodeProcessorResult& gcode_result);
|
||||||
void load_shells(const Print& print, bool initialized);
|
void load_shells(const Print& print, bool initialized);
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
|
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
void render_toolpaths();
|
void render_toolpaths();
|
||||||
void render_shells();
|
void render_shells();
|
||||||
void render_legend(float& legend_height);
|
void render_legend(float& legend_height);
|
||||||
@ -790,7 +839,7 @@ private:
|
|||||||
}
|
}
|
||||||
bool is_visible(const Path& path) const { return is_visible(path.role); }
|
bool is_visible(const Path& path) const { return is_visible(path.role); }
|
||||||
void log_memory_used(const std::string& label, int64_t additional = 0) const;
|
void log_memory_used(const std::string& label, int64_t additional = 0) const;
|
||||||
Color option_color(EMoveType move_type) const;
|
ColorRGBA option_color(EMoveType move_type) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
@ -59,25 +59,24 @@ class RetinaHelper;
|
|||||||
|
|
||||||
class Size
|
class Size
|
||||||
{
|
{
|
||||||
int m_width;
|
int m_width{ 0 };
|
||||||
int m_height;
|
int m_height{ 0 };
|
||||||
float m_scale_factor;
|
float m_scale_factor{ 1.0f };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Size();
|
Size() = default;
|
||||||
Size(int width, int height, float scale_factor = 1.0);
|
Size(int width, int height, float scale_factor = 1.0f) : m_width(width), m_height(height), m_scale_factor(scale_factor) {}
|
||||||
|
|
||||||
int get_width() const;
|
int get_width() const { return m_width; }
|
||||||
void set_width(int width);
|
void set_width(int width) { m_width = width; }
|
||||||
|
|
||||||
int get_height() const;
|
int get_height() const { return m_height; }
|
||||||
void set_height(int height);
|
void set_height(int height) { m_height = height; }
|
||||||
|
|
||||||
int get_scale_factor() const;
|
float get_scale_factor() const { return m_scale_factor; }
|
||||||
void set_scale_factor(int height);
|
void set_scale_factor(float factor) { m_scale_factor = factor; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RenderTimerEvent : public wxEvent
|
class RenderTimerEvent : public wxEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -196,8 +195,8 @@ class GLCanvas3D
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const float THICKNESS_BAR_WIDTH;
|
static const float THICKNESS_BAR_WIDTH;
|
||||||
private:
|
|
||||||
|
|
||||||
|
private:
|
||||||
bool m_enabled{ false };
|
bool m_enabled{ false };
|
||||||
unsigned int m_z_texture_id{ 0 };
|
unsigned int m_z_texture_id{ 0 };
|
||||||
// Not owned by LayersEditing.
|
// Not owned by LayersEditing.
|
||||||
@ -240,6 +239,18 @@ class GLCanvas3D
|
|||||||
int last_object_id{ -1 };
|
int last_object_id{ -1 };
|
||||||
float last_z{ 0.0f };
|
float last_z{ 0.0f };
|
||||||
LayerHeightEditActionType last_action{ LAYER_HEIGHT_EDIT_ACTION_INCREASE };
|
LayerHeightEditActionType last_action{ LAYER_HEIGHT_EDIT_ACTION_INCREASE };
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
struct Profile
|
||||||
|
{
|
||||||
|
GLModel baseline;
|
||||||
|
GLModel profile;
|
||||||
|
GLModel background;
|
||||||
|
Rect old_bar_rect;
|
||||||
|
std::vector<double> old_layer_height_profile;
|
||||||
|
bool dirty{ false };
|
||||||
|
};
|
||||||
|
Profile m_profile;
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
LayersEditing() = default;
|
LayersEditing() = default;
|
||||||
~LayersEditing();
|
~LayersEditing();
|
||||||
@ -254,7 +265,7 @@ class GLCanvas3D
|
|||||||
bool is_enabled() const;
|
bool is_enabled() const;
|
||||||
void set_enabled(bool enabled);
|
void set_enabled(bool enabled);
|
||||||
|
|
||||||
void render_overlay(const GLCanvas3D& canvas) const;
|
void render_overlay(const GLCanvas3D& canvas);
|
||||||
void render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes);
|
void render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes);
|
||||||
|
|
||||||
void adjust_layer_height_profile();
|
void adjust_layer_height_profile();
|
||||||
@ -276,12 +287,11 @@ class GLCanvas3D
|
|||||||
private:
|
private:
|
||||||
bool is_initialized() const;
|
bool is_initialized() const;
|
||||||
void generate_layer_height_texture();
|
void generate_layer_height_texture();
|
||||||
void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const;
|
void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect);
|
||||||
void render_profile(const Rect& bar_rect) const;
|
void render_profile(const Rect& bar_rect);
|
||||||
void update_slicing_parameters();
|
void update_slicing_parameters();
|
||||||
|
|
||||||
static float thickness_bar_width(const GLCanvas3D &canvas);
|
static float thickness_bar_width(const GLCanvas3D &canvas);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Mouse
|
struct Mouse
|
||||||
@ -601,6 +611,19 @@ private:
|
|||||||
}
|
}
|
||||||
m_gizmo_highlighter;
|
m_gizmo_highlighter;
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
#if ENABLE_SHOW_CAMERA_TARGET
|
||||||
|
struct CameraTarget
|
||||||
|
{
|
||||||
|
std::array<GLModel, 3> axis;
|
||||||
|
Vec3d target{ Vec3d::Zero() };
|
||||||
|
};
|
||||||
|
|
||||||
|
CameraTarget m_camera_target;
|
||||||
|
#endif // ENABLE_SHOW_CAMERA_TARGET
|
||||||
|
GLModel m_background;
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed);
|
explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed);
|
||||||
~GLCanvas3D();
|
~GLCanvas3D();
|
||||||
@ -731,7 +754,11 @@ public:
|
|||||||
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
|
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
|
||||||
|
|
||||||
void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
|
void load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors);
|
||||||
|
#if ENABLE_PREVIEW_LAYOUT
|
||||||
|
void refresh_gcode_preview_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last);
|
||||||
|
#else
|
||||||
void refresh_gcode_preview_render_paths();
|
void refresh_gcode_preview_render_paths();
|
||||||
|
#endif // ENABLE_PREVIEW_LAYOUT
|
||||||
void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); }
|
void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); }
|
||||||
GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); }
|
GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); }
|
||||||
void load_sla_preview();
|
void load_sla_preview();
|
||||||
@ -824,6 +851,11 @@ public:
|
|||||||
bool are_labels_shown() const { return m_labels.is_shown(); }
|
bool are_labels_shown() const { return m_labels.is_shown(); }
|
||||||
void show_labels(bool show) { m_labels.show(show); }
|
void show_labels(bool show) { m_labels.show(show); }
|
||||||
|
|
||||||
|
#if ENABLE_PREVIEW_LAYOUT
|
||||||
|
bool is_legend_shown() const { return m_gcode_viewer.is_legend_enabled(); }
|
||||||
|
void show_legend(bool show) { m_gcode_viewer.enable_legend(show); m_dirty = true; }
|
||||||
|
#endif // ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
bool is_using_slope() const { return m_slope.is_used(); }
|
bool is_using_slope() const { return m_slope.is_used(); }
|
||||||
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); }
|
||||||
@ -901,15 +933,15 @@ private:
|
|||||||
|
|
||||||
void _picking_pass();
|
void _picking_pass();
|
||||||
void _rectangular_selection_picking_pass();
|
void _rectangular_selection_picking_pass();
|
||||||
void _render_background() const;
|
void _render_background();
|
||||||
void _render_bed(bool bottom, bool show_axes);
|
void _render_bed(bool bottom, bool show_axes);
|
||||||
void _render_bed_for_picking(bool bottom);
|
void _render_bed_for_picking(bool bottom);
|
||||||
void _render_objects(GLVolumeCollection::ERenderType type);
|
void _render_objects(GLVolumeCollection::ERenderType type);
|
||||||
void _render_gcode();
|
void _render_gcode();
|
||||||
void _render_selection() const;
|
void _render_selection();
|
||||||
void _render_sequential_clearance();
|
void _render_sequential_clearance();
|
||||||
#if ENABLE_RENDER_SELECTION_CENTER
|
#if ENABLE_RENDER_SELECTION_CENTER
|
||||||
void _render_selection_center() const;
|
void _render_selection_center();
|
||||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||||
void _check_and_update_toolbar_icon_scale();
|
void _check_and_update_toolbar_icon_scale();
|
||||||
void _render_overlays();
|
void _render_overlays();
|
||||||
@ -921,10 +953,10 @@ private:
|
|||||||
void _render_collapse_toolbar() const;
|
void _render_collapse_toolbar() const;
|
||||||
void _render_view_toolbar() const;
|
void _render_view_toolbar() const;
|
||||||
#if ENABLE_SHOW_CAMERA_TARGET
|
#if ENABLE_SHOW_CAMERA_TARGET
|
||||||
void _render_camera_target() const;
|
void _render_camera_target();
|
||||||
#endif // ENABLE_SHOW_CAMERA_TARGET
|
#endif // ENABLE_SHOW_CAMERA_TARGET
|
||||||
void _render_sla_slices();
|
void _render_sla_slices();
|
||||||
void _render_selection_sidebar_hints() const;
|
void _render_selection_sidebar_hints();
|
||||||
bool _render_undo_redo_stack(const bool is_undo, float pos_x);
|
bool _render_undo_redo_stack(const bool is_undo, float pos_x);
|
||||||
bool _render_search_list(float pos_x);
|
bool _render_search_list(float pos_x);
|
||||||
bool _render_arrange_menu(float pos_x);
|
bool _render_arrange_menu(float pos_x);
|
||||||
@ -981,8 +1013,6 @@ private:
|
|||||||
bool _deactivate_arrange_menu();
|
bool _deactivate_arrange_menu();
|
||||||
|
|
||||||
float get_overlay_window_width() { return LayersEditing::get_overlay_window_width(); }
|
float get_overlay_window_width() { return LayersEditing::get_overlay_window_width(); }
|
||||||
|
|
||||||
static std::vector<std::array<float, 4>> _parse_colors(const std::vector<std::string>& colors);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
#include "libslic3r/BoundingBox.hpp"
|
#include "libslic3r/BoundingBox.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -19,7 +20,8 @@ namespace GUI {
|
|||||||
class GLModel
|
class GLModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class PrimitiveType : unsigned char
|
#if !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
enum class EPrimitiveType : unsigned char
|
||||||
{
|
{
|
||||||
Triangles,
|
Triangles,
|
||||||
Lines,
|
Lines,
|
||||||
@ -29,22 +31,114 @@ namespace GUI {
|
|||||||
|
|
||||||
struct RenderData
|
struct RenderData
|
||||||
{
|
{
|
||||||
PrimitiveType type;
|
EPrimitiveType type;
|
||||||
unsigned int vbo_id{ 0 };
|
unsigned int vbo_id{ 0 };
|
||||||
unsigned int ibo_id{ 0 };
|
unsigned int ibo_id{ 0 };
|
||||||
size_t indices_count{ 0 };
|
size_t indices_count{ 0 };
|
||||||
std::array<float, 4> color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
ColorRGBA color;
|
||||||
|
};
|
||||||
|
#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
|
struct Geometry
|
||||||
|
{
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
enum class EPrimitiveType : unsigned char
|
||||||
|
{
|
||||||
|
Points,
|
||||||
|
Triangles,
|
||||||
|
TriangleStrip,
|
||||||
|
TriangleFan,
|
||||||
|
Lines,
|
||||||
|
LineStrip,
|
||||||
|
LineLoop
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InitializationData
|
enum class EVertexLayout : unsigned char
|
||||||
{
|
{
|
||||||
|
P2, // position 2 floats
|
||||||
|
P2T2, // position 2 floats + texture coords 2 floats
|
||||||
|
P3, // position 3 floats
|
||||||
|
P3N3, // position 3 floats + normal 3 floats
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EIndexType : unsigned char
|
||||||
|
{
|
||||||
|
UINT, // unsigned int
|
||||||
|
USHORT // unsigned short
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Format
|
||||||
|
{
|
||||||
|
EPrimitiveType type{ EPrimitiveType::Triangles };
|
||||||
|
EVertexLayout vertex_layout{ EVertexLayout::P3N3 };
|
||||||
|
EIndexType index_type{ EIndexType::UINT };
|
||||||
|
};
|
||||||
|
|
||||||
|
Format format;
|
||||||
|
std::vector<float> vertices;
|
||||||
|
std::vector<unsigned char> indices;
|
||||||
|
ColorRGBA color{ ColorRGBA::BLACK() };
|
||||||
|
|
||||||
|
void add_vertex(const Vec2f& position);
|
||||||
|
void add_vertex(const Vec2f& position, const Vec2f& tex_coord);
|
||||||
|
void add_vertex(const Vec3f& position);
|
||||||
|
void add_vertex(const Vec3f& position, const Vec3f& normal);
|
||||||
|
|
||||||
|
void add_ushort_index(unsigned short id);
|
||||||
|
void add_uint_index(unsigned int id);
|
||||||
|
|
||||||
|
void add_ushort_line(unsigned short id1, unsigned short id2);
|
||||||
|
void add_uint_line(unsigned int id1, unsigned int id2);
|
||||||
|
|
||||||
|
void add_ushort_triangle(unsigned short id1, unsigned short id2, unsigned short id3);
|
||||||
|
void add_uint_triangle(unsigned int id1, unsigned int id2, unsigned int id3);
|
||||||
|
|
||||||
|
Vec2f extract_position_2(size_t id) const;
|
||||||
|
Vec3f extract_position_3(size_t id) const;
|
||||||
|
Vec3f extract_normal_3(size_t id) const;
|
||||||
|
Vec2f extract_tex_coord_2(size_t id) const;
|
||||||
|
|
||||||
|
unsigned int extract_uint_index(size_t id) const;
|
||||||
|
unsigned short extract_ushort_index(size_t id) const;
|
||||||
|
|
||||||
|
size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); }
|
||||||
|
size_t indices_count() const { return indices.size() / index_stride_bytes(format); }
|
||||||
|
|
||||||
|
size_t vertices_size_floats() const { return vertices.size(); }
|
||||||
|
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
|
||||||
|
size_t indices_size_bytes() const { return indices.size(); }
|
||||||
|
|
||||||
|
static size_t vertex_stride_floats(const Format& format);
|
||||||
|
static size_t vertex_stride_bytes(const Format& format) { return vertex_stride_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t position_stride_floats(const Format& format);
|
||||||
|
static size_t position_stride_bytes(const Format& format) { return position_stride_floats(format) * sizeof(float); }
|
||||||
|
static size_t position_offset_floats(const Format& format);
|
||||||
|
static size_t position_offset_bytes(const Format& format) { return position_offset_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t normal_stride_floats(const Format& format);
|
||||||
|
static size_t normal_stride_bytes(const Format& format) { return normal_stride_floats(format) * sizeof(float); }
|
||||||
|
static size_t normal_offset_floats(const Format& format);
|
||||||
|
static size_t normal_offset_bytes(const Format& format) { return normal_offset_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t tex_coord_stride_floats(const Format& format);
|
||||||
|
static size_t tex_coord_stride_bytes(const Format& format) { return tex_coord_stride_floats(format) * sizeof(float); }
|
||||||
|
static size_t tex_coord_offset_floats(const Format& format);
|
||||||
|
static size_t tex_coord_offset_bytes(const Format& format) { return tex_coord_offset_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t index_stride_bytes(const Format& format);
|
||||||
|
|
||||||
|
static bool has_position(const Format& format);
|
||||||
|
static bool has_normal(const Format& format);
|
||||||
|
static bool has_tex_coord(const Format& format);
|
||||||
|
#else
|
||||||
struct Entity
|
struct Entity
|
||||||
{
|
{
|
||||||
PrimitiveType type;
|
EPrimitiveType type;
|
||||||
std::vector<Vec3f> positions;
|
std::vector<Vec3f> positions;
|
||||||
std::vector<Vec3f> normals;
|
std::vector<Vec3f> normals;
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
std::array<float, 4> color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
ColorRGBA color;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Entity> entities;
|
std::vector<Entity> entities;
|
||||||
@ -55,10 +149,26 @@ namespace GUI {
|
|||||||
|
|
||||||
size_t indices_count() const;
|
size_t indices_count() const;
|
||||||
size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); }
|
size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); }
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
struct RenderData
|
||||||
|
{
|
||||||
|
Geometry geometry;
|
||||||
|
unsigned int vbo_id{ 0 };
|
||||||
|
unsigned int ibo_id{ 0 };
|
||||||
|
size_t vertices_count{ 0 };
|
||||||
|
size_t indices_count{ 0 };
|
||||||
|
};
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
RenderData m_render_data;
|
||||||
|
#else
|
||||||
std::vector<RenderData> m_render_data;
|
std::vector<RenderData> m_render_data;
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
BoundingBoxf3 m_bounding_box;
|
BoundingBoxf3 m_bounding_box;
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
@ -67,50 +177,82 @@ namespace GUI {
|
|||||||
GLModel() = default;
|
GLModel() = default;
|
||||||
virtual ~GLModel() { reset(); }
|
virtual ~GLModel() { reset(); }
|
||||||
|
|
||||||
void init_from(const InitializationData& data);
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
size_t vertices_count() const { return m_render_data.vertices_count > 0 ?
|
||||||
|
m_render_data.vertices_count : m_render_data.geometry.vertices_count(); }
|
||||||
|
size_t indices_count() const { return m_render_data.indices_count > 0 ?
|
||||||
|
m_render_data.indices_count : m_render_data.geometry.indices_count(); }
|
||||||
|
|
||||||
|
size_t vertices_size_floats() const { return vertices_count() * Geometry::vertex_stride_floats(m_render_data.geometry.format); }
|
||||||
|
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
|
||||||
|
|
||||||
|
size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry.format); }
|
||||||
|
|
||||||
|
void init_from(Geometry&& data);
|
||||||
|
void init_from(const TriangleMesh& mesh);
|
||||||
|
#else
|
||||||
|
void init_from(const Geometry& data);
|
||||||
void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
|
void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
void init_from(const indexed_triangle_set& its);
|
void init_from(const indexed_triangle_set& its);
|
||||||
void init_from(const Polygons& polygons, float z);
|
void init_from(const Polygons& polygons, float z);
|
||||||
bool init_from_file(const std::string& filename);
|
bool init_from_file(const std::string& filename);
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
void set_color(const ColorRGBA& color) { m_render_data.geometry.color = color; }
|
||||||
|
const ColorRGBA& get_color() const { return m_render_data.geometry.color; }
|
||||||
|
#else
|
||||||
// if entity_id == -1 set the color of all entities
|
// if entity_id == -1 set the color of all entities
|
||||||
void set_color(int entity_id, const std::array<float, 4>& color);
|
void set_color(int entity_id, const ColorRGBA& color);
|
||||||
|
ColorRGBA get_color(size_t entity_id = 0U) const;
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
void render();
|
||||||
|
void render_instanced(unsigned int instances_vbo, unsigned int instances_count);
|
||||||
|
|
||||||
|
bool is_initialized() const { return vertices_count() > 0 && indices_count() > 0; }
|
||||||
|
#else
|
||||||
void render() const;
|
void render() const;
|
||||||
void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const;
|
void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const;
|
||||||
|
|
||||||
bool is_initialized() const { return !m_render_data.empty(); }
|
bool is_initialized() const { return !m_render_data.empty(); }
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
|
const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
|
||||||
const std::string& get_filename() const { return m_filename; }
|
const std::string& get_filename() const { return m_filename; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
bool send_to_gpu();
|
||||||
|
#else
|
||||||
void send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices);
|
void send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices);
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
};
|
};
|
||||||
|
|
||||||
// create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
|
// create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
|
||||||
// the origin of the arrow is in the center of the stem cap
|
// the origin of the arrow is in the center of the stem cap
|
||||||
// the arrow has its axis of symmetry along the Z axis and is pointing upward
|
// the arrow has its axis of symmetry along the Z axis and is pointing upward
|
||||||
// used to render bed axes and sequential marker
|
// used to render bed axes and sequential marker
|
||||||
GLModel::InitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
|
GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
|
||||||
|
|
||||||
// create an arrow whose stem is a quarter of circle, with the given dimensions and resolution
|
// create an arrow whose stem is a quarter of circle, with the given dimensions and resolution
|
||||||
// the origin of the arrow is in the center of the circle
|
// the origin of the arrow is in the center of the circle
|
||||||
// the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise
|
// the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise
|
||||||
// used to render sidebar hints for rotations
|
// used to render sidebar hints for rotations
|
||||||
GLModel::InitializationData circular_arrow(int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);
|
GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);
|
||||||
|
|
||||||
// create an arrow with the given dimensions
|
// create an arrow with the given dimensions
|
||||||
// the origin of the arrow is in the center of the stem cap
|
// the origin of the arrow is in the center of the stem cap
|
||||||
// the arrow is contained in XY plane and has its main axis along the Y axis
|
// the arrow is contained in XY plane and has its main axis along the Y axis
|
||||||
// used to render sidebar hints for position and scale
|
// used to render sidebar hints for position and scale
|
||||||
GLModel::InitializationData straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness);
|
GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness);
|
||||||
|
|
||||||
// create a diamond with the given resolution
|
// create a diamond with the given resolution
|
||||||
// the origin of the diamond is in its center
|
// the origin of the diamond is in its center
|
||||||
// the diamond is contained into a box with size [1, 1, 1]
|
// the diamond is contained into a box with size [1, 1, 1]
|
||||||
GLModel::InitializationData diamond(int resolution);
|
GLModel::Geometry diamond(unsigned short resolution);
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -69,7 +69,7 @@ namespace GUI {
|
|||||||
m_state = Off;
|
m_state = Off;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSelectionRectangle::render(const GLCanvas3D& canvas) const
|
void GLSelectionRectangle::render(const GLCanvas3D& canvas)
|
||||||
{
|
{
|
||||||
if (!is_dragging())
|
if (!is_dragging())
|
||||||
return;
|
return;
|
||||||
@ -80,23 +80,25 @@ namespace GUI {
|
|||||||
Size cnv_size = canvas.get_canvas_size();
|
Size cnv_size = canvas.get_canvas_size();
|
||||||
float cnv_half_width = 0.5f * (float)cnv_size.get_width();
|
float cnv_half_width = 0.5f * (float)cnv_size.get_width();
|
||||||
float cnv_half_height = 0.5f * (float)cnv_size.get_height();
|
float cnv_half_height = 0.5f * (float)cnv_size.get_height();
|
||||||
if ((cnv_half_width == 0.0f) || (cnv_half_height == 0.0f))
|
if (cnv_half_width == 0.0f || cnv_half_height == 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Vec2d start(m_start_corner(0) - cnv_half_width, cnv_half_height - m_start_corner(1));
|
Vec2d start(m_start_corner(0) - cnv_half_width, cnv_half_height - m_start_corner(1));
|
||||||
Vec2d end(m_end_corner(0) - cnv_half_width, cnv_half_height - m_end_corner(1));
|
Vec2d end(m_end_corner(0) - cnv_half_width, cnv_half_height - m_end_corner(1));
|
||||||
|
|
||||||
float left = (float)std::min(start(0), end(0)) * inv_zoom;
|
const float left = (float)std::min(start(0), end(0)) * inv_zoom;
|
||||||
float top = (float)std::max(start(1), end(1)) * inv_zoom;
|
const float top = (float)std::max(start(1), end(1)) * inv_zoom;
|
||||||
float right = (float)std::max(start(0), end(0)) * inv_zoom;
|
const float right = (float)std::max(start(0), end(0)) * inv_zoom;
|
||||||
float bottom = (float)std::min(start(1), end(1)) * inv_zoom;
|
const float bottom = (float)std::min(start(1), end(1)) * inv_zoom;
|
||||||
|
|
||||||
glsafe(::glLineWidth(1.5f));
|
glsafe(::glLineWidth(1.5f));
|
||||||
|
#if !ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
float color[3];
|
float color[3];
|
||||||
color[0] = (m_state == Select) ? 0.3f : 1.0f;
|
color[0] = (m_state == Select) ? 0.3f : 1.0f;
|
||||||
color[1] = (m_state == Select) ? 1.0f : 0.3f;
|
color[1] = (m_state == Select) ? 1.0f : 0.3f;
|
||||||
color[2] = 0.3f;
|
color[2] = 0.3f;
|
||||||
glsafe(::glColor3fv(color));
|
glsafe(::glColor3fv(color));
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
@ -105,19 +107,59 @@ namespace GUI {
|
|||||||
// ensure that the rectangle is renderered inside the frustrum
|
// ensure that the rectangle is renderered inside the frustrum
|
||||||
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5)));
|
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5)));
|
||||||
// ensure that the overlay fits the frustrum near z plane
|
// ensure that the overlay fits the frustrum near z plane
|
||||||
double gui_scale = camera.get_gui_scale();
|
const double gui_scale = camera.get_gui_scale();
|
||||||
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
|
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
|
||||||
|
|
||||||
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
||||||
glsafe(::glLineStipple(4, 0xAAAA));
|
glsafe(::glLineStipple(4, 0xAAAA));
|
||||||
glsafe(::glEnable(GL_LINE_STIPPLE));
|
glsafe(::glEnable(GL_LINE_STIPPLE));
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||||
|
if (shader != nullptr) {
|
||||||
|
shader->start_using();
|
||||||
|
|
||||||
|
if (!m_rectangle.is_initialized() || !m_old_start_corner.isApprox(m_start_corner) || !m_old_end_corner.isApprox(m_end_corner)) {
|
||||||
|
m_old_start_corner = m_start_corner;
|
||||||
|
m_old_end_corner = m_end_corner;
|
||||||
|
m_rectangle.reset();
|
||||||
|
|
||||||
|
GLModel::Geometry init_data;
|
||||||
|
init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
|
||||||
|
init_data.vertices.reserve(4 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
|
init_data.indices.reserve(4 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
|
// vertices
|
||||||
|
init_data.add_vertex(Vec2f(left, bottom));
|
||||||
|
init_data.add_vertex(Vec2f(right, bottom));
|
||||||
|
init_data.add_vertex(Vec2f(right, top));
|
||||||
|
init_data.add_vertex(Vec2f(left, top));
|
||||||
|
|
||||||
|
// indices
|
||||||
|
init_data.add_ushort_index(0);
|
||||||
|
init_data.add_ushort_index(1);
|
||||||
|
init_data.add_ushort_index(2);
|
||||||
|
init_data.add_ushort_index(3);
|
||||||
|
|
||||||
|
m_rectangle.init_from(std::move(init_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
const ColorRGBA color(
|
||||||
|
(m_state == Select) ? 0.3f : 1.0f,
|
||||||
|
(m_state == Select) ? 1.0f : 0.3f,
|
||||||
|
0.3f, 1.0f);
|
||||||
|
m_rectangle.set_color(color);
|
||||||
|
m_rectangle.render();
|
||||||
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
#else
|
||||||
::glBegin(GL_LINE_LOOP);
|
::glBegin(GL_LINE_LOOP);
|
||||||
::glVertex2f((GLfloat)left, (GLfloat)bottom);
|
::glVertex2f((GLfloat)left, (GLfloat)bottom);
|
||||||
::glVertex2f((GLfloat)right, (GLfloat)bottom);
|
::glVertex2f((GLfloat)right, (GLfloat)bottom);
|
||||||
::glVertex2f((GLfloat)right, (GLfloat)top);
|
::glVertex2f((GLfloat)right, (GLfloat)top);
|
||||||
::glVertex2f((GLfloat)left, (GLfloat)top);
|
::glVertex2f((GLfloat)left, (GLfloat)top);
|
||||||
glsafe(::glEnd());
|
glsafe(::glEnd());
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
glsafe(::glPopAttrib());
|
glsafe(::glPopAttrib());
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#define slic3r_GLSelectionRectangle_hpp_
|
#define slic3r_GLSelectionRectangle_hpp_
|
||||||
|
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
#include "GLModel.hpp"
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
@ -30,7 +33,7 @@ public:
|
|||||||
// Disables the rectangle.
|
// Disables the rectangle.
|
||||||
void stop_dragging();
|
void stop_dragging();
|
||||||
|
|
||||||
void render(const GLCanvas3D& canvas) const;
|
void render(const GLCanvas3D& canvas);
|
||||||
|
|
||||||
bool is_dragging() const { return m_state != Off; }
|
bool is_dragging() const { return m_state != Off; }
|
||||||
EState get_state() const { return m_state; }
|
EState get_state() const { return m_state; }
|
||||||
@ -43,9 +46,14 @@ public:
|
|||||||
float get_bottom() const { return std::min(m_start_corner(1), m_end_corner(1)); }
|
float get_bottom() const { return std::min(m_start_corner(1), m_end_corner(1)); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EState m_state = Off;
|
EState m_state{ Off };
|
||||||
Vec2d m_start_corner;
|
Vec2d m_start_corner{ Vec2d::Zero() };
|
||||||
Vec2d m_end_corner;
|
Vec2d m_end_corner{ Vec2d::Zero() };
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
GLModel m_rectangle;
|
||||||
|
Vec2d m_old_start_corner{ Vec2d::Zero() };
|
||||||
|
Vec2d m_old_end_corner{ Vec2d::Zero() };
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "3DScene.hpp"
|
#include "3DScene.hpp"
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "libslic3r/format.hpp"
|
#include "libslic3r/format.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
|
|
||||||
#include <boost/nowide/fstream.hpp>
|
#include <boost/nowide/fstream.hpp>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
@ -206,154 +207,114 @@ void GLShaderProgram::stop_using() const
|
|||||||
glsafe(::glUseProgram(0));
|
glsafe(::glUseProgram(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, int value) const
|
void GLShaderProgram::set_uniform(int id, int value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
glsafe(::glUniform1i(id, value));
|
||||||
glsafe(::glUniform1i(id, static_cast<GLint>(value)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, bool value) const
|
void GLShaderProgram::set_uniform(int id, bool value) const
|
||||||
{
|
{
|
||||||
return set_uniform(name, value ? 1 : 0);
|
set_uniform(id, value ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, float value) const
|
void GLShaderProgram::set_uniform(int id, float value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
glsafe(::glUniform1f(id, value));
|
||||||
glsafe(::glUniform1f(id, static_cast<GLfloat>(value)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, double value) const
|
void GLShaderProgram::set_uniform(int id, double value) const
|
||||||
{
|
{
|
||||||
return set_uniform(name, static_cast<float>(value));
|
set_uniform(id, static_cast<float>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const std::array<int, 2>& value) const
|
void GLShaderProgram::set_uniform(int id, const std::array<int, 2>& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniform2iv(id, 1, static_cast<const GLint*>(value.data())));
|
glsafe(::glUniform2iv(id, 1, static_cast<const GLint*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const std::array<int, 3>& value) const
|
void GLShaderProgram::set_uniform(int id, const std::array<int, 3>& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniform3iv(id, 1, static_cast<const GLint*>(value.data())));
|
glsafe(::glUniform3iv(id, 1, static_cast<const GLint*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const std::array<int, 4>& value) const
|
void GLShaderProgram::set_uniform(int id, const std::array<int, 4>& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniform4iv(id, 1, static_cast<const GLint*>(value.data())));
|
glsafe(::glUniform4iv(id, 1, static_cast<const GLint*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const std::array<float, 2>& value) const
|
void GLShaderProgram::set_uniform(int id, const std::array<float, 2>& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniform2fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
glsafe(::glUniform2fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const std::array<float, 3>& value) const
|
void GLShaderProgram::set_uniform(int id, const std::array<float, 3>& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniform3fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
glsafe(::glUniform3fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const std::array<float, 4>& value) const
|
void GLShaderProgram::set_uniform(int id, const std::array<float, 4>& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniform4fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
glsafe(::glUniform4fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const float* value, size_t size) const
|
void GLShaderProgram::set_uniform(int id, const float* value, size_t size) const
|
||||||
{
|
{
|
||||||
if (size == 1)
|
|
||||||
return set_uniform(name, value[0]);
|
|
||||||
else if (size < 5) {
|
|
||||||
int id = get_uniform_location(name);
|
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
if (size == 2)
|
if (size == 1)
|
||||||
|
set_uniform(id, value[0]);
|
||||||
|
else if (size == 2)
|
||||||
glsafe(::glUniform2fv(id, 1, static_cast<const GLfloat*>(value)));
|
glsafe(::glUniform2fv(id, 1, static_cast<const GLfloat*>(value)));
|
||||||
else if (size == 3)
|
else if (size == 3)
|
||||||
glsafe(::glUniform3fv(id, 1, static_cast<const GLfloat*>(value)));
|
glsafe(::glUniform3fv(id, 1, static_cast<const GLfloat*>(value)));
|
||||||
else
|
else if (size == 4)
|
||||||
glsafe(::glUniform4fv(id, 1, static_cast<const GLfloat*>(value)));
|
glsafe(::glUniform4fv(id, 1, static_cast<const GLfloat*>(value)));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const Transform3f& value) const
|
void GLShaderProgram::set_uniform(int id, const Transform3f& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.matrix().data())));
|
glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.matrix().data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const Transform3d& value) const
|
void GLShaderProgram::set_uniform(int id, const Transform3d& value) const
|
||||||
{
|
{
|
||||||
return set_uniform(name, value.cast<float>());
|
set_uniform(id, value.cast<float>());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const Matrix3f& value) const
|
void GLShaderProgram::set_uniform(int id, const Matrix3f& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.data())));
|
glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const Vec3f& value) const
|
void GLShaderProgram::set_uniform(int id, const Vec3f& value) const
|
||||||
{
|
{
|
||||||
int id = get_uniform_location(name);
|
if (id >= 0)
|
||||||
if (id >= 0) {
|
|
||||||
glsafe(::glUniform3fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
glsafe(::glUniform3fv(id, 1, static_cast<const GLfloat*>(value.data())));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLShaderProgram::set_uniform(const char* name, const Vec3d& value) const
|
void GLShaderProgram::set_uniform(int id, const Vec3d& value) const
|
||||||
{
|
{
|
||||||
return set_uniform(name, static_cast<Vec3f>(value.cast<float>()));
|
set_uniform(id, static_cast<Vec3f>(value.cast<float>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLShaderProgram::set_uniform(int id, const ColorRGB& value) const
|
||||||
|
{
|
||||||
|
set_uniform(id, value.data(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLShaderProgram::set_uniform(int id, const ColorRGBA& value) const
|
||||||
|
{
|
||||||
|
set_uniform(id, value.data(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GLShaderProgram::get_attrib_location(const char* name) const
|
int GLShaderProgram::get_attrib_location(const char* name) const
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class ColorRGB;
|
||||||
|
class ColorRGBA;
|
||||||
|
|
||||||
class GLShaderProgram
|
class GLShaderProgram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -44,22 +47,43 @@ public:
|
|||||||
void start_using() const;
|
void start_using() const;
|
||||||
void stop_using() const;
|
void stop_using() const;
|
||||||
|
|
||||||
bool set_uniform(const char* name, int value) const;
|
void set_uniform(const char* name, int value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, bool value) const;
|
void set_uniform(const char* name, bool value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, float value) const;
|
void set_uniform(const char* name, float value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, double value) const;
|
void set_uniform(const char* name, double value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const std::array<int, 2>& value) const;
|
void set_uniform(const char* name, const std::array<int, 2>& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const std::array<int, 3>& value) const;
|
void set_uniform(const char* name, const std::array<int, 3>& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const std::array<int, 4>& value) const;
|
void set_uniform(const char* name, const std::array<int, 4>& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const std::array<float, 2>& value) const;
|
void set_uniform(const char* name, const std::array<float, 2>& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const std::array<float, 3>& value) const;
|
void set_uniform(const char* name, const std::array<float, 3>& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const std::array<float, 4>& value) const;
|
void set_uniform(const char* name, const std::array<float, 4>& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const float* value, size_t size) const;
|
void set_uniform(const char* name, const float* value, size_t size) const { set_uniform(get_uniform_location(name), value, size); }
|
||||||
bool set_uniform(const char* name, const Transform3f& value) const;
|
void set_uniform(const char* name, const Transform3f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const Transform3d& value) const;
|
void set_uniform(const char* name, const Transform3d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const Matrix3f& value) const;
|
void set_uniform(const char* name, const Matrix3f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const Vec3f& value) const;
|
void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
bool set_uniform(const char* name, const Vec3d& value) const;
|
void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
|
void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
|
void set_uniform(const char* name, const ColorRGBA& value) const { set_uniform(get_uniform_location(name), value); }
|
||||||
|
|
||||||
|
void set_uniform(int id, int value) const;
|
||||||
|
void set_uniform(int id, bool value) const;
|
||||||
|
void set_uniform(int id, float value) const;
|
||||||
|
void set_uniform(int id, double value) const;
|
||||||
|
void set_uniform(int id, const std::array<int, 2>& value) const;
|
||||||
|
void set_uniform(int id, const std::array<int, 3>& value) const;
|
||||||
|
void set_uniform(int id, const std::array<int, 4>& value) const;
|
||||||
|
void set_uniform(int id, const std::array<float, 2>& value) const;
|
||||||
|
void set_uniform(int id, const std::array<float, 3>& value) const;
|
||||||
|
void set_uniform(int id, const std::array<float, 4>& value) const;
|
||||||
|
void set_uniform(int id, const float* value, size_t size) const;
|
||||||
|
void set_uniform(int id, const Transform3f& value) const;
|
||||||
|
void set_uniform(int id, const Transform3d& value) const;
|
||||||
|
void set_uniform(int id, const Matrix3f& value) const;
|
||||||
|
void set_uniform(int id, const Vec3f& value) const;
|
||||||
|
void set_uniform(int id, const Vec3d& value) const;
|
||||||
|
void set_uniform(int id, const ColorRGB& value) const;
|
||||||
|
void set_uniform(int id, const ColorRGBA& value) const;
|
||||||
|
|
||||||
// returns -1 if not found
|
// returns -1 if not found
|
||||||
int get_attrib_location(const char* name) const;
|
int get_attrib_location(const char* name) const;
|
||||||
|
@ -33,6 +33,14 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||||||
|
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
// basic shader, used to render all what was previously rendered using the immediate mode
|
||||||
|
valid &= append_shader("flat", { "flat.vs", "flat.fs" });
|
||||||
|
// basic shader for textures, used to render textures
|
||||||
|
valid &= append_shader("flat_texture", { "flat_texture.vs", "flat_texture.fs" });
|
||||||
|
// used to render 3D scene background
|
||||||
|
valid &= append_shader("background", { "background.vs", "background.fs" });
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
|
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
|
||||||
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
|
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
|
||||||
// used to render printbed
|
// used to render printbed
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#include "3DScene.hpp"
|
#include "3DScene.hpp"
|
||||||
#include "OpenGLManager.hpp"
|
#include "OpenGLManager.hpp"
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
#include "GUI_App.hpp"
|
||||||
|
#include "GLModel.hpp"
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
@ -120,11 +124,7 @@ void GLTexture::Compressor::compress()
|
|||||||
GLTexture::Quad_UVs GLTexture::FullTextureUVs = { { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 0.0f, 0.0f } };
|
GLTexture::Quad_UVs GLTexture::FullTextureUVs = { { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 0.0f, 0.0f } };
|
||||||
|
|
||||||
GLTexture::GLTexture()
|
GLTexture::GLTexture()
|
||||||
: m_id(0)
|
: m_compressor(*this)
|
||||||
, m_width(0)
|
|
||||||
, m_height(0)
|
|
||||||
, m_source("")
|
|
||||||
, m_compressor(*this)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,12 +339,39 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
|
|||||||
|
|
||||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id));
|
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id));
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
GLModel::Geometry init_data;
|
||||||
|
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
|
||||||
|
init_data.vertices.reserve(4 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
|
init_data.indices.reserve(6 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
|
// vertices
|
||||||
|
init_data.add_vertex(Vec2f(left, bottom), Vec2f(uvs.left_bottom.u, uvs.left_bottom.v));
|
||||||
|
init_data.add_vertex(Vec2f(right, bottom), Vec2f(uvs.right_bottom.u, uvs.right_bottom.v));
|
||||||
|
init_data.add_vertex(Vec2f(right, top), Vec2f(uvs.right_top.u, uvs.right_top.v));
|
||||||
|
init_data.add_vertex(Vec2f(left, top), Vec2f(uvs.left_top.u, uvs.left_top.v));
|
||||||
|
|
||||||
|
// indices
|
||||||
|
init_data.add_ushort_triangle(0, 1, 2);
|
||||||
|
init_data.add_ushort_triangle(2, 3, 0);
|
||||||
|
|
||||||
|
GLModel model;
|
||||||
|
model.init_from(std::move(init_data));
|
||||||
|
|
||||||
|
GLShaderProgram* shader = wxGetApp().get_shader("flat_texture");
|
||||||
|
if (shader != nullptr) {
|
||||||
|
shader->start_using();
|
||||||
|
model.render();
|
||||||
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
#else
|
||||||
::glBegin(GL_QUADS);
|
::glBegin(GL_QUADS);
|
||||||
::glTexCoord2f(uvs.left_bottom.u, uvs.left_bottom.v); ::glVertex2f(left, bottom);
|
::glTexCoord2f(uvs.left_bottom.u, uvs.left_bottom.v); ::glVertex2f(left, bottom);
|
||||||
::glTexCoord2f(uvs.right_bottom.u, uvs.right_bottom.v); ::glVertex2f(right, bottom);
|
::glTexCoord2f(uvs.right_bottom.u, uvs.right_bottom.v); ::glVertex2f(right, bottom);
|
||||||
::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top);
|
::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top);
|
||||||
::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top);
|
::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top);
|
||||||
glsafe(::glEnd());
|
glsafe(::glEnd());
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ namespace GUI {
|
|||||||
|
|
||||||
struct UV
|
struct UV
|
||||||
{
|
{
|
||||||
float u;
|
float u{ 0.0f };
|
||||||
float v;
|
float v{ 0.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Quad_UVs
|
struct Quad_UVs
|
||||||
@ -79,9 +79,9 @@ namespace GUI {
|
|||||||
static Quad_UVs FullTextureUVs;
|
static Quad_UVs FullTextureUVs;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int m_id;
|
unsigned int m_id{ 0 };
|
||||||
int m_width;
|
int m_width{ 0 };
|
||||||
int m_height;
|
int m_height{ 0 };
|
||||||
std::string m_source;
|
std::string m_source;
|
||||||
Compressor m_compressor;
|
Compressor m_compressor;
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
#include "libslic3r/I18N.hpp"
|
#include "libslic3r/I18N.hpp"
|
||||||
#include "libslic3r/PresetBundle.hpp"
|
#include "libslic3r/PresetBundle.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
|
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "GUI_Utils.hpp"
|
#include "GUI_Utils.hpp"
|
||||||
@ -482,6 +483,7 @@ struct FileWildcards {
|
|||||||
static const FileWildcards file_wildcards_by_type[FT_SIZE] = {
|
static const FileWildcards file_wildcards_by_type[FT_SIZE] = {
|
||||||
/* FT_STL */ { "STL files"sv, { ".stl"sv } },
|
/* FT_STL */ { "STL files"sv, { ".stl"sv } },
|
||||||
/* FT_OBJ */ { "OBJ files"sv, { ".obj"sv } },
|
/* FT_OBJ */ { "OBJ files"sv, { ".obj"sv } },
|
||||||
|
/* FT_OBJECT */ { "Object files"sv, { ".stl"sv, ".obj"sv } },
|
||||||
/* FT_AMF */ { "AMF files"sv, { ".amf"sv, ".zip.amf"sv, ".xml"sv } },
|
/* FT_AMF */ { "AMF files"sv, { ".amf"sv, ".zip.amf"sv, ".xml"sv } },
|
||||||
/* FT_3MF */ { "3MF files"sv, { ".3mf"sv } },
|
/* FT_3MF */ { "3MF files"sv, { ".3mf"sv } },
|
||||||
/* FT_GCODE */ { "G-code files"sv, { ".gcode"sv, ".gco"sv, ".g"sv, ".ngc"sv } },
|
/* FT_GCODE */ { "G-code files"sv, { ".gcode"sv, ".gco"sv, ".g"sv, ".ngc"sv } },
|
||||||
@ -1598,8 +1600,7 @@ void GUI_App::set_label_clr_modified(const wxColour& clr)
|
|||||||
if (m_color_label_modified == clr)
|
if (m_color_label_modified == clr)
|
||||||
return;
|
return;
|
||||||
m_color_label_modified = clr;
|
m_color_label_modified = clr;
|
||||||
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
|
const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
|
||||||
std::string str = clr_str.ToStdString();
|
|
||||||
app_config->set("label_clr_modified", str);
|
app_config->set("label_clr_modified", str);
|
||||||
app_config->save();
|
app_config->save();
|
||||||
}
|
}
|
||||||
@ -1609,8 +1610,7 @@ void GUI_App::set_label_clr_sys(const wxColour& clr)
|
|||||||
if (m_color_label_sys == clr)
|
if (m_color_label_sys == clr)
|
||||||
return;
|
return;
|
||||||
m_color_label_sys = clr;
|
m_color_label_sys = clr;
|
||||||
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
|
const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
|
||||||
std::string str = clr_str.ToStdString();
|
|
||||||
app_config->set("label_clr_sys", str);
|
app_config->set("label_clr_sys", str);
|
||||||
app_config->save();
|
app_config->save();
|
||||||
}
|
}
|
||||||
@ -1814,6 +1814,7 @@ void GUI_App::update_ui_from_settings()
|
|||||||
m_force_colors_update = false;
|
m_force_colors_update = false;
|
||||||
mainframe->force_color_changed();
|
mainframe->force_color_changed();
|
||||||
mainframe->diff_dialog.force_color_changed();
|
mainframe->diff_dialog.force_color_changed();
|
||||||
|
mainframe->preferences_dialog->force_color_changed();
|
||||||
mainframe->printhost_queue_dlg()->force_color_changed();
|
mainframe->printhost_queue_dlg()->force_color_changed();
|
||||||
#ifdef _MSW_DARK_MODE
|
#ifdef _MSW_DARK_MODE
|
||||||
update_scrolls(mainframe);
|
update_scrolls(mainframe);
|
||||||
@ -2334,40 +2335,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
|||||||
break;
|
break;
|
||||||
case ConfigMenuPreferences:
|
case ConfigMenuPreferences:
|
||||||
{
|
{
|
||||||
bool app_layout_changed = false;
|
open_preferences();
|
||||||
{
|
|
||||||
// the dialog needs to be destroyed before the call to recreate_GUI()
|
|
||||||
// or sometimes the application crashes into wxDialogBase() destructor
|
|
||||||
// so we put it into an inner scope
|
|
||||||
PreferencesDialog dlg(mainframe);
|
|
||||||
dlg.ShowModal();
|
|
||||||
app_layout_changed = dlg.settings_layout_changed();
|
|
||||||
if (dlg.seq_top_layer_only_changed())
|
|
||||||
this->plater_->refresh_print();
|
|
||||||
|
|
||||||
if (dlg.recreate_GUI()) {
|
|
||||||
recreate_GUI(_L("Restart application") + dots);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (is_editor()) {
|
|
||||||
if (app_config->get("associate_3mf") == "1")
|
|
||||||
associate_3mf_files();
|
|
||||||
if (app_config->get("associate_stl") == "1")
|
|
||||||
associate_stl_files();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (app_config->get("associate_gcode") == "1")
|
|
||||||
associate_gcode_files();
|
|
||||||
}
|
|
||||||
#endif // _WIN32
|
|
||||||
}
|
|
||||||
if (app_layout_changed) {
|
|
||||||
// hide full main_sizer for mainFrame
|
|
||||||
mainframe->GetSizer()->Show(false);
|
|
||||||
mainframe->update_layout();
|
|
||||||
mainframe->select_tab(size_t(0));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConfigMenuLanguage:
|
case ConfigMenuLanguage:
|
||||||
@ -2415,22 +2383,20 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
|||||||
menu->Append(local_menu, _L("&Configuration"));
|
menu->Append(local_menu, _L("&Configuration"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_option)
|
void GUI_App::open_preferences(const std::string& highlight_option /*= std::string()*/, const std::string& tab_name/*= std::string()*/)
|
||||||
{
|
{
|
||||||
bool app_layout_changed = false;
|
mainframe->preferences_dialog->show(highlight_option, tab_name);
|
||||||
{
|
|
||||||
// the dialog needs to be destroyed before the call to recreate_GUI()
|
if (mainframe->preferences_dialog->recreate_GUI())
|
||||||
// or sometimes the application crashes into wxDialogBase() destructor
|
recreate_GUI(_L("Restart application") + dots);
|
||||||
// so we put it into an inner scope
|
|
||||||
PreferencesDialog dlg(mainframe, open_on_tab, highlight_option);
|
|
||||||
dlg.ShowModal();
|
|
||||||
app_layout_changed = dlg.settings_layout_changed();
|
|
||||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
|
if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
|
||||||
#else
|
#else
|
||||||
if (dlg.seq_top_layer_only_changed())
|
if (mainframe->preferences_dialog->seq_top_layer_only_changed())
|
||||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
this->plater_->refresh_print();
|
this->plater_->refresh_print();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (is_editor()) {
|
if (is_editor()) {
|
||||||
if (app_config->get("associate_3mf") == "1")
|
if (app_config->get("associate_3mf") == "1")
|
||||||
@ -2443,8 +2409,8 @@ void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_
|
|||||||
associate_gcode_files();
|
associate_gcode_files();
|
||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
}
|
|
||||||
if (app_layout_changed) {
|
if (mainframe->preferences_dialog->settings_layout_changed()) {
|
||||||
// hide full main_sizer for mainFrame
|
// hide full main_sizer for mainFrame
|
||||||
mainframe->GetSizer()->Show(false);
|
mainframe->GetSizer()->Show(false);
|
||||||
mainframe->update_layout();
|
mainframe->update_layout();
|
||||||
|
@ -53,6 +53,7 @@ enum FileType
|
|||||||
{
|
{
|
||||||
FT_STL,
|
FT_STL,
|
||||||
FT_OBJ,
|
FT_OBJ,
|
||||||
|
FT_OBJECT,
|
||||||
FT_AMF,
|
FT_AMF,
|
||||||
FT_3MF,
|
FT_3MF,
|
||||||
FT_GCODE,
|
FT_GCODE,
|
||||||
@ -265,7 +266,7 @@ public:
|
|||||||
wxString current_language_code_safe() const;
|
wxString current_language_code_safe() const;
|
||||||
bool is_localized() const { return m_wxLocale->GetLocale() != "English"; }
|
bool is_localized() const { return m_wxLocale->GetLocale() != "English"; }
|
||||||
|
|
||||||
void open_preferences(size_t open_on_tab = 0, const std::string& highlight_option = std::string());
|
void open_preferences(const std::string& highlight_option = std::string(), const std::string& tab_name = std::string());
|
||||||
|
|
||||||
virtual bool OnExceptionInMainLoop() override;
|
virtual bool OnExceptionInMainLoop() override;
|
||||||
// Calls wxLaunchDefaultBrowser if user confirms in dialog.
|
// Calls wxLaunchDefaultBrowser if user confirms in dialog.
|
||||||
|
@ -712,8 +712,8 @@ wxMenuItem* MenuFactory::append_menu_item_simplify(wxMenu* menu)
|
|||||||
|
|
||||||
void MenuFactory::append_menu_item_export_stl(wxMenu* menu)
|
void MenuFactory::append_menu_item_export_stl(wxMenu* menu)
|
||||||
{
|
{
|
||||||
append_menu_item(menu, wxID_ANY, _L("Export as STL") + dots, "",
|
append_menu_item(menu, wxID_ANY, _L("Export as STL/OBJ") + dots, "",
|
||||||
[](wxCommandEvent&) { plater()->export_stl(false, true); }, "", nullptr,
|
[](wxCommandEvent&) { plater()->export_stl_obj(false, true); }, "", nullptr,
|
||||||
[]() {
|
[]() {
|
||||||
const Selection& selection = plater()->canvas3D()->get_selection();
|
const Selection& selection = plater()->canvas3D()->get_selection();
|
||||||
return selection.is_single_full_instance() || selection.is_single_full_object() || selection.is_single_volume() || selection.is_single_modifier();
|
return selection.is_single_full_instance() || selection.is_single_full_object() || selection.is_single_volume() || selection.is_single_modifier();
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "slic3r/GUI/format.hpp"
|
#include "slic3r/GUI/format.hpp"
|
||||||
#include "slic3r/GUI/MainFrame.hpp"
|
#include "slic3r/GUI/MainFrame.hpp"
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
|
|
||||||
|
|
||||||
// To show a message box if GUI initialization ends up with an exception thrown.
|
// To show a message box if GUI initialization ends up with an exception thrown.
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
|
@ -239,6 +239,8 @@ ObjectList::ObjectList(wxWindow* parent) :
|
|||||||
|
|
||||||
ObjectList::~ObjectList()
|
ObjectList::~ObjectList()
|
||||||
{
|
{
|
||||||
|
if (m_objects_model)
|
||||||
|
m_objects_model->DecRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::set_min_height()
|
void ObjectList::set_min_height()
|
||||||
@ -1931,9 +1933,15 @@ void ObjectList::del_layers_from_object(const int obj_idx)
|
|||||||
bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type)
|
bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type)
|
||||||
{
|
{
|
||||||
assert(idx >= 0);
|
assert(idx >= 0);
|
||||||
|
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
|
if (m_objects->empty() || int(m_objects->size()) <= obj_idx)
|
||||||
|
// Cannot delete a wipe tower
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
if (obj_idx == 1000 || idx<0)
|
if (obj_idx == 1000 || idx<0)
|
||||||
// Cannot delete a wipe tower or volume with negative id
|
// Cannot delete a wipe tower or volume with negative id
|
||||||
return false;
|
return false;
|
||||||
|
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
|
||||||
|
|
||||||
ModelObject* object = (*m_objects)[obj_idx];
|
ModelObject* object = (*m_objects)[obj_idx];
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectList(wxWindow* parent);
|
ObjectList(wxWindow* parent);
|
||||||
~ObjectList();
|
~ObjectList() override;
|
||||||
|
|
||||||
void set_min_height();
|
void set_min_height();
|
||||||
void update_min_height();
|
void update_min_height();
|
||||||
|
@ -1103,7 +1103,12 @@ ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
|
|||||||
{
|
{
|
||||||
parent->set_focused_editor(nullptr);
|
parent->set_focused_editor(nullptr);
|
||||||
|
|
||||||
|
#if ENABLE_OBJECT_MANIPULATOR_FOCUS
|
||||||
|
// if the widget loosing focus is not a manipulator field, call kill_focus
|
||||||
|
if (dynamic_cast<ManipulationEditor*>(e.GetWindow()) == nullptr)
|
||||||
|
#else
|
||||||
if (!m_enter_pressed)
|
if (!m_enter_pressed)
|
||||||
|
#endif // ENABLE_OBJECT_MANIPULATOR_FOCUS
|
||||||
kill_focus(parent);
|
kill_focus(parent);
|
||||||
|
|
||||||
e.Skip();
|
e.Skip();
|
||||||
|
@ -208,6 +208,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||||||
m_layers_slider_sizer = create_layers_slider_sizer();
|
m_layers_slider_sizer = create_layers_slider_sizer();
|
||||||
|
|
||||||
wxGetApp().UpdateDarkUI(m_bottom_toolbar_panel = new wxPanel(this));
|
wxGetApp().UpdateDarkUI(m_bottom_toolbar_panel = new wxPanel(this));
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View"));
|
m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View"));
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wxGetApp().UpdateDarkUI(m_choice_view_type = new BitmapComboBox(m_bottom_toolbar_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY));
|
wxGetApp().UpdateDarkUI(m_choice_view_type = new BitmapComboBox(m_bottom_toolbar_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY));
|
||||||
@ -221,6 +222,10 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||||||
m_choice_view_type->Append(_L("Fan speed"));
|
m_choice_view_type->Append(_L("Fan speed"));
|
||||||
m_choice_view_type->Append(_L("Temperature"));
|
m_choice_view_type->Append(_L("Temperature"));
|
||||||
m_choice_view_type->Append(_L("Volumetric flow rate"));
|
m_choice_view_type->Append(_L("Volumetric flow rate"));
|
||||||
|
#if ENABLE_PREVIEW_LAYER_TIME
|
||||||
|
m_choice_view_type->Append(_L("Layer time (linear)"));
|
||||||
|
m_choice_view_type->Append(_L("Layer time (logarithmic)"));
|
||||||
|
#endif // ENABLE_PREVIEW_LAYER_TIME
|
||||||
m_choice_view_type->Append(_L("Tool"));
|
m_choice_view_type->Append(_L("Tool"));
|
||||||
m_choice_view_type->Append(_L("Color Print"));
|
m_choice_view_type->Append(_L("Color Print"));
|
||||||
m_choice_view_type->SetSelection(0);
|
m_choice_view_type->SetSelection(0);
|
||||||
@ -232,6 +237,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||||||
#else
|
#else
|
||||||
long combo_style = wxCB_READONLY;
|
long combo_style = wxCB_READONLY;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_combochecklist_features = new wxComboCtrl();
|
m_combochecklist_features = new wxComboCtrl();
|
||||||
m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, combo_style);
|
m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, combo_style);
|
||||||
std::string feature_items = GUI::into_u8(
|
std::string feature_items = GUI::into_u8(
|
||||||
@ -270,6 +276,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||||||
get_option_type_string(OptionType::Legend) + "|1"
|
get_option_type_string(OptionType::Legend) + "|1"
|
||||||
);
|
);
|
||||||
Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items);
|
Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items);
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
m_left_sizer = new wxBoxSizer(wxVERTICAL);
|
m_left_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
m_left_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
|
m_left_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
|
||||||
@ -281,6 +288,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||||||
m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView);
|
m_moves_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView);
|
||||||
|
|
||||||
wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
bottom_toolbar_sizer->AddSpacer(5);
|
bottom_toolbar_sizer->AddSpacer(5);
|
||||||
bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
|
||||||
bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 0);
|
bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||||
@ -292,6 +300,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Model* model)
|
|||||||
bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5);
|
bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5);
|
||||||
bottom_toolbar_sizer->Hide(m_combochecklist_features);
|
bottom_toolbar_sizer->Hide(m_combochecklist_features);
|
||||||
bottom_toolbar_sizer->AddSpacer(5);
|
bottom_toolbar_sizer->AddSpacer(5);
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 0);
|
bottom_toolbar_sizer->Add(m_moves_slider, 1, wxALL | wxEXPAND, 0);
|
||||||
m_bottom_toolbar_panel->SetSizer(bottom_toolbar_sizer);
|
m_bottom_toolbar_panel->SetSizer(bottom_toolbar_sizer);
|
||||||
|
|
||||||
@ -353,7 +362,9 @@ void Preview::load_print(bool keep_z_range)
|
|||||||
else if (tech == ptSLA)
|
else if (tech == ptSLA)
|
||||||
load_print_as_sla();
|
load_print_as_sla();
|
||||||
|
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
update_bottom_toolbar();
|
update_bottom_toolbar();
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
Layout();
|
Layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,10 +407,12 @@ void Preview::refresh_print()
|
|||||||
|
|
||||||
void Preview::msw_rescale()
|
void Preview::msw_rescale()
|
||||||
{
|
{
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
m_choice_view_type->Rescale();
|
m_choice_view_type->Rescale();
|
||||||
m_choice_view_type->SetMinSize(m_choice_view_type->GetSize());
|
m_choice_view_type->SetMinSize(m_choice_view_type->GetSize());
|
||||||
#endif
|
#endif
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
// rescale slider
|
// rescale slider
|
||||||
if (m_layers_slider != nullptr) m_layers_slider->msw_rescale();
|
if (m_layers_slider != nullptr) m_layers_slider->msw_rescale();
|
||||||
if (m_moves_slider != nullptr) m_moves_slider->msw_rescale();
|
if (m_moves_slider != nullptr) m_moves_slider->msw_rescale();
|
||||||
@ -417,11 +430,13 @@ void Preview::sys_color_changed()
|
|||||||
wxWindowUpdateLocker noUpdates(this);
|
wxWindowUpdateLocker noUpdates(this);
|
||||||
|
|
||||||
wxGetApp().UpdateAllStaticTextDarkUI(m_bottom_toolbar_panel);
|
wxGetApp().UpdateAllStaticTextDarkUI(m_bottom_toolbar_panel);
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
wxGetApp().UpdateDarkUI(m_choice_view_type);
|
wxGetApp().UpdateDarkUI(m_choice_view_type);
|
||||||
wxGetApp().UpdateDarkUI(m_combochecklist_features);
|
wxGetApp().UpdateDarkUI(m_combochecklist_features);
|
||||||
wxGetApp().UpdateDarkUI(static_cast<wxCheckListBoxComboPopup*>(m_combochecklist_features->GetPopupControl()));
|
wxGetApp().UpdateDarkUI(static_cast<wxCheckListBoxComboPopup*>(m_combochecklist_features->GetPopupControl()));
|
||||||
wxGetApp().UpdateDarkUI(m_combochecklist_options);
|
wxGetApp().UpdateDarkUI(m_combochecklist_options);
|
||||||
wxGetApp().UpdateDarkUI(static_cast<wxCheckListBoxComboPopup*>(m_combochecklist_options->GetPopupControl()));
|
wxGetApp().UpdateDarkUI(static_cast<wxCheckListBoxComboPopup*>(m_combochecklist_options->GetPopupControl()));
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_layers_slider != nullptr)
|
if (m_layers_slider != nullptr)
|
||||||
@ -445,19 +460,23 @@ void Preview::edit_layers_slider(wxKeyEvent& evt)
|
|||||||
|
|
||||||
void Preview::bind_event_handlers()
|
void Preview::bind_event_handlers()
|
||||||
{
|
{
|
||||||
this->Bind(wxEVT_SIZE, &Preview::on_size, this);
|
Bind(wxEVT_SIZE, &Preview::on_size, this);
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
m_choice_view_type->Bind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this);
|
m_choice_view_type->Bind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this);
|
||||||
m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this);
|
m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this);
|
||||||
m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this);
|
m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this);
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this);
|
m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preview::unbind_event_handlers()
|
void Preview::unbind_event_handlers()
|
||||||
{
|
{
|
||||||
this->Unbind(wxEVT_SIZE, &Preview::on_size, this);
|
Unbind(wxEVT_SIZE, &Preview::on_size, this);
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
m_choice_view_type->Unbind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this);
|
m_choice_view_type->Unbind(wxEVT_COMBOBOX, &Preview::on_choice_view_type, this);
|
||||||
m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this);
|
m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this);
|
||||||
m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this);
|
m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this);
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
m_moves_slider->Unbind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this);
|
m_moves_slider->Unbind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,6 +497,7 @@ void Preview::on_size(wxSizeEvent& evt)
|
|||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
void Preview::on_choice_view_type(wxCommandEvent& evt)
|
void Preview::on_choice_view_type(wxCommandEvent& evt)
|
||||||
{
|
{
|
||||||
int selection = m_choice_view_type->GetCurrentSelection();
|
int selection = m_choice_view_type->GetCurrentSelection();
|
||||||
@ -544,6 +564,7 @@ void Preview::update_bottom_toolbar()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
wxBoxSizer* Preview::create_layers_slider_sizer()
|
wxBoxSizer* Preview::create_layers_slider_sizer()
|
||||||
{
|
{
|
||||||
@ -953,10 +974,20 @@ void Preview::load_print_as_fff(bool keep_z_range)
|
|||||||
std::vector<Item> gcodes = wxGetApp().is_editor() ?
|
std::vector<Item> gcodes = wxGetApp().is_editor() ?
|
||||||
wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes :
|
wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes :
|
||||||
m_canvas->get_custom_gcode_per_print_z();
|
m_canvas->get_custom_gcode_per_print_z();
|
||||||
|
#if ENABLE_PREVIEW_LAYOUT
|
||||||
|
const GCodeViewer::EViewType choice = !gcodes.empty() ?
|
||||||
|
GCodeViewer::EViewType::ColorPrint :
|
||||||
|
(number_extruders > 1) ? GCodeViewer::EViewType::Tool : GCodeViewer::EViewType::FeatureType;
|
||||||
|
if (choice != gcode_view_type) {
|
||||||
|
m_canvas->set_gcode_view_preview_type(choice);
|
||||||
|
if (wxGetApp().is_gcode_viewer())
|
||||||
|
m_keep_current_preview_type = true;
|
||||||
|
refresh_print();
|
||||||
|
}
|
||||||
|
#else
|
||||||
const wxString choice = !gcodes.empty() ?
|
const wxString choice = !gcodes.empty() ?
|
||||||
_L("Color Print") :
|
_L("Color Print") :
|
||||||
(number_extruders > 1) ? _L("Tool") : _L("Feature type");
|
(number_extruders > 1) ? _L("Tool") : _L("Feature type");
|
||||||
|
|
||||||
int type = m_choice_view_type->FindString(choice);
|
int type = m_choice_view_type->FindString(choice);
|
||||||
if (m_choice_view_type->GetSelection() != type) {
|
if (m_choice_view_type->GetSelection() != type) {
|
||||||
if (0 <= type && type < static_cast<int>(GCodeViewer::EViewType::Count)) {
|
if (0 <= type && type < static_cast<int>(GCodeViewer::EViewType::Count)) {
|
||||||
@ -967,6 +998,7 @@ void Preview::load_print_as_fff(bool keep_z_range)
|
|||||||
refresh_print();
|
refresh_print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_PREVIEW_LAYOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zs.empty()) {
|
if (zs.empty()) {
|
||||||
@ -1042,6 +1074,7 @@ void Preview::on_moves_slider_scroll_changed(wxCommandEvent& event)
|
|||||||
m_canvas->render();
|
m_canvas->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
wxString Preview::get_option_type_string(OptionType type) const
|
wxString Preview::get_option_type_string(OptionType type) const
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -1061,6 +1094,7 @@ wxString Preview::get_option_type_string(OptionType type) const
|
|||||||
default: { return ""; }
|
default: { return ""; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -80,6 +80,7 @@ class Preview : public wxPanel
|
|||||||
wxBoxSizer* m_left_sizer { nullptr };
|
wxBoxSizer* m_left_sizer { nullptr };
|
||||||
wxBoxSizer* m_layers_slider_sizer { nullptr };
|
wxBoxSizer* m_layers_slider_sizer { nullptr };
|
||||||
wxPanel* m_bottom_toolbar_panel { nullptr };
|
wxPanel* m_bottom_toolbar_panel { nullptr };
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
wxStaticText* m_label_view_type { nullptr };
|
wxStaticText* m_label_view_type { nullptr };
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BitmapComboBox* m_choice_view_type { nullptr };
|
BitmapComboBox* m_choice_view_type { nullptr };
|
||||||
@ -90,6 +91,7 @@ class Preview : public wxPanel
|
|||||||
wxComboCtrl* m_combochecklist_features { nullptr };
|
wxComboCtrl* m_combochecklist_features { nullptr };
|
||||||
size_t m_combochecklist_features_pos { 0 };
|
size_t m_combochecklist_features_pos { 0 };
|
||||||
wxComboCtrl* m_combochecklist_options { nullptr };
|
wxComboCtrl* m_combochecklist_options { nullptr };
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
DynamicPrintConfig* m_config;
|
DynamicPrintConfig* m_config;
|
||||||
BackgroundSlicingProcess* m_process;
|
BackgroundSlicingProcess* m_process;
|
||||||
@ -126,7 +128,9 @@ public:
|
|||||||
CustomGCodes,
|
CustomGCodes,
|
||||||
Shells,
|
Shells,
|
||||||
ToolMarker,
|
ToolMarker,
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
Legend
|
Legend
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
};
|
};
|
||||||
|
|
||||||
Preview(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process,
|
Preview(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process,
|
||||||
@ -154,12 +158,18 @@ public:
|
|||||||
|
|
||||||
bool is_loaded() const { return m_loaded; }
|
bool is_loaded() const { return m_loaded; }
|
||||||
|
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
void update_bottom_toolbar();
|
void update_bottom_toolbar();
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
void update_moves_slider();
|
void update_moves_slider();
|
||||||
void enable_moves_slider(bool enable);
|
void enable_moves_slider(bool enable);
|
||||||
void move_moves_slider(wxKeyEvent& evt);
|
void move_moves_slider(wxKeyEvent& evt);
|
||||||
void hide_layers_slider();
|
void hide_layers_slider();
|
||||||
|
|
||||||
|
#if ENABLE_PREVIEW_LAYOUT
|
||||||
|
void set_keep_current_preview_type(bool value) { m_keep_current_preview_type = value; }
|
||||||
|
#endif // ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool init(wxWindow* parent, Bed3D& bed, Model* model);
|
bool init(wxWindow* parent, Bed3D& bed, Model* model);
|
||||||
|
|
||||||
@ -167,9 +177,11 @@ private:
|
|||||||
void unbind_event_handlers();
|
void unbind_event_handlers();
|
||||||
|
|
||||||
void on_size(wxSizeEvent& evt);
|
void on_size(wxSizeEvent& evt);
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
void on_choice_view_type(wxCommandEvent& evt);
|
void on_choice_view_type(wxCommandEvent& evt);
|
||||||
void on_combochecklist_features(wxCommandEvent& evt);
|
void on_combochecklist_features(wxCommandEvent& evt);
|
||||||
void on_combochecklist_options(wxCommandEvent& evt);
|
void on_combochecklist_options(wxCommandEvent& evt);
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
|
|
||||||
// Create/Update/Reset double slider on 3dPreview
|
// Create/Update/Reset double slider on 3dPreview
|
||||||
wxBoxSizer* create_layers_slider_sizer();
|
wxBoxSizer* create_layers_slider_sizer();
|
||||||
@ -186,7 +198,9 @@ private:
|
|||||||
|
|
||||||
void on_layers_slider_scroll_changed(wxCommandEvent& event);
|
void on_layers_slider_scroll_changed(wxCommandEvent& event);
|
||||||
void on_moves_slider_scroll_changed(wxCommandEvent& event);
|
void on_moves_slider_scroll_changed(wxCommandEvent& event);
|
||||||
|
#if !ENABLE_PREVIEW_LAYOUT
|
||||||
wxString get_option_type_string(OptionType type) const;
|
wxString get_option_type_string(OptionType type) const;
|
||||||
|
#endif // !ENABLE_PREVIEW_LAYOUT
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
@ -406,14 +406,6 @@ public:
|
|||||||
|
|
||||||
std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics);
|
std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics);
|
||||||
|
|
||||||
inline int hex_digit_to_int(const char c)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(c >= '0' && c <= '9') ? int(c - '0') :
|
|
||||||
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
|
|
||||||
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
class TaskTimer
|
class TaskTimer
|
||||||
{
|
{
|
||||||
std::chrono::milliseconds start_timer;
|
std::chrono::milliseconds start_timer;
|
||||||
|
@ -14,28 +14,9 @@ const float GLGizmoBase::Grabber::SizeFactor = 0.05f;
|
|||||||
const float GLGizmoBase::Grabber::MinHalfSize = 1.5f;
|
const float GLGizmoBase::Grabber::MinHalfSize = 1.5f;
|
||||||
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
|
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
|
||||||
|
|
||||||
GLGizmoBase::Grabber::Grabber()
|
void GLGizmoBase::Grabber::render(bool hover, float size)
|
||||||
: center(Vec3d::Zero())
|
|
||||||
, angles(Vec3d::Zero())
|
|
||||||
, dragging(false)
|
|
||||||
, enabled(true)
|
|
||||||
{
|
{
|
||||||
color = { 1.0f, 1.0f, 1.0f, 1.0f };
|
render(size, hover ? complementary(color) : color, false);
|
||||||
}
|
|
||||||
|
|
||||||
void GLGizmoBase::Grabber::render(bool hover, float size) const
|
|
||||||
{
|
|
||||||
std::array<float, 4> render_color;
|
|
||||||
if (hover) {
|
|
||||||
render_color[0] = (1.0f - color[0]);
|
|
||||||
render_color[1] = (1.0f - color[1]);
|
|
||||||
render_color[2] = (1.0f - color[2]);
|
|
||||||
render_color[3] = color[3];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
render_color = color;
|
|
||||||
|
|
||||||
render(size, render_color, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float GLGizmoBase::Grabber::get_half_size(float size) const
|
float GLGizmoBase::Grabber::get_half_size(float size) const
|
||||||
@ -48,20 +29,27 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const
|
|||||||
return get_half_size(size) * DraggingScaleFactor;
|
return get_half_size(size) * DraggingScaleFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::Grabber::render(float size, const std::array<float, 4>& render_color, bool picking) const
|
void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking)
|
||||||
{
|
{
|
||||||
if (! cube_initialized) {
|
if (!m_cube.is_initialized()) {
|
||||||
// This cannot be done in constructor, OpenGL is not yet
|
// This cannot be done in constructor, OpenGL is not yet
|
||||||
// initialized at that point (on Linux at least).
|
// initialized at that point (on Linux at least).
|
||||||
indexed_triangle_set mesh = its_make_cube(1., 1., 1.);
|
indexed_triangle_set its = its_make_cube(1., 1., 1.);
|
||||||
its_translate(mesh, Vec3f(-0.5, -0.5, -0.5));
|
its_translate(its, Vec3f(-0.5, -0.5, -0.5));
|
||||||
const_cast<GLModel&>(cube).init_from(mesh, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } });
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
const_cast<bool&>(cube_initialized) = true;
|
m_cube.init_from(its);
|
||||||
|
#else
|
||||||
|
m_cube.init_from(its, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } });
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
float fullsize = 2 * (dragging ? get_dragging_half_size(size) : get_half_size(size));
|
const float fullsize = 2.0f * (dragging ? get_dragging_half_size(size) : get_half_size(size));
|
||||||
|
|
||||||
const_cast<GLModel*>(&cube)->set_color(-1, render_color);
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
m_cube.set_color(render_color);
|
||||||
|
#else
|
||||||
|
m_cube.set_color(-1, render_color);
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||||
@ -69,11 +57,10 @@ void GLGizmoBase::Grabber::render(float size, const std::array<float, 4>& render
|
|||||||
glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0));
|
glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0));
|
||||||
glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0));
|
glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0));
|
||||||
glsafe(::glScaled(fullsize, fullsize, fullsize));
|
glsafe(::glScaled(fullsize, fullsize, fullsize));
|
||||||
cube.render();
|
m_cube.render();
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||||
: m_parent(parent)
|
: m_parent(parent)
|
||||||
, m_group_id(-1)
|
, m_group_id(-1)
|
||||||
@ -90,25 +77,16 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u
|
|||||||
m_base_color = DEFAULT_BASE_COLOR;
|
m_base_color = DEFAULT_BASE_COLOR;
|
||||||
m_drag_color = DEFAULT_DRAG_COLOR;
|
m_drag_color = DEFAULT_DRAG_COLOR;
|
||||||
m_highlight_color = DEFAULT_HIGHLIGHT_COLOR;
|
m_highlight_color = DEFAULT_HIGHLIGHT_COLOR;
|
||||||
m_cone.init_from(its_make_cone(1., 1., 2 * PI / 24));
|
|
||||||
m_sphere.init_from(its_make_sphere(1., (2 * M_PI) / 24.));
|
|
||||||
m_cylinder.init_from(its_make_cylinder(1., 1., 2 * PI / 24.));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::set_hover_id(int id)
|
void GLGizmoBase::set_hover_id(int id)
|
||||||
{
|
{
|
||||||
if (m_grabbers.empty() || (id < (int)m_grabbers.size()))
|
if (m_grabbers.empty() || id < (int)m_grabbers.size()) {
|
||||||
{
|
|
||||||
m_hover_id = id;
|
m_hover_id = id;
|
||||||
on_set_hover_id();
|
on_set_hover_id();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::set_highlight_color(const std::array<float, 4>& color)
|
|
||||||
{
|
|
||||||
m_highlight_color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLGizmoBase::enable_grabber(unsigned int id)
|
void GLGizmoBase::enable_grabber(unsigned int id)
|
||||||
{
|
{
|
||||||
if (id < m_grabbers.size())
|
if (id < m_grabbers.size())
|
||||||
@ -162,22 +140,13 @@ bool GLGizmoBase::update_items_state()
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<float, 4> GLGizmoBase::picking_color_component(unsigned int id) const
|
ColorRGBA GLGizmoBase::picking_color_component(unsigned int id) const
|
||||||
{
|
{
|
||||||
static const float INV_255 = 1.0f / 255.0f;
|
|
||||||
|
|
||||||
id = BASE_ID - id;
|
id = BASE_ID - id;
|
||||||
|
|
||||||
if (m_group_id > -1)
|
if (m_group_id > -1)
|
||||||
id -= m_group_id;
|
id -= m_group_id;
|
||||||
|
|
||||||
// color components are encoded to match the calculation of volume_id made into GLCanvas3D::_picking_pass()
|
return picking_decode(id);
|
||||||
return std::array<float, 4> {
|
|
||||||
float((id >> 0) & 0xff) * INV_255, // red
|
|
||||||
float((id >> 8) & 0xff) * INV_255, // green
|
|
||||||
float((id >> 16) & 0xff) * INV_255, // blue
|
|
||||||
float(picking_checksum_alpha_channel(id & 0xff, (id >> 8) & 0xff, (id >> 16) & 0xff))* INV_255 // checksum for validating against unwanted alpha blending and multi sampling
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const
|
void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const
|
||||||
@ -201,15 +170,23 @@ void GLGizmoBase::render_grabbers(float size) const
|
|||||||
|
|
||||||
void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
|
void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0);
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||||
|
if (shader != nullptr) {
|
||||||
|
shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) {
|
for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) {
|
||||||
if (m_grabbers[i].enabled) {
|
if (m_grabbers[i].enabled) {
|
||||||
std::array<float, 4> color = picking_color_component(i);
|
m_grabbers[i].color = picking_color_component(i);
|
||||||
m_grabbers[i].color = color;
|
|
||||||
m_grabbers[i].render_for_picking(mean_size);
|
m_grabbers[i].render_for_picking(mean_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLGizmoBase::format(float value, unsigned int decimals) const
|
std::string GLGizmoBase::format(float value, unsigned int decimals) const
|
||||||
@ -244,22 +221,5 @@ std::string GLGizmoBase::get_name(bool include_shortcut) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components
|
|
||||||
// were not interpolated by alpha blending or multi sampling.
|
|
||||||
unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue)
|
|
||||||
{
|
|
||||||
// 8 bit hash for the color
|
|
||||||
unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff;
|
|
||||||
// Increase enthropy by a bit reversal
|
|
||||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
|
||||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
|
||||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
|
||||||
// Flip every second bit to increase the enthropy even more.
|
|
||||||
b ^= 0x55;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define slic3r_GLGizmoBase_hpp_
|
#define slic3r_GLGizmoBase_hpp_
|
||||||
|
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
|
#include "libslic3r/Color.hpp"
|
||||||
|
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
#include "slic3r/GUI/GLModel.hpp"
|
#include "slic3r/GUI/GLModel.hpp"
|
||||||
@ -18,15 +19,11 @@ class ModelObject;
|
|||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
static const std::array<float, 4> DEFAULT_BASE_COLOR = { 0.625f, 0.625f, 0.625f, 1.0f };
|
static const ColorRGBA DEFAULT_BASE_COLOR = { 0.625f, 0.625f, 0.625f, 1.0f };
|
||||||
static const std::array<float, 4> DEFAULT_DRAG_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f };
|
static const ColorRGBA DEFAULT_DRAG_COLOR = ColorRGBA::WHITE();
|
||||||
static const std::array<float, 4> DEFAULT_HIGHLIGHT_COLOR = { 1.0f, 0.38f, 0.0f, 1.0f };
|
static const ColorRGBA DEFAULT_HIGHLIGHT_COLOR = ColorRGBA::ORANGE();
|
||||||
static const std::array<std::array<float, 4>, 3> AXES_COLOR = {{
|
static const std::array<ColorRGBA, 3> AXES_COLOR = {{ ColorRGBA::X(), ColorRGBA::Y(), ColorRGBA::Z() }};
|
||||||
{ 0.75f, 0.0f, 0.0f, 1.0f },
|
static const ColorRGBA CONSTRAINED_COLOR = ColorRGBA::GRAY();
|
||||||
{ 0.0f, 0.75f, 0.0f, 1.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.75f, 1.0f }
|
|
||||||
}};
|
|
||||||
static const std::array<float, 4> CONSTRAINED_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f };
|
|
||||||
|
|
||||||
class ImGuiWrapper;
|
class ImGuiWrapper;
|
||||||
class GLCanvas3D;
|
class GLCanvas3D;
|
||||||
@ -48,25 +45,24 @@ protected:
|
|||||||
static const float MinHalfSize;
|
static const float MinHalfSize;
|
||||||
static const float DraggingScaleFactor;
|
static const float DraggingScaleFactor;
|
||||||
|
|
||||||
Vec3d center;
|
bool enabled{ true };
|
||||||
Vec3d angles;
|
bool dragging{ false };
|
||||||
std::array<float, 4> color;
|
Vec3d center{ Vec3d::Zero() };
|
||||||
bool enabled;
|
Vec3d angles{ Vec3d::Zero() };
|
||||||
bool dragging;
|
ColorRGBA color{ ColorRGBA::WHITE() };
|
||||||
|
|
||||||
Grabber();
|
Grabber() = default;
|
||||||
|
|
||||||
void render(bool hover, float size) const;
|
void render(bool hover, float size);
|
||||||
void render_for_picking(float size) const { render(size, color, true); }
|
void render_for_picking(float size) { render(size, color, true); }
|
||||||
|
|
||||||
float get_half_size(float size) const;
|
float get_half_size(float size) const;
|
||||||
float get_dragging_half_size(float size) const;
|
float get_dragging_half_size(float size) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void render(float size, const std::array<float, 4>& render_color, bool picking) const;
|
void render(float size, const ColorRGBA& render_color, bool picking);
|
||||||
|
|
||||||
GLModel cube;
|
GLModel m_cube;
|
||||||
bool cube_initialized = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -97,17 +93,14 @@ protected:
|
|||||||
unsigned int m_sprite_id;
|
unsigned int m_sprite_id;
|
||||||
int m_hover_id;
|
int m_hover_id;
|
||||||
bool m_dragging;
|
bool m_dragging;
|
||||||
std::array<float, 4> m_base_color;
|
ColorRGBA m_base_color;
|
||||||
std::array<float, 4> m_drag_color;
|
ColorRGBA m_drag_color;
|
||||||
std::array<float, 4> m_highlight_color;
|
ColorRGBA m_highlight_color;
|
||||||
mutable std::vector<Grabber> m_grabbers;
|
mutable std::vector<Grabber> m_grabbers;
|
||||||
ImGuiWrapper* m_imgui;
|
ImGuiWrapper* m_imgui;
|
||||||
bool m_first_input_window_render;
|
bool m_first_input_window_render;
|
||||||
mutable std::string m_tooltip;
|
mutable std::string m_tooltip;
|
||||||
CommonGizmosDataPool* m_c;
|
CommonGizmosDataPool* m_c;
|
||||||
GLModel m_cone;
|
|
||||||
GLModel m_cylinder;
|
|
||||||
GLModel m_sphere;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLGizmoBase(GLCanvas3D& parent,
|
GLGizmoBase(GLCanvas3D& parent,
|
||||||
@ -146,7 +139,7 @@ public:
|
|||||||
int get_hover_id() const { return m_hover_id; }
|
int get_hover_id() const { return m_hover_id; }
|
||||||
void set_hover_id(int id);
|
void set_hover_id(int id);
|
||||||
|
|
||||||
void set_highlight_color(const std::array<float, 4>& color);
|
void set_highlight_color(const ColorRGBA& color) { m_highlight_color = color; }
|
||||||
|
|
||||||
void enable_grabber(unsigned int id);
|
void enable_grabber(unsigned int id);
|
||||||
void disable_grabber(unsigned int id);
|
void disable_grabber(unsigned int id);
|
||||||
@ -188,7 +181,8 @@ protected:
|
|||||||
|
|
||||||
// Returns the picking color for the given id, based on the BASE_ID constant
|
// Returns the picking color for the given id, based on the BASE_ID constant
|
||||||
// No check is made for clashing with other picking color (i.e. GLVolumes)
|
// No check is made for clashing with other picking color (i.e. GLVolumes)
|
||||||
std::array<float, 4> picking_color_component(unsigned int id) const;
|
ColorRGBA picking_color_component(unsigned int id) const;
|
||||||
|
|
||||||
void render_grabbers(const BoundingBoxf3& box) const;
|
void render_grabbers(const BoundingBoxf3& box) const;
|
||||||
void render_grabbers(float size) const;
|
void render_grabbers(float size) const;
|
||||||
void render_grabbers_for_picking(const BoundingBoxf3& box) const;
|
void render_grabbers_for_picking(const BoundingBoxf3& box) const;
|
||||||
@ -203,10 +197,6 @@ private:
|
|||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components
|
|
||||||
// were not interpolated by alpha blending or multi sampling.
|
|
||||||
extern unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue);
|
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ namespace GUI {
|
|||||||
|
|
||||||
const double GLGizmoCut::Offset = 10.0;
|
const double GLGizmoCut::Offset = 10.0;
|
||||||
const double GLGizmoCut::Margin = 20.0;
|
const double GLGizmoCut::Margin = 20.0;
|
||||||
const std::array<float, 4> GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0, 1.0 };
|
static const ColorRGBA GRABBER_COLOR = ColorRGBA::ORANGE();
|
||||||
|
|
||||||
GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||||
@ -101,6 +101,38 @@ void GLGizmoCut::on_render()
|
|||||||
glsafe(::glEnable(GL_BLEND));
|
glsafe(::glEnable(GL_BLEND));
|
||||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||||
|
if (shader != nullptr) {
|
||||||
|
shader->start_using();
|
||||||
|
|
||||||
|
const bool z_changed = std::abs(plane_center.z() - m_old_z) > EPSILON;
|
||||||
|
m_old_z = plane_center.z();
|
||||||
|
|
||||||
|
if (!m_plane.is_initialized() || z_changed) {
|
||||||
|
m_plane.reset();
|
||||||
|
|
||||||
|
GLModel::Geometry init_data;
|
||||||
|
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||||
|
init_data.color = { 0.8f, 0.8f, 0.8f, 0.5f };
|
||||||
|
init_data.vertices.reserve(4 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
|
init_data.indices.reserve(6 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
|
// vertices
|
||||||
|
init_data.add_vertex(Vec3f(min_x, min_y, plane_center.z()));
|
||||||
|
init_data.add_vertex(Vec3f(max_x, min_y, plane_center.z()));
|
||||||
|
init_data.add_vertex(Vec3f(max_x, max_y, plane_center.z()));
|
||||||
|
init_data.add_vertex(Vec3f(min_x, max_y, plane_center.z()));
|
||||||
|
|
||||||
|
// indices
|
||||||
|
init_data.add_ushort_triangle(0, 1, 2);
|
||||||
|
init_data.add_ushort_triangle(2, 3, 0);
|
||||||
|
|
||||||
|
m_plane.init_from(std::move(init_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_plane.render();
|
||||||
|
#else
|
||||||
// Draw the cutting plane
|
// Draw the cutting plane
|
||||||
::glBegin(GL_QUADS);
|
::glBegin(GL_QUADS);
|
||||||
::glColor4f(0.8f, 0.8f, 0.8f, 0.5f);
|
::glColor4f(0.8f, 0.8f, 0.8f, 0.5f);
|
||||||
@ -109,12 +141,11 @@ void GLGizmoCut::on_render()
|
|||||||
::glVertex3f(max_x, max_y, plane_center.z());
|
::glVertex3f(max_x, max_y, plane_center.z());
|
||||||
::glVertex3f(min_x, max_y, plane_center.z());
|
::glVertex3f(min_x, max_y, plane_center.z());
|
||||||
glsafe(::glEnd());
|
glsafe(::glEnd());
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
glsafe(::glEnable(GL_CULL_FACE));
|
glsafe(::glEnable(GL_CULL_FACE));
|
||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
|
|
||||||
// TODO: draw cut part contour?
|
|
||||||
|
|
||||||
// Draw the grabber and the connecting line
|
// Draw the grabber and the connecting line
|
||||||
m_grabbers[0].center = plane_center;
|
m_grabbers[0].center = plane_center;
|
||||||
m_grabbers[0].center.z() = plane_center.z() + Offset;
|
m_grabbers[0].center.z() = plane_center.z() + Offset;
|
||||||
@ -122,6 +153,33 @@ void GLGizmoCut::on_render()
|
|||||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||||
|
|
||||||
glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f));
|
glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f));
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
if (!m_grabber_connection.is_initialized() || z_changed) {
|
||||||
|
m_grabber_connection.reset();
|
||||||
|
|
||||||
|
GLModel::Geometry init_data;
|
||||||
|
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
||||||
|
init_data.color = ColorRGBA::YELLOW();
|
||||||
|
init_data.vertices.reserve(2 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
|
init_data.indices.reserve(2 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
|
// vertices
|
||||||
|
init_data.add_vertex((Vec3f)plane_center.cast<float>());
|
||||||
|
init_data.add_vertex((Vec3f)m_grabbers[0].center.cast<float>());
|
||||||
|
|
||||||
|
// indices
|
||||||
|
init_data.add_ushort_line(0, 1);
|
||||||
|
|
||||||
|
m_grabber_connection.init_from(std::move(init_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_grabber_connection.render();
|
||||||
|
|
||||||
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = wxGetApp().get_shader("gouraud_light");
|
||||||
|
#else
|
||||||
glsafe(::glColor3f(1.0, 1.0, 0.0));
|
glsafe(::glColor3f(1.0, 1.0, 0.0));
|
||||||
::glBegin(GL_LINES);
|
::glBegin(GL_LINES);
|
||||||
::glVertex3dv(plane_center.data());
|
::glVertex3dv(plane_center.data());
|
||||||
@ -129,21 +187,31 @@ void GLGizmoCut::on_render()
|
|||||||
glsafe(::glEnd());
|
glsafe(::glEnd());
|
||||||
|
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||||
if (shader == nullptr)
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
return;
|
if (shader != nullptr) {
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
shader->set_uniform("emission_factor", 0.1f);
|
shader->set_uniform("emission_factor", 0.1f);
|
||||||
|
|
||||||
m_grabbers[0].color = GrabberColor;
|
m_grabbers[0].color = GRABBER_COLOR;
|
||||||
m_grabbers[0].render(m_hover_id == 0, (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0));
|
m_grabbers[0].render(m_hover_id == 0, float((box.size().x() + box.size().y() + box.size().z()) / 3.0));
|
||||||
|
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
shader = wxGetApp().get_shader("flat");
|
||||||
|
if (shader != nullptr) {
|
||||||
|
shader->start_using();
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z()));
|
glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z()));
|
||||||
glsafe(::glLineWidth(2.0f));
|
glsafe(::glLineWidth(2.0f));
|
||||||
m_cut_contours.contours.render();
|
m_cut_contours.contours.render();
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut::on_render_for_picking()
|
void GLGizmoCut::on_render_for_picking()
|
||||||
@ -302,7 +370,11 @@ void GLGizmoCut::update_contours()
|
|||||||
const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params);
|
const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params);
|
||||||
if (!polys.empty()) {
|
if (!polys.empty()) {
|
||||||
m_cut_contours.contours.init_from(polys, static_cast<float>(m_cut_z));
|
m_cut_contours.contours.init_from(polys, static_cast<float>(m_cut_z));
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
m_cut_contours.contours.set_color(ColorRGBA::WHITE());
|
||||||
|
#else
|
||||||
m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f });
|
m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f });
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (box.center() != m_cut_contours.position) {
|
else if (box.center() != m_cut_contours.position) {
|
||||||
|
@ -13,7 +13,6 @@ class GLGizmoCut : public GLGizmoBase
|
|||||||
{
|
{
|
||||||
static const double Offset;
|
static const double Offset;
|
||||||
static const double Margin;
|
static const double Margin;
|
||||||
static const std::array<float, 4> GrabberColor;
|
|
||||||
|
|
||||||
double m_cut_z{ 0.0 };
|
double m_cut_z{ 0.0 };
|
||||||
double m_max_z{ 0.0 };
|
double m_max_z{ 0.0 };
|
||||||
@ -23,6 +22,11 @@ class GLGizmoCut : public GLGizmoBase
|
|||||||
bool m_keep_upper{ true };
|
bool m_keep_upper{ true };
|
||||||
bool m_keep_lower{ true };
|
bool m_keep_lower{ true };
|
||||||
bool m_rotate_lower{ false };
|
bool m_rotate_lower{ false };
|
||||||
|
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
GLModel m_plane;
|
||||||
|
GLModel m_grabber_connection;
|
||||||
|
float m_old_z{ 0.0f };
|
||||||
|
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||||
|
|
||||||
struct CutContours
|
struct CutContours
|
||||||
{
|
{
|
||||||
|
@ -69,9 +69,7 @@ bool GLGizmoFdmSupports::on_init()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoFdmSupports::render_painter_gizmo()
|
||||||
|
|
||||||
void GLGizmoFdmSupports::render_painter_gizmo() const
|
|
||||||
{
|
{
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
|
|
||||||
|