Merge remote-tracking branch 'origin/master' into ys_msw_dpi
|
@ -49,6 +49,10 @@ foreach (_cache_var ${_cache_vars})
|
||||||
endif ()
|
endif ()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
if (SLIC3R_GUI)
|
||||||
|
add_definitions(-DSLIC3R_GUI)
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
if (SLIC3R_MSVC_COMPILE_PARALLEL)
|
if (SLIC3R_MSVC_COMPILE_PARALLEL)
|
||||||
add_compile_options(/MP)
|
add_compile_options(/MP)
|
||||||
|
|
19
resources/icons/add_copies.svg
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="add_x5F_copies">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M8,2c3.31,0,6,2.69,6,6s-2.69,6-6,6s-6-2.69-6-6S4.69,2,8,2 M8,1C4.13,1,1,4.13,1,8s3.13,7,7,7s7-3.13,7-7
|
||||||
|
S11.87,1,8,1L8,1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M12,8.75H4C3.59,8.75,3.25,8.41,3.25,8S3.59,7.25,4,7.25h8c0.41,0,0.75,0.34,0.75,0.75S12.41,8.75,12,8.75
|
||||||
|
z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,12.75c-0.41,0-0.75-0.34-0.75-0.75V4c0-0.41,0.34-0.75,0.75-0.75S8.75,3.59,8.75,4v8
|
||||||
|
C8.75,12.41,8.41,12.75,8,12.75z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 846 B |
13
resources/icons/add_modifier.svg
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="add_x5F_modifer">
|
||||||
|
<path fill="#808080" d="M10.98,9.78c-0.29,0-0.52,0.23-0.52,0.52v2.09v1.04c0,0.29-0.23,0.52-0.52,0.52H2.62
|
||||||
|
c-0.29,0-0.53-0.24-0.53-0.53L2.04,6.12c0-0.14,0.05-0.27,0.15-0.37c0.1-0.1,0.23-0.15,0.37-0.15l3.19,0v0
|
||||||
|
c0.29,0,0.52-0.23,0.52-0.52S6.04,4.55,5.75,4.55H3.66c-0.01,0-0.01,0-0.02,0l-1.08,0c-0.42,0-0.81,0.16-1.11,0.46
|
||||||
|
C1.16,5.31,1,5.71,1,6.13l0.04,7.31C1.05,14.3,1.75,15,2.62,15h7.31c0.86,0,1.57-0.7,1.57-1.57v-1.04V10.3
|
||||||
|
C11.5,10.01,11.27,9.78,10.98,9.78z"/>
|
||||||
|
<circle fill="#ED6B21" cx="11" cy="5" r="3.5"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 894 B |
19
resources/icons/add_part.svg
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="add_x5F_part">
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,8.5c-0.28,0-0.5-0.22-0.5-0.5V2c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v6
|
||||||
|
C11.5,8.28,11.28,8.5,11,8.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14,5.5H8C7.72,5.5,7.5,5.28,7.5,5S7.72,4.5,8,4.5h6c0.28,0,0.5,0.22,0.5,0.5S14.28,5.5,14,5.5z"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#808080" d="M10.98,9.78c-0.29,0-0.52,0.23-0.52,0.52v2.09v1.04c0,0.29-0.23,0.52-0.52,0.52H2.62
|
||||||
|
c-0.29,0-0.53-0.24-0.53-0.53L2.04,6.12c0-0.14,0.05-0.27,0.15-0.37c0.1-0.1,0.23-0.15,0.37-0.15l3.19,0v0
|
||||||
|
c0.29,0,0.52-0.23,0.52-0.52S6.04,4.55,5.75,4.55H3.66c-0.01,0-0.01,0-0.02,0l-1.08,0c-0.42,0-0.81,0.16-1.11,0.46
|
||||||
|
C1.16,5.31,1,5.71,1,6.13l0.04,7.31C1.05,14.3,1.75,15,2.62,15h7.31c0.86,0,1.57-0.7,1.57-1.57v-1.04V10.3
|
||||||
|
C11.5,10.01,11.27,9.78,10.98,9.78z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
24
resources/icons/advanced_plus.svg
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="advanced_x2B_">
|
||||||
|
<path fill="#808080" d="M10.98,9.78c-0.29,0-0.52,0.23-0.52,0.52v2.09v1.04c0,0.29-0.23,0.52-0.52,0.52H2.62
|
||||||
|
c-0.29,0-0.53-0.24-0.53-0.53L2.04,6.12c0-0.14,0.05-0.27,0.15-0.37c0.1-0.1,0.23-0.15,0.37-0.15l3.19,0v0
|
||||||
|
c0.29,0,0.52-0.23,0.52-0.52S6.04,4.55,5.75,4.55H3.66c-0.01,0-0.01,0-0.02,0l-1.08,0c-0.42,0-0.81,0.16-1.11,0.46
|
||||||
|
C1.16,5.31,1,5.71,1,6.13l0.04,7.31C1.05,14.3,1.75,15,2.62,15h7.31c0.86,0,1.57-0.7,1.57-1.57v-1.04V10.3
|
||||||
|
C11.5,10.01,11.27,9.78,10.98,9.78z"/>
|
||||||
|
<path fill="#ED6B21" d="M13.56,5.38c-0.01-0.13,0.06-0.33,0.15-0.43l0.13-0.15c0.09-0.1,0.12-0.29,0.07-0.42l-0.2-0.48
|
||||||
|
c-0.05-0.13-0.21-0.24-0.35-0.25l-0.2-0.01c-0.14-0.01-0.32-0.1-0.41-0.2c-0.09-0.1-0.37-0.45-0.38-0.59l-0.01-0.2
|
||||||
|
c-0.01-0.14-0.12-0.29-0.25-0.35l-0.48-0.2c-0.13-0.05-0.32-0.02-0.42,0.07L11.06,2.3c-0.1,0.09-0.3,0.16-0.44,0.15
|
||||||
|
s-0.57-0.06-0.68-0.15L9.79,2.16C9.69,2.07,9.5,2.04,9.37,2.1L8.89,2.3C8.76,2.35,8.65,2.5,8.64,2.64l-0.01,0.2
|
||||||
|
c-0.01,0.14-0.1,0.32-0.2,0.41c-0.1,0.09-0.45,0.37-0.59,0.38l-0.2,0.01C7.5,3.65,7.35,3.76,7.3,3.89L7.1,4.37
|
||||||
|
C7.04,4.5,7.07,4.69,7.16,4.79L7.3,4.94c0.09,0.1,0.16,0.3,0.15,0.44C7.44,5.51,7.38,5.95,7.29,6.06L7.16,6.21
|
||||||
|
C7.07,6.31,7.04,6.5,7.1,6.63l0.2,0.48C7.35,7.24,7.5,7.35,7.64,7.36l0.2,0.01c0.14,0.01,0.32,0.1,0.41,0.2
|
||||||
|
c0.09,0.1,0.37,0.45,0.38,0.59l0.01,0.2C8.65,8.5,8.76,8.65,8.89,8.7l0.48,0.2C9.5,8.96,9.69,8.93,9.79,8.84L9.94,8.7
|
||||||
|
c0.1-0.09,0.3-0.16,0.44-0.15c0.14,0.01,0.57,0.06,0.68,0.15l0.15,0.13c0.1,0.09,0.29,0.12,0.42,0.07l0.48-0.2
|
||||||
|
c0.13-0.05,0.24-0.21,0.25-0.35l0.01-0.2c0.01-0.14,0.1-0.32,0.2-0.41s0.45-0.37,0.59-0.38l0.2-0.01c0.14-0.01,0.29-0.12,0.35-0.25
|
||||||
|
l0.2-0.48c0.05-0.13,0.02-0.32-0.07-0.42L13.7,6.06C13.61,5.95,13.56,5.51,13.56,5.38z M10.5,7.55c-1.13,0-2.05-0.92-2.05-2.05
|
||||||
|
s0.92-2.05,2.05-2.05s2.05,0.92,2.05,2.05S11.63,7.55,10.5,7.55z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
11
resources/icons/browse.svg
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="browse">
|
||||||
|
<path fill="#ED6B21" d="M8.49,2.43c-1.71-1.71-4.49-1.71-6.2,0s-1.71,4.49,0,6.2c1.59,1.59,4.1,1.7,5.82,0.34l1.48,1.48
|
||||||
|
c0,0-0.36,0.36,0,0.73s3.65,3.65,3.65,3.65s0.36,0.36,0.73,0c0.36-0.36,0.73-0.73,0.73-0.73s0.36-0.36,0-0.73s-3.65-3.65-3.65-3.65
|
||||||
|
c-0.36-0.36-0.73,0-0.73,0L8.83,8.25C10.19,6.52,10.08,4.02,8.49,2.43z M8.1,8.25c-1.5,1.5-3.93,1.5-5.43,0s-1.5-3.93,0-5.43
|
||||||
|
s3.93-1.5,5.43,0S9.6,6.75,8.1,8.25z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 777 B |
37
resources/icons/copy.svg
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<g id="copy">
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M115.76,51.2l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04
|
||||||
|
c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.17,118.23,53.67,115.76,51.2z M111.42,54.04h-6.57
|
||||||
|
v-6.57L111.42,54.04z M115.01,112.47c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.42
|
||||||
|
c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54
|
||||||
|
V112.47z"/>
|
||||||
|
<path fill="#ED6B21" d="M53.97,59.13h35.72c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H53.97c-1.4,0-2.54,1.14-2.54,2.54
|
||||||
|
S52.56,59.13,53.97,59.13z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,69.29H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,69.29,104.93,69.29z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,84.53H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,84.53,104.93,84.53z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,99.77H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,99.77,104.93,99.77z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#FFFFFF" d="M85.27,20.71l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04
|
||||||
|
c0,4.2,3.42,7.62,7.62,7.62h17.78c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H15.94c-1.4,0-2.54-1.14-2.54-2.54V15.94
|
||||||
|
c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46V26.1c0,1.4,1.14,2.54,2.54,2.54h12.45c0.16,0.49,0.25,0.93,0.25,1.27
|
||||||
|
v3.81c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54v-3.81C89.61,27.14,87.75,23.19,85.27,20.71z M74.37,16.99l6.57,6.57
|
||||||
|
h-6.57V16.99z"/>
|
||||||
|
<path fill="#FFFFFF" d="M59.21,23.56H23.48c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h35.72c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S60.61,23.56,59.21,23.56z"/>
|
||||||
|
<path fill="#FFFFFF" d="M28.73,38.8h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S30.13,38.8,28.73,38.8z"/>
|
||||||
|
<path fill="#FFFFFF" d="M28.73,54.04h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S30.13,54.04,28.73,54.04z"/>
|
||||||
|
<path fill="#FFFFFF" d="M28.73,69.29h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S30.13,69.29,28.73,69.29z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
37
resources/icons/copy_menu.svg
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<g id="copy">
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M115.76,51.2l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04
|
||||||
|
c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.17,118.23,53.67,115.76,51.2z M111.42,54.04h-6.57
|
||||||
|
v-6.57L111.42,54.04z M115.01,112.47c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.42
|
||||||
|
c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54
|
||||||
|
V112.47z"/>
|
||||||
|
<path fill="#ED6B21" d="M53.97,59.13h35.72c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H53.97c-1.4,0-2.54,1.14-2.54,2.54
|
||||||
|
S52.56,59.13,53.97,59.13z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,69.29H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,69.29,104.93,69.29z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,84.53H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,84.53,104.93,84.53z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,99.77H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,99.77,104.93,99.77z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M85.27,20.71l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04
|
||||||
|
c0,4.2,3.42,7.62,7.62,7.62h17.78c1.4,0,2.54-1.14,2.54-2.54s-1.14-2.54-2.54-2.54H15.94c-1.4,0-2.54-1.14-2.54-2.54V15.94
|
||||||
|
c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46V26.1c0,1.4,1.14,2.54,2.54,2.54h12.45c0.16,0.49,0.25,0.93,0.25,1.27
|
||||||
|
v3.81c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54v-3.81C89.61,27.14,87.75,23.19,85.27,20.71z M74.37,16.99l6.57,6.57
|
||||||
|
h-6.57V16.99z"/>
|
||||||
|
<path fill="#808080" d="M59.21,23.56H23.48c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h35.72c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S60.61,23.56,59.21,23.56z"/>
|
||||||
|
<path fill="#808080" d="M28.73,38.8h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S30.13,38.8,28.73,38.8z"/>
|
||||||
|
<path fill="#808080" d="M28.73,54.04h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S30.13,54.04,28.73,54.04z"/>
|
||||||
|
<path fill="#808080" d="M28.73,69.29h-5.24c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h5.24c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S30.13,69.29,28.73,69.29z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
22
resources/icons/delete.svg
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="delete">
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M13,10c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2v3c0,1.1,0.9,2,2,2h6c1.1,0,2-0.9,2-2V10z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M12,5.01c0.25,0,0.47,0.09,0.62,0.26c0.15,0.17,0.22,0.4,0.2,0.64l-0.64,7.01C12.13,13.49,11.58,14,11,14
|
||||||
|
H5c-0.58,0-1.13-0.51-1.19-1.08L3.18,5.91c-0.02-0.25,0.05-0.47,0.2-0.64C3.53,5.1,3.75,5.01,4,5.01H12 M12,4.01H4
|
||||||
|
c-1.1,0-1.92,0.9-1.82,1.99l0.64,7.01C2.92,14.1,3.9,15,5,15h6c1.1,0,2.08-0.9,2.18-1.99L13.82,6C13.92,4.91,13.1,4.01,12,4.01
|
||||||
|
L12,4.01z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M13,3.5H3C2.72,3.5,2.5,3.28,2.5,3S2.72,2.5,3,2.5h10c0.28,0,0.5,0.22,0.5,0.5S13.28,3.5,13,3.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M10,2.5H6C5.72,2.5,5.5,2.28,5.5,2S5.72,1.5,6,1.5h4c0.28,0,0.5,0.22,0.5,0.5S10.28,2.5,10,2.5z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
31
resources/icons/delete_all_menu.svg
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<g id="DELETE_ALL_1_">
|
||||||
|
<path fill="#808080" d="M103.52,43.87l-13.31,69.97H37.79L24.48,43.87H103.52 M108.77,37.87H19.23c-1.1,0-1.83,0.88-1.63,1.96
|
||||||
|
l14.84,78.04c0.21,1.08,1.27,1.96,2.37,1.96h58.36c1.1,0,2.17-0.88,2.37-1.96l14.84-78.04C110.6,38.75,109.87,37.87,108.77,37.87
|
||||||
|
L108.77,37.87z"/>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M89.38,22.97c-1.1,0-2-0.9-2-2v-10.9c0-1.1-0.9-2-2-2H42.62c-1.1,0-2,0.9-2,2v10.9c0,1.1-0.9,2-2,2H19.23
|
||||||
|
c-1.1,0-2,0.9-2,2v3.45c0,1.1,0.9,2,2,2h89.54c1.1,0,2-0.9,2-2v-3.45c0-1.1-0.9-2-2-2H89.38z M79.59,20.97c0,1.1-0.9,2-2,2H50.41
|
||||||
|
c-1.1,0-2-0.9-2-2v-3.45c0-1.1,0.9-2,2-2h27.18c1.1,0,2,0.9,2,2V20.97z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M93.17,73.5H34.83c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h58.34c0.83,0,1.5,0.67,1.5,1.5
|
||||||
|
S94,73.5,93.17,73.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M90.14,89.45H37.96c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h52.18c0.83,0,1.5,0.67,1.5,1.5
|
||||||
|
S90.97,89.45,90.14,89.45z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M87.1,105.4H40.9c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h46.2c0.83,0,1.5,0.67,1.5,1.5
|
||||||
|
S87.93,105.4,87.1,105.4z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M96.2,57.56H31.8c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h64.4c0.83,0,1.5,0.67,1.5,1.5
|
||||||
|
S97.03,57.56,96.2,57.56z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
8
resources/icons/dot.svg
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<circle fill="#808080" cx="8" cy="8" r="3"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 400 B |
8
resources/icons/dot_white.svg
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<circle fill="#FFFFFF" cx="8" cy="8" r="3"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 400 B |
20
resources/icons/editor_menu.svg
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<g id="editor">
|
||||||
|
<g>
|
||||||
|
<path fill="none" stroke="#101010" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M118.68,8.83L92.1,37.03c-0.75,0.8-2.27,1.46-3.37,1.46H9.44"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<line fill="none" stroke="#101010" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="90.72" y1="118.69" x2="90.72" y2="38.81"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="none" stroke="#101010" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M119.88,91.51v-81.4c0-1.1-0.9-2-2-2H42.92c-1.1,0-2.66,0.61-3.47,1.36L9.59,37.13c-0.81,0.75-1.47,2.26-1.47,3.36v77.39
|
||||||
|
c0,1.1,0.9,2,2,2h78.61c1.1,0,2.65-0.63,3.44-1.39l27.67-26.82"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
17
resources/icons/exclamation.svg
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,11c-0.55,0-1-0.45-1-1V7c0-0.55,0.45-1,1-1s1,0.45,1,1v3C9,10.55,8.55,11,8,11z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<circle fill="#ED6B21" cx="8" cy="13" r="1"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M15,15.5H1c-0.18,0-0.34-0.09-0.43-0.24c-0.09-0.15-0.09-0.34-0.01-0.49l7-13c0.17-0.32,0.71-0.32,0.88,0
|
||||||
|
l7,13c0.08,0.16,0.08,0.34-0.01,0.49C15.34,15.41,15.18,15.5,15,15.5z M1.84,14.5h12.33L8,3.05L1.84,14.5z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 781 B |
20
resources/icons/export_config.svg
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="export_x5F_config">
|
||||||
|
<path fill="#808080" d="M14.22,6.61c-0.25-0.12-0.52-0.43-0.6-0.68s-0.32-1.09-0.23-1.35l0.12-0.35c0.09-0.26,0-0.63-0.2-0.83
|
||||||
|
L12.6,2.7c-0.19-0.19-0.57-0.28-0.83-0.2l-0.35,0.12c-0.26,0.09-0.67,0.06-0.91-0.05s-1-0.54-1.12-0.79L9.22,1.45
|
||||||
|
C9.1,1.2,8.77,1,8.5,1h-1C7.22,1,6.9,1.2,6.78,1.45L6.61,1.78C6.49,2.02,6.18,2.3,5.93,2.38S4.84,2.7,4.58,2.62L4.23,2.5
|
||||||
|
C3.97,2.41,3.6,2.5,3.4,2.7L2.7,3.4C2.5,3.6,2.41,3.97,2.5,4.23l0.12,0.35C2.7,4.84,2.68,5.25,2.57,5.49s-0.54,1-0.79,1.12
|
||||||
|
L1.45,6.78C1.2,6.9,1,7.22,1,7.5v1c0,0.27,0.2,0.6,0.45,0.72l0.33,0.17c0.25,0.12,0.52,0.43,0.6,0.68s0.32,1.09,0.23,1.35
|
||||||
|
L2.5,11.77c-0.09,0.26,0,0.63,0.2,0.83L3.4,13.3c0.19,0.19,0.57,0.28,0.83,0.2l0.35-0.12c0.26-0.09,0.67-0.06,0.91,0.05
|
||||||
|
s1,0.54,1.12,0.79l0.17,0.33C6.9,14.8,7.22,15,7.5,15h1c0.27,0,0.6-0.2,0.72-0.45l0.17-0.33c0.12-0.25,0.43-0.52,0.68-0.6
|
||||||
|
s1.09-0.32,1.35-0.23l0.35,0.12c0.26,0.09,0.63,0,0.83-0.2l0.71-0.71c0.19-0.19,0.28-0.57,0.2-0.83l-0.12-0.35
|
||||||
|
c-0.09-0.26-0.06-0.67,0.05-0.91s0.54-1,0.79-1.12l0.33-0.17C14.8,9.1,15,8.77,15,8.5v-1c0-0.28-0.2-0.6-0.45-0.72L14.22,6.61z
|
||||||
|
M8,13c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S10.76,13,8,13z"/>
|
||||||
|
<path fill="#ED6B21" d="M11.65,8.35c0.19-0.19,0.19-0.51,0-0.71L8.92,4.92C8.73,4.73,8.57,4.8,8.57,5.07v1.29
|
||||||
|
c0,0.28-0.22,0.5-0.5,0.5H4.5C4.22,6.86,4,7.08,4,7.36v1.29c0,0.27,0.22,0.5,0.5,0.5h3.57c0.28,0,0.5,0.22,0.5,0.5v1.29
|
||||||
|
c0,0.27,0.16,0.34,0.35,0.15L11.65,8.35z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
51
resources/icons/export_config_bundle.svg
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="export_x5F_config_x5F_bundle">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M1.2,12.61c0.11,0.08,0.21,0.22,0.23,0.31c0.02,0.09,0.04,0.43-0.03,0.55s-0.05,0.31,0.03,0.42l0.12,0.17
|
||||||
|
c0.08,0.11,0.25,0.19,0.39,0.17c0.13-0.02,0.3,0.01,0.38,0.06s0.33,0.28,0.37,0.41c0.04,0.13,0.18,0.25,0.32,0.27l0.21,0.04
|
||||||
|
c0.14,0.02,0.31-0.05,0.39-0.16s0.22-0.21,0.31-0.23c0.09-0.02,0.43-0.04,0.55,0.03c0.12,0.06,0.31,0.05,0.42-0.03l0.17-0.12
|
||||||
|
c0.11-0.08,0.19-0.25,0.17-0.39c-0.02-0.13,0.01-0.3,0.06-0.38s0.28-0.33,0.41-0.37c0.13-0.04,0.25-0.18,0.27-0.32l0.04-0.21
|
||||||
|
c0.02-0.14-0.05-0.31-0.16-0.39c-0.11-0.08-0.21-0.22-0.23-0.31c-0.02-0.09-0.04-0.43,0.03-0.55c0.06-0.12,0.05-0.31-0.03-0.42
|
||||||
|
L5.5,10.98c-0.08-0.11-0.25-0.19-0.39-0.17c-0.13,0.02-0.3-0.01-0.38-0.06c-0.08-0.05-0.33-0.28-0.37-0.41
|
||||||
|
c-0.04-0.13-0.18-0.25-0.32-0.27l-0.21-0.04c-0.14-0.02-0.31,0.05-0.39,0.16s-0.22,0.21-0.31,0.23S2.7,10.46,2.58,10.4
|
||||||
|
c-0.12-0.06-0.31-0.05-0.42,0.03l-0.17,0.12c-0.11,0.08-0.19,0.25-0.17,0.39s-0.01,0.3-0.06,0.38c-0.05,0.08-0.28,0.33-0.41,0.37
|
||||||
|
c-0.13,0.04-0.25,0.18-0.27,0.32l-0.04,0.21C1.02,12.36,1.09,12.53,1.2,12.61z M3.71,11.42c0.61,0.1,1.02,0.68,0.92,1.28
|
||||||
|
c-0.1,0.61-0.68,1.02-1.28,0.92c-0.61-0.1-1.02-0.68-0.92-1.28C2.53,11.73,3.1,11.32,3.71,11.42z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M10.39,4.47c0.13,0.03,0.28,0.13,0.33,0.21c0.05,0.08,0.19,0.38,0.18,0.52s0.07,0.3,0.19,0.38l0.18,0.11
|
||||||
|
c0.12,0.07,0.31,0.08,0.42,0.01c0.12-0.07,0.28-0.11,0.38-0.09c0.09,0.02,0.41,0.13,0.5,0.24c0.09,0.1,0.26,0.17,0.4,0.13
|
||||||
|
l0.21-0.05c0.13-0.03,0.27-0.16,0.3-0.29c0.03-0.13,0.13-0.28,0.21-0.33c0.08-0.05,0.38-0.19,0.52-0.18
|
||||||
|
c0.13,0.01,0.3-0.07,0.38-0.19l0.11-0.18c0.07-0.12,0.08-0.31,0.01-0.42c-0.07-0.12-0.11-0.28-0.09-0.38
|
||||||
|
c0.02-0.09,0.13-0.41,0.24-0.5c0.1-0.09,0.17-0.26,0.13-0.4l-0.05-0.21c-0.03-0.13-0.16-0.27-0.29-0.3
|
||||||
|
c-0.13-0.03-0.28-0.13-0.33-0.21s-0.19-0.38-0.18-0.52c0.01-0.13-0.07-0.3-0.19-0.38l-0.18-0.11c-0.12-0.07-0.31-0.08-0.42-0.01
|
||||||
|
c-0.12,0.07-0.28,0.11-0.38,0.09c-0.09-0.02-0.41-0.13-0.5-0.24c-0.09-0.1-0.26-0.17-0.4-0.13L11.87,1.1
|
||||||
|
c-0.13,0.03-0.27,0.16-0.3,0.29s-0.13,0.28-0.21,0.33s-0.38,0.19-0.52,0.18s-0.3,0.07-0.38,0.19l-0.11,0.18
|
||||||
|
c-0.07,0.12-0.08,0.31-0.01,0.42c0.07,0.12,0.11,0.28,0.09,0.38s-0.13,0.41-0.24,0.5c-0.1,0.09-0.17,0.26-0.13,0.4l0.05,0.21
|
||||||
|
C10.13,4.3,10.26,4.44,10.39,4.47z M12.27,2.43c0.6-0.13,1.2,0.24,1.33,0.84c0.13,0.6-0.24,1.2-0.84,1.33
|
||||||
|
c-0.6,0.13-1.2-0.24-1.33-0.84C11.3,3.16,11.67,2.56,12.27,2.43z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M1.85,4.19C1.8,4.32,1.66,4.47,1.53,4.53L1.15,4.71C1.02,4.77,0.92,4.93,0.91,5.06L0.89,5.92
|
||||||
|
c0,0.14,0.09,0.3,0.21,0.37l0.37,0.2C1.6,6.55,1.73,6.71,1.77,6.84l0.17,0.44C2,7.41,2,7.62,1.96,7.75l-0.15,0.4
|
||||||
|
C1.76,8.28,1.8,8.47,1.89,8.57l0.58,0.62c0.09,0.1,0.28,0.15,0.41,0.11L3.3,9.17c0.13-0.04,0.34-0.02,0.46,0.04l0.43,0.2
|
||||||
|
c0.13,0.05,0.28,0.19,0.34,0.32l0.18,0.39c0.06,0.12,0.22,0.23,0.35,0.23l0.85,0.03c0.14,0,0.3-0.09,0.37-0.21l0.2-0.37
|
||||||
|
c0.07-0.12,0.23-0.25,0.36-0.29l0.44-0.17c0.13-0.06,0.33-0.06,0.46-0.02l0.4,0.15C8.28,9.5,8.47,9.47,8.57,9.37l0.62-0.58
|
||||||
|
c0.1-0.09,0.15-0.28,0.11-0.41L9.17,7.97C9.13,7.84,9.16,7.63,9.22,7.51l0.2-0.43c0.05-0.13,0.19-0.28,0.32-0.34l0.39-0.18
|
||||||
|
c0.12-0.06,0.23-0.22,0.23-0.35l0.03-0.85c0-0.14-0.09-0.3-0.21-0.37l-0.37-0.2C9.67,4.71,9.54,4.55,9.49,4.42L9.33,3.98
|
||||||
|
C9.27,3.85,9.26,3.64,9.31,3.52l0.15-0.4C9.5,2.99,9.47,2.8,9.37,2.7L8.79,2.08c-0.09-0.1-0.28-0.15-0.41-0.11L7.97,2.09
|
||||||
|
C7.84,2.13,7.63,2.11,7.51,2.05l-0.43-0.2C6.94,1.8,6.79,1.66,6.73,1.53L6.56,1.15C6.5,1.02,6.34,0.92,6.2,0.91L5.35,0.89
|
||||||
|
c-0.14,0-0.3,0.09-0.37,0.21l-0.2,0.37C4.71,1.6,4.55,1.73,4.42,1.77L3.98,1.94C3.85,2,3.64,2,3.52,1.96l-0.4-0.15
|
||||||
|
C2.99,1.76,2.8,1.8,2.7,1.89L2.08,2.48c-0.1,0.09-0.15,0.28-0.11,0.41L2.09,3.3c0.04,0.13,0.02,0.34-0.04,0.46L1.85,4.19z
|
||||||
|
M6.75,3.15c1.37,0.62,1.98,2.23,1.36,3.6s-2.23,1.98-3.6,1.36C3.15,7.5,2.54,5.89,3.15,4.52S5.38,2.54,6.75,3.15z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14.65,11.78c0.19-0.19,0.19-0.51,0-0.71l-2.72-2.72c-0.19-0.19-0.35-0.13-0.35,0.15v1.29
|
||||||
|
c0,0.28-0.22,0.5-0.5,0.5H8.49c-0.28,0-0.5,0.23-0.5,0.5v1.29c0,0.28,0.22,0.5,0.5,0.5h2.58c0.28,0,0.5,0.23,0.5,0.5v1.29
|
||||||
|
c0,0.28,0.16,0.34,0.35,0.15L14.65,11.78z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
14
resources/icons/export_gcode.svg
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="export_x5F_gcode">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M5.02,7.17H9v3.08c0,2.6-1.23,3.72-4.05,3.72S1,12.85,1,10.29V5.54C1,3.12,2.09,2,4.95,2S9,3,9,5.54H6.88
|
||||||
|
c0-1.11-0.28-1.66-1.92-1.66c-1.54,0-1.83,0.69-1.83,1.77v4.65c0,1.12,0.29,1.77,1.83,1.77c1.54,0,2.08-0.65,2.08-1.82V9.09H5.02
|
||||||
|
V7.17z"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#ED6B21" d="M14.65,8.35c0.19-0.19,0.19-0.51,0-0.71l-4.29-4.29C10.16,3.16,10,3.22,10,3.5v9
|
||||||
|
c0,0.27,0.16,0.34,0.35,0.15L14.65,8.35z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 804 B |
12
resources/icons/export_plater.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="export_x5F_plater">
|
||||||
|
<path fill="#808080" d="M13,2c0.55,0,1,0.45,1,1V13c0,0.55-0.45,1-1,1H3c-0.55,0-1-0.45-1-1V3c0-0.55,0.45-1,1-1H13 M13,1H3
|
||||||
|
c-1.1,0-2,0.89-2,2V13c0,1.1,0.89,2,2,2H13c1.1,0,2-0.89,2-2V3C15,1.89,14.11,1,13,1L13,1z"/>
|
||||||
|
<path fill="#ED6B21" d="M11.65,8.35c0.19-0.19,0.19-0.51,0-0.71L8.92,4.92C8.73,4.73,8.57,4.8,8.57,5.07v1.29
|
||||||
|
c0,0.28-0.22,0.5-0.5,0.5H4.5C4.22,6.86,4,7.08,4,7.36v1.29c0,0.27,0.22,0.5,0.5,0.5h3.57c0.28,0,0.5,0.22,0.5,0.5v1.29
|
||||||
|
c0,0.27,0.16,0.34,0.35,0.15L11.65,8.35z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 863 B |
25
resources/icons/import_config.svg
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="import_x5F_config">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M14.22,6.61c-0.25-0.12-0.52-0.43-0.6-0.68s-0.32-1.09-0.23-1.35l0.12-0.35c0.09-0.26,0-0.63-0.2-0.83
|
||||||
|
L12.6,2.7c-0.19-0.19-0.57-0.28-0.83-0.2l-0.35,0.12c-0.26,0.09-0.67,0.06-0.91-0.05s-1-0.54-1.12-0.79L9.22,1.45
|
||||||
|
C9.1,1.2,8.77,1,8.5,1h-1C7.22,1,6.9,1.2,6.78,1.45L6.61,1.78C6.49,2.02,6.18,2.3,5.93,2.38S4.84,2.7,4.58,2.62L4.23,2.5
|
||||||
|
C3.97,2.41,3.6,2.5,3.4,2.7L2.7,3.4C2.5,3.6,2.41,3.97,2.5,4.23l0.12,0.35C2.7,4.84,2.68,5.25,2.57,5.49s-0.54,1-0.79,1.12
|
||||||
|
L1.45,6.78C1.2,6.9,1,7.22,1,7.5v1c0,0.27,0.2,0.6,0.45,0.72l0.33,0.17c0.25,0.12,0.52,0.43,0.6,0.68s0.32,1.09,0.23,1.35
|
||||||
|
L2.5,11.77c-0.09,0.26,0,0.63,0.2,0.83L3.4,13.3c0.19,0.19,0.57,0.28,0.83,0.2l0.35-0.12c0.26-0.09,0.67-0.06,0.91,0.05
|
||||||
|
s1,0.54,1.12,0.79l0.17,0.33C6.9,14.8,7.22,15,7.5,15h1c0.27,0,0.6-0.2,0.72-0.45l0.17-0.33c0.12-0.25,0.43-0.52,0.68-0.6
|
||||||
|
s1.09-0.32,1.35-0.23l0.35,0.12c0.26,0.09,0.63,0,0.83-0.2l0.71-0.71c0.19-0.19,0.28-0.57,0.2-0.83l-0.12-0.35
|
||||||
|
c-0.09-0.26-0.06-0.67,0.05-0.91s0.54-1,0.79-1.12l0.33-0.17C14.8,9.1,15,8.77,15,8.5v-1c0-0.28-0.2-0.6-0.45-0.72L14.22,6.61z
|
||||||
|
M8,13c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S10.76,13,8,13z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,12c-0.55,0-1-0.45-1-1V5c0-0.55,0.45-1,1-1s1,0.45,1,1v6C9,11.55,8.55,12,8,12z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,9H5C4.45,9,4,8.55,4,8s0.45-1,1-1h6c0.55,0,1,0.45,1,1S11.55,9,11,9z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
62
resources/icons/import_config_bundle.svg
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="import_x5F_config_x5F_bundle">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M1.2,12.61c0.11,0.08,0.21,0.22,0.23,0.31c0.02,0.09,0.04,0.43-0.03,0.55s-0.05,0.31,0.03,0.42l0.12,0.17
|
||||||
|
c0.08,0.11,0.25,0.19,0.39,0.17c0.13-0.02,0.3,0.01,0.38,0.06s0.33,0.28,0.37,0.41c0.04,0.13,0.18,0.25,0.32,0.27l0.21,0.04
|
||||||
|
c0.14,0.02,0.31-0.05,0.39-0.16s0.22-0.21,0.31-0.23c0.09-0.02,0.43-0.04,0.55,0.03c0.12,0.06,0.31,0.05,0.42-0.03l0.17-0.12
|
||||||
|
c0.11-0.08,0.19-0.25,0.17-0.39c-0.02-0.13,0.01-0.3,0.06-0.38s0.28-0.33,0.41-0.37c0.13-0.04,0.25-0.18,0.27-0.32l0.04-0.21
|
||||||
|
c0.02-0.14-0.05-0.31-0.16-0.39c-0.11-0.08-0.21-0.22-0.23-0.31c-0.02-0.09-0.04-0.43,0.03-0.55c0.06-0.12,0.05-0.31-0.03-0.42
|
||||||
|
L5.5,10.98c-0.08-0.11-0.25-0.19-0.39-0.17c-0.13,0.02-0.3-0.01-0.38-0.06c-0.08-0.05-0.33-0.28-0.37-0.41
|
||||||
|
c-0.04-0.13-0.18-0.25-0.32-0.27l-0.21-0.04c-0.14-0.02-0.31,0.05-0.39,0.16s-0.22,0.21-0.31,0.23S2.7,10.46,2.58,10.4
|
||||||
|
c-0.12-0.06-0.31-0.05-0.42,0.03l-0.17,0.12c-0.11,0.08-0.19,0.25-0.17,0.39s-0.01,0.3-0.06,0.38c-0.05,0.08-0.28,0.33-0.41,0.37
|
||||||
|
c-0.13,0.04-0.25,0.18-0.27,0.32l-0.04,0.21C1.02,12.36,1.09,12.53,1.2,12.61z M3.71,11.42c0.61,0.1,1.02,0.68,0.92,1.28
|
||||||
|
c-0.1,0.61-0.68,1.02-1.28,0.92c-0.61-0.1-1.02-0.68-0.92-1.28C2.53,11.73,3.1,11.32,3.71,11.42z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M10.39,4.47c0.13,0.03,0.28,0.13,0.33,0.21c0.05,0.08,0.19,0.38,0.18,0.52s0.07,0.3,0.19,0.38l0.18,0.11
|
||||||
|
c0.12,0.07,0.31,0.08,0.42,0.01c0.12-0.07,0.28-0.11,0.38-0.09c0.09,0.02,0.41,0.13,0.5,0.24c0.09,0.1,0.26,0.17,0.4,0.13
|
||||||
|
l0.21-0.05c0.13-0.03,0.27-0.16,0.3-0.29c0.03-0.13,0.13-0.28,0.21-0.33c0.08-0.05,0.38-0.19,0.52-0.18
|
||||||
|
c0.13,0.01,0.3-0.07,0.38-0.19l0.11-0.18c0.07-0.12,0.08-0.31,0.01-0.42c-0.07-0.12-0.11-0.28-0.09-0.38
|
||||||
|
c0.02-0.09,0.13-0.41,0.24-0.5c0.1-0.09,0.17-0.26,0.13-0.4l-0.05-0.21c-0.03-0.13-0.16-0.27-0.29-0.3
|
||||||
|
c-0.13-0.03-0.28-0.13-0.33-0.21s-0.19-0.38-0.18-0.52c0.01-0.13-0.07-0.3-0.19-0.38l-0.18-0.11c-0.12-0.07-0.31-0.08-0.42-0.01
|
||||||
|
c-0.12,0.07-0.28,0.11-0.38,0.09c-0.09-0.02-0.41-0.13-0.5-0.24c-0.09-0.1-0.26-0.17-0.4-0.13L11.87,1.1
|
||||||
|
c-0.13,0.03-0.27,0.16-0.3,0.29s-0.13,0.28-0.21,0.33s-0.38,0.19-0.52,0.18s-0.3,0.07-0.38,0.19l-0.11,0.18
|
||||||
|
c-0.07,0.12-0.08,0.31-0.01,0.42c0.07,0.12,0.11,0.28,0.09,0.38s-0.13,0.41-0.24,0.5c-0.1,0.09-0.17,0.26-0.13,0.4l0.05,0.21
|
||||||
|
C10.13,4.3,10.26,4.44,10.39,4.47z M12.27,2.43c0.6-0.13,1.2,0.24,1.33,0.84c0.13,0.6-0.24,1.2-0.84,1.33
|
||||||
|
c-0.6,0.13-1.2-0.24-1.33-0.84C11.3,3.16,11.67,2.56,12.27,2.43z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M1.85,4.19C1.8,4.32,1.66,4.47,1.53,4.53L1.15,4.71C1.02,4.77,0.92,4.93,0.91,5.06L0.89,5.92
|
||||||
|
c0,0.14,0.09,0.3,0.21,0.37l0.37,0.2C1.6,6.55,1.73,6.71,1.77,6.84l0.17,0.44C2,7.41,2,7.62,1.96,7.75l-0.15,0.4
|
||||||
|
C1.76,8.28,1.8,8.47,1.89,8.57l0.58,0.62c0.09,0.1,0.28,0.15,0.41,0.11L3.3,9.17c0.13-0.04,0.34-0.02,0.46,0.04l0.43,0.2
|
||||||
|
c0.13,0.05,0.28,0.19,0.34,0.32l0.18,0.39c0.06,0.12,0.22,0.23,0.35,0.23l0.85,0.03c0.14,0,0.3-0.09,0.37-0.21l0.2-0.37
|
||||||
|
c0.07-0.12,0.23-0.25,0.36-0.29l0.44-0.17c0.13-0.06,0.33-0.06,0.46-0.02l0.4,0.15C8.28,9.5,8.47,9.47,8.57,9.37l0.62-0.58
|
||||||
|
c0.1-0.09,0.15-0.28,0.11-0.41L9.17,7.97C9.13,7.84,9.16,7.63,9.22,7.51l0.2-0.43c0.05-0.13,0.19-0.28,0.32-0.34l0.39-0.18
|
||||||
|
c0.12-0.06,0.23-0.22,0.23-0.35l0.03-0.85c0-0.14-0.09-0.3-0.21-0.37l-0.37-0.2C9.67,4.71,9.54,4.55,9.49,4.42L9.33,3.98
|
||||||
|
C9.27,3.85,9.26,3.64,9.31,3.52l0.15-0.4C9.5,2.99,9.47,2.8,9.37,2.7L8.79,2.08c-0.09-0.1-0.28-0.15-0.41-0.11L7.97,2.09
|
||||||
|
C7.84,2.13,7.63,2.11,7.51,2.05l-0.43-0.2C6.94,1.8,6.79,1.66,6.73,1.53L6.56,1.15C6.5,1.02,6.34,0.92,6.2,0.91L5.35,0.89
|
||||||
|
c-0.14,0-0.3,0.09-0.37,0.21l-0.2,0.37C4.71,1.6,4.55,1.73,4.42,1.77L3.98,1.94C3.85,2,3.64,2,3.52,1.96l-0.4-0.15
|
||||||
|
C2.99,1.76,2.8,1.8,2.7,1.89L2.08,2.48c-0.1,0.09-0.15,0.28-0.11,0.41L2.09,3.3c0.04,0.13,0.02,0.34-0.04,0.46L1.85,4.19z
|
||||||
|
M6.75,3.15c1.37,0.62,1.98,2.23,1.36,3.6s-2.23,1.98-3.6,1.36C3.15,7.5,2.54,5.89,3.15,4.52S5.38,2.54,6.75,3.15z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,15c-0.55,0-1-0.45-1-1V8c0-0.55,0.45-1,1-1s1,0.45,1,1v6C12,14.55,11.55,15,11,15z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14,12H8c-0.55,0-1-0.45-1-1s0.45-1,1-1h6c0.55,0,1,0.45,1,1S14.55,12,14,12z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
17
resources/icons/import_plater.svg
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="import_x5F_plater">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M13,2c0.55,0,1,0.45,1,1V13c0,0.55-0.45,1-1,1H3c-0.55,0-1-0.45-1-1V3c0-0.55,0.45-1,1-1H13 M13,1H3
|
||||||
|
c-1.1,0-2,0.89-2,2V13c0,1.1,0.89,2,2,2H13c1.1,0,2-0.89,2-2V3C15,1.89,14.11,1,13,1L13,1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,12c-0.55,0-1-0.45-1-1V5c0-0.55,0.45-1,1-1s1,0.45,1,1v6C9,11.55,8.55,12,8,12z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,9H5C4.45,9,4,8.55,4,8s0.45-1,1-1h6c0.55,0,1,0.45,1,1S11.55,9,11,9z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 836 B |
|
@ -5,13 +5,13 @@
|
||||||
<g id="layers">
|
<g id="layers">
|
||||||
<g>
|
<g>
|
||||||
<g>
|
<g>
|
||||||
<rect x="1" y="13" fill="#FFFFFF" width="14" height="2"/>
|
<rect x="1" y="13" fill="#808080" width="14" height="2"/>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<rect x="1" y="10.6" fill="#FFFFFF" width="14" height="1.74"/>
|
<rect x="1" y="10.6" fill="#808080" width="14" height="1.74"/>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<rect x="1" y="8.19" fill="#FFFFFF" width="14" height="1.47"/>
|
<rect x="1" y="8.19" fill="#808080" width="14" height="1.47"/>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<rect x="1" y="5.79" fill="#ED6B21" width="14" height="1.2"/>
|
<rect x="1" y="5.79" fill="#ED6B21" width="14" height="1.2"/>
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<rect x="1" y="3.39" fill="#ED6B21" width="14" height="0.93"/>
|
<rect x="1" y="3.39" fill="#ED6B21" width="14" height="0.93"/>
|
||||||
</g>
|
</g>
|
||||||
<g>
|
<g>
|
||||||
<rect x="1" y="0.99" fill="#FFFFFF" width="14" height="0.67"/>
|
<rect x="1" y="0.99" fill="#808080" width="14" height="0.67"/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|
Before Width: | Height: | Size: 845 B After Width: | Height: | Size: 845 B |
9
resources/icons/mark_X.svg
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="X">
|
||||||
|
<path fill="#FF0000" d="M8,1C4.13,1,1,4.13,1,8c0,3.87,3.13,7,7,7s7-3.13,7-7C15,4.13,11.87,1,8,1z M9.26,12l-0.62-1.33L8,8.93
|
||||||
|
l-0.68,1.83L6.74,12H5.19l1.85-4.04L5.34,4H6.9l0.53,1.3L8,7l0.56-1.67L9.1,4h1.56l-1.7,3.96L10.81,12H9.26z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 596 B |
9
resources/icons/mark_Y.svg
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="Y">
|
||||||
|
<path fill="#00FF00" d="M8,1C4.13,1,1,4.13,1,8c0,3.87,3.13,7,7,7s7-3.13,7-7C15,4.13,11.87,1,8,1z M8.72,8.65V12H7.3V8.65L5.27,4
|
||||||
|
h1.55l0.62,1.47l0.58,1.71L8.6,5.43L9.19,4h1.55L8.72,8.65z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 552 B |
9
resources/icons/mark_Z.svg
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="Y_1_">
|
||||||
|
<path fill="#0000FF" d="M8,1C4.13,1,1,4.13,1,8c0,3.87,3.13,7,7,7s7-3.13,7-7C15,4.13,11.87,1,8,1z M10.42,10.73v1.27H5.41
|
||||||
|
l3.12-6.71H5.84V4.01h4.75l-3.07,6.72H10.42z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 534 B |
28
resources/icons/number_of_copies.svg
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="number_x5F_of_x5F_copies">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M13,2c0.55,0,1,0.45,1,1V13c0,0.55-0.45,1-1,1H3c-0.55,0-1-0.45-1-1V3c0-0.55,0.45-1,1-1H13 M13,1H3
|
||||||
|
c-1.1,0-2,0.89-2,2V13c0,1.1,0.89,2,2,2H13c1.1,0,2-0.89,2-2V3C15,1.89,14.11,1,13,1L13,1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M6,4.5H4C3.72,4.5,3.5,4.28,3.5,4S3.72,3.5,4,3.5h2c0.28,0,0.5,0.22,0.5,0.5S6.28,4.5,6,4.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M12,8.5H8C7.72,8.5,7.5,8.28,7.5,8S7.72,7.5,8,7.5h4c0.28,0,0.5,0.22,0.5,0.5S12.28,8.5,12,8.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M6,12.5H4c-0.28,0-0.5-0.22-0.5-0.5s0.22-0.5,0.5-0.5h2c0.28,0,0.5,0.22,0.5,0.5S6.28,12.5,6,12.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M5,12.5c-0.28,0-0.5-0.22-0.5-0.5V4c0-0.28,0.22-0.5,0.5-0.5S5.5,3.72,5.5,4v8C5.5,12.28,5.28,12.5,5,12.5
|
||||||
|
z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M10,10.5c-0.28,0-0.5-0.22-0.5-0.5V6c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v4
|
||||||
|
C10.5,10.28,10.28,10.5,10,10.5z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
11
resources/icons/open.svg
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="open">
|
||||||
|
<path fill="#808080" d="M1.22,14V3c0,0,0-1,1-1s4,0,5,0s1,2,2,2s4,0,4,0s1,0,1,1v2h-1c0,0,0,0,0-1s-1-1-1-1h-3.5c-1,0-1-2-2-2
|
||||||
|
s-3.5,0-3.5,0c-1,0-1,1-1,1v9v1h1v1c0,0,0,0-1,0S1.22,14,1.22,14z"/>
|
||||||
|
<path fill="#ED6B21" d="M5,6C4.45,6,3.86,6.43,3.68,6.95l-2.37,7.1C1.14,14.57,1.45,15,2,15h10c0.55,0,1.14-0.43,1.32-0.95
|
||||||
|
l2.37-7.1C15.86,6.43,15.55,6,15,6L5,6z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 722 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.8 KiB |
83
resources/icons/pad.svg
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="pad">
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14,14H2c-0.55,0-1-0.45-1-1s0.45-1,1-1h12c0.55,0,1,0.45,1,1S14.55,14,14,14z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M8,8.17c-0.4,0-0.8-0.1-1.11-0.31L2.55,4.97C1.95,4.57,1.5,3.72,1.5,3V2c0-0.28,0.22-0.5,0.5-0.5
|
||||||
|
S2.5,1.72,2.5,2v1c0,0.38,0.29,0.93,0.61,1.14l4.34,2.89c0.29,0.19,0.82,0.19,1.11,0l4.34-2.89C13.21,3.93,13.5,3.38,13.5,3V2
|
||||||
|
c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v1c0,0.72-0.45,1.57-1.05,1.97L9.11,7.86C8.8,8.07,8.4,8.17,8,8.17z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M13,11.38c-0.21,0-0.38-0.17-0.38-0.38V7c0-0.21,0.17-0.38,0.38-0.38S13.38,6.79,13.38,7v4
|
||||||
|
C13.38,11.21,13.21,11.38,13,11.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M12,7.49"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M12,11"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M11,11.38c-0.21,0-0.38-0.17-0.38-0.38V8.12c0-0.21,0.17-0.38,0.38-0.38s0.38,0.17,0.38,0.38V11
|
||||||
|
C11.38,11.21,11.21,11.38,11,11.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M10,8.79"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M10,11"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M9,11.38c-0.21,0-0.38-0.17-0.38-0.38V9.5c0-0.21,0.17-0.38,0.38-0.38S9.38,9.29,9.38,9.5V11
|
||||||
|
C9.38,11.21,9.21,11.38,9,11.38z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M3,11.38c-0.21,0-0.38-0.17-0.38-0.38V7c0-0.21,0.17-0.38,0.38-0.38S3.37,6.79,3.37,7v4
|
||||||
|
C3.37,11.21,3.2,11.38,3,11.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M4,7.49"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M4,11"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M5,11.38c-0.21,0-0.38-0.17-0.38-0.38V8.12c0-0.21,0.17-0.38,0.38-0.38s0.38,0.17,0.38,0.38V11
|
||||||
|
C5.37,11.21,5.2,11.38,5,11.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M6,8.79"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
|
||||||
|
<path fill="none" stroke="#808080" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
|
||||||
|
M6,11"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M7,11.38c-0.21,0-0.38-0.17-0.38-0.38V9.5c0-0.21,0.17-0.38,0.38-0.38S7.37,9.29,7.37,9.5V11
|
||||||
|
C7.37,11.21,7.2,11.38,7,11.38z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
27
resources/icons/paste.svg
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<g id="paste">
|
||||||
|
<path fill="#FFFFFF" d="M33.73,107.03H15.94c-1.4,0-2.54-1.14-2.54-2.54V23.52c0-1.4,1.14-2.54,2.54-2.54h7.62v5.08
|
||||||
|
c0,1.4,1.14,2.54,2.54,2.54h45.72c1.4,0,2.54-1.14,2.54-2.54v-5.08h7.62c1.4,0,2.54,1.14,2.54,2.54v10.16
|
||||||
|
c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54V23.52c0-4.2-3.42-7.62-7.62-7.62h-7.62v-5.08c0-1.4-1.14-2.54-2.54-2.54
|
||||||
|
H26.11c-1.4,0-2.54,1.14-2.54,2.54v5.08h-7.62c-4.2,0-7.62,3.42-7.62,7.62v80.97c0,4.2,3.42,7.62,7.62,7.62h17.78
|
||||||
|
c1.4,0,2.54-1.14,2.54-2.54C36.27,108.16,35.13,107.03,33.73,107.03z M28.65,13.36h40.64v10.16H28.65V13.36z"/>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M53.97,59.08h35.72c1.4,0,2.54-1.14,2.54-2.54c0-1.4-1.14-2.54-2.54-2.54H53.97
|
||||||
|
c-1.4,0-2.54,1.14-2.54,2.54C51.43,57.94,52.56,59.08,53.97,59.08z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,69.24H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96
|
||||||
|
c1.4,0,2.54-1.14,2.54-2.54C107.47,70.38,106.33,69.24,104.93,69.24z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,99.72H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,99.72,104.93,99.72z"/>
|
||||||
|
<path fill="#ED6B21" d="M115.75,51.15l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04
|
||||||
|
c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.12,118.23,53.62,115.75,51.15z M104.85,47.43
|
||||||
|
l6.57,6.57h-6.57V47.43z M115.01,112.42c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.38
|
||||||
|
c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54
|
||||||
|
V112.42z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,84.48H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96
|
||||||
|
c1.4,0,2.54-1.14,2.54-2.54C107.47,85.62,106.33,84.48,104.93,84.48z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
27
resources/icons/paste_menu.svg
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<g id="paste">
|
||||||
|
<path fill="#808080" d="M33.73,107.03H15.94c-1.4,0-2.54-1.14-2.54-2.54V23.52c0-1.4,1.14-2.54,2.54-2.54h7.62v5.08
|
||||||
|
c0,1.4,1.14,2.54,2.54,2.54h45.72c1.4,0,2.54-1.14,2.54-2.54v-5.08h7.62c1.4,0,2.54,1.14,2.54,2.54v10.16
|
||||||
|
c0,1.4,1.14,2.54,2.54,2.54c1.4,0,2.54-1.14,2.54-2.54V23.52c0-4.2-3.42-7.62-7.62-7.62h-7.62v-5.08c0-1.4-1.14-2.54-2.54-2.54
|
||||||
|
H26.11c-1.4,0-2.54,1.14-2.54,2.54v5.08h-7.62c-4.2,0-7.62,3.42-7.62,7.62v80.97c0,4.2,3.42,7.62,7.62,7.62h17.78
|
||||||
|
c1.4,0,2.54-1.14,2.54-2.54C36.27,108.16,35.13,107.03,33.73,107.03z M28.65,13.36h40.64v10.16H28.65V13.36z"/>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M53.97,59.08h35.72c1.4,0,2.54-1.14,2.54-2.54c0-1.4-1.14-2.54-2.54-2.54H53.97
|
||||||
|
c-1.4,0-2.54,1.14-2.54,2.54C51.43,57.94,52.56,59.08,53.97,59.08z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,69.24H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96
|
||||||
|
c1.4,0,2.54-1.14,2.54-2.54C107.47,70.38,106.33,69.24,104.93,69.24z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,99.72H53.97c-1.4,0-2.54,1.14-2.54,2.54s1.14,2.54,2.54,2.54h50.96c1.4,0,2.54-1.14,2.54-2.54
|
||||||
|
S106.33,99.72,104.93,99.72z"/>
|
||||||
|
<path fill="#ED6B21" d="M115.75,51.15l-8.06-8.06c-2.47-2.47-6.97-4.34-10.47-4.34h-50.8c-4.2,0-7.62,3.42-7.62,7.62v66.04
|
||||||
|
c0,4.2,3.42,7.62,7.62,7.62h66.04c4.2,0,7.62-3.42,7.62-7.62v-50.8C120.09,58.12,118.23,53.62,115.75,51.15z M104.85,47.43
|
||||||
|
l6.57,6.57h-6.57V47.43z M115.01,112.42c0,1.4-1.14,2.54-2.54,2.54H46.43c-1.4,0-2.54-1.14-2.54-2.54V46.38
|
||||||
|
c0-1.4,1.14-2.54,2.54-2.54h50.8c0.74,0,1.63,0.18,2.54,0.46v12.24c0,1.4,1.14,2.54,2.54,2.54h12.24c0.28,0.91,0.46,1.8,0.46,2.54
|
||||||
|
V112.42z"/>
|
||||||
|
<path fill="#ED6B21" d="M104.93,84.48H53.97c-1.4,0-2.54,1.14-2.54,2.54c0,1.4,1.14,2.54,2.54,2.54h50.96
|
||||||
|
c1.4,0,2.54-1.14,2.54-2.54C107.47,85.62,106.33,84.48,104.93,84.48z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
12
resources/icons/plater.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="plater">
|
||||||
|
<path fill="#808080" d="M13,2c0.55,0,1,0.45,1,1V13c0,0.55-0.45,1-1,1H3c-0.55,0-1-0.45-1-1V3c0-0.55,0.45-1,1-1H13 M13,1H3
|
||||||
|
c-1.1,0-2,0.89-2,2V13c0,1.1,0.89,2,2,2H13c1.1,0,2-0.89,2-2V3C15,1.89,14.11,1,13,1L13,1z"/>
|
||||||
|
<path fill="#ED6B21" d="M8.42,3.28c-0.23-0.15-0.6-0.15-0.83,0l-3.46,2.3C3.9,5.73,3.71,6.08,3.71,6.36v1.85c0,0.28,0,0.54,0,0.58
|
||||||
|
s0,0.31,0,0.58v0.27c0,0.27,0.19,0.62,0.42,0.78l3.46,2.3c0.23,0.15,0.6,0.15,0.83,0l3.46-2.3c0.23-0.15,0.42-0.5,0.42-0.78V9.38
|
||||||
|
c0-0.28,0-0.54,0-0.58s0-0.31,0-0.58V6.36c0-0.28-0.19-0.62-0.42-0.78L8.42,3.28z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 920 B |
48
resources/icons/preview_menu.svg
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<g id="preview">
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M90.72,121.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.15
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02c0.58,0.59,0.57,1.54-0.02,2.12l-29.16,28.57C91.49,121.23,91.11,121.38,90.72,121.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M90.72,111.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.14
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02c0.58,0.59,0.57,1.54-0.02,2.12l-29.16,28.57C91.49,111.23,91.11,111.38,90.72,111.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M90.72,101.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.14
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02s0.57,1.54-0.02,2.12l-29.16,28.57C91.49,101.23,91.11,101.38,90.72,101.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M90.72,91.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.15
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02s0.57,1.54-0.02,2.12L91.77,90.95C91.49,91.23,91.11,91.38,90.72,91.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M90.72,81.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.15
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02c0.58,0.59,0.57,1.54-0.02,2.12L91.77,80.95C91.49,81.23,91.11,81.38,90.72,81.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M90.72,71.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.15
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02c0.58,0.59,0.57,1.54-0.02,2.12L91.77,70.95C91.49,71.23,91.11,71.38,90.72,71.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M90.72,61.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.15
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02c0.58,0.59,0.57,1.54-0.02,2.12L91.77,60.95C91.49,61.23,91.11,61.38,90.72,61.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M90.72,51.38H8.12c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5h81.99l28.72-28.15
|
||||||
|
c0.59-0.58,1.54-0.57,2.12,0.02s0.57,1.54-0.02,2.12L91.77,50.95C91.49,51.23,91.11,51.38,90.72,51.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#101010" d="M88.72,41.38H9.18c-1.68,0-2.22-0.95-2.37-1.36s-0.37-1.48,0.89-2.59L38.43,10.5
|
||||||
|
c1.1-0.96,3.03-1.69,4.49-1.69h75.85c1.65,0,2.22,0.94,2.38,1.34s0.42,1.47-0.75,2.63c0,0,0,0,0,0L93.2,39.55
|
||||||
|
C92.14,40.59,90.21,41.38,88.72,41.38z M11.17,38.38h77.55c0.71,0,1.87-0.47,2.37-0.97l26.01-25.6H42.92
|
||||||
|
c-0.74,0-1.96,0.46-2.51,0.95L11.17,38.38z M118.89,11.82C118.89,11.82,118.89,11.82,118.89,11.82
|
||||||
|
C118.89,11.82,118.89,11.82,118.89,11.82z M119.34,11.71L119.34,11.71L119.34,11.71z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
14
resources/icons/printer_white.svg
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="printer">
|
||||||
|
<rect x="1" y="1" fill="#FFFFFF" width="1" height="14"/>
|
||||||
|
<rect x="14" y="1" fill="#FFFFFF" width="1" height="14"/>
|
||||||
|
<rect x="1" y="5" fill="#FFFFFF" width="14" height="1"/>
|
||||||
|
<rect x="1" y="1" fill="#FFFFFF" width="14" height="1"/>
|
||||||
|
<rect x="1" y="13" fill="#FFFFFF" width="14" height="2"/>
|
||||||
|
<rect x="3" y="4" fill="#ED6B21" width="4" height="4"/>
|
||||||
|
<polygon fill="#ED6B21" points="5,9 4,8 6,8 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 766 B |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 62 KiB |
19
resources/icons/re_slice.svg
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="slice">
|
||||||
|
<path fill="#808080" d="M14.22,6.61c-0.25-0.12-0.52-0.43-0.6-0.68s-0.32-1.09-0.23-1.35l0.12-0.35c0.09-0.26,0-0.63-0.2-0.83
|
||||||
|
L12.6,2.7c-0.19-0.19-0.57-0.28-0.83-0.2l-0.35,0.12c-0.26,0.09-0.67,0.06-0.91-0.05s-1-0.54-1.12-0.79L9.22,1.45
|
||||||
|
C9.1,1.2,8.77,1,8.5,1h-1C7.22,1,6.9,1.2,6.78,1.45L6.61,1.78C6.49,2.02,6.18,2.3,5.93,2.38S4.84,2.7,4.58,2.62L4.23,2.5
|
||||||
|
C3.97,2.41,3.6,2.5,3.4,2.7L2.7,3.4C2.5,3.6,2.41,3.97,2.5,4.23l0.12,0.35C2.7,4.84,2.68,5.25,2.57,5.49s-0.54,1-0.79,1.12
|
||||||
|
L1.45,6.78C1.2,6.9,1,7.22,1,7.5v1c0,0.27,0.2,0.6,0.45,0.72l0.33,0.17c0.25,0.12,0.52,0.43,0.6,0.68s0.32,1.09,0.23,1.35
|
||||||
|
L2.5,11.77c-0.09,0.26,0,0.63,0.2,0.83l0.7,0.7c0.19,0.19,0.57,0.28,0.83,0.2l0.35-0.12c0.26-0.09,0.67-0.06,0.91,0.05
|
||||||
|
s1,0.54,1.12,0.79l0.17,0.33C6.9,14.8,7.22,15,7.5,15h1c0.27,0,0.6-0.2,0.72-0.45l0.17-0.33c0.12-0.25,0.43-0.52,0.68-0.6
|
||||||
|
s1.09-0.32,1.35-0.23l0.35,0.12c0.26,0.09,0.63,0,0.83-0.2l0.71-0.71c0.19-0.19,0.28-0.57,0.2-0.83l-0.12-0.35
|
||||||
|
c-0.09-0.26-0.06-0.67,0.05-0.91s0.54-1,0.79-1.12l0.33-0.17C14.8,9.1,15,8.77,15,8.5v-1c0-0.28-0.2-0.6-0.45-0.72L14.22,6.61z
|
||||||
|
M8,13c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S10.76,13,8,13z"/>
|
||||||
|
<path fill="#ED6B21" d="M6.86,5.51C6.39,5.23,6,5.45,6,6v4c0,0.55,0.39,0.77,0.86,0.49l3.29-1.97c0.47-0.28,0.47-0.75,0-1.03
|
||||||
|
L6.86,5.51z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
15
resources/icons/remove_copies.svg
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="remove_x5F_copies">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M8,2c3.31,0,6,2.69,6,6s-2.69,6-6,6s-6-2.69-6-6S4.69,2,8,2 M8,1C4.13,1,1,4.13,1,8s3.13,7,7,7s7-3.13,7-7
|
||||||
|
S11.87,1,8,1L8,1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M12,8.75H4C3.59,8.75,3.25,8.41,3.25,8S3.59,7.25,4,7.25h8c0.41,0,0.75,0.34,0.75,0.75S12.41,8.75,12,8.75
|
||||||
|
z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 689 B |
44
resources/icons/remove_menu.svg
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
|
||||||
|
<path fill="#808080" d="M38.11,44.25H25.75c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72H38.1c0.95,0,1.72-0.77,1.72-1.72
|
||||||
|
C39.83,45.02,39.06,44.25,38.11,44.25z M45.89,45.97c0,0.95,0.77,1.72,1.72,1.72h12.35c0.95,0,1.72-0.77,1.72-1.72
|
||||||
|
s-0.77-1.72-1.72-1.72H47.61C46.66,44.25,45.89,45.02,45.89,45.97z M68.11,43.6c-0.33,0.28-0.52,0.65-0.59,1.04
|
||||||
|
c-0.59,0.27-1,0.87-1,1.56v5.6c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72v-5.34c0.12-0.06,0.24-0.13,0.35-0.22
|
||||||
|
c0.13-0.11,0.25-0.23,0.36-0.34l8.27-8.77c0.65-0.69,0.62-1.78-0.07-2.43s-1.78-0.62-2.43,0.07l-8.27,8.78
|
||||||
|
C68.16,43.56,68.14,43.58,68.11,43.6z M68.25,76.84c-0.95,0-1.72,0.77-1.72,1.72V89.1c0,0.95,0.77,1.72,1.72,1.72
|
||||||
|
c0.95,0,1.72-0.77,1.72-1.72V78.56C69.97,77.61,69.2,76.84,68.25,76.84z M69.97,59.91c0-0.95-0.77-1.72-1.72-1.72
|
||||||
|
c-0.95,0-1.72,0.77-1.72,1.72v10.54c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72V59.91z M88.92,56.35
|
||||||
|
c-0.95,0-1.72,0.77-1.72,1.72v3.4c0,0.34-0.02,0.63-0.04,0.85c-0.51,0.55-0.62,1.38-0.22,2.06c0.32,0.54,0.89,0.84,1.48,0.84
|
||||||
|
c0.3,0,0.6-0.08,0.88-0.24l0.25-0.15c0.67-0.4,1.09-1.1,1.09-3.35v-3.4C90.64,57.12,89.87,56.35,88.92,56.35z M41.81,26.17h11.3
|
||||||
|
c0.95,0,1.72-0.77,1.72-1.72s-0.77-1.72-1.72-1.72h-11.3c-0.95,0-1.72,0.77-1.72,1.72S40.86,26.17,41.81,26.17z M87.2,22.73h-5.39
|
||||||
|
c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72h2.75l-1.58,1.68c-0.65,0.69-0.62,1.78,0.07,2.43c0.33,0.31,0.76,0.47,1.18,0.47
|
||||||
|
c0.46,0,0.91-0.18,1.25-0.54l1.72-1.82v0.99c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72v-3.21
|
||||||
|
C90.64,24.27,89.09,22.73,87.2,22.73z M61.81,26.17h11.3c0.95,0,1.72-0.77,1.72-1.72s-0.77-1.72-1.72-1.72h-11.3
|
||||||
|
c-0.95,0-1.72,0.77-1.72,1.72S60.86,26.17,61.81,26.17z M9.71,67.54c0.95,0,1.72-0.77,1.72-1.72v-11.3c0-0.95-0.77-1.72-1.72-1.72
|
||||||
|
s-1.72,0.77-1.72,1.72v11.3C7.99,66.77,8.76,67.54,9.71,67.54z M24.65,33.86c0.42,0,0.84-0.15,1.17-0.46l7.04-6.52
|
||||||
|
c0.14-0.13,0.46-0.34,0.9-0.51c0.89-0.34,1.34-1.33,1-2.22s-1.33-1.34-2.22-1c-0.8,0.3-1.52,0.73-2.03,1.2l-7.04,6.52
|
||||||
|
c-0.7,0.65-0.74,1.74-0.09,2.43C23.73,33.68,24.19,33.86,24.65,33.86z M70.35,99.28l-0.37,0.36v-2.43c0-0.95-0.77-1.72-1.72-1.72
|
||||||
|
c-0.95,0-1.72,0.77-1.72,1.72v4.72H61.3c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72h5.23c1.4,0,3.15-0.7,4.16-1.66l2.03-1.94
|
||||||
|
c0.69-0.66,0.71-1.75,0.06-2.43C72.13,98.65,71.03,98.63,70.35,99.28z M52.6,101.93H41.3c-0.95,0-1.72,0.77-1.72,1.72
|
||||||
|
s0.77,1.72,1.72,1.72h11.3c0.95,0,1.72-0.77,1.72-1.72S53.55,101.93,52.6,101.93z M88.92,36.35c-0.95,0-1.72,0.77-1.72,1.72v11.3
|
||||||
|
c0,0.95,0.77,1.72,1.72,1.72c0.95,0,1.72-0.77,1.72-1.72v-11.3C90.64,37.12,89.87,36.35,88.92,36.35z M32.61,101.93H21.3
|
||||||
|
c-0.95,0-1.72,0.77-1.72,1.72s0.77,1.72,1.72,1.72h11.3c0.95,0,1.72-0.77,1.72-1.72S33.56,101.93,32.61,101.93z M9.71,87.54
|
||||||
|
c0.95,0,1.72-0.77,1.72-1.72v-11.3c0-0.95-0.77-1.72-1.72-1.72s-1.72,0.77-1.72,1.72v11.3C7.99,86.77,8.76,87.54,9.71,87.54z
|
||||||
|
M12.61,101.93h-1.18v-7.42c0-0.95-0.77-1.72-1.72-1.72s-1.72,0.77-1.72,1.72v7.42c0,1.9,1.54,3.44,3.44,3.44h1.18
|
||||||
|
c0.95,0,1.72-0.77,1.72-1.72S13.56,101.93,12.61,101.93z M19.53,36.88c-0.65-0.7-1.74-0.74-2.43-0.09l-7.3,6.76
|
||||||
|
c-0.55,0.51-0.93,1.15-1.16,1.6C8.22,46,8.56,47.03,9.41,47.46c0.25,0.12,0.51,0.18,0.77,0.18h0.01c0.14,0.04,0.29,0.07,0.45,0.07
|
||||||
|
h5.6c0.95,0,1.72-0.77,1.72-1.72s-0.77-1.72-1.72-1.72h-2.13l5.33-4.94C20.14,38.66,20.18,37.57,19.53,36.88z M80.7,89.4l-4.05,3.86
|
||||||
|
c-0.69,0.66-0.71,1.75-0.06,2.43c0.34,0.35,0.79,0.53,1.25,0.53c0.43,0,0.86-0.16,1.19-0.48l4.05-3.86
|
||||||
|
c0.69-0.66,0.71-1.75,0.06-2.43C82.48,88.77,81.39,88.75,80.7,89.4z"/>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M98.82,101.06c-11.63,0-21.09-9.46-21.09-21.09s9.46-21.09,21.09-21.09s21.09,9.46,21.09,21.09
|
||||||
|
S110.45,101.06,98.82,101.06z M98.82,62.32c-9.73,0-17.65,7.92-17.65,17.65s7.92,17.65,17.65,17.65s17.65-7.92,17.65-17.65
|
||||||
|
S108.55,62.32,98.82,62.32z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M110.44,81.84c0,1.1-0.9,2-2,2H89.2c-1.1,0-2-0.9-2-2v-3.75c0-1.1,0.9-2,2-2h19.25c1.1,0,2,0.9,2,2
|
||||||
|
L110.44,81.84L110.44,81.84z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
29
resources/icons/set_separate_obj.svg
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="set_x5F_separate_x5F_obj">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M6,15.49H2.04c-0.83,0-1.5-0.67-1.51-1.5l-0.02-3.96c0-0.4,0.15-0.78,0.44-1.06C1.22,8.69,1.6,8.53,2,8.53
|
||||||
|
l4,0c0.83,0,1.5,0.67,1.5,1.5v3.96C7.5,14.82,6.83,15.49,6,15.49z M6,9.53l-4,0c-0.13,0-0.26,0.05-0.35,0.15
|
||||||
|
C1.56,9.77,1.51,9.9,1.51,10.03l0.02,3.96c0,0.28,0.23,0.5,0.51,0.5H6c0.28,0,0.5-0.22,0.5-0.5v-3.96C6.5,9.75,6.28,9.53,6,9.53z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M6,7.5H2.04c-0.83,0-1.5-0.67-1.51-1.5L0.51,2.04c0-0.4,0.15-0.78,0.44-1.06C1.22,0.7,1.6,0.54,2,0.54l4,0
|
||||||
|
c0.83,0,1.5,0.67,1.5,1.5V6C7.5,6.83,6.83,7.5,6,7.5z M6,1.54l-4,0c-0.13,0-0.26,0.05-0.35,0.15C1.56,1.78,1.51,1.9,1.51,2.04
|
||||||
|
L1.53,6c0,0.28,0.23,0.5,0.51,0.5H6c0.28,0,0.5-0.22,0.5-0.5V2.04C6.5,1.76,6.28,1.54,6,1.54z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14,7.5h-3.96c-0.83,0-1.5-0.67-1.51-1.5L8.51,2.04c0-0.4,0.15-0.78,0.44-1.06C9.22,0.7,9.6,0.54,10,0.54
|
||||||
|
l4,0c0.83,0,1.5,0.67,1.5,1.5V6C15.5,6.83,14.83,7.5,14,7.5z M14,1.54l-4,0c-0.13,0-0.26,0.05-0.35,0.15
|
||||||
|
C9.56,1.78,9.5,1.9,9.51,2.04L9.53,6c0,0.27,0.23,0.5,0.51,0.5H14c0.28,0,0.5-0.22,0.5-0.5V2.04C14.5,1.76,14.28,1.54,14,1.54z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M14,15.5h-3.96c-0.83,0-1.5-0.67-1.51-1.5l-0.02-3.96c0-0.4,0.15-0.78,0.44-1.06
|
||||||
|
C9.22,8.7,9.6,8.54,10,8.54l4,0c0.83,0,1.5,0.67,1.5,1.5V14C15.5,14.83,14.83,15.5,14,15.5z M14,9.54l-4,0
|
||||||
|
c-0.13,0-0.26,0.05-0.35,0.15C9.56,9.78,9.5,9.9,9.51,10.04L9.53,14c0,0.27,0.23,0.5,0.51,0.5H14c0.28,0,0.5-0.22,0.5-0.5v-3.96
|
||||||
|
C14.5,9.76,14.28,9.54,14,9.54z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
19
resources/icons/split_object_SMALL.svg
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="split_x5F_object_x5F_small">
|
||||||
|
<path fill="#808080" d="M10.98,7.22c-0.29,0-0.52-0.23-0.52-0.52V4.61V3.57c0-0.29-0.23-0.52-0.52-0.52H2.62
|
||||||
|
c-0.29,0-0.53,0.24-0.53,0.53l-0.04,7.31c0,0.14,0.05,0.27,0.15,0.37c0.1,0.1,0.23,0.15,0.37,0.15l3.19,0v0
|
||||||
|
c0.29,0,0.52,0.23,0.52,0.52s-0.23,0.52-0.52,0.52H3.66c-0.01,0-0.01,0-0.02,0l-1.08,0c-0.42,0-0.81-0.16-1.11-0.46
|
||||||
|
C1.16,11.69,1,11.29,1,10.87l0.04-7.31C1.05,2.7,1.75,2,2.62,2h7.31c0.86,0,1.57,0.7,1.57,1.57v1.04V6.7
|
||||||
|
C11.5,6.99,11.27,7.22,10.98,7.22z"/>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M13.53,8H7.47C7.21,8,7,8.21,7,8.47v6.07C7,14.79,7.21,15,7.47,15h6.07c0.26,0,0.47-0.21,0.47-0.47V8.47
|
||||||
|
C14,8.21,13.79,8,13.53,8z M12.36,12.68c0,1.14-0.57,1.65-1.88,1.65s-1.84-0.51-1.84-1.65v-2.33c0-1.17,0.51-1.65,1.84-1.65
|
||||||
|
c1.33,0,1.88,0.48,1.88,1.65V12.68z"/>
|
||||||
|
<path fill="#ED6B21" d="M10.47,9.57c-0.72,0-0.85,0.32-0.85,0.82v2.23c0,0.52,0.14,0.82,0.85,0.82c0.72,0,0.89-0.3,0.89-0.82V10.4
|
||||||
|
C11.37,9.9,11.24,9.57,10.47,9.57z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
18
resources/icons/split_parts_SMALL.svg
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="split_x5F_parts_x5F_small">
|
||||||
|
<path fill="#808080" d="M10.98,7.22c-0.29,0-0.52-0.23-0.52-0.52V4.61V3.57c0-0.29-0.23-0.52-0.52-0.52H2.62
|
||||||
|
c-0.29,0-0.53,0.24-0.53,0.53l-0.04,7.31c0,0.14,0.05,0.27,0.15,0.37c0.1,0.1,0.23,0.15,0.37,0.15l3.19,0v0
|
||||||
|
c0.29,0,0.52,0.23,0.52,0.52s-0.23,0.52-0.52,0.52H3.66c-0.01,0-0.01,0-0.02,0l-1.08,0c-0.42,0-0.81-0.16-1.11-0.46
|
||||||
|
C1.16,11.69,1,11.29,1,10.87l0.04-7.31C1.05,2.7,1.75,2,2.62,2h7.31c0.86,0,1.57,0.7,1.57,1.57v1.04V6.7
|
||||||
|
C11.5,6.99,11.27,7.22,10.98,7.22z"/>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M13.53,8H7.47C7.21,8,7,8.21,7,8.47v6.07C7,14.79,7.21,15,7.47,15h6.07c0.26,0,0.47-0.21,0.47-0.47V8.47
|
||||||
|
C14,8.21,13.79,8,13.53,8z M12.19,10.89c0,1.16-0.65,1.69-1.99,1.69H9.81v1.72H8.79V8.7h1.41c1.35,0,1.99,0.49,1.99,1.67V10.89z"
|
||||||
|
/>
|
||||||
|
<path fill="#ED6B21" d="M10.21,9.62H9.81v2h0.39c0.73,0,0.97-0.25,0.97-0.78v-0.41C11.17,9.89,10.99,9.62,10.21,9.62z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
48
resources/icons/support_blocker.svg
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="support_x5F_blocker">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M8,8.17c-0.4,0-0.8-0.1-1.11-0.31L2.55,4.97C1.95,4.57,1.5,3.72,1.5,3V2c0-0.28,0.22-0.5,0.5-0.5
|
||||||
|
S2.5,1.72,2.5,2v1c0,0.38,0.29,0.93,0.61,1.14l4.34,2.89c0.29,0.19,0.82,0.19,1.11,0l4.34-2.89C13.21,3.93,13.5,3.38,13.5,3V2
|
||||||
|
c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v1c0,0.72-0.45,1.57-1.05,1.97L9.11,7.86C8.8,8.07,8.4,8.17,8,8.17z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,8.38c-0.12,0-0.24-0.06-0.31-0.17c-0.11-0.17-0.07-0.41,0.1-0.52l3-2c0.12-0.08,0.26-0.08,0.38-0.02
|
||||||
|
s0.2,0.19,0.2,0.33v2c0,0.21-0.17,0.38-0.38,0.38S13.62,8.21,13.62,8V6.7l-2.42,1.61C11.14,8.35,11.07,8.38,11,8.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14,14.38h-3c-0.21,0-0.38-0.17-0.38-0.38s0.17-0.38,0.38-0.38h2.62V13c0-0.21,0.17-0.38,0.38-0.38
|
||||||
|
s0.38,0.17,0.38,0.38v1C14.38,14.21,14.21,14.38,14,14.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M9,14.38H7c-0.21,0-0.38-0.17-0.38-0.38S6.79,13.62,7,13.62h2c0.21,0,0.38,0.17,0.38,0.38
|
||||||
|
S9.21,14.38,9,14.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14,11.38c-0.21,0-0.38-0.17-0.38-0.38v-1c0-0.21,0.17-0.38,0.38-0.38s0.38,0.17,0.38,0.38v1
|
||||||
|
C14.38,11.21,14.21,11.38,14,11.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,10.38c-0.13,0-0.25-0.06-0.32-0.18C7.57,10.02,7.63,9.79,7.8,9.68l1.62-1C9.6,8.57,9.83,8.63,9.94,8.8
|
||||||
|
c0.11,0.18,0.05,0.41-0.12,0.52l-1.62,1C8.14,10.36,8.07,10.38,8,10.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M5,8.38c-0.07,0-0.14-0.02-0.21-0.06L2.38,6.7V8c0,0.21-0.17,0.38-0.38,0.38S1.62,8.21,1.62,8V6
|
||||||
|
c0-0.14,0.08-0.27,0.2-0.33C1.95,5.6,2.09,5.61,2.21,5.69l3,2c0.17,0.11,0.22,0.35,0.1,0.52C5.24,8.32,5.12,8.38,5,8.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M5,14.38H2c-0.21,0-0.38-0.17-0.38-0.38v-1c0-0.21,0.17-0.38,0.38-0.38S2.38,12.79,2.38,13v0.62H5
|
||||||
|
c0.21,0,0.38,0.17,0.38,0.38S5.21,14.38,5,14.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M2,11.38c-0.21,0-0.38-0.17-0.38-0.38v-1c0-0.21,0.17-0.38,0.38-0.38S2.38,9.79,2.38,10v1
|
||||||
|
C2.38,11.21,2.21,11.38,2,11.38z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,10.38c-0.07,0-0.14-0.02-0.2-0.06l-1.62-1C6.01,9.21,5.96,8.98,6.06,8.8C6.17,8.63,6.4,8.57,6.58,8.68
|
||||||
|
l1.62,1c0.18,0.11,0.23,0.34,0.12,0.52C8.25,10.31,8.13,10.38,8,10.38z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
19
resources/icons/support_enforcer.svg
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="support_x5F_enfocer">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M8,8.17c-0.4,0-0.8-0.1-1.11-0.31L2.55,4.97C1.95,4.57,1.5,3.72,1.5,3V2c0-0.28,0.22-0.5,0.5-0.5
|
||||||
|
S2.5,1.72,2.5,2v1c0,0.38,0.29,0.93,0.61,1.14l4.34,2.89c0.29,0.19,0.82,0.19,1.11,0l4.34-2.89C13.21,3.93,13.5,3.38,13.5,3V2
|
||||||
|
c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v1c0,0.72-0.45,1.57-1.05,1.97L9.11,7.86C8.8,8.07,8.4,8.17,8,8.17z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M13,14.5H3c-0.83,0-1.5-0.67-1.5-1.5V7c0-0.45,0.19-0.81,0.51-0.98c0.32-0.17,0.72-0.13,1.1,0.12
|
||||||
|
l4.34,2.89c0.29,0.19,0.82,0.19,1.11,0l4.34-2.89c0.38-0.25,0.78-0.3,1.1-0.12C14.31,6.19,14.5,6.55,14.5,7v6
|
||||||
|
C14.5,13.83,13.83,14.5,13,14.5z M2.5,6.94c0,0.02,0,0.04,0,0.06v6c0,0.28,0.22,0.5,0.5,0.5h10c0.28,0,0.5-0.22,0.5-0.5V7
|
||||||
|
c0-0.02,0-0.04,0-0.06c-0.02,0.01-0.03,0.02-0.05,0.03L9.11,9.86c-0.62,0.41-1.6,0.41-2.22,0L2.55,6.97
|
||||||
|
C2.54,6.96,2.52,6.95,2.5,6.94z M8.83,9.45L8.83,9.45L8.83,9.45z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
37
resources/icons/test.svg
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="test">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M13,1.5h-1.5v1h1v12h-9v-12h1v-1H3C2.72,1.5,2.5,1.72,2.5,2v13c0,0.28,0.22,0.5,0.5,0.5h10
|
||||||
|
c0.28,0,0.5-0.22,0.5-0.5V2C13.5,1.72,13.28,1.5,13,1.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,8.5H5C4.72,8.5,4.5,8.28,4.5,8V5c0-0.28,0.22-0.5,0.5-0.5h3c0.28,0,0.5,0.22,0.5,0.5v3
|
||||||
|
C8.5,8.28,8.28,8.5,8,8.5z M5.5,7.5h2v-2h-2V7.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M8,13.5H5c-0.28,0-0.5-0.22-0.5-0.5v-3c0-0.28,0.22-0.5,0.5-0.5h3c0.28,0,0.5,0.22,0.5,0.5v3
|
||||||
|
C8.5,13.28,8.28,13.5,8,13.5z M5.5,12.5h2v-2h-2V12.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,5.5h-1C9.72,5.5,9.5,5.28,9.5,5S9.72,4.5,10,4.5h1c0.28,0,0.5,0.22,0.5,0.5S11.28,5.5,11,5.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,7.5h-1C9.72,7.5,9.5,7.28,9.5,7S9.72,6.5,10,6.5h1c0.28,0,0.5,0.22,0.5,0.5S11.28,7.5,11,7.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,10.5h-1c-0.28,0-0.5-0.22-0.5-0.5S9.72,9.5,10,9.5h1c0.28,0,0.5,0.22,0.5,0.5S11.28,10.5,11,10.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M11,12.5h-1c-0.28,0-0.5-0.22-0.5-0.5s0.22-0.5,0.5-0.5h1c0.28,0,0.5,0.22,0.5,0.5S11.28,12.5,11,12.5z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M11,3.5H5C4.72,3.5,4.5,3.28,4.5,3V1c0-0.28,0.22-0.5,0.5-0.5h6c0.28,0,0.5,0.22,0.5,0.5v2
|
||||||
|
C11.5,3.28,11.28,3.5,11,3.5z M5.5,2.5h5v-1h-5V2.5z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
29
resources/icons/upload_queue.svg
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
|
<g id="gueue">
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M6,15.49H2.04c-0.83,0-1.5-0.67-1.51-1.5l-0.02-3.96c0-0.4,0.15-0.78,0.44-1.06C1.22,8.69,1.6,8.53,2,8.53
|
||||||
|
l4,0c0.83,0,1.5,0.67,1.5,1.5v3.96C7.5,14.82,6.83,15.49,6,15.49z M6,9.53l-4,0c-0.13,0-0.26,0.05-0.35,0.15
|
||||||
|
C1.56,9.77,1.51,9.9,1.51,10.03l0.02,3.96c0,0.28,0.23,0.5,0.51,0.5H6c0.28,0,0.5-0.22,0.5-0.5v-3.96C6.5,9.75,6.28,9.53,6,9.53z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M6,7.5H2.04c-0.83,0-1.5-0.67-1.51-1.5L0.51,2.04c0-0.4,0.15-0.78,0.44-1.06C1.22,0.7,1.6,0.54,2,0.54l4,0
|
||||||
|
c0,0,0,0,0,0c0.4,0,0.77,0.16,1.06,0.44C7.34,1.26,7.5,1.64,7.5,2.04V6C7.5,6.83,6.83,7.5,6,7.5z M6,1.54C6,1.54,6,1.54,6,1.54
|
||||||
|
l-4,0c-0.13,0-0.26,0.05-0.35,0.15C1.56,1.78,1.51,1.9,1.51,2.04L1.53,6c0,0.28,0.23,0.5,0.51,0.5H6c0.28,0,0.5-0.22,0.5-0.5V2.04
|
||||||
|
c0-0.13-0.05-0.26-0.15-0.35C6.26,1.59,6.13,1.54,6,1.54z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#808080" d="M14,7.5h-3.96c-0.83,0-1.5-0.67-1.51-1.5L8.51,2.04c0-0.4,0.15-0.78,0.44-1.06C9.22,0.7,9.6,0.54,10,0.54
|
||||||
|
l4,0h0c0.4,0,0.78,0.16,1.06,0.44c0.28,0.28,0.44,0.66,0.44,1.06V6C15.5,6.83,14.83,7.5,14,7.5z M14,1.54C14,1.54,14,1.54,14,1.54
|
||||||
|
l-4,0c-0.13,0-0.26,0.05-0.35,0.15C9.56,1.78,9.5,1.9,9.51,2.04L9.53,6c0,0.27,0.23,0.5,0.51,0.5H14c0.28,0,0.5-0.22,0.5-0.5V2.04
|
||||||
|
c0-0.13-0.05-0.26-0.15-0.35S14.13,1.54,14,1.54z"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#ED6B21" d="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5s3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M13.45,12.58H12
|
||||||
|
c-0.09,0-0.17-0.02-0.24-0.06c-0.02-0.01-0.04-0.02-0.05-0.04c-0.05-0.03-0.1-0.07-0.14-0.12c-0.01-0.01-0.02-0.01-0.03-0.02
|
||||||
|
l-1.25-1.67c-0.19-0.26-0.14-0.62,0.12-0.82c0.26-0.19,0.62-0.14,0.82,0.12l1.07,1.43h1.17c0.32,0,0.58,0.26,0.58,0.58
|
||||||
|
C14.04,12.32,13.78,12.58,13.45,12.58z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
|
@ -3,22 +3,41 @@
|
||||||
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||||
<g id="advanced_x2B_wrench">
|
<g id="advanced_x2B_wrench">
|
||||||
<path fill="#808080" d="M7.39,3.69C7.32,3.46,7.23,3.24,7.11,3.03l0.22-0.65L6.62,1.67L5.97,1.89C5.76,1.77,5.54,1.68,5.31,1.61
|
<g>
|
||||||
L5,1H4L3.69,1.61C3.46,1.68,3.24,1.77,3.03,1.89L2.38,1.67L1.67,2.38l0.22,0.65C1.77,3.24,1.68,3.46,1.61,3.69L1,4v1l0.61,0.31
|
<path fill="#808080" d="M7.61,3.81c-0.12-0.06-0.26-0.21-0.3-0.34S7.15,2.92,7.19,2.79l0.06-0.17c0.04-0.13,0-0.32-0.1-0.41
|
||||||
c0.07,0.23,0.16,0.46,0.27,0.67L1.67,6.62l0.71,0.71l0.65-0.22c0.21,0.12,0.43,0.21,0.67,0.28L4,8h1l0.31-0.61
|
L6.8,1.85c-0.1-0.1-0.28-0.14-0.41-0.1L6.21,1.81C6.08,1.85,5.88,1.84,5.76,1.78s-0.5-0.27-0.56-0.39L5.11,1.22
|
||||||
c0.23-0.07,0.46-0.16,0.67-0.28l0.65,0.22l0.71-0.71L7.11,5.97c0.12-0.21,0.21-0.43,0.27-0.67L8,5V4L7.39,3.69z"/>
|
C5.05,1.1,4.89,1,4.75,1h-0.5c-0.14,0-0.3,0.1-0.36,0.22L3.81,1.39c-0.06,0.12-0.21,0.26-0.34,0.3S2.92,1.85,2.79,1.81L2.62,1.75
|
||||||
<path fill="#808080" d="M12.4,2.49c-0.05-0.17-0.11-0.33-0.2-0.48l0.15-0.46l-0.51-0.51L11.39,1.2c-0.15-0.08-0.31-0.15-0.48-0.2
|
c-0.13-0.04-0.32,0-0.41,0.1L1.85,2.2c-0.1,0.1-0.14,0.28-0.1,0.41l0.06,0.17c0.04,0.13,0.03,0.33-0.03,0.45s-0.27,0.5-0.39,0.56
|
||||||
l-0.22-0.44H9.98L9.76,1C9.59,1.05,9.43,1.11,9.28,1.2L8.82,1.04L8.31,1.55l0.15,0.46c-0.08,0.15-0.15,0.31-0.2,0.48L7.83,2.71
|
L1.22,3.89C1.1,3.95,1,4.11,1,4.25v0.5c0,0.14,0.1,0.3,0.22,0.36l0.17,0.08c0.12,0.06,0.26,0.21,0.3,0.34s0.16,0.54,0.12,0.67
|
||||||
v0.71l0.44,0.22c0.05,0.17,0.11,0.33,0.2,0.48L8.31,4.58l0.51,0.51l0.46-0.15c0.15,0.08,0.31,0.15,0.48,0.2l0.22,0.44h0.71
|
L1.75,6.38c-0.04,0.13,0,0.32,0.1,0.41L2.2,7.15c0.1,0.1,0.28,0.14,0.41,0.1l0.17-0.06c0.13-0.04,0.33-0.03,0.45,0.03
|
||||||
l0.22-0.44c0.17-0.05,0.33-0.11,0.48-0.2l0.46,0.15l0.51-0.51L12.2,4.12c0.08-0.15,0.15-0.31,0.2-0.48l0.44-0.22V2.71L12.4,2.49z"
|
s0.5,0.27,0.56,0.39l0.08,0.17C3.95,7.9,4.11,8,4.25,8h0.5c0.14,0,0.3-0.1,0.36-0.22l0.08-0.17c0.06-0.12,0.21-0.26,0.34-0.3
|
||||||
/>
|
s0.54-0.16,0.67-0.12l0.17,0.06c0.13,0.04,0.32,0,0.41-0.1L7.15,6.8c0.1-0.1,0.14-0.28,0.1-0.41L7.19,6.21
|
||||||
<path fill="#ED6B21" d="M14.36,10.66c0.04-0.34,0.04-0.68,0-1.02L15,8.91L14.46,7.6l-0.97-0.07c-0.21-0.27-0.45-0.51-0.72-0.72
|
C7.15,6.08,7.16,5.88,7.22,5.76s0.27-0.5,0.39-0.56l0.17-0.08C7.9,5.05,8,4.89,8,4.75v-0.5c0-0.14-0.1-0.3-0.22-0.36L7.61,3.81z
|
||||||
L12.7,5.84L11.39,5.3l-0.73,0.64c-0.34-0.04-0.68-0.04-1.02,0L8.91,5.3L7.6,5.84L7.53,6.81C7.26,7.02,7.02,7.26,6.81,7.53L5.84,7.6
|
M4.5,6.42c-1.06,0-1.92-0.86-1.92-1.92c0-1.06,0.86-1.92,1.92-1.92S6.42,3.44,6.42,4.5C6.42,5.56,5.56,6.42,4.5,6.42z"/>
|
||||||
L5.3,8.91l0.64,0.73c-0.04,0.34-0.04,0.68,0,1.02L5.3,11.39l0.54,1.31l0.97,0.07c0.21,0.27,0.45,0.51,0.72,0.72l0.07,0.97L8.91,15
|
</g>
|
||||||
l0.73-0.64c0.34,0.04,0.68,0.04,1.02,0L11.39,15l1.31-0.54l0.07-0.97c0.27-0.21,0.51-0.45,0.72-0.72l0.97-0.07L15,11.39
|
<g>
|
||||||
L14.36,10.66z"/>
|
<path fill="#808080" d="M12.61,2.6c-0.12-0.06-0.24-0.18-0.28-0.27s-0.11-0.42-0.06-0.54s0-0.31-0.1-0.41l-0.15-0.15
|
||||||
<circle fill="#FFFFFF" cx="4.5" cy="4.5" r="1.92"/>
|
c-0.1-0.1-0.28-0.14-0.41-0.1s-0.3,0.04-0.39,0S10.86,0.9,10.8,0.78s-0.22-0.22-0.36-0.22h-0.21c-0.14,0-0.3,0.1-0.36,0.22
|
||||||
<circle fill="#FFFFFF" cx="10.33" cy="3.06" r="1.11"/>
|
S9.68,1.03,9.59,1.06S9.18,1.16,9.05,1.12s-0.31,0-0.41,0.1L8.49,1.37c-0.1,0.1-0.14,0.28-0.1,0.41s0.04,0.3,0,0.39
|
||||||
<circle fill="#FFFFFF" cx="10.15" cy="10.15" r="2.85"/>
|
S8.17,2.54,8.05,2.6S7.83,2.82,7.83,2.96v0.21c0,0.14,0.1,0.3,0.22,0.36S8.3,3.71,8.33,3.8s0.11,0.42,0.06,0.54s0,0.31,0.1,0.41
|
||||||
|
l0.15,0.15c0.1,0.1,0.28,0.14,0.41,0.1s0.3-0.04,0.39,0s0.37,0.22,0.43,0.34s0.22,0.22,0.36,0.22h0.21c0.14,0,0.3-0.1,0.36-0.22
|
||||||
|
s0.18-0.24,0.27-0.28s0.42-0.11,0.54-0.06s0.31,0,0.41-0.1l0.15-0.15c0.1-0.1,0.14-0.28,0.1-0.41s-0.04-0.3,0-0.39
|
||||||
|
s0.22-0.37,0.34-0.43s0.22-0.22,0.22-0.36V2.96C12.83,2.82,12.74,2.66,12.61,2.6z M10.33,4.18c-0.62,0-1.11-0.5-1.11-1.11
|
||||||
|
c0-0.62,0.5-1.11,1.11-1.11s1.11,0.5,1.11,1.11C11.45,3.68,10.95,4.18,10.33,4.18z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path fill="#ED6B21" d="M14.38,9.89c-0.01-0.14,0.06-0.33,0.15-0.44l0.31-0.35c0.09-0.1,0.12-0.29,0.07-0.42l-0.35-0.85
|
||||||
|
c-0.05-0.13-0.21-0.24-0.35-0.25l-0.47-0.03c-0.14-0.01-0.32-0.1-0.42-0.2l-0.37-0.37c-0.1-0.09-0.2-0.28-0.2-0.41l-0.03-0.47
|
||||||
|
c-0.01-0.14-0.12-0.29-0.25-0.35L11.62,5.4c-0.13-0.05-0.32-0.02-0.42,0.07l-0.36,0.31c-0.1,0.09-0.3,0.16-0.44,0.15l-0.52,0
|
||||||
|
C9.75,5.93,9.55,5.86,9.45,5.77L9.1,5.46C8.99,5.37,8.8,5.34,8.68,5.4L7.83,5.75C7.7,5.8,7.59,5.95,7.58,6.09L7.55,6.56
|
||||||
|
c-0.01,0.14-0.1,0.32-0.2,0.42L6.98,7.34c-0.09,0.1-0.28,0.2-0.41,0.2L6.09,7.58C5.95,7.59,5.8,7.7,5.75,7.83L5.4,8.68
|
||||||
|
C5.34,8.8,5.37,8.99,5.46,9.1l0.31,0.36c0.09,0.1,0.16,0.3,0.15,0.44l0,0.52c0.01,0.14-0.06,0.33-0.15,0.44L5.46,11.2
|
||||||
|
c-0.09,0.1-0.12,0.29-0.07,0.42l0.35,0.85c0.05,0.13,0.21,0.24,0.35,0.25l0.47,0.03c0.14,0.01,0.32,0.1,0.42,0.2l0.37,0.37
|
||||||
|
c0.1,0.09,0.2,0.28,0.2,0.41l0.03,0.47c0.01,0.14,0.12,0.29,0.25,0.35l0.85,0.35c0.13,0.05,0.32,0.02,0.42-0.07l0.36-0.31
|
||||||
|
c0.1-0.09,0.3-0.16,0.44-0.15l0.52,0c0.14-0.01,0.33,0.06,0.44,0.15l0.35,0.31c0.1,0.09,0.29,0.12,0.42,0.07l0.85-0.35
|
||||||
|
c0.13-0.05,0.24-0.21,0.25-0.35l0.03-0.47c0.01-0.14,0.1-0.32,0.2-0.42l0.37-0.37c0.09-0.1,0.28-0.2,0.41-0.21l0.47-0.03
|
||||||
|
c0.14-0.01,0.29-0.12,0.35-0.25l0.35-0.85c0.05-0.13,0.02-0.32-0.07-0.42l-0.31-0.36c-0.09-0.1-0.16-0.3-0.15-0.44L14.38,9.89z
|
||||||
|
M10.15,13c-1.57,0-2.85-1.27-2.85-2.85S8.58,7.3,10.15,7.3S13,8.58,13,10.15S11.72,13,10.15,13z"/>
|
||||||
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 3.9 KiB |
|
@ -2,24 +2,21 @@
|
||||||
|
|
||||||
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
varying vec3 clipping_planes_dots;
|
||||||
|
|
||||||
// x = tainted, y = specular;
|
// x = tainted, y = specular;
|
||||||
varying vec2 intensity;
|
varying vec2 intensity;
|
||||||
|
|
||||||
varying vec3 delta_box_min;
|
varying vec3 delta_box_min;
|
||||||
varying vec3 delta_box_max;
|
varying vec3 delta_box_max;
|
||||||
|
|
||||||
varying float world_z;
|
|
||||||
|
|
||||||
uniform vec4 uniform_color;
|
uniform vec4 uniform_color;
|
||||||
|
|
||||||
// x = min z, y = max z;
|
|
||||||
uniform vec2 z_range;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
if ((world_z < z_range.x) || (z_range.y < world_z))
|
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
// if the fragment is outside the print volume -> use darker color
|
// if the fragment is outside the print volume -> use darker color
|
||||||
vec3 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(uniform_color.rgb, ZERO, 0.3333) : uniform_color.rgb;
|
vec3 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(uniform_color.rgb, ZERO, 0.3333) : uniform_color.rgb;
|
||||||
gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a);
|
gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a);
|
||||||
|
|
|
@ -28,13 +28,18 @@ struct PrintBoxDetection
|
||||||
|
|
||||||
uniform PrintBoxDetection print_box;
|
uniform PrintBoxDetection print_box;
|
||||||
|
|
||||||
|
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
|
||||||
|
uniform vec2 z_range;
|
||||||
|
// Clipping plane - general orientation. Used by the SLA gizmo.
|
||||||
|
uniform vec4 clipping_plane;
|
||||||
|
|
||||||
// x = tainted, y = specular;
|
// x = tainted, y = specular;
|
||||||
varying vec2 intensity;
|
varying vec2 intensity;
|
||||||
|
|
||||||
varying vec3 delta_box_min;
|
varying vec3 delta_box_min;
|
||||||
varying vec3 delta_box_max;
|
varying vec3 delta_box_max;
|
||||||
|
|
||||||
varying float world_z;
|
varying vec3 clipping_planes_dots;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
@ -66,8 +71,11 @@ void main()
|
||||||
{
|
{
|
||||||
delta_box_min = ZERO;
|
delta_box_min = ZERO;
|
||||||
delta_box_max = ZERO;
|
delta_box_max = ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_Position = ftransform();
|
gl_Position = ftransform();
|
||||||
world_z = vec3(print_box.volume_world_matrix * gl_Vertex).z;
|
// Point in homogenous coordinates.
|
||||||
}
|
vec4 world_pos = print_box.volume_world_matrix * gl_Vertex;
|
||||||
|
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
|
||||||
|
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
|
||||||
|
}
|
||||||
|
|
|
@ -43,11 +43,21 @@ typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> stl_normal;
|
||||||
static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect");
|
static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect");
|
||||||
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
|
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
|
||||||
|
|
||||||
typedef struct {
|
struct stl_facet {
|
||||||
stl_normal normal;
|
stl_normal normal;
|
||||||
stl_vertex vertex[3];
|
stl_vertex vertex[3];
|
||||||
char extra[2];
|
char extra[2];
|
||||||
} stl_facet;
|
|
||||||
|
stl_facet rotated(const Eigen::Quaternion<float, Eigen::DontAlign> &rot) {
|
||||||
|
stl_facet out;
|
||||||
|
out.normal = rot * this->normal;
|
||||||
|
out.vertex[0] = rot * this->vertex[0];
|
||||||
|
out.vertex[1] = rot * this->vertex[1];
|
||||||
|
out.vertex[2] = rot * this->vertex[2];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#define SIZEOF_STL_FACET 50
|
#define SIZEOF_STL_FACET 50
|
||||||
|
|
||||||
static_assert(offsetof(stl_facet, normal) == 0, "stl_facet.normal has correct offset");
|
static_assert(offsetof(stl_facet, normal) == 0, "stl_facet.normal has correct offset");
|
||||||
|
|
|
@ -41,10 +41,12 @@ stl_open(stl_file *stl, const char *file) {
|
||||||
stl_count_facets(stl, file);
|
stl_count_facets(stl, file);
|
||||||
stl_allocate(stl);
|
stl_allocate(stl);
|
||||||
stl_read(stl, 0, true);
|
stl_read(stl, 0, true);
|
||||||
if (!stl->error) fclose(stl->fp);
|
if (stl->fp != nullptr) {
|
||||||
|
fclose(stl->fp);
|
||||||
|
stl->fp = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
stl_initialize(stl_file *stl) {
|
stl_initialize(stl_file *stl) {
|
||||||
memset(stl, 0, sizeof(stl_file));
|
memset(stl, 0, sizeof(stl_file));
|
||||||
|
@ -118,7 +120,7 @@ stl_count_facets(stl_file *stl, const char *file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the int following the header. This should contain # of facets */
|
/* Read the int following the header. This should contain # of facets */
|
||||||
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, stl->fp);
|
bool header_num_faces_read = fread(&header_num_facets, sizeof(uint32_t), 1, stl->fp) != 0;
|
||||||
#ifndef BOOST_LITTLE_ENDIAN
|
#ifndef BOOST_LITTLE_ENDIAN
|
||||||
// Convert from little endian to big endian.
|
// Convert from little endian to big endian.
|
||||||
stl_internal_reverse_quads((char*)&header_num_facets, 4);
|
stl_internal_reverse_quads((char*)&header_num_facets, 4);
|
||||||
|
@ -257,7 +259,6 @@ stl_reallocate(stl_file *stl) {
|
||||||
time running this for the stl and therefore we should reset our max and min stats. */
|
time running this for the stl and therefore we should reset our max and min stats. */
|
||||||
void stl_read(stl_file *stl, int first_facet, bool first) {
|
void stl_read(stl_file *stl, int first_facet, bool first) {
|
||||||
stl_facet facet;
|
stl_facet facet;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (stl->error) return;
|
if (stl->error) return;
|
||||||
|
|
||||||
|
@ -268,7 +269,7 @@ void stl_read(stl_file *stl, int first_facet, bool first) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char normal_buf[3][32];
|
char normal_buf[3][32];
|
||||||
for(i = first_facet; i < stl->stats.number_of_facets; i++) {
|
for(uint32_t i = first_facet; i < stl->stats.number_of_facets; i++) {
|
||||||
if(stl->stats.type == binary)
|
if(stl->stats.type == binary)
|
||||||
/* Read a single facet from a binary .STL file */
|
/* Read a single facet from a binary .STL file */
|
||||||
{
|
{
|
||||||
|
@ -366,17 +367,19 @@ void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void stl_close(stl_file *stl)
|
||||||
stl_close(stl_file *stl) {
|
{
|
||||||
if (stl->error) return;
|
assert(stl->fp == nullptr);
|
||||||
|
assert(stl->heads == nullptr);
|
||||||
|
assert(stl->tail == nullptr);
|
||||||
|
|
||||||
if(stl->neighbors_start != NULL)
|
if (stl->facet_start != NULL)
|
||||||
free(stl->neighbors_start);
|
free(stl->facet_start);
|
||||||
if(stl->facet_start != NULL)
|
if (stl->neighbors_start != NULL)
|
||||||
free(stl->facet_start);
|
free(stl->neighbors_start);
|
||||||
if(stl->v_indices != NULL)
|
if (stl->v_indices != NULL)
|
||||||
free(stl->v_indices);
|
free(stl->v_indices);
|
||||||
if(stl->v_shared != NULL)
|
if (stl->v_shared != NULL)
|
||||||
free(stl->v_shared);
|
free(stl->v_shared);
|
||||||
|
memset(stl, 0, sizeof(stl_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,6 @@ target_link_libraries(libslic3r
|
||||||
clipper
|
clipper
|
||||||
nowide
|
nowide
|
||||||
${EXPAT_LIBRARIES}
|
${EXPAT_LIBRARIES}
|
||||||
${GLEW_LIBRARIES}
|
|
||||||
glu-libtess
|
glu-libtess
|
||||||
polypartition
|
polypartition
|
||||||
poly2tri
|
poly2tri
|
||||||
|
|
|
@ -593,6 +593,8 @@ ModelObject& ModelObject::assign_copy(const ModelObject &rhs)
|
||||||
this->origin_translation = rhs.origin_translation;
|
this->origin_translation = rhs.origin_translation;
|
||||||
m_bounding_box = rhs.m_bounding_box;
|
m_bounding_box = rhs.m_bounding_box;
|
||||||
m_bounding_box_valid = rhs.m_bounding_box_valid;
|
m_bounding_box_valid = rhs.m_bounding_box_valid;
|
||||||
|
m_raw_bounding_box = rhs.m_raw_bounding_box;
|
||||||
|
m_raw_bounding_box_valid = rhs.m_raw_bounding_box_valid;
|
||||||
m_raw_mesh_bounding_box = rhs.m_raw_mesh_bounding_box;
|
m_raw_mesh_bounding_box = rhs.m_raw_mesh_bounding_box;
|
||||||
m_raw_mesh_bounding_box_valid = rhs.m_raw_mesh_bounding_box_valid;
|
m_raw_mesh_bounding_box_valid = rhs.m_raw_mesh_bounding_box_valid;
|
||||||
|
|
||||||
|
@ -627,6 +629,8 @@ ModelObject& ModelObject::assign_copy(ModelObject &&rhs)
|
||||||
this->origin_translation = std::move(rhs.origin_translation);
|
this->origin_translation = std::move(rhs.origin_translation);
|
||||||
m_bounding_box = std::move(rhs.m_bounding_box);
|
m_bounding_box = std::move(rhs.m_bounding_box);
|
||||||
m_bounding_box_valid = std::move(rhs.m_bounding_box_valid);
|
m_bounding_box_valid = std::move(rhs.m_bounding_box_valid);
|
||||||
|
m_raw_bounding_box = rhs.m_raw_bounding_box;
|
||||||
|
m_raw_bounding_box_valid = rhs.m_raw_bounding_box_valid;
|
||||||
m_raw_mesh_bounding_box = rhs.m_raw_mesh_bounding_box;
|
m_raw_mesh_bounding_box = rhs.m_raw_mesh_bounding_box;
|
||||||
m_raw_mesh_bounding_box_valid = rhs.m_raw_mesh_bounding_box_valid;
|
m_raw_mesh_bounding_box_valid = rhs.m_raw_mesh_bounding_box_valid;
|
||||||
|
|
||||||
|
@ -859,7 +863,7 @@ TriangleMesh ModelObject::full_raw_mesh() const
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBoxf3 ModelObject::raw_mesh_bounding_box() const
|
const BoundingBoxf3& ModelObject::raw_mesh_bounding_box() const
|
||||||
{
|
{
|
||||||
if (! m_raw_mesh_bounding_box_valid) {
|
if (! m_raw_mesh_bounding_box_valid) {
|
||||||
m_raw_mesh_bounding_box_valid = true;
|
m_raw_mesh_bounding_box_valid = true;
|
||||||
|
@ -880,33 +884,36 @@ BoundingBoxf3 ModelObject::full_raw_mesh_bounding_box() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
|
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
|
||||||
// This bounding box is only used for the actual slicing.
|
// This bounding box is only used for the actual slicing and for layer editing UI to calculate the layers.
|
||||||
BoundingBoxf3 ModelObject::raw_bounding_box() const
|
const BoundingBoxf3& ModelObject::raw_bounding_box() const
|
||||||
{
|
{
|
||||||
BoundingBoxf3 bb;
|
if (! m_raw_bounding_box_valid) {
|
||||||
#if ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
m_raw_bounding_box_valid = true;
|
||||||
if (this->instances.empty())
|
m_raw_bounding_box.reset();
|
||||||
throw std::invalid_argument("Can't call raw_bounding_box() with no instances");
|
#if ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
|
if (this->instances.empty())
|
||||||
|
throw std::invalid_argument("Can't call raw_bounding_box() with no instances");
|
||||||
|
|
||||||
const Transform3d& inst_matrix = this->instances.front()->get_transformation().get_matrix(true);
|
const Transform3d& inst_matrix = this->instances.front()->get_transformation().get_matrix(true);
|
||||||
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
for (const ModelVolume *v : this->volumes)
|
for (const ModelVolume *v : this->volumes)
|
||||||
if (v->is_model_part()) {
|
if (v->is_model_part()) {
|
||||||
#if !ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
#if !ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
if (this->instances.empty())
|
if (this->instances.empty())
|
||||||
throw std::invalid_argument("Can't call raw_bounding_box() with no instances");
|
throw std::invalid_argument("Can't call raw_bounding_box() with no instances");
|
||||||
#endif // !ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
#endif // !ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
|
|
||||||
TriangleMesh vol_mesh(v->mesh);
|
#if ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
#if ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
m_raw_bounding_box.merge(v->mesh.transformed_bounding_box(inst_matrix * v->get_matrix()));
|
||||||
vol_mesh.transform(inst_matrix * v->get_matrix());
|
#else
|
||||||
bb.merge(vol_mesh.bounding_box());
|
// unmaintaned
|
||||||
#else
|
assert(false);
|
||||||
vol_mesh.transform(v->get_matrix());
|
// vol_mesh.transform(v->get_matrix());
|
||||||
bb.merge(this->instances.front()->transform_mesh_bounding_box(vol_mesh, true));
|
// m_raw_bounding_box_valid.merge(this->instances.front()->transform_mesh_bounding_box(vol_mesh, true));
|
||||||
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
}
|
}
|
||||||
return bb;
|
}
|
||||||
|
return m_raw_bounding_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This returns an accurate snug bounding box of the transformed object instance, without the translation applied.
|
// This returns an accurate snug bounding box of the transformed object instance, without the translation applied.
|
||||||
|
@ -920,13 +927,13 @@ BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_
|
||||||
{
|
{
|
||||||
if (v->is_model_part())
|
if (v->is_model_part())
|
||||||
{
|
{
|
||||||
TriangleMesh mesh(v->mesh);
|
|
||||||
#if ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
#if ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
mesh.transform(inst_matrix * v->get_matrix());
|
bb.merge(v->mesh.transformed_bounding_box(inst_matrix * v->get_matrix()));
|
||||||
bb.merge(mesh.bounding_box());
|
|
||||||
#else
|
#else
|
||||||
mesh.transform(v->get_matrix());
|
// not maintained
|
||||||
bb.merge(this->instances[instance_idx]->transform_mesh_bounding_box(mesh, dont_translate));
|
assert(false);
|
||||||
|
//mesh.transform(v->get_matrix());
|
||||||
|
//bb.merge(this->instances[instance_idx]->transform_mesh_bounding_box(mesh, dont_translate));
|
||||||
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
#endif // ENABLE_GENERIC_SUBPARTS_PLACEMENT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ public:
|
||||||
// This bounding box is approximate and not snug.
|
// This bounding box is approximate and not snug.
|
||||||
// This bounding box is being cached.
|
// This bounding box is being cached.
|
||||||
const BoundingBoxf3& bounding_box() const;
|
const BoundingBoxf3& bounding_box() const;
|
||||||
void invalidate_bounding_box() { m_bounding_box_valid = false; m_raw_mesh_bounding_box_valid = false; }
|
void invalidate_bounding_box() { m_bounding_box_valid = false; m_raw_bounding_box_valid = false; m_raw_mesh_bounding_box_valid = false; }
|
||||||
|
|
||||||
// A mesh containing all transformed instances of this object.
|
// A mesh containing all transformed instances of this object.
|
||||||
TriangleMesh mesh() const;
|
TriangleMesh mesh() const;
|
||||||
|
@ -223,11 +223,11 @@ public:
|
||||||
TriangleMesh full_raw_mesh() const;
|
TriangleMesh full_raw_mesh() const;
|
||||||
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
|
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
|
||||||
// This bounding box is only used for the actual slicing.
|
// This bounding box is only used for the actual slicing.
|
||||||
BoundingBoxf3 raw_bounding_box() const;
|
const BoundingBoxf3& raw_bounding_box() const;
|
||||||
// A snug bounding box around the transformed non-modifier object volumes.
|
// A snug bounding box around the transformed non-modifier object volumes.
|
||||||
BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const;
|
BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const;
|
||||||
// A snug bounding box of non-transformed (non-rotated, non-scaled, non-translated) sum of non-modifier object volumes.
|
// A snug bounding box of non-transformed (non-rotated, non-scaled, non-translated) sum of non-modifier object volumes.
|
||||||
BoundingBoxf3 raw_mesh_bounding_box() const;
|
const BoundingBoxf3& raw_mesh_bounding_box() const;
|
||||||
// A snug bounding box of non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
|
// A snug bounding box of non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
|
||||||
BoundingBoxf3 full_raw_mesh_bounding_box() const;
|
BoundingBoxf3 full_raw_mesh_bounding_box() const;
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModelObject(Model *model) : m_model(model), origin_translation(Vec3d::Zero()),
|
ModelObject(Model *model) : m_model(model), origin_translation(Vec3d::Zero()),
|
||||||
m_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) {}
|
m_bounding_box_valid(false), m_raw_bounding_box_valid(false), m_raw_mesh_bounding_box_valid(false) {}
|
||||||
~ModelObject();
|
~ModelObject();
|
||||||
|
|
||||||
/* To be able to return an object from own copy / clone methods. Hopefully the compiler will do the "Copy elision" */
|
/* To be able to return an object from own copy / clone methods. Hopefully the compiler will do the "Copy elision" */
|
||||||
|
@ -304,6 +304,8 @@ private:
|
||||||
// Bounding box, cached.
|
// Bounding box, cached.
|
||||||
mutable BoundingBoxf3 m_bounding_box;
|
mutable BoundingBoxf3 m_bounding_box;
|
||||||
mutable bool m_bounding_box_valid;
|
mutable bool m_bounding_box_valid;
|
||||||
|
mutable BoundingBoxf3 m_raw_bounding_box;
|
||||||
|
mutable bool m_raw_bounding_box_valid;
|
||||||
mutable BoundingBoxf3 m_raw_mesh_bounding_box;
|
mutable BoundingBoxf3 m_raw_mesh_bounding_box;
|
||||||
mutable bool m_raw_mesh_bounding_box_valid;
|
mutable bool m_raw_mesh_bounding_box_valid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -132,7 +132,7 @@ public:
|
||||||
// The slicing parameters are dependent on various configuration values
|
// The slicing parameters are dependent on various configuration values
|
||||||
// (layer height, first layer height, raft settings, print nozzle diameter etc).
|
// (layer height, first layer height, raft settings, print nozzle diameter etc).
|
||||||
const SlicingParameters& slicing_parameters() const { return m_slicing_params; }
|
const SlicingParameters& slicing_parameters() const { return m_slicing_params; }
|
||||||
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object);
|
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z);
|
||||||
|
|
||||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||||
std::vector<unsigned int> object_extruders() const;
|
std::vector<unsigned int> object_extruders() const;
|
||||||
|
|
|
@ -2528,14 +2528,17 @@ void PrintConfigDef::init_sla_params()
|
||||||
|
|
||||||
def = this->add("pad_wall_height", coFloat);
|
def = this->add("pad_wall_height", coFloat);
|
||||||
def->label = L("Pad wall height");
|
def->label = L("Pad wall height");
|
||||||
def->tooltip = L("Defines the cavity depth. Set to zero to disable the cavity.");
|
def->tooltip = L("Defines the pad cavity depth. Set to zero to disable the cavity. "
|
||||||
|
"Be careful when enabling this feature, as some resins may "
|
||||||
|
"produce an extreme suction effect inside the cavity, "
|
||||||
|
"which makes pealing the print off the vat foil difficult.");
|
||||||
def->category = L("Pad");
|
def->category = L("Pad");
|
||||||
// def->tooltip = L("");
|
// def->tooltip = L("");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->max = 30;
|
def->max = 30;
|
||||||
def->mode = comSimple;
|
def->mode = comExpert;
|
||||||
def->default_value = new ConfigOptionFloat(5.0);
|
def->default_value = new ConfigOptionFloat(0.);
|
||||||
|
|
||||||
def = this->add("pad_max_merge_distance", coFloat);
|
def = this->add("pad_max_merge_distance", coFloat);
|
||||||
def->label = L("Max merge distance");
|
def->label = L("Max merge distance");
|
||||||
|
@ -3114,6 +3117,13 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||||
def->label = L("Logging level");
|
def->label = L("Logging level");
|
||||||
def->tooltip = L("Messages with severity lower or eqal to the loglevel will be printed out. 0:trace, 1:debug, 2:info, 3:warning, 4:error, 5:fatal");
|
def->tooltip = L("Messages with severity lower or eqal to the loglevel will be printed out. 0:trace, 1:debug, 2:info, 3:warning, 4:error, 5:fatal");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(SLIC3R_GUI)
|
||||||
|
def = this->add("sw_renderer", coBool);
|
||||||
|
def->label = L("Render with a software renderer");
|
||||||
|
def->tooltip = L("Render with a software renderer. The bundled MESA software renderer is loaded instead of the default OpenGL driver.");
|
||||||
|
def->min = 0;
|
||||||
|
#endif /* _MSC_VER */
|
||||||
}
|
}
|
||||||
|
|
||||||
const CLIActionsConfigDef cli_actions_config_def;
|
const CLIActionsConfigDef cli_actions_config_def;
|
||||||
|
|
|
@ -1370,7 +1370,7 @@ void PrintObject::update_slicing_parameters()
|
||||||
this->print()->config(), m_config, unscale<double>(this->size(2)), this->object_extruders());
|
this->print()->config(), m_config, unscale<double>(this->size(2)), this->object_extruders());
|
||||||
}
|
}
|
||||||
|
|
||||||
SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object)
|
SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z)
|
||||||
{
|
{
|
||||||
PrintConfig print_config;
|
PrintConfig print_config;
|
||||||
PrintObjectConfig object_config;
|
PrintObjectConfig object_config;
|
||||||
|
@ -1390,7 +1390,9 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full
|
||||||
object_extruders);
|
object_extruders);
|
||||||
sort_remove_duplicates(object_extruders);
|
sort_remove_duplicates(object_extruders);
|
||||||
|
|
||||||
return SlicingParameters::create_from_config(print_config, object_config, model_object.bounding_box().max.z(), object_extruders);
|
if (object_max_z <= 0.f)
|
||||||
|
object_max_z = model_object.raw_bounding_box().size().z();
|
||||||
|
return SlicingParameters::create_from_config(print_config, object_config, object_max_z, object_extruders);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||||
|
|
|
@ -1572,10 +1572,8 @@ public:
|
||||||
auto hit = bridge_mesh_intersect(headjp, n, r);
|
auto hit = bridge_mesh_intersect(headjp, n, r);
|
||||||
|
|
||||||
if(std::isinf(hit.distance())) ground_head_indices.emplace_back(i);
|
if(std::isinf(hit.distance())) ground_head_indices.emplace_back(i);
|
||||||
else {
|
else if(m_cfg.ground_facing_only) head.invalidate();
|
||||||
if(m_cfg.ground_facing_only) head.invalidate();
|
else m_iheads_onmodel.emplace_back(std::make_pair(i, hit));
|
||||||
m_iheads_onmodel.emplace_back(std::make_pair(i, hit));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to search for clusters of points that are far enough
|
// We want to search for clusters of points that are far enough
|
||||||
|
@ -1872,7 +1870,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cascade_pillars() {
|
void interconnect_pillars() {
|
||||||
// Now comes the algorithm that connects pillars with each other.
|
// Now comes the algorithm that connects pillars with each other.
|
||||||
// Ideally every pillar should be connected with at least one of its
|
// Ideally every pillar should be connected with at least one of its
|
||||||
// neighbors if that neighbor is within max_pillar_link_distance
|
// neighbors if that neighbor is within max_pillar_link_distance
|
||||||
|
@ -2121,7 +2119,7 @@ bool SLASupportTree::generate(const std::vector<SupportPoint> &support_points,
|
||||||
|
|
||||||
std::bind(&Algorithm::routing_to_model, &alg),
|
std::bind(&Algorithm::routing_to_model, &alg),
|
||||||
|
|
||||||
std::bind(&Algorithm::cascade_pillars, &alg),
|
std::bind(&Algorithm::interconnect_pillars, &alg),
|
||||||
|
|
||||||
std::bind(&Algorithm::routing_headless, &alg),
|
std::bind(&Algorithm::routing_headless, &alg),
|
||||||
|
|
||||||
|
@ -2150,16 +2148,16 @@ bool SLASupportTree::generate(const std::vector<SupportPoint> &support_points,
|
||||||
// Let's define a simple automaton that will run our program.
|
// Let's define a simple automaton that will run our program.
|
||||||
auto progress = [&ctl, &pc] () {
|
auto progress = [&ctl, &pc] () {
|
||||||
static const std::array<std::string, NUM_STEPS> stepstr {
|
static const std::array<std::string, NUM_STEPS> stepstr {
|
||||||
L("Starting"),
|
"Starting",
|
||||||
L("Filtering"),
|
"Filtering",
|
||||||
L("Generate pinheads"),
|
"Generate pinheads",
|
||||||
L("Classification"),
|
"Classification",
|
||||||
L("Routing to ground"),
|
"Routing to ground",
|
||||||
L("Routing supports to model surface"),
|
"Routing supports to model surface",
|
||||||
L("Cascading pillars"),
|
"Interconnecting pillars",
|
||||||
L("Processing small holes"),
|
"Processing small holes",
|
||||||
L("Done"),
|
"Done",
|
||||||
L("Abort")
|
"Abort"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::array<unsigned, NUM_STEPS> stepstate {
|
static const std::array<unsigned, NUM_STEPS> stepstate {
|
||||||
|
|
|
@ -693,6 +693,16 @@ void TriangleMeshSlicer::init(TriangleMesh *_mesh, throw_on_cancel_callback_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void TriangleMeshSlicer::set_up_direction(const Vec3f& up)
|
||||||
|
{
|
||||||
|
m_quaternion.setFromTwoVectors(up, Vec3f::UnitZ());
|
||||||
|
m_use_quaternion = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const
|
void TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::slice";
|
BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::slice";
|
||||||
|
@ -795,7 +805,7 @@ void TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons
|
||||||
void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLines>* lines, boost::mutex* lines_mutex,
|
void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLines>* lines, boost::mutex* lines_mutex,
|
||||||
const std::vector<float> &z) const
|
const std::vector<float> &z) const
|
||||||
{
|
{
|
||||||
const stl_facet &facet = this->mesh->stl.facet_start[facet_idx];
|
const stl_facet &facet = m_use_quaternion ? this->mesh->stl.facet_start[facet_idx].rotated(m_quaternion) : this->mesh->stl.facet_start[facet_idx];
|
||||||
|
|
||||||
// find facet extents
|
// find facet extents
|
||||||
const float min_z = fminf(facet.vertex[0](2), fminf(facet.vertex[1](2), facet.vertex[2](2)));
|
const float min_z = fminf(facet.vertex[0](2), fminf(facet.vertex[1](2), facet.vertex[2](2)));
|
||||||
|
@ -860,26 +870,43 @@ TriangleMeshSlicer::FacetSliceType TriangleMeshSlicer::slice_facet(
|
||||||
IntersectionPoint points[3];
|
IntersectionPoint points[3];
|
||||||
size_t num_points = 0;
|
size_t num_points = 0;
|
||||||
size_t point_on_layer = size_t(-1);
|
size_t point_on_layer = size_t(-1);
|
||||||
|
|
||||||
// Reorder vertices so that the first one is the one with lowest Z.
|
// Reorder vertices so that the first one is the one with lowest Z.
|
||||||
// This is needed to get all intersection lines in a consistent order
|
// This is needed to get all intersection lines in a consistent order
|
||||||
// (external on the right of the line)
|
// (external on the right of the line)
|
||||||
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
|
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
|
||||||
int i = (facet.vertex[1].z() == min_z) ? 1 : ((facet.vertex[2].z() == min_z) ? 2 : 0);
|
int i = (facet.vertex[1].z() == min_z) ? 1 : ((facet.vertex[2].z() == min_z) ? 2 : 0);
|
||||||
|
|
||||||
|
// These are used only if the cut plane is tilted:
|
||||||
|
stl_vertex rotated_a;
|
||||||
|
stl_vertex rotated_b;
|
||||||
|
|
||||||
for (int j = i; j - i < 3; ++j) { // loop through facet edges
|
for (int j = i; j - i < 3; ++j) { // loop through facet edges
|
||||||
int edge_id = this->facets_edges[facet_idx * 3 + (j % 3)];
|
int edge_id = this->facets_edges[facet_idx * 3 + (j % 3)];
|
||||||
int a_id = vertices[j % 3];
|
int a_id = vertices[j % 3];
|
||||||
int b_id = vertices[(j+1) % 3];
|
int b_id = vertices[(j+1) % 3];
|
||||||
const stl_vertex *a = &this->v_scaled_shared[a_id];
|
|
||||||
const stl_vertex *b = &this->v_scaled_shared[b_id];
|
const stl_vertex *a;
|
||||||
|
const stl_vertex *b;
|
||||||
|
if (m_use_quaternion) {
|
||||||
|
rotated_a = m_quaternion * this->v_scaled_shared[a_id];
|
||||||
|
rotated_b = m_quaternion * this->v_scaled_shared[b_id];
|
||||||
|
a = &rotated_a;
|
||||||
|
b = &rotated_b;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a = &this->v_scaled_shared[a_id];
|
||||||
|
b = &this->v_scaled_shared[b_id];
|
||||||
|
}
|
||||||
|
|
||||||
// Is edge or face aligned with the cutting plane?
|
// Is edge or face aligned with the cutting plane?
|
||||||
if (a->z() == slice_z && b->z() == slice_z) {
|
if (a->z() == slice_z && b->z() == slice_z) {
|
||||||
// Edge is horizontal and belongs to the current layer.
|
// Edge is horizontal and belongs to the current layer.
|
||||||
const stl_vertex &v0 = this->v_scaled_shared[vertices[0]];
|
// The following rotation of the three vertices may not be efficient, but this branch happens rarely.
|
||||||
const stl_vertex &v1 = this->v_scaled_shared[vertices[1]];
|
const stl_vertex &v0 = m_use_quaternion ? stl_vertex(m_quaternion * this->v_scaled_shared[vertices[0]]) : this->v_scaled_shared[vertices[0]];
|
||||||
const stl_vertex &v2 = this->v_scaled_shared[vertices[2]];
|
const stl_vertex &v1 = m_use_quaternion ? stl_vertex(m_quaternion * this->v_scaled_shared[vertices[1]]) : this->v_scaled_shared[vertices[1]];
|
||||||
const stl_normal &normal = this->mesh->stl.facet_start[facet_idx].normal;
|
const stl_vertex &v2 = m_use_quaternion ? stl_vertex(m_quaternion * this->v_scaled_shared[vertices[2]]) : this->v_scaled_shared[vertices[2]];
|
||||||
|
const stl_normal &normal = facet.normal;
|
||||||
// We may ignore this edge for slicing purposes, but we may still use it for object cutting.
|
// We may ignore this edge for slicing purposes, but we may still use it for object cutting.
|
||||||
FacetSliceType result = Slicing;
|
FacetSliceType result = Slicing;
|
||||||
if (min_z == max_z) {
|
if (min_z == max_z) {
|
||||||
|
@ -995,7 +1022,9 @@ TriangleMeshSlicer::FacetSliceType TriangleMeshSlicer::slice_facet(
|
||||||
if (i == line_out->a_id || i == line_out->b_id)
|
if (i == line_out->a_id || i == line_out->b_id)
|
||||||
i = vertices[2];
|
i = vertices[2];
|
||||||
assert(i != line_out->a_id && i != line_out->b_id);
|
assert(i != line_out->a_id && i != line_out->b_id);
|
||||||
line_out->edge_type = (this->v_scaled_shared[i].z() < slice_z) ? feTop : feBottom;
|
line_out->edge_type = ((m_use_quaternion ?
|
||||||
|
(m_quaternion * this->v_scaled_shared[i]).z()
|
||||||
|
: this->v_scaled_shared[i].z()) < slice_z) ? feTop : feBottom;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return Slicing;
|
return Slicing;
|
||||||
|
|
|
@ -25,9 +25,10 @@ public:
|
||||||
TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd> &facets);
|
TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd> &facets);
|
||||||
TriangleMesh(const TriangleMesh &other) : repaired(false) { stl_initialize(&this->stl); *this = other; }
|
TriangleMesh(const TriangleMesh &other) : repaired(false) { stl_initialize(&this->stl); *this = other; }
|
||||||
TriangleMesh(TriangleMesh &&other) : repaired(false) { stl_initialize(&this->stl); this->swap(other); }
|
TriangleMesh(TriangleMesh &&other) : repaired(false) { stl_initialize(&this->stl); this->swap(other); }
|
||||||
~TriangleMesh() { stl_close(&this->stl); }
|
~TriangleMesh() { clear(); }
|
||||||
TriangleMesh& operator=(const TriangleMesh &other);
|
TriangleMesh& operator=(const TriangleMesh &other);
|
||||||
TriangleMesh& operator=(TriangleMesh &&other) { this->swap(other); return *this; }
|
TriangleMesh& operator=(TriangleMesh &&other) { this->swap(other); return *this; }
|
||||||
|
void clear() { stl_close(&this->stl); this->repaired = false; }
|
||||||
void swap(TriangleMesh &other) { std::swap(this->stl, other.stl); std::swap(this->repaired, other.repaired); }
|
void swap(TriangleMesh &other) { std::swap(this->stl, other.stl); std::swap(this->repaired, other.repaired); }
|
||||||
void ReadSTLFile(const char* input_file) { stl_open(&stl, input_file); }
|
void ReadSTLFile(const char* input_file) { stl_open(&stl, input_file); }
|
||||||
void write_ascii(const char* output_file) { stl_write_ascii(&this->stl, output_file, ""); }
|
void write_ascii(const char* output_file) { stl_write_ascii(&this->stl, output_file, ""); }
|
||||||
|
@ -171,6 +172,7 @@ public:
|
||||||
FacetSliceType slice_facet(float slice_z, const stl_facet &facet, const int facet_idx,
|
FacetSliceType slice_facet(float slice_z, const stl_facet &facet, const int facet_idx,
|
||||||
const float min_z, const float max_z, IntersectionLine *line_out) const;
|
const float min_z, const float max_z, IntersectionLine *line_out) const;
|
||||||
void cut(float z, TriangleMesh* upper, TriangleMesh* lower) const;
|
void cut(float z, TriangleMesh* upper, TriangleMesh* lower) const;
|
||||||
|
void set_up_direction(const Vec3f& up);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TriangleMesh *mesh;
|
const TriangleMesh *mesh;
|
||||||
|
@ -178,6 +180,10 @@ private:
|
||||||
std::vector<int> facets_edges;
|
std::vector<int> facets_edges;
|
||||||
// Scaled copy of this->mesh->stl.v_shared
|
// Scaled copy of this->mesh->stl.v_shared
|
||||||
std::vector<stl_vertex> v_scaled_shared;
|
std::vector<stl_vertex> v_scaled_shared;
|
||||||
|
// Quaternion that will be used to rotate every facet before the slicing
|
||||||
|
Eigen::Quaternion<float, Eigen::DontAlign> m_quaternion;
|
||||||
|
// Whether or not the above quaterion should be used
|
||||||
|
bool m_use_quaternion = false;
|
||||||
|
|
||||||
void _slice_do(size_t facet_idx, std::vector<IntersectionLines>* lines, boost::mutex* lines_mutex, const std::vector<float> &z) const;
|
void _slice_do(size_t facet_idx, std::vector<IntersectionLines>* lines, boost::mutex* lines_mutex, const std::vector<float> &z) const;
|
||||||
void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops) const;
|
void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops) const;
|
||||||
|
|
|
@ -6,10 +6,12 @@
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
// Let the NVIDIA and AMD know we want to use their graphics card
|
#ifdef SLIC3R_GUI
|
||||||
// on a dual graphics card system.
|
// Let the NVIDIA and AMD know we want to use their graphics card
|
||||||
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
// on a dual graphics card system.
|
||||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||||
|
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||||
|
#endif /* SLIC3R_GUI */
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -38,8 +40,11 @@
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
|
|
||||||
#include "slic3r.hpp"
|
#include "slic3r.hpp"
|
||||||
#include "slic3r/GUI/GUI.hpp"
|
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#ifdef SLIC3R_GUI
|
||||||
|
#include "slic3r/GUI/GUI.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
|
#endif /* SLIC3R_GUI */
|
||||||
|
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
@ -448,7 +453,7 @@ int CLI::run(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start_gui) {
|
if (start_gui) {
|
||||||
#if 1
|
#ifdef SLIC3R_GUI
|
||||||
// #ifdef USE_WX
|
// #ifdef USE_WX
|
||||||
GUI::GUI_App *gui = new GUI::GUI_App();
|
GUI::GUI_App *gui = new GUI::GUI_App();
|
||||||
// gui->autosave = m_config.opt_string("autosave");
|
// gui->autosave = m_config.opt_string("autosave");
|
||||||
|
@ -477,12 +482,12 @@ int CLI::run(int argc, char **argv)
|
||||||
gui->mainframe->load_config(m_extra_config);
|
gui->mainframe->load_config(m_extra_config);
|
||||||
});
|
});
|
||||||
return wxEntry(argc, argv);
|
return wxEntry(argc, argv);
|
||||||
#else
|
#else /* SLIC3R_GUI */
|
||||||
// No GUI support. Just print out a help.
|
// No GUI support. Just print out a help.
|
||||||
this->print_help(false);
|
this->print_help(false);
|
||||||
// If started without a parameter, consider it to be OK, otherwise report an error code (no action etc).
|
// If started without a parameter, consider it to be OK, otherwise report an error code (no action etc).
|
||||||
return (argc == 0) ? 0 : 1;
|
return (argc == 0) ? 0 : 1;
|
||||||
#endif
|
#endif /* SLIC3R_GUI */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -563,7 +568,13 @@ bool CLI::setup(int argc, char **argv)
|
||||||
void CLI::print_help(bool include_print_options, PrinterTechnology printer_technology) const
|
void CLI::print_help(bool include_print_options, PrinterTechnology printer_technology) const
|
||||||
{
|
{
|
||||||
boost::nowide::cout
|
boost::nowide::cout
|
||||||
<< "Slic3r Prusa Edition " << SLIC3R_BUILD << std::endl
|
<< "Slic3r Prusa Edition " << SLIC3R_BUILD
|
||||||
|
#ifdef SLIC3R_GUI
|
||||||
|
<< " (with GUI support)"
|
||||||
|
#else /* SLIC3R_GUI */
|
||||||
|
<< " (without GUI support)"
|
||||||
|
#endif /* SLIC3R_GUI */
|
||||||
|
<< std::endl
|
||||||
<< "https://github.com/prusa3d/Slic3r" << std::endl << std::endl
|
<< "https://github.com/prusa3d/Slic3r" << std::endl << std::endl
|
||||||
<< "Usage: slic3r [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ file.stl ... ]" << std::endl
|
<< "Usage: slic3r [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ file.stl ... ]" << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
|
|
|
@ -154,7 +154,7 @@ endif ()
|
||||||
|
|
||||||
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
|
||||||
|
|
||||||
target_link_libraries(libslic3r_gui libslic3r avrdude imgui)
|
target_link_libraries(libslic3r_gui libslic3r avrdude imgui ${GLEW_LIBRARIES})
|
||||||
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
|
if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY)
|
||||||
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
|
add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
|
@ -721,32 +721,37 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
return int(this->volumes.size() - 1);
|
return int(this->volumes.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::pair<GLVolume*, double> GLVolumeWithZ;
|
GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func)
|
||||||
typedef std::vector<GLVolumeWithZ> GLVolumesWithZList;
|
|
||||||
static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func)
|
|
||||||
{
|
{
|
||||||
GLVolumesWithZList list;
|
GLVolumeWithIdAndZList list;
|
||||||
list.reserve(volumes.size());
|
list.reserve(volumes.size());
|
||||||
|
|
||||||
for (GLVolume* volume : volumes)
|
for (unsigned int i = 0; i < (unsigned int)volumes.size(); ++i)
|
||||||
{
|
{
|
||||||
|
GLVolume* volume = volumes[i];
|
||||||
bool is_transparent = (volume->render_color[3] < 1.0f);
|
bool is_transparent = (volume->render_color[3] < 1.0f);
|
||||||
if ((((type == GLVolumeCollection::Opaque) && !is_transparent) ||
|
if ((((type == GLVolumeCollection::Opaque) && !is_transparent) ||
|
||||||
((type == GLVolumeCollection::Transparent) && is_transparent) ||
|
((type == GLVolumeCollection::Transparent) && is_transparent) ||
|
||||||
(type == GLVolumeCollection::All)) &&
|
(type == GLVolumeCollection::All)) &&
|
||||||
(! filter_func || filter_func(*volume)))
|
(! filter_func || filter_func(*volume)))
|
||||||
list.emplace_back(std::make_pair(volume, 0.0));
|
list.emplace_back(std::make_pair(volume, std::make_pair(i, 0.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
|
if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
|
||||||
{
|
{
|
||||||
for (GLVolumeWithZ& volume : list)
|
for (GLVolumeWithIdAndZ& volume : list)
|
||||||
{
|
{
|
||||||
volume.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2);
|
volume.second.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(list.begin(), list.end(),
|
std::sort(list.begin(), list.end(),
|
||||||
[](const GLVolumeWithZ& v1, const GLVolumeWithZ& v2) -> bool { return v1.second < v2.second; }
|
[](const GLVolumeWithIdAndZ& v1, const GLVolumeWithIdAndZ& v2) -> bool { return v1.second.second < v2.second.second; }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ((type == GLVolumeCollection::Opaque) && (list.size() > 1))
|
||||||
|
{
|
||||||
|
std::sort(list.begin(), list.end(),
|
||||||
|
[](const GLVolumeWithIdAndZ& v1, const GLVolumeWithIdAndZ& v2) -> bool { return v1.first->selected && !v2.first->selected; }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,6 +774,7 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
|
||||||
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id));
|
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id));
|
||||||
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
|
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
|
||||||
GLint z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "z_range") : -1;
|
GLint z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "z_range") : -1;
|
||||||
|
GLint clipping_plane_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "clipping_plane") : -1;
|
||||||
GLint print_box_min_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.min") : -1;
|
GLint print_box_min_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.min") : -1;
|
||||||
GLint print_box_max_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.max") : -1;
|
GLint print_box_max_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.max") : -1;
|
||||||
GLint print_box_detection_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1;
|
GLint print_box_detection_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1;
|
||||||
|
@ -784,8 +790,11 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
|
||||||
if (z_range_id != -1)
|
if (z_range_id != -1)
|
||||||
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range));
|
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range));
|
||||||
|
|
||||||
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
if (clipping_plane_id != -1)
|
||||||
for (GLVolumeWithZ& volume : to_render) {
|
glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)clipping_plane));
|
||||||
|
|
||||||
|
GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
||||||
|
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||||
volume.first->set_render_color();
|
volume.first->set_render_color();
|
||||||
volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
|
volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
|
||||||
}
|
}
|
||||||
|
@ -814,8 +823,8 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface,
|
||||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||||
|
|
||||||
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
||||||
for (GLVolumeWithZ& volume : to_render)
|
for (GLVolumeWithIdAndZ& volume : to_render)
|
||||||
{
|
{
|
||||||
volume.first->set_render_color();
|
volume.first->set_render_color();
|
||||||
volume.first->render_legacy();
|
volume.first->render_legacy();
|
||||||
|
|
|
@ -412,6 +412,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<GLVolume*> GLVolumePtrs;
|
typedef std::vector<GLVolume*> GLVolumePtrs;
|
||||||
|
typedef std::pair<GLVolume*, std::pair<unsigned int, double>> GLVolumeWithIdAndZ;
|
||||||
|
typedef std::vector<GLVolumeWithIdAndZ> GLVolumeWithIdAndZList;
|
||||||
|
|
||||||
class GLVolumeCollection
|
class GLVolumeCollection
|
||||||
{
|
{
|
||||||
|
@ -431,6 +433,9 @@ private:
|
||||||
// z range for clipping in shaders
|
// z range for clipping in shaders
|
||||||
float z_range[2];
|
float z_range[2];
|
||||||
|
|
||||||
|
// plane coeffs for clipping in shaders
|
||||||
|
float clipping_plane[4];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLVolumePtrs volumes;
|
GLVolumePtrs volumes;
|
||||||
|
|
||||||
|
@ -489,6 +494,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_z_range(float min_z, float max_z) { z_range[0] = min_z; z_range[1] = max_z; }
|
void set_z_range(float min_z, float max_z) { z_range[0] = min_z; z_range[1] = max_z; }
|
||||||
|
void set_clipping_plane(const double* coeffs) { clipping_plane[0] = coeffs[0]; clipping_plane[1] = coeffs[1]; clipping_plane[2] = coeffs[2]; clipping_plane[3] = coeffs[3]; }
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -505,6 +511,8 @@ private:
|
||||||
GLVolumeCollection& operator=(const GLVolumeCollection &);
|
GLVolumeCollection& operator=(const GLVolumeCollection &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = nullptr);
|
||||||
|
|
||||||
class GLModel
|
class GLModel
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -255,16 +255,21 @@ void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config)
|
||||||
void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
|
void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
|
||||||
{
|
{
|
||||||
const ModelObject *model_object_new = (object_id >= 0) ? model.objects[object_id] : nullptr;
|
const ModelObject *model_object_new = (object_id >= 0) ? model.objects[object_id] : nullptr;
|
||||||
if (model_object_new == nullptr || this->last_object_id != object_id || m_model_object != model_object_new || m_model_object->id() != model_object_new->id()) {
|
// Maximum height of an object changes when the object gets rotated or scaled.
|
||||||
|
// Changing maximum height of an object will invalidate the layer heigth editing profile.
|
||||||
|
// m_model_object->raw_bounding_box() is cached, therefore it is cheap even if this method is called frequently.
|
||||||
|
float new_max_z = (m_model_object == nullptr) ? 0.f : m_model_object->raw_bounding_box().size().z();
|
||||||
|
if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z ||
|
||||||
|
(model_object_new != nullptr && m_model_object->id() != model_object_new->id())) {
|
||||||
m_layer_height_profile.clear();
|
m_layer_height_profile.clear();
|
||||||
m_layer_height_profile_modified = false;
|
m_layer_height_profile_modified = false;
|
||||||
delete m_slicing_parameters;
|
delete m_slicing_parameters;
|
||||||
m_slicing_parameters = nullptr;
|
m_slicing_parameters = nullptr;
|
||||||
m_layers_texture.valid = false;
|
m_layers_texture.valid = false;
|
||||||
|
this->last_object_id = object_id;
|
||||||
|
m_model_object = model_object_new;
|
||||||
|
m_object_max_z = new_max_z;
|
||||||
}
|
}
|
||||||
this->last_object_id = object_id;
|
|
||||||
m_model_object = model_object_new;
|
|
||||||
m_object_max_z = (m_model_object == nullptr) ? 0.f : m_model_object->bounding_box().max.z();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLCanvas3D::LayersEditing::is_allowed() const
|
bool GLCanvas3D::LayersEditing::is_allowed() const
|
||||||
|
@ -623,7 +628,7 @@ void GLCanvas3D::LayersEditing::update_slicing_parameters()
|
||||||
{
|
{
|
||||||
if (m_slicing_parameters == nullptr) {
|
if (m_slicing_parameters == nullptr) {
|
||||||
m_slicing_parameters = new SlicingParameters();
|
m_slicing_parameters = new SlicingParameters();
|
||||||
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object);
|
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2204,6 +2209,9 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
|
||||||
|
|
||||||
void GLCanvas3D::on_char(wxKeyEvent& evt)
|
void GLCanvas3D::on_char(wxKeyEvent& evt)
|
||||||
{
|
{
|
||||||
|
if (!m_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
// see include/wx/defs.h enum wxKeyCode
|
// see include/wx/defs.h enum wxKeyCode
|
||||||
int keyCode = evt.GetKeyCode();
|
int keyCode = evt.GetKeyCode();
|
||||||
int ctrlMask = wxMOD_CONTROL;
|
int ctrlMask = wxMOD_CONTROL;
|
||||||
|
@ -2222,9 +2230,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
||||||
//#endif /* __APPLE__ */
|
//#endif /* __APPLE__ */
|
||||||
if ((evt.GetModifiers() & ctrlMask) != 0) {
|
if ((evt.GetModifiers() & ctrlMask) != 0) {
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
|
#ifdef __APPLE__
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'A':
|
case 'A':
|
||||||
|
#else /* __APPLE__ */
|
||||||
case WXK_CONTROL_A:
|
case WXK_CONTROL_A:
|
||||||
|
#endif /* __APPLE__ */
|
||||||
post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL));
|
post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL));
|
||||||
break;
|
break;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -3134,6 +3145,11 @@ Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
|
||||||
return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1));
|
return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
|
||||||
|
{
|
||||||
|
return factor * m_bed.get_bounding_box().max_size();
|
||||||
|
}
|
||||||
|
|
||||||
bool GLCanvas3D::_is_shown_on_screen() const
|
bool GLCanvas3D::_is_shown_on_screen() const
|
||||||
{
|
{
|
||||||
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
|
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
|
||||||
|
@ -3226,12 +3242,37 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
if (!m_toolbar.add_separator())
|
if (!m_toolbar.add_separator())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
item.name = "copy";
|
||||||
|
#if ENABLE_SVG_ICONS
|
||||||
|
item.icon_filename = "copy.svg";
|
||||||
|
#endif // ENABLE_SVG_ICONS
|
||||||
|
item.tooltip = GUI::L_str("Copy") + " [" + GUI::shortkey_ctrl_prefix() + "C]";
|
||||||
|
item.sprite_id = 4;
|
||||||
|
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); };
|
||||||
|
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_copy(); };
|
||||||
|
if (!m_toolbar.add_item(item))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
item.name = "paste";
|
||||||
|
#if ENABLE_SVG_ICONS
|
||||||
|
item.icon_filename = "paste.svg";
|
||||||
|
#endif // ENABLE_SVG_ICONS
|
||||||
|
item.tooltip = GUI::L_str("Paste") + " [" + GUI::shortkey_ctrl_prefix() + "V]";
|
||||||
|
item.sprite_id = 5;
|
||||||
|
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); };
|
||||||
|
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_paste(); };
|
||||||
|
if (!m_toolbar.add_item(item))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!m_toolbar.add_separator())
|
||||||
|
return false;
|
||||||
|
|
||||||
item.name = "more";
|
item.name = "more";
|
||||||
#if ENABLE_SVG_ICONS
|
#if ENABLE_SVG_ICONS
|
||||||
item.icon_filename = "instance_add.svg";
|
item.icon_filename = "instance_add.svg";
|
||||||
#endif // ENABLE_SVG_ICONS
|
#endif // ENABLE_SVG_ICONS
|
||||||
item.tooltip = GUI::L_str("Add instance [+]");
|
item.tooltip = GUI::L_str("Add instance [+]");
|
||||||
item.sprite_id = 4;
|
item.sprite_id = 6;
|
||||||
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); };
|
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); };
|
||||||
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
|
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
|
||||||
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_increase_instances(); };
|
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_increase_instances(); };
|
||||||
|
@ -3243,7 +3284,7 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.icon_filename = "instance_remove.svg";
|
item.icon_filename = "instance_remove.svg";
|
||||||
#endif // ENABLE_SVG_ICONS
|
#endif // ENABLE_SVG_ICONS
|
||||||
item.tooltip = GUI::L_str("Remove instance [-]");
|
item.tooltip = GUI::L_str("Remove instance [-]");
|
||||||
item.sprite_id = 5;
|
item.sprite_id = 7;
|
||||||
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); };
|
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); };
|
||||||
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
|
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
|
||||||
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_decrease_instances(); };
|
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_decrease_instances(); };
|
||||||
|
@ -3258,7 +3299,7 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.icon_filename = "split_objects.svg";
|
item.icon_filename = "split_objects.svg";
|
||||||
#endif // ENABLE_SVG_ICONS
|
#endif // ENABLE_SVG_ICONS
|
||||||
item.tooltip = GUI::L_str("Split to objects");
|
item.tooltip = GUI::L_str("Split to objects");
|
||||||
item.sprite_id = 6;
|
item.sprite_id = 8;
|
||||||
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); };
|
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); };
|
||||||
item.visibility_callback = GLToolbarItem::Default_Visibility_Callback;
|
item.visibility_callback = GLToolbarItem::Default_Visibility_Callback;
|
||||||
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_objects(); };
|
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_objects(); };
|
||||||
|
@ -3270,7 +3311,7 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.icon_filename = "split_parts.svg";
|
item.icon_filename = "split_parts.svg";
|
||||||
#endif // ENABLE_SVG_ICONS
|
#endif // ENABLE_SVG_ICONS
|
||||||
item.tooltip = GUI::L_str("Split to parts");
|
item.tooltip = GUI::L_str("Split to parts");
|
||||||
item.sprite_id = 7;
|
item.sprite_id = 9;
|
||||||
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); };
|
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); };
|
||||||
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
|
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
|
||||||
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_volumes(); };
|
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_volumes(); };
|
||||||
|
@ -3285,7 +3326,7 @@ bool GLCanvas3D::_init_toolbar()
|
||||||
item.icon_filename = "layers.svg";
|
item.icon_filename = "layers.svg";
|
||||||
#endif // ENABLE_SVG_ICONS
|
#endif // ENABLE_SVG_ICONS
|
||||||
item.tooltip = GUI::L_str("Layers editing");
|
item.tooltip = GUI::L_str("Layers editing");
|
||||||
item.sprite_id = 8;
|
item.sprite_id = 10;
|
||||||
item.is_toggable = true;
|
item.is_toggable = true;
|
||||||
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
|
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
|
||||||
item.visibility_callback = [this]()->bool { return m_process->current_printer_technology() == ptFFF; };
|
item.visibility_callback = [this]()->bool { return m_process->current_printer_technology() == ptFFF; };
|
||||||
|
@ -3490,7 +3531,15 @@ void GLCanvas3D::_picking_pass() const
|
||||||
|
|
||||||
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||||
|
|
||||||
_render_volumes(true);
|
m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane();
|
||||||
|
if (m_camera_clipping_plane.is_active()) {
|
||||||
|
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data());
|
||||||
|
::glEnable(GL_CLIP_PLANE0);
|
||||||
|
}
|
||||||
|
_render_volumes_for_picking();
|
||||||
|
if (m_camera_clipping_plane.is_active())
|
||||||
|
::glDisable(GL_CLIP_PLANE0);
|
||||||
|
|
||||||
m_gizmos.render_current_gizmo_for_picking_pass(m_selection);
|
m_gizmos.render_current_gizmo_for_picking_pass(m_selection);
|
||||||
|
|
||||||
if (m_multisample_allowed)
|
if (m_multisample_allowed)
|
||||||
|
@ -3571,6 +3620,8 @@ void GLCanvas3D::_render_axes() const
|
||||||
m_bed.render_axes();
|
m_bed.render_axes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GLCanvas3D::_render_objects() const
|
void GLCanvas3D::_render_objects() const
|
||||||
{
|
{
|
||||||
if (m_volumes.empty())
|
if (m_volumes.empty())
|
||||||
|
@ -3579,6 +3630,8 @@ void GLCanvas3D::_render_objects() const
|
||||||
glsafe(::glEnable(GL_LIGHTING));
|
glsafe(::glEnable(GL_LIGHTING));
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
|
m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane();
|
||||||
|
|
||||||
if (m_use_VBOs)
|
if (m_use_VBOs)
|
||||||
{
|
{
|
||||||
if (m_picking_enabled)
|
if (m_picking_enabled)
|
||||||
|
@ -3599,6 +3652,8 @@ void GLCanvas3D::_render_objects() const
|
||||||
else
|
else
|
||||||
m_volumes.set_z_range(-FLT_MAX, FLT_MAX);
|
m_volumes.set_z_range(-FLT_MAX, FLT_MAX);
|
||||||
|
|
||||||
|
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
|
||||||
|
|
||||||
m_shader.start_using();
|
m_shader.start_using();
|
||||||
if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) {
|
if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) {
|
||||||
int object_id = m_layers_editing.last_object_id;
|
int object_id = m_layers_editing.last_object_id;
|
||||||
|
@ -3619,13 +3674,17 @@ void GLCanvas3D::_render_objects() const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data());
|
||||||
|
::glEnable(GL_CLIP_PLANE0);
|
||||||
|
|
||||||
if (m_use_clipping_planes)
|
if (m_use_clipping_planes)
|
||||||
{
|
{
|
||||||
glsafe(::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_clipping_planes[0].get_data()));
|
glsafe(::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[0].get_data()));
|
||||||
glsafe(::glEnable(GL_CLIP_PLANE0));
|
|
||||||
glsafe(::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[1].get_data()));
|
|
||||||
glsafe(::glEnable(GL_CLIP_PLANE1));
|
glsafe(::glEnable(GL_CLIP_PLANE1));
|
||||||
|
glsafe(::glClipPlane(GL_CLIP_PLANE2, (GLdouble*)m_clipping_planes[1].get_data()));
|
||||||
|
glsafe(::glEnable(GL_CLIP_PLANE2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// do not cull backfaces to show broken geometry, if any
|
// do not cull backfaces to show broken geometry, if any
|
||||||
m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) {
|
m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) {
|
||||||
|
@ -3633,13 +3692,16 @@ void GLCanvas3D::_render_objects() const
|
||||||
});
|
});
|
||||||
m_volumes.render_legacy(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix());
|
m_volumes.render_legacy(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix());
|
||||||
|
|
||||||
|
::glDisable(GL_CLIP_PLANE0);
|
||||||
|
|
||||||
if (m_use_clipping_planes)
|
if (m_use_clipping_planes)
|
||||||
{
|
{
|
||||||
glsafe(::glDisable(GL_CLIP_PLANE0));
|
|
||||||
glsafe(::glDisable(GL_CLIP_PLANE1));
|
glsafe(::glDisable(GL_CLIP_PLANE1));
|
||||||
|
glsafe(::glDisable(GL_CLIP_PLANE2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_camera_clipping_plane = ClippingPlane::ClipsNothing();
|
||||||
glsafe(::glDisable(GL_LIGHTING));
|
glsafe(::glDisable(GL_LIGHTING));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3675,13 +3737,10 @@ void GLCanvas3D::_render_legend_texture() const
|
||||||
m_legend_texture.render(*this);
|
m_legend_texture.render(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_render_volumes(bool fake_colors) const
|
void GLCanvas3D::_render_volumes_for_picking() const
|
||||||
{
|
{
|
||||||
static const GLfloat INV_255 = 1.0f / 255.0f;
|
static const GLfloat INV_255 = 1.0f / 255.0f;
|
||||||
|
|
||||||
if (!fake_colors)
|
|
||||||
glsafe(::glEnable(GL_LIGHTING));
|
|
||||||
|
|
||||||
// do not cull backfaces to show broken geometry, if any
|
// do not cull backfaces to show broken geometry, if any
|
||||||
glsafe(::glDisable(GL_CULL_FACE));
|
glsafe(::glDisable(GL_CULL_FACE));
|
||||||
|
|
||||||
|
@ -3691,27 +3750,31 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||||
|
|
||||||
unsigned int volume_id = 0;
|
const Transform3d& view_matrix = m_camera.get_view_matrix();
|
||||||
for (GLVolume* vol : m_volumes.volumes)
|
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Opaque, view_matrix);
|
||||||
|
for (const GLVolumeWithIdAndZ& volume : to_render)
|
||||||
{
|
{
|
||||||
if (fake_colors)
|
// Object picking mode. Render the object with a color encoding the object index.
|
||||||
{
|
unsigned int r = (volume.second.first & 0x000000FF) >> 0;
|
||||||
// Object picking mode. Render the object with a color encoding the object index.
|
unsigned int g = (volume.second.first & 0x0000FF00) >> 8;
|
||||||
unsigned int r = (volume_id & 0x000000FF) >> 0;
|
unsigned int b = (volume.second.first & 0x00FF0000) >> 16;
|
||||||
unsigned int g = (volume_id & 0x0000FF00) >> 8;
|
glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255));
|
||||||
unsigned int b = (volume_id & 0x00FF0000) >> 16;
|
|
||||||
glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vol->set_render_color();
|
|
||||||
glsafe(::glColor4fv(vol->render_color));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!fake_colors || !vol->disabled) && (vol->composite_id.volume_id >= 0 || m_render_sla_auxiliaries))
|
if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries))
|
||||||
vol->render();
|
volume.first->render();
|
||||||
|
}
|
||||||
|
|
||||||
++volume_id;
|
to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Transparent, view_matrix);
|
||||||
|
for (const GLVolumeWithIdAndZ& volume : to_render)
|
||||||
|
{
|
||||||
|
// Object picking mode. Render the object with a color encoding the object index.
|
||||||
|
unsigned int r = (volume.second.first & 0x000000FF) >> 0;
|
||||||
|
unsigned int g = (volume.second.first & 0x0000FF00) >> 8;
|
||||||
|
unsigned int b = (volume.second.first & 0x00FF0000) >> 16;
|
||||||
|
glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255));
|
||||||
|
|
||||||
|
if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries))
|
||||||
|
volume.first->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||||
|
@ -3719,9 +3782,6 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
|
|
||||||
glsafe(::glEnable(GL_CULL_FACE));
|
glsafe(::glEnable(GL_CULL_FACE));
|
||||||
|
|
||||||
if (!fake_colors)
|
|
||||||
glsafe(::glDisable(GL_LIGHTING));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::_render_current_gizmo() const
|
void GLCanvas3D::_render_current_gizmo() const
|
||||||
|
@ -3999,15 +4059,9 @@ void GLCanvas3D::_update_volumes_hover_state() const
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GLVolume* volume = m_volumes.volumes[m_hover_volume_id];
|
GLVolume* volume = m_volumes.volumes[m_hover_volume_id];
|
||||||
|
if (volume->is_modifier)
|
||||||
switch (m_selection.get_mode())
|
|
||||||
{
|
|
||||||
case Selection::Volume:
|
|
||||||
{
|
|
||||||
volume->hover = true;
|
volume->hover = true;
|
||||||
break;
|
else
|
||||||
}
|
|
||||||
case Selection::Instance:
|
|
||||||
{
|
{
|
||||||
int object_idx = volume->object_idx();
|
int object_idx = volume->object_idx();
|
||||||
int instance_idx = volume->instance_idx();
|
int instance_idx = volume->instance_idx();
|
||||||
|
@ -4017,9 +4071,6 @@ void GLCanvas3D::_update_volumes_hover_state() const
|
||||||
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
|
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
|
||||||
v->hover = true;
|
v->hover = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,37 @@ public:
|
||||||
void set_scale_factor(int height);
|
void set_scale_factor(int height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ClippingPlane
|
||||||
|
{
|
||||||
|
double m_data[4];
|
||||||
|
|
||||||
|
public:
|
||||||
|
ClippingPlane()
|
||||||
|
{
|
||||||
|
m_data[0] = 0.0;
|
||||||
|
m_data[1] = 0.0;
|
||||||
|
m_data[2] = 1.0;
|
||||||
|
m_data[3] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClippingPlane(const Vec3d& direction, double offset)
|
||||||
|
{
|
||||||
|
Vec3d norm_dir = direction.normalized();
|
||||||
|
m_data[0] = norm_dir(0);
|
||||||
|
m_data[1] = norm_dir(1);
|
||||||
|
m_data[2] = norm_dir(2);
|
||||||
|
m_data[3] = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_active() const { return m_data[3] != DBL_MAX; }
|
||||||
|
|
||||||
|
static ClippingPlane ClipsNothing() { return ClippingPlane(Vec3d(0., 0., 1.), DBL_MAX); }
|
||||||
|
|
||||||
|
const double* get_data() const { return m_data; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
|
||||||
|
|
||||||
using Vec2dEvent = Event<Vec2d>;
|
using Vec2dEvent = Event<Vec2d>;
|
||||||
|
@ -288,32 +319,6 @@ class GLCanvas3D
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
|
||||||
class ClippingPlane
|
|
||||||
{
|
|
||||||
double m_data[4];
|
|
||||||
|
|
||||||
public:
|
|
||||||
ClippingPlane()
|
|
||||||
{
|
|
||||||
m_data[0] = 0.0;
|
|
||||||
m_data[1] = 0.0;
|
|
||||||
m_data[2] = 1.0;
|
|
||||||
m_data[3] = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClippingPlane(const Vec3d& direction, double offset)
|
|
||||||
{
|
|
||||||
Vec3d norm_dir = direction.normalized();
|
|
||||||
m_data[0] = norm_dir(0);
|
|
||||||
m_data[1] = norm_dir(1);
|
|
||||||
m_data[2] = norm_dir(2);
|
|
||||||
m_data[3] = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
const double* get_data() const { return m_data; }
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SlaCap
|
struct SlaCap
|
||||||
{
|
{
|
||||||
|
@ -405,6 +410,7 @@ private:
|
||||||
mutable GLGizmosManager m_gizmos;
|
mutable GLGizmosManager m_gizmos;
|
||||||
mutable GLToolbar m_toolbar;
|
mutable GLToolbar m_toolbar;
|
||||||
ClippingPlane m_clipping_planes[2];
|
ClippingPlane m_clipping_planes[2];
|
||||||
|
mutable ClippingPlane m_camera_clipping_plane;
|
||||||
bool m_use_clipping_planes;
|
bool m_use_clipping_planes;
|
||||||
mutable SlaCap m_sla_caps[2];
|
mutable SlaCap m_sla_caps[2];
|
||||||
std::string m_sidebar_field;
|
std::string m_sidebar_field;
|
||||||
|
@ -579,6 +585,8 @@ public:
|
||||||
void refresh_camera_scene_box() { m_camera.set_scene_box(scene_bounding_box()); }
|
void refresh_camera_scene_box() { m_camera.set_scene_box(scene_bounding_box()); }
|
||||||
bool is_mouse_dragging() const { return m_mouse.dragging; }
|
bool is_mouse_dragging() const { return m_mouse.dragging; }
|
||||||
|
|
||||||
|
double get_size_proportional_to_max_bed_size(double factor) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_shown_on_screen() const;
|
bool _is_shown_on_screen() const;
|
||||||
|
|
||||||
|
@ -605,7 +613,7 @@ private:
|
||||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||||
void _render_warning_texture() const;
|
void _render_warning_texture() const;
|
||||||
void _render_legend_texture() const;
|
void _render_legend_texture() const;
|
||||||
void _render_volumes(bool fake_colors) const;
|
void _render_volumes_for_picking() const;
|
||||||
void _render_current_gizmo() const;
|
void _render_current_gizmo() const;
|
||||||
void _render_gizmos_overlay() const;
|
void _render_gizmos_overlay() const;
|
||||||
void _render_toolbar() const;
|
void _render_toolbar() const;
|
||||||
|
|
|
@ -21,6 +21,8 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
|
||||||
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent);
|
||||||
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
|
||||||
|
|
|
@ -20,6 +20,8 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
|
||||||
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent);
|
||||||
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
|
||||||
wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
|
wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
|
||||||
|
|
|
@ -61,19 +61,22 @@ ObjectList::ObjectList(wxWindow* parent) :
|
||||||
{
|
{
|
||||||
// Fill CATEGORY_ICON
|
// Fill CATEGORY_ICON
|
||||||
{
|
{
|
||||||
|
// Note: `this` isn't passed to create_scaled_bitmap() here because of bugs in the widget,
|
||||||
|
// see note in PresetBundle::load_compatible_bitmaps()
|
||||||
|
|
||||||
// ptFFF
|
// ptFFF
|
||||||
CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap(this, "layers");
|
CATEGORY_ICON[L("Layers and Perimeters")] = create_scaled_bitmap(nullptr, "layers");
|
||||||
CATEGORY_ICON[L("Infill")] = create_scaled_bitmap(this, "infill");
|
CATEGORY_ICON[L("Infill")] = create_scaled_bitmap(nullptr, "infill");
|
||||||
CATEGORY_ICON[L("Support material")] = create_scaled_bitmap(this, "support");
|
CATEGORY_ICON[L("Support material")] = create_scaled_bitmap(nullptr, "support");
|
||||||
CATEGORY_ICON[L("Speed")] = create_scaled_bitmap(this, "time");
|
CATEGORY_ICON[L("Speed")] = create_scaled_bitmap(nullptr, "time");
|
||||||
CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap(this, "funnel");
|
CATEGORY_ICON[L("Extruders")] = create_scaled_bitmap(nullptr, "funnel");
|
||||||
CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap(this, "funnel");
|
CATEGORY_ICON[L("Extrusion Width")] = create_scaled_bitmap(nullptr, "funnel");
|
||||||
// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap(this, "skirt+brim");
|
// CATEGORY_ICON[L("Skirt and brim")] = create_scaled_bitmap(nullptr, "skirt+brim");
|
||||||
// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap(this, "time");
|
// CATEGORY_ICON[L("Speed > Acceleration")] = create_scaled_bitmap(nullptr, "time");
|
||||||
CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap(this, "wrench");
|
CATEGORY_ICON[L("Advanced")] = create_scaled_bitmap(nullptr, "wrench");
|
||||||
// ptSLA
|
// ptSLA
|
||||||
CATEGORY_ICON[L("Supports")] = create_scaled_bitmap(this, "sla_supports");
|
CATEGORY_ICON[L("Supports")] = create_scaled_bitmap(nullptr, "support"/*"sla_supports"*/);
|
||||||
CATEGORY_ICON[L("Pad")] = create_scaled_bitmap(this, "brick.png");
|
CATEGORY_ICON[L("Pad")] = create_scaled_bitmap(nullptr, "pad");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create control
|
// create control
|
||||||
|
@ -392,10 +395,10 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const
|
||||||
|
|
||||||
void ObjectList::init_icons()
|
void ObjectList::init_icons()
|
||||||
{
|
{
|
||||||
m_bmp_modifiermesh = create_scaled_bitmap(this, "lambda.png");
|
m_bmp_modifiermesh = create_scaled_bitmap(nullptr, "add_modifier");
|
||||||
m_bmp_solidmesh = create_scaled_bitmap(this, "object.png");
|
m_bmp_solidmesh = create_scaled_bitmap(nullptr, "add_part");
|
||||||
m_bmp_support_enforcer = create_scaled_bitmap(this, "support_enforcer_.png");
|
m_bmp_support_enforcer = create_scaled_bitmap(nullptr, "support_enforcer");
|
||||||
m_bmp_support_blocker = create_scaled_bitmap(this, "support_blocker_.png");
|
m_bmp_support_blocker = create_scaled_bitmap(nullptr, "support_blocker");
|
||||||
|
|
||||||
|
|
||||||
m_bmp_vector.reserve(4); // bitmaps for different types of parts
|
m_bmp_vector.reserve(4); // bitmaps for different types of parts
|
||||||
|
@ -406,13 +409,13 @@ void ObjectList::init_icons()
|
||||||
m_objects_model->SetVolumeBitmaps(m_bmp_vector);
|
m_objects_model->SetVolumeBitmaps(m_bmp_vector);
|
||||||
|
|
||||||
// init icon for manifold warning
|
// init icon for manifold warning
|
||||||
m_bmp_manifold_warning = create_scaled_bitmap(this, "exclamation_mark_.png");
|
m_bmp_manifold_warning = create_scaled_bitmap(nullptr, "exclamation");
|
||||||
|
|
||||||
// init bitmap for "Split to sub-objects" context menu
|
// init bitmap for "Split to sub-objects" context menu
|
||||||
m_bmp_split = create_scaled_bitmap(this, "split_parts");
|
m_bmp_split = create_scaled_bitmap(nullptr, "split_parts_SMALL");
|
||||||
|
|
||||||
// init bitmap for "Add Settings" context menu
|
// init bitmap for "Add Settings" context menu
|
||||||
m_bmp_cog = create_scaled_bitmap(this, "cog");
|
m_bmp_cog = create_scaled_bitmap(nullptr, "cog");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -436,6 +439,66 @@ void ObjectList::selection_changed()
|
||||||
part_selection_changed();
|
part_selection_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes)
|
||||||
|
{
|
||||||
|
if ((obj_idx < 0) || ((int)m_objects->size() <= obj_idx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (volumes.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ModelObject& model_object = *(*m_objects)[obj_idx];
|
||||||
|
const auto object_item = m_objects_model->GetItemById(obj_idx);
|
||||||
|
|
||||||
|
wxDataViewItemArray items;
|
||||||
|
|
||||||
|
for (const ModelVolume* volume : volumes)
|
||||||
|
{
|
||||||
|
auto vol_item = m_objects_model->AddVolumeChild(object_item, volume->name, volume->type(),
|
||||||
|
volume->config.has("extruder") ? volume->config.option<ConfigOptionInt>("extruder")->value : 0);
|
||||||
|
auto opt_keys = volume->config.keys();
|
||||||
|
if (!opt_keys.empty() && !((opt_keys.size() == 1) && (opt_keys[0] == "extruder")))
|
||||||
|
select_item(m_objects_model->AddSettingsChild(vol_item));
|
||||||
|
|
||||||
|
items.Add(vol_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_parts_changed = true;
|
||||||
|
parts_changed(obj_idx);
|
||||||
|
|
||||||
|
if (items.size() > 1)
|
||||||
|
{
|
||||||
|
m_selection_mode = smVolume;
|
||||||
|
m_last_selected_item = wxDataViewItem(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
select_items(items);
|
||||||
|
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
|
||||||
|
selection_changed();
|
||||||
|
#endif //no __WXOSX__ //__WXMSW__
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectList::paste_objects_into_list(const std::vector<size_t>& object_idxs)
|
||||||
|
{
|
||||||
|
if (object_idxs.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxDataViewItemArray items;
|
||||||
|
for (const size_t object : object_idxs)
|
||||||
|
{
|
||||||
|
add_object_to_list(object);
|
||||||
|
m_parts_changed = true;
|
||||||
|
parts_changed(object);
|
||||||
|
|
||||||
|
items.Add(m_objects_model->GetItemById(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
select_items(items);
|
||||||
|
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
|
||||||
|
selection_changed();
|
||||||
|
#endif //no __WXOSX__ //__WXMSW__
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectList::OnChar(wxKeyEvent& event)
|
void ObjectList::OnChar(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
if (event.GetKeyCode() == WXK_BACK){
|
if (event.GetKeyCode() == WXK_BACK){
|
||||||
|
@ -1374,9 +1437,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
||||||
const wxString name = _(L("Generic")) + "-" + _(type_name);
|
const wxString name = _(L("Generic")) + "-" + _(type_name);
|
||||||
TriangleMesh mesh;
|
TriangleMesh mesh;
|
||||||
|
|
||||||
auto& bed_shape = printer_config().option<ConfigOptionPoints>("bed_shape")->values;
|
double side = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.1);
|
||||||
const auto& sz = BoundingBoxf(bed_shape).size();
|
|
||||||
const auto side = 0.1 * std::max(sz(0), sz(1));
|
|
||||||
|
|
||||||
if (type_name == "Box")
|
if (type_name == "Box")
|
||||||
// Sitting on the print bed, left front front corner at (0, 0).
|
// Sitting on the print bed, left front front corner at (0, 0).
|
||||||
|
@ -1573,11 +1634,11 @@ void ObjectList::split()
|
||||||
|
|
||||||
for (auto id = 0; id < model_object->volumes.size(); id++) {
|
for (auto id = 0; id < model_object->volumes.size(); id++) {
|
||||||
const auto vol_item = m_objects_model->AddVolumeChild(parent, from_u8(model_object->volumes[id]->name),
|
const auto vol_item = m_objects_model->AddVolumeChild(parent, from_u8(model_object->volumes[id]->name),
|
||||||
model_object->volumes[id]->is_modifier() ?
|
model_object->volumes[id]->is_modifier() ?
|
||||||
ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART,
|
ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART,
|
||||||
model_object->volumes[id]->config.has("extruder") ?
|
model_object->volumes[id]->config.has("extruder") ?
|
||||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||||
false);
|
false);
|
||||||
// add settings to the part, if it has those
|
// add settings to the part, if it has those
|
||||||
auto opt_keys = model_object->volumes[id]->config.keys();
|
auto opt_keys = model_object->volumes[id]->config.keys();
|
||||||
if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) {
|
if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) {
|
||||||
|
@ -2132,6 +2193,7 @@ void ObjectList::update_selections_on_canvas()
|
||||||
add_to_selection(item, selection, instance_idx, false);
|
add_to_selection(item, selection, instance_idx, false);
|
||||||
|
|
||||||
wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state();
|
wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state();
|
||||||
|
wxGetApp().plater()->canvas3D()->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::select_item(const wxDataViewItem& item)
|
void ObjectList::select_item(const wxDataViewItem& item)
|
||||||
|
|
|
@ -31,6 +31,8 @@ typedef std::map<std::string, std::vector<std::string>> FreqSettingsBundle;
|
||||||
// category -> vector ( option ; label )
|
// category -> vector ( option ; label )
|
||||||
typedef std::map< std::string, std::vector< std::pair<std::string, std::string> > > settings_menu_hierarchy;
|
typedef std::map< std::string, std::vector< std::pair<std::string, std::string> > > settings_menu_hierarchy;
|
||||||
|
|
||||||
|
typedef std::vector<ModelVolume*> ModelVolumePtrs;
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
wxDECLARE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent);
|
wxDECLARE_EVENT(EVT_OBJ_LIST_OBJECT_SELECT, SimpleEvent);
|
||||||
|
@ -286,6 +288,9 @@ public:
|
||||||
void fix_through_netfabb() const;
|
void fix_through_netfabb() const;
|
||||||
void update_item_error_icon(const int obj_idx, int vol_idx) const ;
|
void update_item_error_icon(const int obj_idx, int vol_idx) const ;
|
||||||
|
|
||||||
|
void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes);
|
||||||
|
void paste_objects_into_list(const std::vector<size_t>& object_idxs);
|
||||||
|
|
||||||
void rescale();
|
void rescale();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -818,8 +818,8 @@ void Preview::on_sliders_scroll_changed(wxEvent& event)
|
||||||
}
|
}
|
||||||
else if (tech == ptSLA)
|
else if (tech == ptSLA)
|
||||||
{
|
{
|
||||||
m_canvas->set_clipping_plane(0, GLCanvas3D::ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD()));
|
m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD()));
|
||||||
m_canvas->set_clipping_plane(1, GLCanvas3D::ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD()));
|
m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD()));
|
||||||
m_canvas->set_use_clipping_planes(m_slider->GetHigherValue() != 0);
|
m_canvas->set_use_clipping_planes(m_slider->GetHigherValue() != 0);
|
||||||
m_canvas_widget->Refresh();
|
m_canvas_widget->Refresh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "slic3r/GUI/GUI_ObjectSettings.hpp"
|
#include "slic3r/GUI/GUI_ObjectSettings.hpp"
|
||||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
#include "slic3r/GUI/PresetBundle.hpp"
|
#include "slic3r/GUI/PresetBundle.hpp"
|
||||||
|
#include "libslic3r/Tesselate.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
@ -47,24 +48,24 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S
|
||||||
{
|
{
|
||||||
if (selection.is_empty()) {
|
if (selection.is_empty()) {
|
||||||
m_model_object = nullptr;
|
m_model_object = nullptr;
|
||||||
m_old_model_object = nullptr;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_old_model_object = m_model_object;
|
|
||||||
m_model_object = model_object;
|
m_model_object = model_object;
|
||||||
m_active_instance = selection.get_instance_idx();
|
m_active_instance = selection.get_instance_idx();
|
||||||
|
|
||||||
if (model_object && selection.is_from_single_instance())
|
if (model_object && selection.is_from_single_instance())
|
||||||
{
|
{
|
||||||
|
// Cache the bb - it's needed for dealing with the clipping plane quite often
|
||||||
|
// It could be done inside update_mesh but one has to account for scaling of the instance.
|
||||||
|
//FIXME calling ModelObject::instance_bounding_box() is expensive!
|
||||||
|
m_active_instance_bb_radius = m_model_object->instance_bounding_box(m_active_instance).radius();
|
||||||
|
|
||||||
if (is_mesh_update_necessary()) {
|
if (is_mesh_update_necessary()) {
|
||||||
update_mesh();
|
update_mesh();
|
||||||
editing_mode_reload_cache();
|
editing_mode_reload_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_model_object != m_old_model_object)
|
|
||||||
m_editing_mode = false;
|
|
||||||
|
|
||||||
if (m_editing_mode_cache.empty() && m_model_object->sla_points_status != sla::PointsStatus::UserModified)
|
if (m_editing_mode_cache.empty() && m_model_object->sla_points_status != sla::PointsStatus::UserModified)
|
||||||
get_data_from_backend();
|
get_data_from_backend();
|
||||||
|
|
||||||
|
@ -88,12 +89,75 @@ void GLGizmoSlaSupports::on_render(const Selection& selection) const
|
||||||
glsafe(::glEnable(GL_BLEND));
|
glsafe(::glEnable(GL_BLEND));
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
render_points(selection, false);
|
// we'll recover current look direction from the modelview matrix (in world coords):
|
||||||
|
Eigen::Matrix<double, 4, 4, Eigen::DontAlign> modelview_matrix;
|
||||||
|
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
|
||||||
|
Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]);
|
||||||
|
m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
|
||||||
|
|
||||||
|
if (m_quadric != nullptr && selection.is_from_single_instance())
|
||||||
|
render_points(selection, direction_to_camera, false);
|
||||||
|
|
||||||
render_selection_rectangle();
|
render_selection_rectangle();
|
||||||
|
render_clipping_plane(selection, direction_to_camera);
|
||||||
|
|
||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection, const Vec3d& direction_to_camera) const
|
||||||
|
{
|
||||||
|
if (m_clipping_plane_distance == 0.f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
|
Transform3f instance_matrix = vol->get_instance_transformation().get_matrix().cast<float>();
|
||||||
|
Transform3f instance_matrix_no_translation_no_scaling = vol->get_instance_transformation().get_matrix(true,false,true).cast<float>();
|
||||||
|
Vec3f scaling = vol->get_instance_scaling_factor().cast<float>();
|
||||||
|
|
||||||
|
Vec3f up_noscale = instance_matrix_no_translation_no_scaling.inverse() * direction_to_camera.cast<float>();
|
||||||
|
Vec3f up = Vec3f(up_noscale(0)*scaling(0), up_noscale(1)*scaling(1), up_noscale(2)*scaling(2));
|
||||||
|
float height_mesh = (m_active_instance_bb_radius - m_clipping_plane_distance * 2*m_active_instance_bb_radius) * (up_noscale.norm()/up.norm());
|
||||||
|
|
||||||
|
if (m_clipping_plane_distance != m_old_clipping_plane_distance
|
||||||
|
|| m_old_direction_to_camera != direction_to_camera) {
|
||||||
|
|
||||||
|
std::vector<ExPolygons> list_of_expolys;
|
||||||
|
if (! m_tms) {
|
||||||
|
m_tms.reset(new TriangleMeshSlicer);
|
||||||
|
m_tms->init(const_cast<TriangleMesh*>(&m_mesh), [](){});
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tms->set_up_direction(up);
|
||||||
|
m_tms->slice(std::vector<float>{height_mesh}, 0.f, &list_of_expolys, [](){});
|
||||||
|
m_triangles = triangulate_expolygons_2f(list_of_expolys[0]);
|
||||||
|
|
||||||
|
m_old_direction_to_camera = direction_to_camera;
|
||||||
|
m_old_clipping_plane_distance = m_clipping_plane_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! m_triangles.empty()) {
|
||||||
|
::glPushMatrix();
|
||||||
|
::glTranslated(0.0, 0.0, m_z_shift);
|
||||||
|
::glMultMatrixf(instance_matrix.data());
|
||||||
|
Eigen::Quaternionf q;
|
||||||
|
q.setFromTwoVectors(Vec3f::UnitZ(), up);
|
||||||
|
Eigen::AngleAxisf aa(q);
|
||||||
|
::glRotatef(aa.angle() * (180./M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2));
|
||||||
|
::glTranslatef(0.f, 0.f, -0.001f); // to make sure the cut is safely beyond the near clipping plane
|
||||||
|
::glColor3f(1.0f, 0.37f, 0.0f);
|
||||||
|
::glBegin(GL_TRIANGLES);
|
||||||
|
::glColor3f(1.0f, 0.37f, 0.0f);
|
||||||
|
for (const Vec2f& point : m_triangles)
|
||||||
|
::glVertex3f(point(0), point(1), height_mesh);
|
||||||
|
::glEnd();
|
||||||
|
::glPopMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GLGizmoSlaSupports::render_selection_rectangle() const
|
void GLGizmoSlaSupports::render_selection_rectangle() const
|
||||||
{
|
{
|
||||||
if (m_selection_rectangle_status == srOff)
|
if (m_selection_rectangle_status == srOff)
|
||||||
|
@ -143,24 +207,25 @@ void GLGizmoSlaSupports::on_render_for_picking(const Selection& selection) const
|
||||||
{
|
{
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
render_points(selection, true);
|
// we'll recover current look direction from the modelview matrix (in world coords):
|
||||||
|
Eigen::Matrix<double, 4, 4, Eigen::DontAlign> modelview_matrix;
|
||||||
|
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
|
||||||
|
Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]);
|
||||||
|
|
||||||
|
render_points(selection, direction_to_camera, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) const
|
void GLGizmoSlaSupports::render_points(const Selection& selection, const Vec3d& direction_to_camera, bool picking) const
|
||||||
{
|
{
|
||||||
if (m_quadric == nullptr || !selection.is_from_single_instance())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!picking)
|
if (!picking)
|
||||||
glsafe(::glEnable(GL_LIGHTING));
|
glsafe(::glEnable(GL_LIGHTING));
|
||||||
|
|
||||||
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
double z_shift = vol->get_sla_shift_z();
|
|
||||||
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
|
||||||
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
|
||||||
|
|
||||||
glsafe(::glPushMatrix());
|
glsafe(::glPushMatrix());
|
||||||
glsafe(::glTranslated(0.0, 0.0, z_shift));
|
glsafe(::glTranslated(0.0, 0.0, m_z_shift));
|
||||||
glsafe(::glMultMatrixd(instance_matrix.data()));
|
glsafe(::glMultMatrixd(instance_matrix.data()));
|
||||||
|
|
||||||
float render_color[3];
|
float render_color[3];
|
||||||
|
@ -169,6 +234,9 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
||||||
const sla::SupportPoint& support_point = m_editing_mode_cache[i].support_point;
|
const sla::SupportPoint& support_point = m_editing_mode_cache[i].support_point;
|
||||||
const bool& point_selected = m_editing_mode_cache[i].selected;
|
const bool& point_selected = m_editing_mode_cache[i].selected;
|
||||||
|
|
||||||
|
if (is_point_clipped(support_point.pos.cast<double>(), direction_to_camera))
|
||||||
|
continue;
|
||||||
|
|
||||||
// First decide about the color of the point.
|
// First decide about the color of the point.
|
||||||
if (picking) {
|
if (picking) {
|
||||||
std::array<float, 3> color = picking_color_component(i);
|
std::array<float, 3> color = picking_color_component(i);
|
||||||
|
@ -238,13 +306,25 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool GLGizmoSlaSupports::is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera) const
|
||||||
|
{
|
||||||
|
if (m_clipping_plane_distance == 0.f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Vec3d transformed_point = m_model_object->instances.front()->get_transformation().get_matrix() * point;
|
||||||
|
transformed_point(2) += m_z_shift;
|
||||||
|
return direction_to_camera.dot(m_model_object->instances[m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift)) + m_active_instance_bb_radius
|
||||||
|
- m_clipping_plane_distance * 2*m_active_instance_bb_radius < direction_to_camera.dot(transformed_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool GLGizmoSlaSupports::is_mesh_update_necessary() const
|
bool GLGizmoSlaSupports::is_mesh_update_necessary() const
|
||||||
{
|
{
|
||||||
return ((m_state == On) && (m_model_object != nullptr) && !m_model_object->instances.empty())
|
return ((m_state == On) && (m_model_object != nullptr) && !m_model_object->instances.empty())
|
||||||
&& ((m_model_object != m_old_model_object) || m_V.size()==0);
|
&& ((m_model_object->id() != m_current_mesh_model_id) || m_V.size()==0);
|
||||||
|
|
||||||
//if (m_state != On || !m_model_object || m_model_object->instances.empty() || ! m_instance_matrix.isApprox(m_source_data.matrix))
|
|
||||||
// return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoSlaSupports::update_mesh()
|
void GLGizmoSlaSupports::update_mesh()
|
||||||
|
@ -252,10 +332,9 @@ void GLGizmoSlaSupports::update_mesh()
|
||||||
wxBusyCursor wait;
|
wxBusyCursor wait;
|
||||||
Eigen::MatrixXf& V = m_V;
|
Eigen::MatrixXf& V = m_V;
|
||||||
Eigen::MatrixXi& F = m_F;
|
Eigen::MatrixXi& F = m_F;
|
||||||
// Composite mesh of all instances in the world coordinate system.
|
|
||||||
// This mesh does not account for the possible Z up SLA offset.
|
// This mesh does not account for the possible Z up SLA offset.
|
||||||
TriangleMesh mesh = m_model_object->raw_mesh();
|
m_mesh = m_model_object->raw_mesh();
|
||||||
const stl_file& stl = mesh.stl;
|
const stl_file& stl = m_mesh.stl;
|
||||||
V.resize(3 * stl.stats.number_of_facets, 3);
|
V.resize(3 * stl.stats.number_of_facets, 3);
|
||||||
F.resize(stl.stats.number_of_facets, 3);
|
F.resize(stl.stats.number_of_facets, 3);
|
||||||
for (unsigned int i=0; i<stl.stats.number_of_facets; ++i) {
|
for (unsigned int i=0; i<stl.stats.number_of_facets; ++i) {
|
||||||
|
@ -267,11 +346,15 @@ void GLGizmoSlaSupports::update_mesh()
|
||||||
F(i, 1) = 3*i+1;
|
F(i, 1) = 3*i+1;
|
||||||
F(i, 2) = 3*i+2;
|
F(i, 2) = 3*i+2;
|
||||||
}
|
}
|
||||||
|
m_current_mesh_model_id = m_model_object->id();
|
||||||
|
m_editing_mode = false;
|
||||||
|
|
||||||
m_AABB = igl::AABB<Eigen::MatrixXf,3>();
|
m_AABB = igl::AABB<Eigen::MatrixXf,3>();
|
||||||
m_AABB.init(m_V, m_F);
|
m_AABB.init(m_V, m_F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unprojects the mouse position on the mesh and return the hit point and normal of the facet.
|
||||||
|
// The function throws if no intersection if found.
|
||||||
std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
|
std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
|
||||||
{
|
{
|
||||||
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
|
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
|
||||||
|
@ -288,31 +371,53 @@ std::pair<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse
|
||||||
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2));
|
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2));
|
||||||
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2));
|
::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2));
|
||||||
|
|
||||||
igl::Hit hit;
|
std::vector<igl::Hit> hits;
|
||||||
|
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
double z_offset = volume->get_sla_shift_z();
|
|
||||||
|
|
||||||
point1(2) -= z_offset;
|
// we'll recover current look direction from the modelview matrix (in world coords):
|
||||||
point2(2) -= z_offset;
|
Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]);
|
||||||
|
|
||||||
|
point1(2) -= m_z_shift;
|
||||||
|
point2(2) -= m_z_shift;
|
||||||
|
|
||||||
Transform3d inv = volume->get_instance_transformation().get_matrix().inverse();
|
Transform3d inv = volume->get_instance_transformation().get_matrix().inverse();
|
||||||
|
|
||||||
point1 = inv * point1;
|
point1 = inv * point1;
|
||||||
point2 = inv * point2;
|
point2 = inv * point2;
|
||||||
|
|
||||||
if (!m_AABB.intersect_ray(m_V, m_F, point1.cast<float>(), (point2-point1).cast<float>(), hit))
|
if (!m_AABB.intersect_ray(m_V, m_F, point1.cast<float>(), (point2-point1).cast<float>(), hits))
|
||||||
throw std::invalid_argument("unproject_on_mesh(): No intersection found.");
|
throw std::invalid_argument("unproject_on_mesh(): No intersection found.");
|
||||||
|
|
||||||
int fid = hit.id; // facet id
|
std::sort(hits.begin(), hits.end(), [](const igl::Hit& a, const igl::Hit& b) { return a.t < b.t; });
|
||||||
Vec3f bc(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
|
|
||||||
Vec3f a = (m_V.row(m_F(fid, 1)) - m_V.row(m_F(fid, 0)));
|
// Now let's iterate through the points and find the first that is not clipped:
|
||||||
Vec3f b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0)));
|
unsigned int i=0;
|
||||||
|
Vec3f bc;
|
||||||
|
Vec3f a;
|
||||||
|
Vec3f b;
|
||||||
|
Vec3f result;
|
||||||
|
for (i=0; i<hits.size(); ++i) {
|
||||||
|
igl::Hit& hit = hits[i];
|
||||||
|
int fid = hit.id; // facet id
|
||||||
|
bc = Vec3f(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
|
||||||
|
a = (m_V.row(m_F(fid, 1)) - m_V.row(m_F(fid, 0)));
|
||||||
|
b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0)));
|
||||||
|
result = bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2));
|
||||||
|
if (m_clipping_plane_distance == 0.f || !is_point_clipped(result.cast<double>(), direction_to_camera))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i==hits.size() || (hits.size()-i) % 2 != 0) {
|
||||||
|
// All hits are either clipped, or there is an odd number of unclipped
|
||||||
|
// hits - meaning the nearest must be from inside the mesh.
|
||||||
|
throw std::invalid_argument("unproject_on_mesh(): No intersection found.");
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate and return both the point and the facet normal.
|
// Calculate and return both the point and the facet normal.
|
||||||
return std::make_pair(
|
return std::make_pair(
|
||||||
bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2)),
|
result,
|
||||||
a.cross(b)
|
a.cross(b)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -383,36 +488,64 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||||
|
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
double z_offset = volume->get_sla_shift_z();
|
|
||||||
|
|
||||||
// bounding box created from the rectangle corners - will take care of order of the corners
|
// bounding box created from the rectangle corners - will take care of order of the corners
|
||||||
BoundingBox rectangle(Points{Point(m_selection_rectangle_start_corner.cast<int>()), Point(m_selection_rectangle_end_corner.cast<int>())});
|
BoundingBox rectangle(Points{Point(m_selection_rectangle_start_corner.cast<int>()), Point(m_selection_rectangle_end_corner.cast<int>())});
|
||||||
|
|
||||||
const Transform3d& instance_matrix_no_translation = volume->get_instance_transformation().get_matrix(true);
|
const Transform3d& instance_matrix_no_translation_no_scaling = volume->get_instance_transformation().get_matrix(true,false,true);
|
||||||
|
|
||||||
// we'll recover current look direction from the modelview matrix (in world coords)...
|
// we'll recover current look direction from the modelview matrix (in world coords)...
|
||||||
Vec3f direction_to_camera = camera.get_dir_forward().cast<float>();
|
Vec3f direction_to_camera = camera.get_dir_forward().cast<float>();
|
||||||
// ...and transform it to model coords.
|
// ...and transform it to model coords.
|
||||||
direction_to_camera = (instance_matrix_no_translation.inverse().cast<float>() * direction_to_camera).normalized().eval();
|
Vec3f direction_to_camera_mesh = (instance_matrix_no_translation_no_scaling.inverse().cast<float>() * direction_to_camera).normalized().eval();
|
||||||
|
Vec3f scaling = volume->get_instance_scaling_factor().cast<float>();
|
||||||
|
direction_to_camera_mesh = Vec3f(direction_to_camera_mesh(0)*scaling(0), direction_to_camera_mesh(1)*scaling(1), direction_to_camera_mesh(2)*scaling(2));
|
||||||
|
|
||||||
// Iterate over all points, check if they're in the rectangle and if so, check that they are not obscured by the mesh:
|
// Iterate over all points, check if they're in the rectangle and if so, check that they are not obscured by the mesh:
|
||||||
for (unsigned int i=0; i<m_editing_mode_cache.size(); ++i) {
|
for (unsigned int i=0; i<m_editing_mode_cache.size(); ++i) {
|
||||||
const sla::SupportPoint &support_point = m_editing_mode_cache[i].support_point;
|
const sla::SupportPoint &support_point = m_editing_mode_cache[i].support_point;
|
||||||
Vec3f pos = instance_matrix.cast<float>() * support_point.pos;
|
Vec3f pos = instance_matrix.cast<float>() * support_point.pos;
|
||||||
pos(2) += z_offset;
|
pos(2) += m_z_shift;
|
||||||
GLdouble out_x, out_y, out_z;
|
GLdouble out_x, out_y, out_z;
|
||||||
::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z);
|
::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z);
|
||||||
out_y = m_canvas_height - out_y;
|
out_y = m_canvas_height - out_y;
|
||||||
|
|
||||||
if (rectangle.contains(Point(out_x, out_y))) {
|
if (rectangle.contains(Point(out_x, out_y)) && !is_point_clipped(support_point.pos.cast<double>(), direction_to_camera.cast<double>())) {
|
||||||
bool is_obscured = false;
|
bool is_obscured = false;
|
||||||
// Cast a ray in the direction of the camera and look for intersection with the mesh:
|
// Cast a ray in the direction of the camera and look for intersection with the mesh:
|
||||||
std::vector<igl::Hit> hits;
|
std::vector<igl::Hit> hits;
|
||||||
// Offset the start of the ray to the front of the ball + EPSILON to account for numerical inaccuracies.
|
// Offset the start of the ray to the front of the ball + EPSILON to account for numerical inaccuracies.
|
||||||
if (m_AABB.intersect_ray(m_V, m_F, support_point.pos + direction_to_camera * (support_point.head_front_radius + EPSILON), direction_to_camera, hits))
|
if (m_AABB.intersect_ray(m_V, m_F, support_point.pos + direction_to_camera_mesh * (support_point.head_front_radius + EPSILON), direction_to_camera_mesh, hits)) {
|
||||||
|
std::sort(hits.begin(), hits.end(), [](const igl::Hit& h1, const igl::Hit& h2) { return h1.t < h2.t; });
|
||||||
|
|
||||||
|
if (m_clipping_plane_distance != 0.f) {
|
||||||
|
// If the closest hit facet normal points in the same direction as the ray,
|
||||||
|
// we are looking through the mesh and should therefore discard the point:
|
||||||
|
int fid = hits.front().id; // facet id
|
||||||
|
Vec3f a = (m_V.row(m_F(fid, 1)) - m_V.row(m_F(fid, 0)));
|
||||||
|
Vec3f b = (m_V.row(m_F(fid, 2)) - m_V.row(m_F(fid, 0)));
|
||||||
|
if ((a.cross(b)).dot(direction_to_camera_mesh) > 0.f)
|
||||||
|
is_obscured = true;
|
||||||
|
|
||||||
|
// Eradicate all hits that are on clipped surfaces:
|
||||||
|
for (unsigned int j=0; j<hits.size(); ++j) {
|
||||||
|
const igl::Hit& hit = hits[j];
|
||||||
|
int fid = hit.id; // facet id
|
||||||
|
|
||||||
|
Vec3f bc = Vec3f(1-hit.u-hit.v, hit.u, hit.v); // barycentric coordinates of the hit
|
||||||
|
Vec3f hit_pos = bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2));
|
||||||
|
if (is_point_clipped(hit_pos.cast<double>(), direction_to_camera.cast<double>())) {
|
||||||
|
hits.erase(hits.begin()+j);
|
||||||
|
--j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: the intersection could in theory be behind the camera, but as of now we only have camera direction.
|
// FIXME: the intersection could in theory be behind the camera, but as of now we only have camera direction.
|
||||||
// Also, the threshold is in mesh coordinates, not in actual dimensions.
|
// Also, the threshold is in mesh coordinates, not in actual dimensions.
|
||||||
if (hits.size() > 1 || hits.front().t > 0.001f)
|
if (!hits.empty())
|
||||||
is_obscured = true;
|
is_obscured = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_obscured) {
|
if (!is_obscured) {
|
||||||
if (m_selection_rectangle_status == srDeselect)
|
if (m_selection_rectangle_status == srDeselect)
|
||||||
|
@ -570,6 +703,64 @@ void GLGizmoSlaSupports::update_cache_entry_normal(unsigned int i) const
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
|
||||||
|
{
|
||||||
|
if (!m_model_object || m_state == Off)
|
||||||
|
return ClippingPlane::ClipsNothing();
|
||||||
|
|
||||||
|
Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> modelview_matrix;
|
||||||
|
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
|
||||||
|
|
||||||
|
// we'll recover current look direction from the modelview matrix (in world coords):
|
||||||
|
Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]);
|
||||||
|
float dist = direction_to_camera.dot(m_model_object->instances[m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift));
|
||||||
|
|
||||||
|
return ClippingPlane(-direction_to_camera.normalized(),(dist - (-m_active_instance_bb_radius) - m_clipping_plane_distance * 2*m_active_instance_bb_radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
void GLGizmoSlaSupports::find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& idxs) const
|
||||||
|
{
|
||||||
|
if (aabb->is_leaf()) { // this is a facet
|
||||||
|
// corner.dot(normal) - offset
|
||||||
|
idxs.push_back(aabb->m_primitive);
|
||||||
|
}
|
||||||
|
else { // not a leaf
|
||||||
|
using CornerType = Eigen::AlignedBox<float, 3>::CornerType;
|
||||||
|
bool sign = std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(0))));
|
||||||
|
for (unsigned int i=1; i<8; ++i)
|
||||||
|
if (std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(i)))) != sign) {
|
||||||
|
find_intersecting_facets(aabb->m_left, normal, offset, idxs);
|
||||||
|
find_intersecting_facets(aabb->m_right, normal, offset, idxs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GLGizmoSlaSupports::make_line_segments() const
|
||||||
|
{
|
||||||
|
TriangleMeshSlicer tms(&m_model_object->volumes.front()->mesh);
|
||||||
|
Vec3f normal(0.f, 1.f, 1.f);
|
||||||
|
double d = 0.;
|
||||||
|
|
||||||
|
std::vector<IntersectionLine> lines;
|
||||||
|
find_intersections(&m_AABB, normal, d, lines);
|
||||||
|
ExPolygons expolys;
|
||||||
|
tms.make_expolygons_simple(lines, &expolys);
|
||||||
|
|
||||||
|
SVG svg("slice_loops.svg", get_extents(expolys));
|
||||||
|
svg.draw(expolys);
|
||||||
|
//for (const IntersectionLine &l : lines[i])
|
||||||
|
// svg.draw(l, "red", 0);
|
||||||
|
//svg.draw_outline(expolygons, "black", "blue", 0);
|
||||||
|
svg.Close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection)
|
void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection)
|
||||||
{
|
{
|
||||||
if (!m_model_object)
|
if (!m_model_object)
|
||||||
|
@ -580,7 +771,7 @@ void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_l
|
||||||
RENDER_AGAIN:
|
RENDER_AGAIN:
|
||||||
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
|
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
|
||||||
|
|
||||||
const ImVec2 window_size(m_imgui->scaled(17.f, 18.f));
|
const ImVec2 window_size(m_imgui->scaled(17.f, 20.f));
|
||||||
ImGui::SetNextWindowPos(ImVec2(x, y - std::max(0.f, y+window_size.y-bottom_limit) ));
|
ImGui::SetNextWindowPos(ImVec2(x, y - std::max(0.f, y+window_size.y-bottom_limit) ));
|
||||||
ImGui::SetNextWindowSize(ImVec2(window_size));
|
ImGui::SetNextWindowSize(ImVec2(window_size));
|
||||||
|
|
||||||
|
@ -687,6 +878,13 @@ RENDER_AGAIN:
|
||||||
(m_model_object->sla_points_status == sla::PointsStatus::Generating ? "Generation in progress..." : "UNKNOWN STATUS"))));
|
(m_model_object->sla_points_status == sla::PointsStatus::Generating ? "Generation in progress..." : "UNKNOWN STATUS"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Following is rendered in both editing and non-editing mode:
|
||||||
|
m_imgui->text("Clipping of view: ");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::PushItemWidth(150.0f);
|
||||||
|
bool value_changed = ImGui::SliderFloat(" ", &m_clipping_plane_distance, 0.f, 1.f, "%.2f");
|
||||||
|
|
||||||
m_imgui->end();
|
m_imgui->end();
|
||||||
|
|
||||||
if (m_editing_mode != m_old_editing_state) { // user toggled between editing/non-editing mode
|
if (m_editing_mode != m_old_editing_state) { // user toggled between editing/non-editing mode
|
||||||
|
@ -740,12 +938,7 @@ std::string GLGizmoSlaSupports::on_get_name() const
|
||||||
|
|
||||||
void GLGizmoSlaSupports::on_set_state()
|
void GLGizmoSlaSupports::on_set_state()
|
||||||
{
|
{
|
||||||
// Following is called through CallAfter, because otherwise there was a problem
|
|
||||||
// on OSX with the wxMessageDialog being shown several times when clicked into.
|
|
||||||
|
|
||||||
wxGetApp().CallAfter([this]() {
|
|
||||||
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
|
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
|
||||||
|
|
||||||
if (is_mesh_update_necessary())
|
if (is_mesh_update_necessary())
|
||||||
update_mesh();
|
update_mesh();
|
||||||
|
|
||||||
|
@ -762,23 +955,32 @@ void GLGizmoSlaSupports::on_set_state()
|
||||||
m_new_point_head_diameter = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
|
m_new_point_head_diameter = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
|
||||||
}
|
}
|
||||||
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
|
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
|
||||||
if (m_model_object) {
|
wxGetApp().CallAfter([this]() {
|
||||||
if (m_unsaved_changes) {
|
// Following is called through CallAfter, because otherwise there was a problem
|
||||||
wxMessageDialog dlg(GUI::wxGetApp().mainframe, _(L("Do you want to save your manually edited support points ?\n")),
|
// on OSX with the wxMessageDialog being shown several times when clicked into.
|
||||||
_(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO);
|
if (m_model_object) {
|
||||||
if (dlg.ShowModal() == wxID_YES)
|
if (m_unsaved_changes) {
|
||||||
editing_mode_apply_changes();
|
wxMessageDialog dlg(GUI::wxGetApp().mainframe, _(L("Do you want to save your manually edited support points ?\n")),
|
||||||
else
|
_(L("Save changes?")), wxICON_QUESTION | wxYES | wxNO);
|
||||||
editing_mode_discard_changes();
|
if (dlg.ShowModal() == wxID_YES)
|
||||||
|
editing_mode_apply_changes();
|
||||||
|
else
|
||||||
|
editing_mode_discard_changes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
m_parent.toggle_model_objects_visibility(true);
|
||||||
|
m_editing_mode = false; // so it is not active next time the gizmo opens
|
||||||
m_parent.toggle_model_objects_visibility(true);
|
m_editing_mode_cache.clear();
|
||||||
m_editing_mode = false; // so it is not active next time the gizmo opens
|
m_clipping_plane_distance = 0.f;
|
||||||
m_editing_mode_cache.clear();
|
// Release copy of the mesh, triangle slicer and the AABB spatial search structure.
|
||||||
|
m_mesh.clear();
|
||||||
|
m_AABB.deinit();
|
||||||
|
m_V = Eigen::MatrixXf();
|
||||||
|
m_F = Eigen::MatrixXi();
|
||||||
|
m_tms.reset(nullptr);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
m_old_state = m_state;
|
m_old_state = m_state;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -827,11 +1029,19 @@ void GLGizmoSlaSupports::unselect_point(int i)
|
||||||
|
|
||||||
void GLGizmoSlaSupports::editing_mode_discard_changes()
|
void GLGizmoSlaSupports::editing_mode_discard_changes()
|
||||||
{
|
{
|
||||||
m_editing_mode_cache.clear();
|
// If the points were autogenerated, they may not be on the ModelObject yet.
|
||||||
for (const sla::SupportPoint& point : m_model_object->sla_support_points)
|
// Because the user probably messed with the cache, we will get the data
|
||||||
m_editing_mode_cache.emplace_back(point, false);
|
// from the backend again.
|
||||||
m_editing_mode = false;
|
|
||||||
m_unsaved_changes = false;
|
if (m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated)
|
||||||
|
get_data_from_backend();
|
||||||
|
else {
|
||||||
|
m_editing_mode_cache.clear();
|
||||||
|
for (const sla::SupportPoint& point : m_model_object->sla_support_points)
|
||||||
|
m_editing_mode_cache.emplace_back(point, false);
|
||||||
|
}
|
||||||
|
m_editing_mode = false;
|
||||||
|
m_unsaved_changes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,17 @@ namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
|
class ClippingPlane;
|
||||||
|
|
||||||
|
|
||||||
class GLGizmoSlaSupports : public GLGizmoBase
|
class GLGizmoSlaSupports : public GLGizmoBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ModelObject* m_model_object = nullptr;
|
ModelObject* m_model_object = nullptr;
|
||||||
ModelObject* m_old_model_object = nullptr;
|
ModelID m_current_mesh_model_id = 0;
|
||||||
int m_active_instance = -1;
|
int m_active_instance = -1;
|
||||||
|
float m_active_instance_bb_radius; // to cache the bb
|
||||||
|
mutable float m_z_shift = 0.f;
|
||||||
std::pair<Vec3f, Vec3f> unproject_on_mesh(const Vec2d& mouse_pos);
|
std::pair<Vec3f, Vec3f> unproject_on_mesh(const Vec2d& mouse_pos);
|
||||||
|
|
||||||
const float RenderPointScale = 1.f;
|
const float RenderPointScale = 1.f;
|
||||||
|
@ -31,6 +36,8 @@ private:
|
||||||
Eigen::MatrixXf m_V; // vertices
|
Eigen::MatrixXf m_V; // vertices
|
||||||
Eigen::MatrixXi m_F; // facets indices
|
Eigen::MatrixXi m_F; // facets indices
|
||||||
igl::AABB<Eigen::MatrixXf,3> m_AABB;
|
igl::AABB<Eigen::MatrixXf,3> m_AABB;
|
||||||
|
TriangleMesh m_mesh;
|
||||||
|
mutable std::vector<Vec2f> m_triangles;
|
||||||
|
|
||||||
class CacheEntry {
|
class CacheEntry {
|
||||||
public:
|
public:
|
||||||
|
@ -52,7 +59,7 @@ public:
|
||||||
void set_sla_support_data(ModelObject* model_object, const Selection& selection);
|
void set_sla_support_data(ModelObject* model_object, const Selection& selection);
|
||||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||||
void delete_selected_points(bool force = false);
|
void delete_selected_points(bool force = false);
|
||||||
std::pair<float, float> get_sla_clipping_plane() const;
|
ClippingPlane get_sla_clipping_plane() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool on_init();
|
bool on_init();
|
||||||
|
@ -61,7 +68,8 @@ private:
|
||||||
virtual void on_render_for_picking(const Selection& selection) const;
|
virtual void on_render_for_picking(const Selection& selection) const;
|
||||||
|
|
||||||
void render_selection_rectangle() const;
|
void render_selection_rectangle() const;
|
||||||
void render_points(const Selection& selection, bool picking = false) const;
|
void render_points(const Selection& selection, const Vec3d& direction_to_camera, bool picking = false) const;
|
||||||
|
void render_clipping_plane(const Selection& selection, const Vec3d& direction_to_camera) const;
|
||||||
bool is_mesh_update_necessary() const;
|
bool is_mesh_update_necessary() const;
|
||||||
void update_mesh();
|
void update_mesh();
|
||||||
void update_cache_entry_normal(unsigned int i) const;
|
void update_cache_entry_normal(unsigned int i) const;
|
||||||
|
@ -74,6 +82,8 @@ private:
|
||||||
float m_density = 100.f;
|
float m_density = 100.f;
|
||||||
mutable std::vector<CacheEntry> m_editing_mode_cache; // a support point and whether it is currently selected
|
mutable std::vector<CacheEntry> m_editing_mode_cache; // a support point and whether it is currently selected
|
||||||
float m_clipping_plane_distance = 0.f;
|
float m_clipping_plane_distance = 0.f;
|
||||||
|
mutable float m_old_clipping_plane_distance = 0.f;
|
||||||
|
mutable Vec3d m_old_direction_to_camera;
|
||||||
|
|
||||||
enum SelectionRectangleStatus {
|
enum SelectionRectangleStatus {
|
||||||
srOff = 0,
|
srOff = 0,
|
||||||
|
@ -90,7 +100,11 @@ private:
|
||||||
int m_canvas_width;
|
int m_canvas_width;
|
||||||
int m_canvas_height;
|
int m_canvas_height;
|
||||||
|
|
||||||
|
mutable std::unique_ptr<TriangleMeshSlicer> m_tms;
|
||||||
|
|
||||||
std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
|
std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
|
||||||
|
bool is_point_clipped(const Vec3d& point, const Vec3d& direction_to_camera) const;
|
||||||
|
void find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& out) const;
|
||||||
|
|
||||||
// Methods that do the model_object and editing cache synchronization,
|
// Methods that do the model_object and editing cache synchronization,
|
||||||
// editing mode selection, etc:
|
// editing mode selection, etc:
|
||||||
|
|
|
@ -467,6 +467,19 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClippingPlane GLGizmosManager::get_sla_clipping_plane() const
|
||||||
|
{
|
||||||
|
if (!m_enabled || m_current != SlaSupports)
|
||||||
|
return ClippingPlane::ClipsNothing();
|
||||||
|
|
||||||
|
GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
|
||||||
|
if (it != m_gizmos.end())
|
||||||
|
return reinterpret_cast<GLGizmoSlaSupports*>(it->second)->get_sla_clipping_plane();
|
||||||
|
|
||||||
|
return ClippingPlane::ClipsNothing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLGizmosManager::render_current_gizmo(const Selection& selection) const
|
void GLGizmosManager::render_current_gizmo(const Selection& selection) const
|
||||||
{
|
{
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
|
@ -713,7 +726,12 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas)
|
||||||
{
|
{
|
||||||
switch (keyCode)
|
switch (keyCode)
|
||||||
{
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
#else /* __APPLE__ */
|
||||||
case WXK_CONTROL_A:
|
case WXK_CONTROL_A:
|
||||||
|
#endif /* __APPLE__ */
|
||||||
{
|
{
|
||||||
// Sla gizmo selects all support points
|
// Sla gizmo selects all support points
|
||||||
if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::SelectAll))
|
if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::SelectAll))
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace GUI {
|
||||||
class Selection;
|
class Selection;
|
||||||
class GLGizmoBase;
|
class GLGizmoBase;
|
||||||
class GLCanvas3D;
|
class GLCanvas3D;
|
||||||
|
class ClippingPlane;
|
||||||
|
|
||||||
class Rect
|
class Rect
|
||||||
{
|
{
|
||||||
|
@ -146,7 +147,7 @@ public:
|
||||||
|
|
||||||
void set_sla_support_data(ModelObject* model_object, const Selection& selection);
|
void set_sla_support_data(ModelObject* model_object, const Selection& selection);
|
||||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false);
|
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false);
|
||||||
|
ClippingPlane get_sla_clipping_plane() const;
|
||||||
|
|
||||||
void render_current_gizmo(const Selection& selection) const;
|
void render_current_gizmo(const Selection& selection) const;
|
||||||
void render_current_gizmo_for_picking_pass(const Selection& selection) const;
|
void render_current_gizmo_for_picking_pass(const Selection& selection) const;
|
||||||
|
|
|
@ -321,7 +321,7 @@ void MainFrame::init_menubar()
|
||||||
wxMenu* fileMenu = new wxMenu;
|
wxMenu* fileMenu = new wxMenu;
|
||||||
{
|
{
|
||||||
wxMenuItem* item_open = append_menu_item(fileMenu, wxID_ANY, _(L("&Open Project")) + dots + "\tCtrl+O", _(L("Open a project file")),
|
wxMenuItem* item_open = append_menu_item(fileMenu, wxID_ANY, _(L("&Open Project")) + dots + "\tCtrl+O", _(L("Open a project file")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->load_project(); }, "brick_add.png");
|
[this](wxCommandEvent&) { if (m_plater) m_plater->load_project(); }, "open");
|
||||||
wxMenuItem* item_save = append_menu_item(fileMenu, wxID_ANY, _(L("&Save Project")) + "\tCtrl+S", _(L("Save current project file")),
|
wxMenuItem* item_save = append_menu_item(fileMenu, wxID_ANY, _(L("&Save Project")) + "\tCtrl+S", _(L("Save current project file")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_3mf(into_path(m_plater->get_project_filename())); }, "save");
|
[this](wxCommandEvent&) { if (m_plater) m_plater->export_3mf(into_path(m_plater->get_project_filename())); }, "save");
|
||||||
wxMenuItem* item_save_as = append_menu_item(fileMenu, wxID_ANY, _(L("Save Project &as")) + dots + "\tCtrl+Alt+S", _(L("Save current project file as")),
|
wxMenuItem* item_save_as = append_menu_item(fileMenu, wxID_ANY, _(L("Save Project &as")) + dots + "\tCtrl+Alt+S", _(L("Save current project file as")),
|
||||||
|
@ -331,30 +331,30 @@ void MainFrame::init_menubar()
|
||||||
|
|
||||||
wxMenu* import_menu = new wxMenu();
|
wxMenu* import_menu = new wxMenu();
|
||||||
wxMenuItem* item_import_model = append_menu_item(import_menu, wxID_ANY, _(L("Import STL/OBJ/AM&F/3MF")) + dots + "\tCtrl+I", _(L("Load a model")),
|
wxMenuItem* item_import_model = append_menu_item(import_menu, wxID_ANY, _(L("Import STL/OBJ/AM&F/3MF")) + dots + "\tCtrl+I", _(L("Load a model")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, "brick_add.png");
|
[this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, "import_plater");
|
||||||
import_menu->AppendSeparator();
|
import_menu->AppendSeparator();
|
||||||
append_menu_item(import_menu, wxID_ANY, _(L("Import &Config")) + dots + "\tCtrl+L", _(L("Load exported configuration file")),
|
append_menu_item(import_menu, wxID_ANY, _(L("Import &Config")) + dots + "\tCtrl+L", _(L("Load exported configuration file")),
|
||||||
[this](wxCommandEvent&) { load_config_file(); }, "plugin_add.png");
|
[this](wxCommandEvent&) { load_config_file(); }, "import_config");
|
||||||
append_menu_item(import_menu, wxID_ANY, _(L("Import Config from &project")) + dots +"\tCtrl+Alt+L", _(L("Load configuration from project file")),
|
append_menu_item(import_menu, wxID_ANY, _(L("Import Config from &project")) + dots +"\tCtrl+Alt+L", _(L("Load configuration from project file")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->extract_config_from_project(); }, "plugin_add.png");
|
[this](wxCommandEvent&) { if (m_plater) m_plater->extract_config_from_project(); }, "import_config");
|
||||||
import_menu->AppendSeparator();
|
import_menu->AppendSeparator();
|
||||||
append_menu_item(import_menu, wxID_ANY, _(L("Import Config &Bundle")) + dots, _(L("Load presets from a bundle")),
|
append_menu_item(import_menu, wxID_ANY, _(L("Import Config &Bundle")) + dots, _(L("Load presets from a bundle")),
|
||||||
[this](wxCommandEvent&) { load_configbundle(); }, "lorry_add.png");
|
[this](wxCommandEvent&) { load_configbundle(); }, "import_config_bundle");
|
||||||
append_submenu(fileMenu, import_menu, wxID_ANY, _(L("&Import")), "");
|
append_submenu(fileMenu, import_menu, wxID_ANY, _(L("&Import")), "");
|
||||||
|
|
||||||
wxMenu* export_menu = new wxMenu();
|
wxMenu* export_menu = new wxMenu();
|
||||||
wxMenuItem* item_export_gcode = append_menu_item(export_menu, wxID_ANY, _(L("Export &G-code")) + dots +"\tCtrl+G", _(L("Export current plate as G-code")),
|
wxMenuItem* item_export_gcode = append_menu_item(export_menu, wxID_ANY, _(L("Export &G-code")) + dots +"\tCtrl+G", _(L("Export current plate as G-code")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(); }, "cog_go.png");
|
[this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(); }, "export_gcode");
|
||||||
export_menu->AppendSeparator();
|
export_menu->AppendSeparator();
|
||||||
wxMenuItem* item_export_stl = append_menu_item(export_menu, wxID_ANY, _(L("Export plate as &STL")) + dots, _(L("Export current plate as STL")),
|
wxMenuItem* item_export_stl = append_menu_item(export_menu, wxID_ANY, _(L("Export plate as &STL")) + dots, _(L("Export current plate as STL")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "brick_go.png");
|
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "export_plater");
|
||||||
wxMenuItem* item_export_amf = append_menu_item(export_menu, wxID_ANY, _(L("Export plate as &AMF")) + dots, _(L("Export current plate as AMF")),
|
wxMenuItem* item_export_amf = append_menu_item(export_menu, wxID_ANY, _(L("Export plate as &AMF")) + dots, _(L("Export current plate as AMF")),
|
||||||
[this](wxCommandEvent&) { if (m_plater) m_plater->export_amf(); }, "brick_go.png");
|
[this](wxCommandEvent&) { if (m_plater) m_plater->export_amf(); }, "export_plater");
|
||||||
export_menu->AppendSeparator();
|
export_menu->AppendSeparator();
|
||||||
append_menu_item(export_menu, wxID_ANY, _(L("Export &Config")) +dots +"\tCtrl+E", _(L("Export current configuration to file")),
|
append_menu_item(export_menu, wxID_ANY, _(L("Export &Config")) +dots +"\tCtrl+E", _(L("Export current configuration to file")),
|
||||||
[this](wxCommandEvent&) { export_config(); }, "plugin_go.png");
|
[this](wxCommandEvent&) { export_config(); }, "export_config");
|
||||||
append_menu_item(export_menu, wxID_ANY, _(L("Export Config &Bundle")) + dots, _(L("Export all presets to file")),
|
append_menu_item(export_menu, wxID_ANY, _(L("Export Config &Bundle")) + dots, _(L("Export all presets to file")),
|
||||||
[this](wxCommandEvent&) { export_configbundle(); }, "lorry_go.png");
|
[this](wxCommandEvent&) { export_configbundle(); }, "export_config_bundle");
|
||||||
append_submenu(fileMenu, export_menu, wxID_ANY, _(L("&Export")), "");
|
append_submenu(fileMenu, export_menu, wxID_ANY, _(L("&Export")), "");
|
||||||
|
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
|
@ -382,10 +382,10 @@ void MainFrame::init_menubar()
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
#endif
|
#endif
|
||||||
m_menu_item_reslice_now = append_menu_item(fileMenu, wxID_ANY, _(L("(Re)Slice &Now")) + "\tCtrl+R", _(L("Start new slicing process")),
|
m_menu_item_reslice_now = append_menu_item(fileMenu, wxID_ANY, _(L("(Re)Slice &Now")) + "\tCtrl+R", _(L("Start new slicing process")),
|
||||||
[this](wxCommandEvent&) { reslice_now(); }, "shape_handles.png");
|
[this](wxCommandEvent&) { reslice_now(); }, "re_slice");
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
append_menu_item(fileMenu, wxID_ANY, _(L("&Repair STL file")) + dots, _(L("Automatically repair an STL file")),
|
append_menu_item(fileMenu, wxID_ANY, _(L("&Repair STL file")) + dots, _(L("Automatically repair an STL file")),
|
||||||
[this](wxCommandEvent&) { repair_stl(); }, "wrench.png");
|
[this](wxCommandEvent&) { repair_stl(); }, "wrench");
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), _(L("Quit Slic3r")),
|
append_menu_item(fileMenu, wxID_EXIT, _(L("&Quit")), _(L("Quit Slic3r")),
|
||||||
[this](wxCommandEvent&) { Close(false); });
|
[this](wxCommandEvent&) { Close(false); });
|
||||||
|
@ -425,13 +425,22 @@ void MainFrame::init_menubar()
|
||||||
[this](wxCommandEvent&) { m_plater->select_all(); }, "");
|
[this](wxCommandEvent&) { m_plater->select_all(); }, "");
|
||||||
editMenu->AppendSeparator();
|
editMenu->AppendSeparator();
|
||||||
wxMenuItem* item_delete_sel = append_menu_item(editMenu, wxID_ANY, _(L("&Delete selected")) + sep + hotkey_delete, _(L("Deletes the current selection")),
|
wxMenuItem* item_delete_sel = append_menu_item(editMenu, wxID_ANY, _(L("&Delete selected")) + sep + hotkey_delete, _(L("Deletes the current selection")),
|
||||||
[this](wxCommandEvent&) { m_plater->remove_selected(); }, "");
|
[this](wxCommandEvent&) { m_plater->remove_selected(); }, "remove_menu");
|
||||||
wxMenuItem* item_delete_all = append_menu_item(editMenu, wxID_ANY, _(L("Delete &all")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + hotkey_delete, _(L("Deletes all objects")),
|
wxMenuItem* item_delete_all = append_menu_item(editMenu, wxID_ANY, _(L("Delete &all")) + sep + GUI::shortkey_ctrl_prefix() + sep_space + hotkey_delete, _(L("Deletes all objects")),
|
||||||
[this](wxCommandEvent&) { m_plater->reset(); }, "");
|
[this](wxCommandEvent&) { m_plater->reset(); }, "delete_all_menu");
|
||||||
|
|
||||||
|
editMenu->AppendSeparator();
|
||||||
|
|
||||||
|
wxMenuItem* item_copy = append_menu_item(editMenu, wxID_ANY, _(L("&Copy")) + "\tCtrl+C", _(L("Copy selection to clipboard")),
|
||||||
|
[this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, "copy_menu");
|
||||||
|
wxMenuItem* item_paste = append_menu_item(editMenu, wxID_ANY, _(L("&Paste")) + "\tCtrl+V", _(L("Paste clipboard")),
|
||||||
|
[this](wxCommandEvent&) { m_plater->paste_from_clipboard(); }, "paste_menu");
|
||||||
|
|
||||||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_select()); }, item_select_all->GetId());
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_select()); }, item_select_all->GetId());
|
||||||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete()); }, item_delete_sel->GetId());
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete()); }, item_delete_sel->GetId());
|
||||||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete_all()); }, item_delete_all->GetId());
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete_all()); }, item_delete_all->GetId());
|
||||||
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater->can_copy()); }, item_copy->GetId());
|
||||||
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater->can_paste()); }, item_paste->GetId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window menu
|
// Window menu
|
||||||
|
@ -440,7 +449,7 @@ void MainFrame::init_menubar()
|
||||||
size_t tab_offset = 0;
|
size_t tab_offset = 0;
|
||||||
if (m_plater) {
|
if (m_plater) {
|
||||||
append_menu_item(windowMenu, wxID_HIGHEST + 1, _(L("&Plater Tab")) + "\tCtrl+1", _(L("Show the plater")),
|
append_menu_item(windowMenu, wxID_HIGHEST + 1, _(L("&Plater Tab")) + "\tCtrl+1", _(L("Show the plater")),
|
||||||
[this](wxCommandEvent&) { select_tab(0); }, "application_view_tile.png");
|
[this](wxCommandEvent&) { select_tab(0); }, "plater");
|
||||||
tab_offset += 1;
|
tab_offset += 1;
|
||||||
}
|
}
|
||||||
if (tab_offset > 0) {
|
if (tab_offset > 0) {
|
||||||
|
@ -455,9 +464,9 @@ void MainFrame::init_menubar()
|
||||||
if (m_plater) {
|
if (m_plater) {
|
||||||
windowMenu->AppendSeparator();
|
windowMenu->AppendSeparator();
|
||||||
wxMenuItem* item_3d = append_menu_item(windowMenu, wxID_HIGHEST + 5, _(L("3&D")) + "\tCtrl+5", _(L("Show the 3D editing view")),
|
wxMenuItem* item_3d = append_menu_item(windowMenu, wxID_HIGHEST + 5, _(L("3&D")) + "\tCtrl+5", _(L("Show the 3D editing view")),
|
||||||
[this](wxCommandEvent&) { m_plater->select_view_3D("3D"); }, "");
|
[this](wxCommandEvent&) { m_plater->select_view_3D("3D"); }, "editor_menu");
|
||||||
wxMenuItem* item_preview = append_menu_item(windowMenu, wxID_HIGHEST + 6, _(L("Pre&view")) + "\tCtrl+6", _(L("Show the 3D slices preview")),
|
wxMenuItem* item_preview = append_menu_item(windowMenu, wxID_HIGHEST + 6, _(L("Pre&view")) + "\tCtrl+6", _(L("Show the 3D slices preview")),
|
||||||
[this](wxCommandEvent&) { m_plater->select_view_3D("Preview"); }, "");
|
[this](wxCommandEvent&) { m_plater->select_view_3D("Preview"); }, "preview_menu");
|
||||||
|
|
||||||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_3d->GetId());
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_3d->GetId());
|
||||||
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_preview->GetId());
|
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_preview->GetId());
|
||||||
|
@ -478,7 +487,7 @@ void MainFrame::init_menubar()
|
||||||
|
|
||||||
windowMenu->AppendSeparator();
|
windowMenu->AppendSeparator();
|
||||||
append_menu_item(windowMenu, wxID_ANY, _(L("Print &Host Upload Queue")) + "\tCtrl+J", _(L("Display the Print Host Upload Queue window")),
|
append_menu_item(windowMenu, wxID_ANY, _(L("Print &Host Upload Queue")) + "\tCtrl+J", _(L("Display the Print Host Upload Queue window")),
|
||||||
[this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "arrow_up.png");
|
[this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
// View menu
|
// View menu
|
||||||
|
@ -590,7 +599,7 @@ void MainFrame::quick_slice(const int qs)
|
||||||
dlg->ShowModal();
|
dlg->ShowModal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (std::ifstream(m_qs_last_input_file.char_str())) {
|
if (std::ifstream(m_qs_last_input_file.ToUTF8().data())) {
|
||||||
auto dlg = new wxMessageDialog(this, _(L("Previously sliced file ("))+m_qs_last_input_file+_(L(") not found.")),
|
auto dlg = new wxMessageDialog(this, _(L("Previously sliced file ("))+m_qs_last_input_file+_(L(") not found.")),
|
||||||
_(L("File Not Found")), wxICON_ERROR | wxOK);
|
_(L("File Not Found")), wxICON_ERROR | wxOK);
|
||||||
dlg->ShowModal();
|
dlg->ShowModal();
|
||||||
|
@ -705,24 +714,23 @@ void MainFrame::repair_stl()
|
||||||
dlg->Destroy();
|
dlg->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto output_file = input_file;
|
wxString output_file = input_file;
|
||||||
{
|
{
|
||||||
// output_file = ~s / \.[sS][tT][lL]$ / _fixed.obj / ;
|
|
||||||
auto dlg = new wxFileDialog( this, L("Save OBJ file (less prone to coordinate errors than STL) as:"),
|
auto dlg = new wxFileDialog( this, L("Save OBJ file (less prone to coordinate errors than STL) as:"),
|
||||||
get_dir_name(output_file), get_base_name(output_file),
|
get_dir_name(output_file), get_base_name(output_file, ".obj"),
|
||||||
file_wildcards(FT_OBJ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
file_wildcards(FT_OBJ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||||
if (dlg->ShowModal() != wxID_OK) {
|
if (dlg->ShowModal() != wxID_OK) {
|
||||||
dlg->Destroy();
|
dlg->Destroy();
|
||||||
return /*undef*/;
|
return;
|
||||||
}
|
}
|
||||||
output_file = dlg->GetPath();
|
output_file = dlg->GetPath();
|
||||||
dlg->Destroy();
|
dlg->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tmesh = new Slic3r::TriangleMesh();
|
auto tmesh = new Slic3r::TriangleMesh();
|
||||||
tmesh->ReadSTLFile(input_file.char_str());
|
tmesh->ReadSTLFile(input_file.ToUTF8().data());
|
||||||
tmesh->repair();
|
tmesh->repair();
|
||||||
tmesh->WriteOBJFile(output_file.char_str());
|
tmesh->WriteOBJFile(output_file.ToUTF8().data());
|
||||||
Slic3r::GUI::show_info(this, L("Your file was repaired."), L("Repair"));
|
Slic3r::GUI::show_info(this, L("Your file was repaired."), L("Repair"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,9 +970,12 @@ void MainFrame::update_ui_from_settings()
|
||||||
tab->update_ui_from_settings();
|
tab->update_ui_from_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MainFrame::get_base_name(const wxString &full_name) const
|
std::string MainFrame::get_base_name(const wxString &full_name, const char *extension) const
|
||||||
{
|
{
|
||||||
return boost::filesystem::path(full_name.wx_str()).filename().string();
|
boost::filesystem::path filename = boost::filesystem::path(full_name.wx_str()).filename();
|
||||||
|
if (extension != nullptr)
|
||||||
|
filename = filename.replace_extension(extension);
|
||||||
|
return filename.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MainFrame::get_dir_name(const wxString &full_name) const
|
std::string MainFrame::get_dir_name(const wxString &full_name) const
|
||||||
|
|
|
@ -54,7 +54,7 @@ class MainFrame : public DPIFrame
|
||||||
|
|
||||||
PrintHostQueueDialog *m_printhost_queue_dlg;
|
PrintHostQueueDialog *m_printhost_queue_dlg;
|
||||||
|
|
||||||
std::string get_base_name(const wxString &full_name) const;
|
std::string get_base_name(const wxString &full_name, const char *extension = nullptr) const;
|
||||||
std::string get_dir_name(const wxString &full_name) const;
|
std::string get_dir_name(const wxString &full_name) const;
|
||||||
|
|
||||||
void on_presets_changed(SimpleEvent&);
|
void on_presets_changed(SimpleEvent&);
|
||||||
|
|
|
@ -144,8 +144,7 @@ ObjectInfo::ObjectInfo(wxWindow *parent) :
|
||||||
info_manifold_text->SetFont(wxGetApp().small_font());
|
info_manifold_text->SetFont(wxGetApp().small_font());
|
||||||
info_manifold = new wxStaticText(parent, wxID_ANY, "");
|
info_manifold = new wxStaticText(parent, wxID_ANY, "");
|
||||||
info_manifold->SetFont(wxGetApp().small_font());
|
info_manifold->SetFont(wxGetApp().small_font());
|
||||||
wxBitmap bitmap(GUI::from_u8(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG);
|
manifold_warning_icon = new wxStaticBitmap(parent, wxID_ANY, create_scaled_bitmap(parent, "exclamation"));
|
||||||
manifold_warning_icon = new wxStaticBitmap(parent, wxID_ANY, bitmap);
|
|
||||||
auto *sizer_manifold = new wxBoxSizer(wxHORIZONTAL);
|
auto *sizer_manifold = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sizer_manifold->Add(info_manifold_text, 0);
|
sizer_manifold->Add(info_manifold_text, 0);
|
||||||
sizer_manifold->Add(manifold_warning_icon, 0, wxLEFT, 2);
|
sizer_manifold->Add(manifold_warning_icon, 0, wxLEFT, 2);
|
||||||
|
@ -1477,6 +1476,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); });
|
||||||
|
view3D_canvas->Bind(EVT_GLTOOLBAR_COPY, [q](SimpleEvent&) { q->copy_selection_to_clipboard(); });
|
||||||
|
view3D_canvas->Bind(EVT_GLTOOLBAR_PASTE, [q](SimpleEvent&) { q->paste_from_clipboard(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); });
|
view3D_canvas->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); });
|
||||||
view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this);
|
view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this);
|
||||||
|
@ -1719,11 +1720,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||||
|
|
||||||
if (advanced)
|
if (advanced)
|
||||||
{
|
{
|
||||||
wxMessageDialog dlg(q, _(L("This file cannot be loaded in simple mode. Do you want to switch to expert mode?\n")),
|
wxMessageDialog dlg(q, _(L("This file cannot be loaded in a simple mode. Do you want to switch to an advanced mode?\n")),
|
||||||
_(L("Detected advanced data")), wxICON_WARNING | wxYES | wxNO);
|
_(L("Detected advanced data")), wxICON_WARNING | wxYES | wxNO);
|
||||||
if (dlg.ShowModal() == wxID_YES)
|
if (dlg.ShowModal() == wxID_YES)
|
||||||
{
|
{
|
||||||
Slic3r::GUI::wxGetApp().save_mode(comExpert);
|
Slic3r::GUI::wxGetApp().save_mode(comAdvanced);
|
||||||
view3D->set_as_dirty();
|
view3D->set_as_dirty();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2669,25 +2670,21 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
|
||||||
this->statusbar()->set_progress(evt.status.percent);
|
this->statusbar()->set_progress(evt.status.percent);
|
||||||
this->statusbar()->set_status_text(_(L(evt.status.text)) + wxString::FromUTF8("…"));
|
this->statusbar()->set_status_text(_(L(evt.status.text)) + wxString::FromUTF8("…"));
|
||||||
}
|
}
|
||||||
if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SCENE) {
|
if (evt.status.flags & (PrintBase::SlicingStatus::RELOAD_SCENE || PrintBase::SlicingStatus::RELOAD_SLA_SUPPORT_POINTS)) {
|
||||||
switch (this->printer_technology) {
|
switch (this->printer_technology) {
|
||||||
case ptFFF:
|
case ptFFF:
|
||||||
this->update_fff_scene();
|
this->update_fff_scene();
|
||||||
break;
|
break;
|
||||||
case ptSLA:
|
case ptSLA:
|
||||||
|
// If RELOAD_SLA_SUPPORT_POINTS, then the SLA gizmo is updated (reload_scene calls update_gizmos_data)
|
||||||
if (view3D->is_dragging())
|
if (view3D->is_dragging())
|
||||||
delayed_scene_refresh = true;
|
delayed_scene_refresh = true;
|
||||||
else
|
else
|
||||||
this->update_sla_scene();
|
this->update_sla_scene();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) {
|
||||||
if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_SUPPORT_POINTS) {
|
// Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways.
|
||||||
// Update SLA gizmo (reload_scene calls update_gizmos_data)
|
|
||||||
q->canvas3D()->reload_scene(true);
|
|
||||||
}
|
|
||||||
if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) {
|
|
||||||
// Update the SLA preview
|
|
||||||
this->preview->reload_print();
|
this->preview->reload_print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2895,17 +2892,17 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
|
||||||
wxMenuItem* item_delete = nullptr;
|
wxMenuItem* item_delete = nullptr;
|
||||||
if (is_part) {
|
if (is_part) {
|
||||||
item_delete = append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")),
|
item_delete = append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")),
|
||||||
[this](wxCommandEvent&) { q->remove_selected(); }, "remove");
|
[this](wxCommandEvent&) { q->remove_selected(); }, "delete");
|
||||||
|
|
||||||
sidebar->obj_list()->append_menu_item_export_stl(menu);
|
sidebar->obj_list()->append_menu_item_export_stl(menu);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wxMenuItem* item_increase = append_menu_item(menu, wxID_ANY, _(L("Increase copies")) + "\t+", _(L("Place one more copy of the selected object")),
|
wxMenuItem* item_increase = append_menu_item(menu, wxID_ANY, _(L("Increase copies")) + "\t+", _(L("Place one more copy of the selected object")),
|
||||||
[this](wxCommandEvent&) { q->increase_instances(); }, "instance_add");
|
[this](wxCommandEvent&) { q->increase_instances(); }, "add_copies");
|
||||||
wxMenuItem* item_decrease = append_menu_item(menu, wxID_ANY, _(L("Decrease copies")) + "\t-", _(L("Remove one copy of the selected object")),
|
wxMenuItem* item_decrease = append_menu_item(menu, wxID_ANY, _(L("Decrease copies")) + "\t-", _(L("Remove one copy of the selected object")),
|
||||||
[this](wxCommandEvent&) { q->decrease_instances(); }, "instance_remove");
|
[this](wxCommandEvent&) { q->decrease_instances(); }, "remove_copies");
|
||||||
wxMenuItem* item_set_number_of_copies = append_menu_item(menu, wxID_ANY, _(L("Set number of copies")) + dots, _(L("Change the number of copies of the selected object")),
|
wxMenuItem* item_set_number_of_copies = append_menu_item(menu, wxID_ANY, _(L("Set number of copies")) + dots, _(L("Change the number of copies of the selected object")),
|
||||||
[this](wxCommandEvent&) { q->set_number_of_copies(); }, "textfield.png");
|
[this](wxCommandEvent&) { q->set_number_of_copies(); }, "number_of_copies");
|
||||||
|
|
||||||
items_increase.push_back(item_increase);
|
items_increase.push_back(item_increase);
|
||||||
items_decrease.push_back(item_decrease);
|
items_decrease.push_back(item_decrease);
|
||||||
|
@ -2913,7 +2910,7 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
|
||||||
|
|
||||||
// Delete menu was moved to be after +/- instace to make it more difficult to be selected by mistake.
|
// Delete menu was moved to be after +/- instace to make it more difficult to be selected by mistake.
|
||||||
item_delete = append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")),
|
item_delete = append_menu_item(menu, wxID_ANY, _(L("Delete")) + "\tDel", _(L("Remove the selected object")),
|
||||||
[this](wxCommandEvent&) { q->remove_selected(); }, "remove");
|
[this](wxCommandEvent&) { q->remove_selected(); }, "delete");
|
||||||
|
|
||||||
menu->AppendSeparator();
|
menu->AppendSeparator();
|
||||||
wxMenuItem* item_instance_to_object = sidebar->obj_list()->append_menu_item_instance_to_object(menu);
|
wxMenuItem* item_instance_to_object = sidebar->obj_list()->append_menu_item_instance_to_object(menu);
|
||||||
|
@ -2943,11 +2940,11 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
append_menu_item(mirror_menu, wxID_ANY, _(L("Along X axis")), _(L("Mirror the selected object along the X axis")),
|
append_menu_item(mirror_menu, wxID_ANY, _(L("Along X axis")), _(L("Mirror the selected object along the X axis")),
|
||||||
[this](wxCommandEvent&) { mirror(X); }, "bullet_red.png", menu);
|
[this](wxCommandEvent&) { mirror(X); }, "mark_X", menu);
|
||||||
append_menu_item(mirror_menu, wxID_ANY, _(L("Along Y axis")), _(L("Mirror the selected object along the Y axis")),
|
append_menu_item(mirror_menu, wxID_ANY, _(L("Along Y axis")), _(L("Mirror the selected object along the Y axis")),
|
||||||
[this](wxCommandEvent&) { mirror(Y); }, "bullet_green.png", menu);
|
[this](wxCommandEvent&) { mirror(Y); }, "mark_Y", menu);
|
||||||
append_menu_item(mirror_menu, wxID_ANY, _(L("Along Z axis")), _(L("Mirror the selected object along the Z axis")),
|
append_menu_item(mirror_menu, wxID_ANY, _(L("Along Z axis")), _(L("Mirror the selected object along the Z axis")),
|
||||||
[this](wxCommandEvent&) { mirror(Z); }, "bullet_blue.png", menu);
|
[this](wxCommandEvent&) { mirror(Z); }, "mark_Z", menu);
|
||||||
|
|
||||||
wxMenuItem* item_mirror = append_submenu(menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object")));
|
wxMenuItem* item_mirror = append_submenu(menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object")));
|
||||||
|
|
||||||
|
@ -2968,9 +2965,9 @@ bool Plater::priv::complit_init_object_menu()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wxMenuItem* item_split_objects = append_menu_item(split_menu, wxID_ANY, _(L("To objects")), _(L("Split the selected object into individual objects")),
|
wxMenuItem* item_split_objects = append_menu_item(split_menu, wxID_ANY, _(L("To objects")), _(L("Split the selected object into individual objects")),
|
||||||
[this](wxCommandEvent&) { split_object(); }, "split_objects.png", &object_menu);
|
[this](wxCommandEvent&) { split_object(); }, "split_object_SMALL", &object_menu);
|
||||||
wxMenuItem* item_split_volumes = append_menu_item(split_menu, wxID_ANY, _(L("To parts")), _(L("Split the selected object into individual sub-parts")),
|
wxMenuItem* item_split_volumes = append_menu_item(split_menu, wxID_ANY, _(L("To parts")), _(L("Split the selected object into individual sub-parts")),
|
||||||
[this](wxCommandEvent&) { split_volume(); }, "split_parts.png", &object_menu);
|
[this](wxCommandEvent&) { split_volume(); }, "split_parts_SMALL", &object_menu);
|
||||||
|
|
||||||
wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object"))/*, "shape_ungroup.png"*/);
|
wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object"))/*, "shape_ungroup.png"*/);
|
||||||
object_menu.AppendSeparator();
|
object_menu.AppendSeparator();
|
||||||
|
@ -2990,7 +2987,7 @@ bool Plater::priv::complit_init_object_menu()
|
||||||
bool Plater::priv::complit_init_sla_object_menu()
|
bool Plater::priv::complit_init_sla_object_menu()
|
||||||
{
|
{
|
||||||
wxMenuItem* item_split = append_menu_item(&sla_object_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual objects")),
|
wxMenuItem* item_split = append_menu_item(&sla_object_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual objects")),
|
||||||
[this](wxCommandEvent&) { split_object(); }, "shape_ungroup_o.png");
|
[this](wxCommandEvent&) { split_object(); }, "split_object_SMALL");
|
||||||
|
|
||||||
sla_object_menu.AppendSeparator();
|
sla_object_menu.AppendSeparator();
|
||||||
|
|
||||||
|
@ -3010,7 +3007,7 @@ bool Plater::priv::complit_init_sla_object_menu()
|
||||||
bool Plater::priv::complit_init_part_menu()
|
bool Plater::priv::complit_init_part_menu()
|
||||||
{
|
{
|
||||||
wxMenuItem* item_split = append_menu_item(&part_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual sub-parts")),
|
wxMenuItem* item_split = append_menu_item(&part_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual sub-parts")),
|
||||||
[this](wxCommandEvent&) { split_volume(); }, "shape_ungroup_p.png");
|
[this](wxCommandEvent&) { split_volume(); }, "split_parts_SMALL");
|
||||||
|
|
||||||
part_menu.AppendSeparator();
|
part_menu.AppendSeparator();
|
||||||
|
|
||||||
|
@ -3117,7 +3114,7 @@ void Plater::priv::set_bed_shape(const Pointfs& shape)
|
||||||
|
|
||||||
bool Plater::priv::can_delete() const
|
bool Plater::priv::can_delete() const
|
||||||
{
|
{
|
||||||
return !get_selection().is_empty();
|
return !get_selection().is_empty() && !get_selection().is_wipe_tower();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Plater::priv::can_delete_all() const
|
bool Plater::priv::can_delete_all() const
|
||||||
|
@ -3299,8 +3296,9 @@ void Plater::increase_instances(size_t num)
|
||||||
|
|
||||||
bool was_one_instance = model_object->instances.size()==1;
|
bool was_one_instance = model_object->instances.size()==1;
|
||||||
|
|
||||||
float offset = 10.0;
|
double offset_base = canvas3D()->get_size_proportional_to_max_bed_size(0.05);
|
||||||
for (size_t i = 0; i < num; i++, offset += 10.0) {
|
double offset = offset_base;
|
||||||
|
for (size_t i = 0; i < num; i++, offset += offset_base) {
|
||||||
Vec3d offset_vec = model_instance->get_offset() + Vec3d(offset, offset, 0.0);
|
Vec3d offset_vec = model_instance->get_offset() + Vec3d(offset, offset, 0.0);
|
||||||
model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation(), model_instance->get_mirror());
|
model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation(), model_instance->get_mirror());
|
||||||
// p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec));
|
// p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec));
|
||||||
|
@ -3368,7 +3366,7 @@ void Plater::set_number_of_copies(/*size_t num*/)
|
||||||
|
|
||||||
bool Plater::is_selection_empty() const
|
bool Plater::is_selection_empty() const
|
||||||
{
|
{
|
||||||
return p->get_selection().is_empty();
|
return p->get_selection().is_empty() || p->get_selection().is_wipe_tower();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower)
|
void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower)
|
||||||
|
@ -3771,10 +3769,43 @@ void Plater::changed_object(int obj_idx)
|
||||||
this->p->schedule_background_process();
|
this->p->schedule_background_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plater::schedule_background_process()
|
||||||
|
{
|
||||||
|
this->p->schedule_background_process();
|
||||||
|
}
|
||||||
|
|
||||||
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
|
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
|
||||||
|
|
||||||
void Plater::update_object_menu() { p->update_object_menu(); }
|
void Plater::update_object_menu() { p->update_object_menu(); }
|
||||||
|
|
||||||
|
void Plater::copy_selection_to_clipboard()
|
||||||
|
{
|
||||||
|
p->view3D->get_canvas3d()->get_selection().copy_to_clipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Plater::paste_from_clipboard()
|
||||||
|
{
|
||||||
|
p->view3D->get_canvas3d()->get_selection().paste_from_clipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Plater::can_paste_from_clipboard() const
|
||||||
|
{
|
||||||
|
const Selection& selection = p->view3D->get_canvas3d()->get_selection();
|
||||||
|
const Selection::Clipboard& clipboard = selection.get_clipboard();
|
||||||
|
Selection::EMode mode = clipboard.get_mode();
|
||||||
|
|
||||||
|
if (clipboard.is_empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((mode == Selection::Volume) && !selection.is_from_single_instance())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((mode == Selection::Instance) && (selection.get_mode() != Selection::Instance))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Plater::can_delete() const { return p->can_delete(); }
|
bool Plater::can_delete() const { return p->can_delete(); }
|
||||||
bool Plater::can_delete_all() const { return p->can_delete_all(); }
|
bool Plater::can_delete_all() const { return p->can_delete_all(); }
|
||||||
bool Plater::can_increase_instances() const { return p->can_increase_instances(); }
|
bool Plater::can_increase_instances() const { return p->can_increase_instances(); }
|
||||||
|
@ -3783,5 +3814,7 @@ bool Plater::can_split_to_objects() const { return p->can_split_to_objects(); }
|
||||||
bool Plater::can_split_to_volumes() const { return p->can_split_to_volumes(); }
|
bool Plater::can_split_to_volumes() const { return p->can_split_to_volumes(); }
|
||||||
bool Plater::can_arrange() const { return p->can_arrange(); }
|
bool Plater::can_arrange() const { return p->can_arrange(); }
|
||||||
bool Plater::can_layers_editing() const { return p->can_layers_editing(); }
|
bool Plater::can_layers_editing() const { return p->can_layers_editing(); }
|
||||||
|
bool Plater::can_copy() const { return !is_selection_empty(); }
|
||||||
|
bool Plater::can_paste() const { return can_paste_from_clipboard(); }
|
||||||
|
|
||||||
}} // namespace Slic3r::GUI
|
}} // namespace Slic3r::GUI
|
||||||
|
|
|
@ -167,6 +167,7 @@ public:
|
||||||
void reslice();
|
void reslice();
|
||||||
void reslice_SLA_supports(const ModelObject &object);
|
void reslice_SLA_supports(const ModelObject &object);
|
||||||
void changed_object(int obj_idx);
|
void changed_object(int obj_idx);
|
||||||
|
void schedule_background_process();
|
||||||
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
|
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
|
||||||
void send_gcode();
|
void send_gcode();
|
||||||
|
|
||||||
|
@ -187,6 +188,10 @@ public:
|
||||||
PrinterTechnology printer_technology() const;
|
PrinterTechnology printer_technology() const;
|
||||||
void set_printer_technology(PrinterTechnology printer_technology);
|
void set_printer_technology(PrinterTechnology printer_technology);
|
||||||
|
|
||||||
|
void copy_selection_to_clipboard();
|
||||||
|
void paste_from_clipboard();
|
||||||
|
bool can_paste_from_clipboard() const;
|
||||||
|
|
||||||
bool can_delete() const;
|
bool can_delete() const;
|
||||||
bool can_delete_all() const;
|
bool can_delete_all() const;
|
||||||
bool can_increase_instances() const;
|
bool can_increase_instances() const;
|
||||||
|
@ -195,6 +200,8 @@ public:
|
||||||
bool can_split_to_volumes() const;
|
bool can_split_to_volumes() const;
|
||||||
bool can_arrange() const;
|
bool can_arrange() const;
|
||||||
bool can_layers_editing() const;
|
bool can_layers_editing() const;
|
||||||
|
bool can_copy() const;
|
||||||
|
bool can_paste() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct priv;
|
struct priv;
|
||||||
|
|
|
@ -801,12 +801,16 @@ bool PresetCollection::delete_current_preset()
|
||||||
|
|
||||||
void PresetCollection::load_bitmap_default(wxWindow *window, const std::string &file_name)
|
void PresetCollection::load_bitmap_default(wxWindow *window, const std::string &file_name)
|
||||||
{
|
{
|
||||||
*m_bitmap_main_frame = create_scaled_bitmap(window, file_name);
|
// XXX: See note in PresetBundle::load_compatible_bitmaps()
|
||||||
|
(void)window;
|
||||||
|
*m_bitmap_main_frame = create_scaled_bitmap(nullptr, file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresetCollection::load_bitmap_add(wxWindow *window, const std::string &file_name)
|
void PresetCollection::load_bitmap_add(wxWindow *window, const std::string &file_name)
|
||||||
{
|
{
|
||||||
*m_bitmap_add = create_scaled_bitmap(window, file_name);
|
// XXX: See note in PresetBundle::load_compatible_bitmaps()
|
||||||
|
(void)window;
|
||||||
|
*m_bitmap_add = create_scaled_bitmap(nullptr, file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Preset* PresetCollection::get_selected_preset_parent() const
|
const Preset* PresetCollection::get_selected_preset_parent() const
|
||||||
|
|
|
@ -398,22 +398,27 @@ void PresetBundle::export_selections(AppConfig &config)
|
||||||
|
|
||||||
void PresetBundle::load_compatible_bitmaps(wxWindow *window)
|
void PresetBundle::load_compatible_bitmaps(wxWindow *window)
|
||||||
{
|
{
|
||||||
*m_bitmapCompatible = create_scaled_bitmap(window, "flag_green");
|
// We don't actually pass the window pointer here and instead generate
|
||||||
*m_bitmapIncompatible = create_scaled_bitmap(window, "flag_red");
|
// a low DPI bitmap, because the wxBitmapComboBox and wxDataViewCtrl don't support
|
||||||
*m_bitmapLock = create_scaled_bitmap(window, "lock_closed");
|
// high DPI bitmaps very well, they compute their dimensions wrong.
|
||||||
*m_bitmapLockOpen = create_scaled_bitmap(window, "sys_unlock.png");
|
// TODO: Update this when fixed in wxWidgets
|
||||||
|
// See also PresetCollection::load_bitmap_default() and PresetCollection::load_bitmap_add()
|
||||||
|
|
||||||
|
(void)window;
|
||||||
|
*m_bitmapCompatible = create_scaled_bitmap(nullptr, "flag_green");
|
||||||
|
*m_bitmapIncompatible = create_scaled_bitmap(nullptr, "flag_red");
|
||||||
|
*m_bitmapLock = create_scaled_bitmap(nullptr, "lock_closed");
|
||||||
|
*m_bitmapLockOpen = create_scaled_bitmap(nullptr, "sys_unlock.png");
|
||||||
|
|
||||||
prints .set_bitmap_compatible(m_bitmapCompatible);
|
prints .set_bitmap_compatible(m_bitmapCompatible);
|
||||||
filaments .set_bitmap_compatible(m_bitmapCompatible);
|
filaments .set_bitmap_compatible(m_bitmapCompatible);
|
||||||
sla_prints .set_bitmap_compatible(m_bitmapCompatible);
|
sla_prints .set_bitmap_compatible(m_bitmapCompatible);
|
||||||
sla_materials.set_bitmap_compatible(m_bitmapCompatible);
|
sla_materials.set_bitmap_compatible(m_bitmapCompatible);
|
||||||
printers .set_bitmap_compatible(m_bitmapCompatible);
|
|
||||||
|
|
||||||
prints .set_bitmap_incompatible(m_bitmapIncompatible);
|
prints .set_bitmap_incompatible(m_bitmapIncompatible);
|
||||||
filaments .set_bitmap_incompatible(m_bitmapIncompatible);
|
filaments .set_bitmap_incompatible(m_bitmapIncompatible);
|
||||||
sla_prints .set_bitmap_incompatible(m_bitmapIncompatible);
|
sla_prints .set_bitmap_incompatible(m_bitmapIncompatible);
|
||||||
sla_materials.set_bitmap_incompatible(m_bitmapIncompatible);
|
sla_materials.set_bitmap_incompatible(m_bitmapIncompatible);
|
||||||
printers .set_bitmap_incompatible(m_bitmapIncompatible);
|
|
||||||
|
|
||||||
prints .set_bitmap_lock(m_bitmapLock);
|
prints .set_bitmap_lock(m_bitmapLock);
|
||||||
filaments .set_bitmap_lock(m_bitmapLock);
|
filaments .set_bitmap_lock(m_bitmapLock);
|
||||||
|
|
|
@ -1022,6 +1022,77 @@ bool Selection::requires_local_axes() const
|
||||||
return (m_mode == Volume) && is_from_single_instance();
|
return (m_mode == Volume) && is_from_single_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Selection::copy_to_clipboard()
|
||||||
|
{
|
||||||
|
if (!m_valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_clipboard.reset();
|
||||||
|
|
||||||
|
for (const ObjectIdxsToInstanceIdxsMap::value_type& object : m_cache.content)
|
||||||
|
{
|
||||||
|
ModelObject* src_object = m_model->objects[object.first];
|
||||||
|
ModelObject* dst_object = m_clipboard.add_object();
|
||||||
|
dst_object->name = src_object->name;
|
||||||
|
dst_object->input_file = src_object->input_file;
|
||||||
|
dst_object->config = src_object->config;
|
||||||
|
dst_object->sla_support_points = src_object->sla_support_points;
|
||||||
|
dst_object->sla_points_status = src_object->sla_points_status;
|
||||||
|
dst_object->layer_height_ranges = src_object->layer_height_ranges;
|
||||||
|
dst_object->layer_height_profile = src_object->layer_height_profile;
|
||||||
|
dst_object->origin_translation = src_object->origin_translation;
|
||||||
|
|
||||||
|
for (int i : object.second)
|
||||||
|
{
|
||||||
|
dst_object->add_instance(*src_object->instances[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i : m_list)
|
||||||
|
{
|
||||||
|
// Copy the ModelVolumes only for the selected GLVolumes of the 1st selected instance.
|
||||||
|
const GLVolume* volume = (*m_volumes)[i];
|
||||||
|
if ((volume->object_idx() == object.first) && (volume->instance_idx() == *object.second.begin()))
|
||||||
|
{
|
||||||
|
int volume_idx = volume->volume_idx();
|
||||||
|
if ((0 <= volume_idx) && (volume_idx < (int)src_object->volumes.size()))
|
||||||
|
{
|
||||||
|
ModelVolume* src_volume = src_object->volumes[volume_idx];
|
||||||
|
ModelVolume* dst_volume = dst_object->add_volume(*src_volume);
|
||||||
|
dst_volume->set_new_unique_id();
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_clipboard.set_mode(m_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Selection::paste_from_clipboard()
|
||||||
|
{
|
||||||
|
if (!m_valid || m_clipboard.is_empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (m_clipboard.get_mode())
|
||||||
|
{
|
||||||
|
case Volume:
|
||||||
|
{
|
||||||
|
if (is_from_single_instance())
|
||||||
|
paste_volumes_from_clipboard();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Instance:
|
||||||
|
{
|
||||||
|
if (m_mode == Instance)
|
||||||
|
paste_objects_from_clipboard();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Selection::update_valid()
|
void Selection::update_valid()
|
||||||
{
|
{
|
||||||
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
|
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
|
||||||
|
@ -1697,5 +1768,44 @@ bool Selection::is_from_fully_selected_instance(unsigned int volume_idx) const
|
||||||
return count == (unsigned int)m_model->objects[object_idx]->volumes.size();
|
return count == (unsigned int)m_model->objects[object_idx]->volumes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Selection::paste_volumes_from_clipboard()
|
||||||
|
{
|
||||||
|
int obj_idx = get_object_idx();
|
||||||
|
if ((obj_idx < 0) || ((int)m_model->objects.size() <= obj_idx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ModelObject* src_object = m_clipboard.get_object(0);
|
||||||
|
if (src_object != nullptr)
|
||||||
|
{
|
||||||
|
ModelObject* dst_object = m_model->objects[obj_idx];
|
||||||
|
|
||||||
|
ModelVolumePtrs volumes;
|
||||||
|
for (ModelVolume* src_volume : src_object->volumes)
|
||||||
|
{
|
||||||
|
ModelVolume* dst_volume = dst_object->add_volume(*src_volume);
|
||||||
|
dst_volume->set_new_unique_id();
|
||||||
|
double offset = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.05);
|
||||||
|
dst_volume->translate(offset, offset, 0.0);
|
||||||
|
volumes.push_back(dst_volume);
|
||||||
|
}
|
||||||
|
wxGetApp().obj_list()->paste_volumes_into_list(obj_idx, volumes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Selection::paste_objects_from_clipboard()
|
||||||
|
{
|
||||||
|
std::vector<size_t> object_idxs;
|
||||||
|
const ModelObjectPtrs& src_objects = m_clipboard.get_objects();
|
||||||
|
for (const ModelObject* src_object : src_objects)
|
||||||
|
{
|
||||||
|
ModelObject* dst_object = m_model->add_object(*src_object);
|
||||||
|
double offset = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.05);
|
||||||
|
dst_object->translate(offset, offset, 0.0);
|
||||||
|
object_idxs.push_back(m_model->objects.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGetApp().obj_list()->paste_objects_into_list(object_idxs);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -138,6 +138,23 @@ public:
|
||||||
typedef std::set<int> InstanceIdxsList;
|
typedef std::set<int> InstanceIdxsList;
|
||||||
typedef std::map<int, InstanceIdxsList> ObjectIdxsToInstanceIdxsMap;
|
typedef std::map<int, InstanceIdxsList> ObjectIdxsToInstanceIdxsMap;
|
||||||
|
|
||||||
|
class Clipboard
|
||||||
|
{
|
||||||
|
Model m_model;
|
||||||
|
Selection::EMode m_mode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void reset() { m_model.clear_objects(); }
|
||||||
|
bool is_empty() const { return m_model.objects.empty(); }
|
||||||
|
|
||||||
|
ModelObject* add_object() { return m_model.add_object(); }
|
||||||
|
ModelObject* get_object(unsigned int id) { return (id < (unsigned int)m_model.objects.size()) ? m_model.objects[id] : nullptr; }
|
||||||
|
const ModelObjectPtrs& get_objects() const { return m_model.objects; }
|
||||||
|
|
||||||
|
Selection::EMode get_mode() const { return m_mode; }
|
||||||
|
void set_mode(Selection::EMode mode) { m_mode = mode; }
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Cache
|
struct Cache
|
||||||
{
|
{
|
||||||
|
@ -163,6 +180,7 @@ private:
|
||||||
// set of indices to m_volumes
|
// set of indices to m_volumes
|
||||||
IndicesList m_list;
|
IndicesList m_list;
|
||||||
Cache m_cache;
|
Cache m_cache;
|
||||||
|
Clipboard m_clipboard;
|
||||||
mutable BoundingBoxf3 m_bounding_box;
|
mutable BoundingBoxf3 m_bounding_box;
|
||||||
mutable bool m_bounding_box_dirty;
|
mutable bool m_bounding_box_dirty;
|
||||||
|
|
||||||
|
@ -267,6 +285,11 @@ public:
|
||||||
|
|
||||||
bool requires_local_axes() const;
|
bool requires_local_axes() const;
|
||||||
|
|
||||||
|
void copy_to_clipboard();
|
||||||
|
void paste_from_clipboard();
|
||||||
|
|
||||||
|
const Clipboard& get_clipboard() const { return m_clipboard; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update_valid();
|
void update_valid();
|
||||||
void update_type();
|
void update_type();
|
||||||
|
@ -301,6 +324,9 @@ private:
|
||||||
void synchronize_unselected_volumes();
|
void synchronize_unselected_volumes();
|
||||||
void ensure_on_bed();
|
void ensure_on_bed();
|
||||||
bool is_from_fully_selected_instance(unsigned int volume_idx) const;
|
bool is_from_fully_selected_instance(unsigned int volume_idx) const;
|
||||||
|
|
||||||
|
void paste_volumes_from_clipboard();
|
||||||
|
void paste_objects_from_clipboard();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
|
|
@ -165,10 +165,13 @@ void Tab::create_preset_tab()
|
||||||
add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open");
|
add_scaled_bitmap(this, m_bmp_value_unlock, "lock_open");
|
||||||
m_bmp_non_system = &m_bmp_white_bullet;
|
m_bmp_non_system = &m_bmp_white_bullet;
|
||||||
// Bitmaps to be shown on the "Undo user changes" button next to each input field.
|
// Bitmaps to be shown on the "Undo user changes" button next to each input field.
|
||||||
|
// m_bmp_value_revert = create_scaled_bitmap(this, "undo");
|
||||||
|
// m_bmp_white_bullet = create_scaled_bitmap(this, luma >= 128 ? "dot" : "dot_white"/*"bullet_white.png"*/);
|
||||||
|
// m_bmp_question = create_scaled_bitmap(this, "question");
|
||||||
// m_bmp_value_revert = create_scaled_bitmap(this, "undo");
|
// m_bmp_value_revert = create_scaled_bitmap(this, "undo");
|
||||||
// m_bmp_white_bullet = create_scaled_bitmap(this, "bullet_white.png");
|
// m_bmp_white_bullet = create_scaled_bitmap(this, "bullet_white.png");
|
||||||
add_scaled_bitmap(this, m_bmp_value_revert, "undo");
|
add_scaled_bitmap(this, m_bmp_value_revert, "undo");
|
||||||
add_scaled_bitmap(this, m_bmp_white_bullet, "bullet_white.png");
|
add_scaled_bitmap(this, m_bmp_white_bullet, luma >= 128 ? "dot" : "dot_white"/*"bullet_white.png"*/);
|
||||||
|
|
||||||
fill_icon_descriptions();
|
fill_icon_descriptions();
|
||||||
set_tooltips_text();
|
set_tooltips_text();
|
||||||
|
@ -1163,7 +1166,7 @@ void TabPrint::build()
|
||||||
optgroup = page->new_optgroup(_(L("Advanced")));
|
optgroup = page->new_optgroup(_(L("Advanced")));
|
||||||
optgroup->append_single_option_line("interface_shells");
|
optgroup->append_single_option_line("interface_shells");
|
||||||
|
|
||||||
page = add_options_page(_(L("Advanced")), "wrench.png");
|
page = add_options_page(_(L("Advanced")), "wrench");
|
||||||
optgroup = page->new_optgroup(_(L("Extrusion width")));
|
optgroup = page->new_optgroup(_(L("Extrusion width")));
|
||||||
optgroup->append_single_option_line("extrusion_width");
|
optgroup->append_single_option_line("extrusion_width");
|
||||||
optgroup->append_single_option_line("first_layer_extrusion_width");
|
optgroup->append_single_option_line("first_layer_extrusion_width");
|
||||||
|
@ -1536,7 +1539,7 @@ void TabFilament::build()
|
||||||
optgroup->append_single_option_line("slowdown_below_layer_time");
|
optgroup->append_single_option_line("slowdown_below_layer_time");
|
||||||
optgroup->append_single_option_line("min_print_speed");
|
optgroup->append_single_option_line("min_print_speed");
|
||||||
|
|
||||||
page = add_options_page(_(L("Advanced")), "wrench.png");
|
page = add_options_page(_(L("Advanced")), "wrench");
|
||||||
optgroup = page->new_optgroup(_(L("Filament properties")));
|
optgroup = page->new_optgroup(_(L("Filament properties")));
|
||||||
optgroup->append_single_option_line("filament_type");
|
optgroup->append_single_option_line("filament_type");
|
||||||
optgroup->append_single_option_line("filament_soluble");
|
optgroup->append_single_option_line("filament_soluble");
|
||||||
|
@ -1702,12 +1705,17 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto printhost_browse = [=](wxWindow* parent) {
|
auto printhost_browse = [=](wxWindow* parent) {
|
||||||
|
// auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots,
|
||||||
|
// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||||
|
// btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||||
|
// btn->SetBitmap(create_scaled_bitmap(this, "browse"));
|
||||||
// auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots,
|
// auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse ")) + dots,
|
||||||
// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||||
// btn->SetBitmap(create_scaled_bitmap(this, "zoom.png"));
|
// btn->SetBitmap(create_scaled_bitmap(this, "zoom.png"));
|
||||||
add_scaled_button(parent, &m_printhost_browse_btn, "zoom.png", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
|
add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
|
||||||
PrusaButton* btn = m_printhost_browse_btn;
|
PrusaButton* btn = m_printhost_browse_btn;
|
||||||
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||||
|
|
||||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sizer->Add(btn);
|
sizer->Add(btn);
|
||||||
|
|
||||||
|
@ -1722,6 +1730,11 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
|
||||||
return sizer;
|
return sizer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto print_host_test = [this](wxWindow* parent) {
|
||||||
|
auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")),
|
||||||
|
wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||||
|
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||||
|
btn->SetBitmap(create_scaled_bitmap(this, "test"));
|
||||||
auto print_host_test = [this](wxWindow* parent) {
|
auto print_host_test = [this](wxWindow* parent) {
|
||||||
// auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")),
|
// auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")),
|
||||||
// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
// wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
|
||||||
|
@ -1765,7 +1778,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
|
||||||
auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) {
|
auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) {
|
||||||
auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
|
auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
|
||||||
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||||
btn->SetBitmap(create_scaled_bitmap(this, "zoom.png"));
|
btn->SetBitmap(create_scaled_bitmap(this, "browse"));
|
||||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sizer->Add(btn);
|
sizer->Add(btn);
|
||||||
|
|
||||||
|
@ -3330,7 +3343,8 @@ void TabSLAMaterial::build()
|
||||||
optgroup = page->new_optgroup(_(L("Corrections")));
|
optgroup = page->new_optgroup(_(L("Corrections")));
|
||||||
optgroup->label_width = 19;//190;
|
optgroup->label_width = 19;//190;
|
||||||
std::vector<std::string> corrections = {"material_correction"};
|
std::vector<std::string> corrections = {"material_correction"};
|
||||||
std::vector<std::string> axes{ "X", "Y", "Z" };
|
// std::vector<std::string> axes{ "X", "Y", "Z" };
|
||||||
|
std::vector<std::string> axes{ "XY", "Z" };
|
||||||
for (auto& opt_key : corrections) {
|
for (auto& opt_key : corrections) {
|
||||||
auto line = Line{ m_config->def()->get(opt_key)->full_label, "" };
|
auto line = Line{ m_config->def()->get(opt_key)->full_label, "" };
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
@ -3413,7 +3427,7 @@ void TabSLAPrint::build()
|
||||||
optgroup->append_single_option_line("layer_height");
|
optgroup->append_single_option_line("layer_height");
|
||||||
optgroup->append_single_option_line("faded_layers");
|
optgroup->append_single_option_line("faded_layers");
|
||||||
|
|
||||||
page = add_options_page(_(L("Supports")), "sla_supports");
|
page = add_options_page(_(L("Supports")), "support"/*"sla_supports"*/);
|
||||||
optgroup = page->new_optgroup(_(L("Supports")));
|
optgroup = page->new_optgroup(_(L("Supports")));
|
||||||
optgroup->append_single_option_line("supports_enable");
|
optgroup->append_single_option_line("supports_enable");
|
||||||
|
|
||||||
|
@ -3441,7 +3455,7 @@ void TabSLAPrint::build()
|
||||||
optgroup->append_single_option_line("support_points_density_relative");
|
optgroup->append_single_option_line("support_points_density_relative");
|
||||||
optgroup->append_single_option_line("support_points_minimal_distance");
|
optgroup->append_single_option_line("support_points_minimal_distance");
|
||||||
|
|
||||||
page = add_options_page(_(L("Pad")), "brick.png");
|
page = add_options_page(_(L("Pad")), "pad");
|
||||||
optgroup = page->new_optgroup(_(L("Pad")));
|
optgroup = page->new_optgroup(_(L("Pad")));
|
||||||
optgroup->append_single_option_line("pad_enable");
|
optgroup->append_single_option_line("pad_enable");
|
||||||
optgroup->append_single_option_line("pad_wall_thickness");
|
optgroup->append_single_option_line("pad_wall_thickness");
|
||||||
|
|