Merge remote-tracking branch 'origin/master' into ys_optgroup_refact

This commit is contained in:
YuSanka 2020-09-23 08:38:21 +02:00
commit fc3aa61dc4
115 changed files with 3693 additions and 2589 deletions

View file

@ -12,7 +12,7 @@ compatible with any modern printer based on the RepRap toolchain, including all
those based on the Marlin, Prusa, Sprinter and Repetier firmware. It also works
with Mach3, LinuxCNC and Machinekit controllers.
PrusaSlicer is based on [Slic3r](https://github.com/Slic3r/Slic3r) by Alessandro Ranelucci and the RepRap community.
PrusaSlicer is based on [Slic3r](https://github.com/Slic3r/Slic3r) by Alessandro Ranellucci and the RepRap community.
See the [project homepage](https://www.prusa3d.com/slic3r-prusa-edition/) and
the [documentation directory](doc/) for more information.

View file

@ -1,17 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="#FFFFFF" d="M87.29,22.62H34.71c-1.39,0-3.14,0.69-4.16,1.63L9.81,43.46c-1.05,0.98-1.82,2.73-1.82,4.16v54.31
c0,1.9,1.55,3.45,3.45,3.45h55.17c1.4,0,3.15-0.7,4.16-1.67l12.41-11.83c0.69-0.66,0.72-1.75,0.06-2.44s-1.75-0.71-2.44-0.06
L70.05,99.63v-53.2c0.26-0.19,0.51-0.39,0.72-0.61L87.3,28.29v33.12c0,0.35-0.02,0.64-0.04,0.85c-0.51,0.55-0.62,1.39-0.22,2.06
c0.49,0.82,1.55,1.08,2.37,0.59l0.25-0.15c0.67-0.4,1.09-1.1,1.09-3.35V26.07C90.74,24.17,89.2,22.62,87.29,22.62z M11.44,47.62
L11.44,47.62h55.17v54.31H11.44V47.62z M68.26,43.46c-0.33,0.35-1.18,0.71-1.65,0.71H14.12L32.9,26.78
c0.37-0.35,1.31-0.71,1.82-0.71h49.94L68.26,43.46z"/>
<path id="_x2B__1_" fill="#ED6B21" d="M110.57,82.1c0,0.95-0.78,1.72-1.72,1.72h-4.31c-0.95,0-1.72,0.78-1.72,1.72v4.31
c0,0.95-0.78,1.72-1.72,1.72h-4.31c-0.95,0-1.72-0.78-1.72-1.72v-4.31c0-0.95-0.78-1.72-1.72-1.72h-4.31
c-0.95,0-1.72-0.78-1.72-1.72v-4.31c0-0.95,0.78-1.72,1.72-1.72h4.31c0.95,0,1.72-0.78,1.72-1.72v-4.31c0-0.95,0.78-1.72,1.72-1.72
h4.31c0.95,0,1.72,0.78,1.72,1.72v4.31c0,0.95,0.78,1.72,1.72,1.72h4.31c0.95,0,1.72,0.78,1.72,1.72V82.1z M120.05,79.95
c0-11.65-9.47-21.12-21.12-21.12S77.81,68.3,77.81,79.95s9.47,21.12,21.12,21.12S120.05,91.59,120.05,79.95z M116.6,79.95
c0,9.74-7.93,17.67-17.67,17.67s-17.67-7.93-17.67-17.67s7.93-17.67,17.67-17.67S116.6,70.2,116.6,79.95z"/>
<g id="ADD">
<path fill="#FFFFFF" d="M72.3,117.5H10.5v-75h75v23.27c1.61-0.56,3.28-0.99,5-1.29V41.04l27-27V72.3c1.89,1.71,3.57,3.65,5,5.76V8
c0-0.05-0.01-0.1-0.02-0.15c0-0.06-0.01-0.11-0.02-0.17c-0.03-0.22-0.08-0.43-0.15-0.62c0,0,0-0.01,0-0.01c0,0,0,0,0,0
c-0.01-0.03-0.03-0.05-0.04-0.08c-0.05-0.11-0.11-0.21-0.17-0.31c-0.03-0.04-0.05-0.08-0.08-0.11c-0.06-0.08-0.13-0.16-0.2-0.24
c-0.03-0.03-0.06-0.07-0.09-0.1c-0.09-0.09-0.19-0.17-0.3-0.25c-0.01-0.01-0.02-0.02-0.04-0.03c-0.12-0.08-0.24-0.15-0.38-0.2
c-0.04-0.02-0.09-0.03-0.13-0.05c-0.1-0.04-0.2-0.07-0.3-0.09c-0.05-0.01-0.09-0.02-0.14-0.03c-0.15-0.03-0.3-0.05-0.45-0.05H48
c-0.57,0-1.12,0.19-1.56,0.55l-40,32c-0.03,0.03-0.06,0.06-0.09,0.09c-0.07,0.06-0.13,0.12-0.19,0.19
c-0.05,0.06-0.1,0.12-0.15,0.18c-0.05,0.07-0.09,0.13-0.14,0.2c-0.04,0.07-0.08,0.14-0.12,0.21c-0.03,0.07-0.07,0.15-0.09,0.22
c-0.03,0.08-0.05,0.16-0.07,0.24c-0.02,0.08-0.04,0.15-0.05,0.23c-0.01,0.09-0.02,0.18-0.03,0.27c0,0.04-0.01,0.08-0.01,0.13v80
c0,1.38,1.12,2.5,2.5,2.5h70.06C75.95,121.07,74.01,119.39,72.3,117.5z M48.88,10.5h65.09l-27,27H15.13L48.88,10.5z"/>
<g>
<path fill="#ED6B21" d="M96,69.5c-14.61,0-26.5,11.89-26.5,26.5s11.89,26.5,26.5,26.5s26.5-11.89,26.5-26.5S110.61,69.5,96,69.5z
M96,117.5c-11.86,0-21.5-9.64-21.5-21.5S84.14,74.5,96,74.5s21.5,9.64,21.5,21.5S107.86,117.5,96,117.5z"/>
<path fill="#ED6B21" d="M112,93.5H98.5V80c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v13.5H80c-1.38,0-2.5,1.12-2.5,2.5
s1.12,2.5,2.5,2.5h13.5V112c0,1.38,1.12,2.5,2.5,2.5s2.5-1.12,2.5-2.5V98.5H112c1.38,0,2.5-1.12,2.5-2.5S113.38,93.5,112,93.5z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -1,24 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="ARRANGE">
<path fill="#FFFFFF" d="M113.85,14.27v99.36h-99.7V14.27H113.85 M115.85,8.27H12.15c-2.2,0-4,1.8-4,4v103.36c0,2.2,1.8,4,4,4h103.7
c2.2,0,4-1.8,4-4V12.27C119.85,10.07,118.05,8.27,115.85,8.27L115.85,8.27z"/>
<g id="arrange">
<g>
<path fill="#ED6B21" d="M48.04,99.24c0,2.2-1.8,4-4,4H28.11c-2.2,0-4-1.8-4-4v-47c0-2.2,1.8-4,4-4h15.94c2.2,0,4,1.8,4,4
L48.04,99.24L48.04,99.24z"/>
<path fill="#FFFFFF" d="M120,122.5H8c-1.38,0-2.5-1.12-2.5-2.5V8c0-1.38,1.12-2.5,2.5-2.5h112c1.38,0,2.5,1.12,2.5,2.5v112
C122.5,121.38,121.38,122.5,120,122.5z M10.5,117.5h107v-107h-107V117.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M28.11,40.38c-2.2,0-4-1.8-4-4v-7.72c0-2.2,1.8-4,4-4h15.94c2.2,0,4,1.8,4,4v7.72c0,2.2-1.8,4-4,4H28.11z"
/>
<path fill="#ED6B21" d="M104,58.5H24c-1.38,0-2.5-1.12-2.5-2.5V24c0-1.38,1.12-2.5,2.5-2.5h80c1.38,0,2.5,1.12,2.5,2.5v32
C106.5,57.38,105.38,58.5,104,58.5z M26.5,53.5h75v-27h-75V53.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M68,103.24c-2.2,0-4-1.8-4-4V83.67c0-2.2,1.8-4,4-4h31.89c2.2,0,4,1.8,4,4v15.57c0,2.2-1.8,4-4,4H68z"/>
<path fill="#ED6B21" d="M48,106.5H24c-1.38,0-2.5-1.12-2.5-2.5V72c0-1.38,1.12-2.5,2.5-2.5h24c1.38,0,2.5,1.12,2.5,2.5v32
C50.5,105.38,49.38,106.5,48,106.5z M26.5,101.5h19v-27h-19V101.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M103.89,59.95c0,2.2-1.8,4-4,4H68c-2.2,0-4-1.8-4-4V28.66c0-2.2,1.8-4,4-4h31.89c2.2,0,4,1.8,4,4V59.95z"
/>
<path fill="#ED6B21" d="M104,106.5H64c-1.38,0-2.5-1.12-2.5-2.5V72c0-1.38,1.12-2.5,2.5-2.5h40c1.38,0,2.5,1.12,2.5,2.5v32
C106.5,105.38,105.38,106.5,104,106.5z M66.5,101.5h35v-27h-35V101.5z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,37 +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) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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"/>
<path fill="#FFFFFF" d="M38.24,29.83l-15.49,8.94c-0.77,0.45-1.25,1.27-1.25,2.17v17.89c0,0.89,0.48,1.72,1.25,2.17l15.49,8.94
c0.39,0.22,0.82,0.33,1.25,0.33s0.86-0.11,1.25-0.33L48,65.75v-5.77l-8.51,4.91l-12.99-7.5v-15l12.99-7.5L48,39.8v-5.77
l-7.26-4.19C39.97,29.39,39.02,29.39,38.24,29.83z"/>
<path fill="#FFFFFF" d="M48,85.5H10.5v-75h43V24c0,1.38,1.12,2.5,2.5,2.5h13.5V32h5v-8c0-0.17-0.02-0.33-0.05-0.49
c-0.02-0.11-0.06-0.22-0.1-0.33c-0.02-0.05-0.02-0.09-0.04-0.14c-0.05-0.12-0.11-0.23-0.18-0.34c-0.02-0.03-0.03-0.06-0.05-0.09
c-0.09-0.14-0.2-0.26-0.31-0.38L57.77,6.23c-0.12-0.12-0.24-0.22-0.38-0.31c-0.04-0.02-0.08-0.04-0.11-0.06
c-0.1-0.06-0.2-0.12-0.32-0.17c-0.05-0.02-0.11-0.03-0.16-0.05c-0.1-0.03-0.2-0.07-0.3-0.09C56.33,5.52,56.17,5.5,56,5.5H8
C6.62,5.5,5.5,6.62,5.5,8v80c0,1.38,1.12,2.5,2.5,2.5h40V85.5z M58.5,14.04l7.46,7.46H58.5V14.04z"/>
</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"/>
<path fill="#ED6B21" d="M122.45,55.51c-0.02-0.11-0.06-0.22-0.1-0.33c-0.02-0.05-0.02-0.09-0.04-0.14
c-0.05-0.12-0.11-0.23-0.18-0.34c-0.02-0.03-0.03-0.06-0.05-0.09c-0.09-0.14-0.2-0.26-0.31-0.38l-15.99-15.99
c-0.12-0.12-0.24-0.22-0.38-0.31c-0.04-0.02-0.08-0.04-0.11-0.06c-0.1-0.06-0.2-0.12-0.32-0.17c-0.05-0.02-0.11-0.03-0.16-0.05
c-0.1-0.03-0.2-0.07-0.3-0.09c-0.16-0.03-0.33-0.05-0.49-0.05H56c-1.38,0-2.5,1.12-2.5,2.5v80c0,1.38,1.12,2.5,2.5,2.5h64
c1.38,0,2.5-1.12,2.5-2.5V56C122.5,55.83,122.48,55.67,122.45,55.51z M106.5,46.04l7.46,7.46h-7.46V46.04z M58.5,117.5v-75h43V56
c0,1.38,1.12,2.5,2.5,2.5h13.5v59H58.5z"/>
<path fill="#ED6B21" d="M104.23,70.78l-15.49-8.94c-0.77-0.45-1.73-0.45-2.5,0l-15.49,8.94c-0.77,0.45-1.25,1.27-1.25,2.17v17.89
c0,0.89,0.48,1.72,1.25,2.17l15.49,8.94c0.39,0.22,0.82,0.33,1.25,0.33s0.86-0.11,1.25-0.33L104.23,93
c0.77-0.45,1.25-1.27,1.25-2.17V72.94C105.48,72.05,105.01,71.23,104.23,70.78z M100.48,89.39l-12.99,7.5l-12.99-7.5v-15
l12.99-7.5l12.99,7.5V89.39z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -1,31 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="#FFFFFF" 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 id="delete_x5F_all">
<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"/>
<path fill="#FFFFFF" d="M104,122.5H24c-1.29,0-2.37-0.99-2.49-2.27l-8-88c-0.06-0.7,0.17-1.39,0.64-1.91
C14.63,29.8,15.3,29.5,16,29.5h96c0.7,0,1.37,0.3,1.85,0.81c0.47,0.52,0.71,1.21,0.64,1.91l-8,88
C106.37,121.51,105.29,122.5,104,122.5z M26.28,117.5h75.43l7.55-83H18.74L26.28,117.5z"/>
</g>
<g>
<path fill="#FFFFFF" 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="#FFFFFF" 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="#FFFFFF" 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="#FFFFFF" 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"/>
<path fill="#ED6B21" d="M112,26.5H16c-1.38,0-2.5-1.12-2.5-2.5v-8c0-1.38,1.12-2.5,2.5-2.5h29.5V8c0-1.38,1.12-2.5,2.5-2.5h32
c1.38,0,2.5,1.12,2.5,2.5v5.5H112c1.38,0,2.5,1.12,2.5,2.5v8C114.5,25.38,113.38,26.5,112,26.5z M18.5,21.5h91v-3H80
c-1.38,0-2.5-1.12-2.5-2.5v-5.5h-27V16c0,1.38-1.12,2.5-2.5,2.5H18.5V21.5z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1,012 B

View file

@ -1,50 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="ADD_INSTANCE">
<g id="instance_x5F_add">
<g>
<path fill="#ED6B21" d="M88.01,57.95c0-1.1-0.9-2-2-2H74c-1.1,0-2-0.9-2-2V41.94c0-1.1-0.9-2-2-2H58c-1.1,0-2,0.9-2,2v12.01
c0,1.1-0.9,2-2,2H41.99c-1.1,0-2,0.9-2,2v12.01c0,1.1,0.9,2,2,2H54c1.1,0,2,0.9,2,2v12.01c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2
V73.95c0-1.1,0.9-2,2-2h12.01c1.1,0,2-0.9,2-2V57.95z"/>
<path fill="#FFFFFF" d="M65.02,122.49c-1.36,0-2.47-1.09-2.5-2.45c-0.03-1.38,1.07-2.52,2.45-2.55c3.71-0.07,7.4-0.52,10.98-1.33
c1.34-0.31,2.69,0.54,2.99,1.88c0.31,1.35-0.54,2.69-1.88,2.99c-3.91,0.89-7.95,1.38-12,1.46
C65.05,122.49,65.04,122.49,65.02,122.49z M51.6,121.12c-0.18,0-0.37-0.02-0.55-0.06c-3.93-0.89-7.79-2.19-11.46-3.88
c-1.25-0.58-1.8-2.06-1.23-3.32c0.58-1.25,2.06-1.8,3.32-1.23c3.35,1.54,6.88,2.73,10.47,3.55c1.35,0.3,2.19,1.64,1.89,2.99
C53.78,120.33,52.74,121.12,51.6,121.12z M89.21,116.52c-0.91,0-1.79-0.5-2.23-1.37c-0.62-1.23-0.13-2.74,1.1-3.36
c3.29-1.66,6.42-3.67,9.3-5.98c1.08-0.86,2.65-0.69,3.51,0.39c0.86,1.08,0.69,2.65-0.39,3.51c-3.15,2.52-6.58,4.72-10.17,6.53
C89.97,116.44,89.58,116.52,89.21,116.52z M29.14,110.33c-0.55,0-1.1-0.18-1.56-0.54c-3.15-2.51-6.06-5.36-8.63-8.46
c-0.88-1.06-0.73-2.64,0.33-3.52c1.06-0.88,2.64-0.74,3.52,0.33c2.35,2.84,5.01,5.44,7.9,7.74c1.08,0.86,1.26,2.43,0.4,3.51
C30.61,110.01,29.88,110.33,29.14,110.33z M108.39,100.64c-0.53,0-1.07-0.17-1.52-0.52c-1.09-0.84-1.3-2.41-0.46-3.51
c2.25-2.93,4.21-6.09,5.81-9.41c0.6-1.24,2.1-1.77,3.34-1.17c1.24,0.6,1.77,2.09,1.17,3.34c-1.75,3.63-3.89,7.09-6.35,10.29
C109.88,100.31,109.14,100.64,108.39,100.64z M13.58,90.89c-0.93,0-1.82-0.52-2.25-1.41c-1.76-3.63-3.14-7.46-4.11-11.37
c-0.33-1.34,0.49-2.7,1.83-3.03c1.34-0.33,2.7,0.49,3.03,1.83c0.89,3.58,2.15,7.07,3.76,10.39c0.6,1.24,0.08,2.74-1.16,3.34
C14.32,90.81,13.94,90.89,13.58,90.89z M118.82,78.01c-0.17,0-0.34-0.02-0.51-0.05c-1.35-0.28-2.22-1.61-1.94-2.96
c0.75-3.59,1.13-7.29,1.13-11l0-0.23c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5l0,0.2c0,4.08-0.42,8.12-1.24,12.05
C121.02,77.2,119.98,78.01,118.82,78.01z M8,66.62c-1.38,0-2.5-1.12-2.5-2.5V64c0-4.01,0.41-8.01,1.21-11.9
c0.28-1.35,1.6-2.22,2.95-1.94c1.35,0.28,2.22,1.6,1.94,2.95C10.87,56.67,10.5,60.33,10.5,64v0.12C10.5,65.5,9.38,66.62,8,66.62z
M118.33,52.88c-1.12,0-2.14-0.76-2.42-1.89c-0.89-3.57-2.17-7.07-3.78-10.39c-0.61-1.24-0.09-2.74,1.15-3.34
c1.24-0.6,2.74-0.09,3.34,1.15c1.77,3.63,3.16,7.45,4.14,11.36c0.33,1.34-0.48,2.7-1.82,3.03
C118.74,52.85,118.53,52.88,118.33,52.88z M13.48,42.32c-0.36,0-0.73-0.08-1.08-0.25c-1.25-0.6-1.77-2.09-1.17-3.34
c1.74-3.63,3.87-7.1,6.33-10.3c0.84-1.09,2.41-1.3,3.51-0.46c1.1,0.84,1.3,2.41,0.46,3.51c-2.25,2.93-4.2,6.1-5.79,9.42
C15.3,41.79,14.41,42.32,13.48,42.32z M107.05,30.68c-0.72,0-1.43-0.31-1.92-0.9c-2.36-2.84-5.03-5.44-7.92-7.73
c-1.08-0.86-1.26-2.43-0.41-3.51c0.86-1.08,2.43-1.26,3.51-0.41c3.16,2.5,6.07,5.34,8.65,8.44c0.88,1.06,0.74,2.64-0.32,3.52
C108.18,30.49,107.61,30.68,107.05,30.68z M28.97,22.81c-0.73,0-1.46-0.32-1.95-0.94c-0.86-1.08-0.69-2.65,0.38-3.51
c3.15-2.53,6.56-4.73,10.16-6.55c1.23-0.63,2.74-0.13,3.36,1.1c0.62,1.23,0.13,2.74-1.1,3.36c-3.28,1.67-6.41,3.69-9.29,6
C30.07,22.63,29.52,22.81,28.97,22.81z M87.25,15.54c-0.35,0-0.7-0.07-1.04-0.23c-3.36-1.53-6.88-2.72-10.48-3.52
c-1.35-0.3-2.2-1.64-1.89-2.99c0.3-1.35,1.64-2.2,2.99-1.89c3.94,0.88,7.79,2.18,11.46,3.86c1.26,0.57,1.81,2.06,1.23,3.31
C89.11,15,88.2,15.54,87.25,15.54z M51.37,11.93c-1.14,0-2.17-0.78-2.43-1.94c-0.31-1.35,0.53-2.69,1.88-3
c3.91-0.9,7.95-1.4,12-1.48c1.38-0.04,2.52,1.07,2.55,2.45c0.03,1.38-1.07,2.52-2.45,2.55c-3.7,0.07-7.39,0.53-10.97,1.35
C51.75,11.91,51.56,11.93,51.37,11.93z"/>
</g>
<g>
<path fill="#FFFFFF" d="M67.06,119.73c-2.1,0-3.87-1.64-3.99-3.77c-0.13-2.21,1.56-4.1,3.76-4.23c1.85-0.11,3.71-0.32,5.53-0.64
c2.17-0.38,4.25,1.07,4.63,3.25s-1.07,4.25-3.25,4.63c-2.12,0.37-4.29,0.63-6.45,0.75C67.22,119.73,67.14,119.73,67.06,119.73z
M55.05,119.05c-0.23,0-0.46-0.02-0.69-0.06c-2.13-0.37-4.26-0.87-6.32-1.49c-2.12-0.63-3.32-2.86-2.69-4.98s2.86-3.32,4.98-2.69
c1.77,0.53,3.59,0.96,5.41,1.27c2.18,0.38,3.63,2.45,3.25,4.63C58.65,117.68,56.96,119.05,55.05,119.05z M84.58,115.58
c-1.55,0-3.02-0.9-3.67-2.41c-0.88-2.03,0.06-4.38,2.08-5.26c1.69-0.73,3.36-1.57,4.96-2.5c1.91-1.11,4.36-0.46,5.47,1.46
c1.11,1.91,0.46,4.36-1.46,5.47c-1.87,1.08-3.82,2.07-5.8,2.92C85.65,115.47,85.11,115.58,84.58,115.58z M38.12,112.91
c-0.68,0-1.37-0.17-2-0.54c-1.87-1.08-3.69-2.28-5.43-3.57c-1.77-1.32-2.14-3.82-0.82-5.6c1.32-1.77,3.82-2.14,5.6-0.82
c1.49,1.11,3.05,2.13,4.65,3.06c1.91,1.1,2.57,3.55,1.47,5.46C40.84,112.2,39.5,112.91,38.12,112.91z M99.61,105.67
c-1.06,0-2.12-0.42-2.91-1.25c-1.52-1.61-1.45-4.14,0.16-5.66c1.35-1.27,2.63-2.64,3.82-4.05c1.42-1.69,3.94-1.91,5.64-0.49
c1.69,1.42,1.91,3.94,0.49,5.64c-1.39,1.65-2.88,3.24-4.45,4.72C101.58,105.3,100.59,105.67,99.61,105.67z M24.32,101.35
c-1.14,0-2.27-0.48-3.06-1.42c-1.39-1.65-2.7-3.4-3.89-5.2c-1.22-1.84-0.71-4.32,1.13-5.54c1.84-1.22,4.32-0.71,5.54,1.13
c1.02,1.54,2.14,3.04,3.33,4.46c1.42,1.69,1.21,4.21-0.48,5.64C26.14,101.04,25.23,101.35,24.32,101.35z M110.36,91.23
c-0.6,0-1.22-0.14-1.79-0.43c-1.97-0.99-2.77-3.4-1.78-5.37c0.83-1.65,1.57-3.37,2.2-5.11c0.75-2.08,3.05-3.15,5.13-2.39
c2.08,0.75,3.15,3.05,2.39,5.13c-0.74,2.03-1.61,4.04-2.58,5.97C113.24,90.42,111.83,91.23,110.36,91.23z M15.28,85.78
c-1.63,0-3.16-1-3.76-2.63c-0.74-2.03-1.37-4.12-1.87-6.22c-0.51-2.15,0.82-4.31,2.97-4.82s4.31,0.82,4.82,2.97
c0.43,1.8,0.97,3.59,1.6,5.32c0.76,2.08-0.31,4.37-2.38,5.13C16.2,85.7,15.73,85.78,15.28,85.78z M115.53,73.97
c-0.15,0-0.31-0.01-0.46-0.03c-2.19-0.25-3.77-2.24-3.52-4.43c0.21-1.83,0.32-3.7,0.32-5.56v-0.21c0-2.21,1.79-4,4-4s4,1.79,4,4
v0.15c0,2.22-0.12,4.4-0.37,6.53C119.26,72.47,117.53,73.97,115.53,73.97z M12.13,68.05c-2.21,0-4-1.79-4-4h4l-4-0.05
c0-2.18,0.12-4.33,0.36-6.42c0.25-2.19,2.24-3.76,4.43-3.52c2.2,0.25,3.77,2.23,3.52,4.43c-0.21,1.8-0.31,3.64-0.31,5.46v0.1
C16.13,66.26,14.34,68.05,12.13,68.05z M114.43,55.8c-1.81,0-3.45-1.23-3.89-3.07c-0.43-1.8-0.98-3.59-1.61-5.32
c-0.76-2.07,0.3-4.37,2.37-5.14c2.07-0.76,4.37,0.3,5.14,2.37c0.74,2.02,1.38,4.11,1.88,6.22c0.52,2.15-0.81,4.31-2.95,4.82
C115.06,55.76,114.74,55.8,114.43,55.8z M15.21,50.31c-0.45,0-0.91-0.08-1.36-0.24c-2.08-0.75-3.15-3.04-2.4-5.12
c0.73-2.03,1.6-4.04,2.56-5.97C15,37,17.4,36.2,19.38,37.19c1.98,0.99,2.77,3.39,1.79,5.37c-0.83,1.65-1.57,3.37-2.19,5.11
C18.38,49.3,16.85,50.31,15.21,50.31z M107.24,39.3c-1.29,0-2.57-0.63-3.34-1.79c-1.02-1.54-2.15-3.04-3.34-4.45
c-1.43-1.69-1.22-4.21,0.47-5.64s4.21-1.22,5.64,0.47c1.39,1.65,2.71,3.39,3.9,5.19c1.22,1.84,0.72,4.32-1.12,5.54
C108.77,39.08,108,39.3,107.24,39.3z M24.19,34.7c-0.91,0-1.82-0.31-2.56-0.93c-1.69-1.42-1.92-3.94-0.5-5.63
c1.38-1.66,2.88-3.25,4.44-4.73c1.6-1.52,4.13-1.45,5.65,0.15s1.45,4.13-0.15,5.65c-1.34,1.27-2.62,2.64-3.81,4.06
C26.47,34.21,25.33,34.7,24.19,34.7z M94.83,26.24c-0.83,0-1.66-0.26-2.38-0.79c-1.49-1.1-3.05-2.13-4.66-3.05
c-1.92-1.1-2.58-3.54-1.48-5.46c1.1-1.91,3.54-2.58,5.46-1.48c1.87,1.07,3.7,2.27,5.44,3.56c1.78,1.31,2.15,3.82,0.83,5.6
C97.27,25.68,96.06,26.24,94.83,26.24z M37.95,23.09c-1.38,0-2.72-0.71-3.46-1.99c-1.11-1.91-0.46-4.36,1.44-5.47
c1.86-1.08,3.81-2.07,5.79-2.93c2.03-0.88,4.38,0.05,5.26,2.07c0.88,2.03-0.05,4.38-2.07,5.26c-1.69,0.74-3.36,1.58-4.96,2.51
C39.33,22.92,38.64,23.09,37.95,23.09z M78.72,18.21c-0.38,0-0.76-0.05-1.13-0.17c-1.77-0.52-3.59-0.95-5.42-1.26
c-2.18-0.37-3.64-2.44-3.26-4.62s2.45-3.64,4.62-3.26c2.13,0.37,4.26,0.86,6.33,1.47c2.12,0.63,3.33,2.85,2.7,4.97
C82.04,17.08,80.45,18.21,78.72,18.21z M54.84,16.89c-1.9,0-3.59-1.36-3.93-3.3c-0.39-2.17,1.06-4.25,3.24-4.64
c2.12-0.38,4.29-0.63,6.45-0.76c2.19-0.14,4.1,1.55,4.23,3.75c0.13,2.21-1.55,4.1-3.75,4.23c-1.85,0.11-3.71,0.33-5.52,0.66
C55.31,16.87,55.07,16.89,54.84,16.89z"/>
<path fill="#ED6B21" d="M64,98.5c-1.38,0-2.5-1.12-2.5-2.5V32c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5v64
C66.5,97.38,65.38,98.5,64,98.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M96,66.5H32c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5h64c1.38,0,2.5,1.12,2.5,2.5S97.38,66.5,96,66.5z"
/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -1,49 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="REMOVE_INSTANCE">
<g id="instance_x5F_remove">
<g>
<path fill="#ED6B21" d="M88.01,57.95c0-1.1-0.9-2-2-2H41.99c-1.1,0-2,0.9-2,2v12.01c0,1.1,0.9,2,2,2h44.02c1.1,0,2-0.9,2-2V57.95z
"/>
<path fill="#FFFFFF" d="M65.02,122.49c-1.36,0-2.47-1.09-2.5-2.45c-0.03-1.38,1.07-2.52,2.45-2.55c3.71-0.07,7.4-0.52,10.98-1.33
c1.34-0.31,2.69,0.54,2.99,1.88c0.31,1.35-0.54,2.69-1.88,2.99c-3.91,0.89-7.95,1.38-12,1.46
C65.05,122.49,65.04,122.49,65.02,122.49z M51.6,121.12c-0.18,0-0.37-0.02-0.55-0.06c-3.93-0.89-7.79-2.19-11.46-3.88
c-1.25-0.58-1.8-2.06-1.23-3.32c0.58-1.25,2.06-1.8,3.32-1.23c3.35,1.54,6.88,2.73,10.47,3.55c1.35,0.3,2.19,1.64,1.89,2.99
C53.78,120.33,52.74,121.12,51.6,121.12z M89.21,116.52c-0.91,0-1.79-0.5-2.23-1.37c-0.62-1.23-0.13-2.74,1.1-3.36
c3.29-1.66,6.42-3.67,9.3-5.98c1.08-0.86,2.65-0.69,3.51,0.39c0.86,1.08,0.69,2.65-0.39,3.51c-3.15,2.52-6.58,4.72-10.17,6.53
C89.97,116.44,89.58,116.52,89.21,116.52z M29.14,110.33c-0.55,0-1.1-0.18-1.56-0.54c-3.15-2.51-6.06-5.36-8.63-8.46
c-0.88-1.06-0.73-2.64,0.33-3.52c1.06-0.88,2.64-0.74,3.52,0.33c2.35,2.84,5.01,5.44,7.9,7.74c1.08,0.86,1.26,2.43,0.4,3.51
C30.61,110.01,29.88,110.33,29.14,110.33z M108.39,100.64c-0.53,0-1.07-0.17-1.52-0.52c-1.09-0.84-1.3-2.41-0.46-3.51
c2.25-2.93,4.21-6.09,5.81-9.41c0.6-1.24,2.1-1.77,3.34-1.17c1.24,0.6,1.77,2.09,1.17,3.34c-1.75,3.63-3.89,7.09-6.35,10.29
C109.88,100.31,109.14,100.64,108.39,100.64z M13.58,90.89c-0.93,0-1.82-0.52-2.25-1.41c-1.76-3.63-3.14-7.46-4.11-11.37
c-0.33-1.34,0.49-2.7,1.83-3.03c1.34-0.33,2.7,0.49,3.03,1.83c0.89,3.58,2.15,7.07,3.76,10.39c0.6,1.24,0.08,2.74-1.16,3.34
C14.32,90.81,13.94,90.89,13.58,90.89z M118.82,78.01c-0.17,0-0.34-0.02-0.51-0.05c-1.35-0.28-2.22-1.61-1.94-2.96
c0.75-3.59,1.13-7.29,1.13-11l0-0.23c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5l0,0.2c0,4.08-0.42,8.12-1.24,12.05
C121.02,77.2,119.98,78.01,118.82,78.01z M8,66.62c-1.38,0-2.5-1.12-2.5-2.5V64c0-4.01,0.41-8.01,1.21-11.9
c0.28-1.35,1.6-2.22,2.95-1.94c1.35,0.28,2.22,1.6,1.94,2.95C10.87,56.67,10.5,60.33,10.5,64v0.12C10.5,65.5,9.38,66.62,8,66.62z
M118.33,52.88c-1.12,0-2.14-0.76-2.42-1.89c-0.89-3.57-2.17-7.07-3.78-10.39c-0.61-1.24-0.09-2.74,1.15-3.34
c1.24-0.6,2.74-0.09,3.34,1.15c1.77,3.63,3.16,7.45,4.14,11.36c0.33,1.34-0.48,2.7-1.82,3.03
C118.74,52.85,118.53,52.88,118.33,52.88z M13.48,42.32c-0.36,0-0.73-0.08-1.08-0.25c-1.25-0.6-1.77-2.09-1.17-3.34
c1.74-3.63,3.87-7.1,6.33-10.3c0.84-1.09,2.41-1.3,3.51-0.46c1.1,0.84,1.3,2.41,0.46,3.51c-2.25,2.93-4.2,6.1-5.79,9.42
C15.3,41.79,14.41,42.32,13.48,42.32z M107.05,30.68c-0.72,0-1.43-0.31-1.92-0.9c-2.36-2.84-5.03-5.44-7.92-7.73
c-1.08-0.86-1.26-2.43-0.41-3.51c0.86-1.08,2.43-1.26,3.51-0.41c3.16,2.5,6.07,5.34,8.65,8.44c0.88,1.06,0.74,2.64-0.32,3.52
C108.18,30.49,107.61,30.68,107.05,30.68z M28.97,22.81c-0.73,0-1.46-0.32-1.95-0.94c-0.86-1.08-0.69-2.65,0.38-3.51
c3.15-2.53,6.56-4.73,10.16-6.55c1.23-0.63,2.74-0.13,3.36,1.1c0.62,1.23,0.13,2.74-1.1,3.36c-3.28,1.67-6.41,3.69-9.29,6
C30.07,22.63,29.52,22.81,28.97,22.81z M87.25,15.54c-0.35,0-0.7-0.07-1.04-0.23c-3.36-1.53-6.88-2.72-10.48-3.52
c-1.35-0.3-2.2-1.64-1.89-2.99c0.3-1.35,1.64-2.2,2.99-1.89c3.94,0.88,7.79,2.18,11.46,3.86c1.26,0.57,1.81,2.06,1.23,3.31
C89.11,15,88.2,15.54,87.25,15.54z M51.37,11.93c-1.14,0-2.17-0.78-2.43-1.94c-0.31-1.35,0.53-2.69,1.88-3
c3.91-0.9,7.95-1.4,12-1.48c1.38-0.04,2.52,1.07,2.55,2.45c0.03,1.38-1.07,2.52-2.45,2.55c-3.7,0.07-7.39,0.53-10.97,1.35
C51.75,11.91,51.56,11.93,51.37,11.93z"/>
</g>
<g>
<path fill="#FFFFFF" d="M67.06,119.73c-2.1,0-3.87-1.64-3.99-3.77c-0.13-2.21,1.56-4.1,3.76-4.23c1.85-0.11,3.71-0.32,5.53-0.64
c2.17-0.38,4.25,1.07,4.63,3.25s-1.07,4.25-3.25,4.63c-2.12,0.37-4.29,0.63-6.45,0.75C67.22,119.73,67.14,119.73,67.06,119.73z
M55.05,119.05c-0.23,0-0.46-0.02-0.69-0.06c-2.13-0.37-4.26-0.87-6.32-1.49c-2.12-0.63-3.32-2.86-2.69-4.98s2.86-3.32,4.98-2.69
c1.77,0.53,3.59,0.96,5.41,1.27c2.18,0.38,3.63,2.45,3.25,4.63C58.65,117.68,56.96,119.05,55.05,119.05z M84.58,115.58
c-1.55,0-3.02-0.9-3.67-2.41c-0.88-2.03,0.06-4.38,2.08-5.26c1.69-0.73,3.36-1.57,4.96-2.5c1.91-1.11,4.36-0.46,5.47,1.46
c1.11,1.91,0.46,4.36-1.46,5.47c-1.87,1.08-3.82,2.07-5.8,2.92C85.65,115.47,85.11,115.58,84.58,115.58z M38.12,112.91
c-0.68,0-1.37-0.17-2-0.54c-1.87-1.08-3.69-2.28-5.43-3.57c-1.77-1.32-2.14-3.82-0.82-5.6c1.32-1.77,3.82-2.14,5.6-0.82
c1.49,1.11,3.05,2.13,4.65,3.06c1.91,1.1,2.57,3.55,1.47,5.46C40.84,112.2,39.5,112.91,38.12,112.91z M99.61,105.67
c-1.06,0-2.12-0.42-2.91-1.25c-1.52-1.61-1.45-4.14,0.16-5.66c1.35-1.27,2.63-2.64,3.82-4.05c1.42-1.69,3.94-1.91,5.64-0.49
c1.69,1.42,1.91,3.94,0.49,5.64c-1.39,1.65-2.88,3.24-4.45,4.72C101.58,105.3,100.59,105.67,99.61,105.67z M24.32,101.35
c-1.14,0-2.27-0.48-3.06-1.42c-1.39-1.65-2.7-3.4-3.89-5.2c-1.22-1.84-0.71-4.32,1.13-5.54c1.84-1.22,4.32-0.71,5.54,1.13
c1.02,1.54,2.14,3.04,3.33,4.46c1.42,1.69,1.21,4.21-0.48,5.64C26.14,101.04,25.23,101.35,24.32,101.35z M110.36,91.23
c-0.6,0-1.22-0.14-1.79-0.43c-1.97-0.99-2.77-3.4-1.78-5.37c0.83-1.65,1.57-3.37,2.2-5.11c0.75-2.08,3.05-3.15,5.13-2.39
c2.08,0.75,3.15,3.05,2.39,5.13c-0.74,2.03-1.61,4.04-2.58,5.97C113.24,90.42,111.83,91.23,110.36,91.23z M15.28,85.78
c-1.63,0-3.16-1-3.76-2.63c-0.74-2.03-1.37-4.12-1.87-6.22c-0.51-2.15,0.82-4.31,2.97-4.82s4.31,0.82,4.82,2.97
c0.43,1.8,0.97,3.59,1.6,5.32c0.76,2.08-0.31,4.37-2.38,5.13C16.2,85.7,15.73,85.78,15.28,85.78z M115.53,73.97
c-0.15,0-0.31-0.01-0.46-0.03c-2.19-0.25-3.77-2.24-3.52-4.43c0.21-1.83,0.32-3.7,0.32-5.56v-0.21c0-2.21,1.79-4,4-4s4,1.79,4,4
v0.15c0,2.22-0.12,4.4-0.37,6.53C119.26,72.47,117.53,73.97,115.53,73.97z M12.13,68.05c-2.21,0-4-1.79-4-4h4l-4-0.05
c0-2.18,0.12-4.33,0.36-6.42c0.25-2.19,2.24-3.76,4.43-3.52c2.2,0.25,3.77,2.23,3.52,4.43c-0.21,1.8-0.31,3.64-0.31,5.46v0.1
C16.13,66.26,14.34,68.05,12.13,68.05z M114.43,55.8c-1.81,0-3.45-1.23-3.89-3.07c-0.43-1.8-0.98-3.59-1.61-5.32
c-0.76-2.07,0.3-4.37,2.37-5.14c2.07-0.76,4.37,0.3,5.14,2.37c0.74,2.02,1.38,4.11,1.88,6.22c0.52,2.15-0.81,4.31-2.95,4.82
C115.06,55.76,114.74,55.8,114.43,55.8z M15.21,50.31c-0.45,0-0.91-0.08-1.36-0.24c-2.08-0.75-3.15-3.04-2.4-5.12
c0.73-2.03,1.6-4.04,2.56-5.97C15,37,17.4,36.2,19.38,37.19c1.98,0.99,2.77,3.39,1.79,5.37c-0.83,1.65-1.57,3.37-2.19,5.11
C18.38,49.3,16.85,50.31,15.21,50.31z M107.24,39.3c-1.29,0-2.57-0.63-3.34-1.79c-1.02-1.54-2.15-3.04-3.34-4.45
c-1.43-1.69-1.22-4.21,0.47-5.64s4.21-1.22,5.64,0.47c1.39,1.65,2.71,3.39,3.9,5.19c1.22,1.84,0.72,4.32-1.12,5.54
C108.77,39.08,108,39.3,107.24,39.3z M24.19,34.7c-0.91,0-1.82-0.31-2.56-0.93c-1.69-1.42-1.92-3.94-0.5-5.63
c1.38-1.66,2.88-3.25,4.44-4.73c1.6-1.52,4.13-1.45,5.65,0.15s1.45,4.13-0.15,5.65c-1.34,1.27-2.62,2.64-3.81,4.06
C26.47,34.21,25.33,34.7,24.19,34.7z M94.83,26.24c-0.83,0-1.66-0.26-2.38-0.79c-1.49-1.1-3.05-2.13-4.66-3.05
c-1.92-1.1-2.58-3.54-1.48-5.46c1.1-1.91,3.54-2.58,5.46-1.48c1.87,1.07,3.7,2.27,5.44,3.56c1.78,1.31,2.15,3.82,0.83,5.6
C97.27,25.68,96.06,26.24,94.83,26.24z M37.95,23.09c-1.38,0-2.72-0.71-3.46-1.99c-1.11-1.91-0.46-4.36,1.44-5.47
c1.86-1.08,3.81-2.07,5.79-2.93c2.03-0.88,4.38,0.05,5.26,2.07c0.88,2.03-0.05,4.38-2.07,5.26c-1.69,0.74-3.36,1.58-4.96,2.51
C39.33,22.92,38.64,23.09,37.95,23.09z M78.72,18.21c-0.38,0-0.76-0.05-1.13-0.17c-1.77-0.52-3.59-0.95-5.42-1.26
c-2.18-0.37-3.64-2.44-3.26-4.62s2.45-3.64,4.62-3.26c2.13,0.37,4.26,0.86,6.33,1.47c2.12,0.63,3.33,2.85,2.7,4.97
C82.04,17.08,80.45,18.21,78.72,18.21z M54.84,16.89c-1.9,0-3.59-1.36-3.93-3.3c-0.39-2.17,1.06-4.25,3.24-4.64
c2.12-0.38,4.29-0.63,6.45-0.76c2.19-0.14,4.1,1.55,4.23,3.75c0.13,2.21-1.55,4.1-3.75,4.23c-1.85,0.11-3.71,0.33-5.52,0.66
C55.31,16.87,55.07,16.89,54.84,16.89z"/>
<path fill="#ED6B21" d="M96,66.5H32c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5h64c1.38,0,2.5,1.12,2.5,2.5S97.38,66.5,96,66.5z"
/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -1,27 +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) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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"/>
<path fill="#FFFFFF" d="M48,101.5H10.5v-83h11V24c0,1.38,1.12,2.5,2.5,2.5h48c1.38,0,2.5-1.12,2.5-2.5v-5.5h11V32h5V16
c0-1.38-1.12-2.5-2.5-2.5H74.5V8c0-1.38-1.12-2.5-2.5-2.5H24c-1.38,0-2.5,1.12-2.5,2.5v5.5H8c-1.38,0-2.5,1.12-2.5,2.5v88
c0,1.38,1.12,2.5,2.5,2.5h40V101.5z M26.5,10.5h43v11h-43V10.5z"/>
<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"/>
<path fill="#ED6B21" d="M122.45,55.51c-0.02-0.11-0.06-0.22-0.1-0.33c-0.02-0.05-0.02-0.09-0.04-0.14
c-0.05-0.12-0.11-0.23-0.18-0.34c-0.02-0.03-0.03-0.06-0.05-0.09c-0.09-0.14-0.2-0.26-0.31-0.38l-15.99-15.99
c-0.12-0.12-0.24-0.22-0.38-0.31c-0.04-0.02-0.08-0.04-0.11-0.06c-0.1-0.06-0.2-0.12-0.32-0.17c-0.05-0.02-0.11-0.03-0.16-0.05
c-0.1-0.03-0.2-0.07-0.3-0.09c-0.16-0.03-0.33-0.05-0.49-0.05H56c-1.38,0-2.5,1.12-2.5,2.5v80c0,1.38,1.12,2.5,2.5,2.5h64
c1.38,0,2.5-1.12,2.5-2.5V56C122.5,55.83,122.48,55.67,122.45,55.51z M106.5,46.04l7.46,7.46h-7.46V46.04z M58.5,117.5v-75h43V56
c0,1.38,1.12,2.5,2.5,2.5h13.5v59H58.5z"/>
<path fill="#ED6B21" d="M104.23,70.78l-15.49-8.94c-0.77-0.45-1.73-0.45-2.5,0l-15.49,8.94c-0.77,0.45-1.25,1.27-1.25,2.17v17.89
c0,0.89,0.48,1.72,1.25,2.17l15.49,8.94c0.39,0.22,0.82,0.33,1.25,0.33s0.86-0.11,1.25-0.33L104.23,93
c0.77-0.45,1.25-1.27,1.25-2.17V72.94C105.48,72.05,105.01,71.23,104.23,70.78z M100.48,89.39l-12.99,7.5l-12.99-7.5v-15
l12.99-7.5l12.99,7.5V89.39z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -1,13 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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">
<path id="undo_1_" fill="#ED6B21" d="M1.95,7.01h10.24L8.86,2.51c-0.31-0.42-0.22-1.01,0.2-1.32c0.42-0.31,1.01-0.22,1.32,0.2
l4.44,6.01c0,0.01,0.01,0.01,0.01,0.02c0.01,0.01,0.02,0.03,0.03,0.04c0.01,0.02,0.03,0.05,0.04,0.07c0.01,0.02,0.02,0.03,0.03,0.05
c0.01,0.01,0.01,0.03,0.02,0.04c0.01,0.02,0.02,0.05,0.02,0.07c0.01,0.02,0.01,0.04,0.02,0.06c0,0.01,0,0.03,0.01,0.04
c0,0.02,0.01,0.05,0.01,0.07c0,0.02,0.01,0.05,0.01,0.07c0,0.01,0,0.01,0,0.02c0,0.01,0,0.01,0,0.02c0,0.02,0,0.05-0.01,0.07
c0,0.02,0,0.05-0.01,0.07c0,0.01,0,0.03-0.01,0.04c0,0.02-0.01,0.04-0.02,0.06c-0.01,0.02-0.01,0.05-0.02,0.07
c-0.01,0.01-0.01,0.03-0.02,0.04c-0.01,0.02-0.02,0.04-0.03,0.05c-0.01,0.02-0.02,0.04-0.04,0.07c-0.01,0.01-0.02,0.03-0.03,0.04
c0,0.01-0.01,0.01-0.01,0.02l-4.54,6.05c-0.19,0.25-0.47,0.38-0.76,0.38c-0.2,0-0.4-0.06-0.57-0.19c-0.42-0.31-0.5-0.91-0.19-1.32
l3.41-4.54H1.95C1.42,8.91,1,8.48,1,7.96C1,7.44,1.42,7.01,1.95,7.01z"/>
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g id="redo">
<g>
<path fill="#ED6B21" d="M91.43,72.21c-0.73,0-1.46-0.32-1.95-0.94c-0.86-1.08-0.69-2.65,0.39-3.51L116,46.86l-26.13-20.9
c-1.08-0.86-1.25-2.44-0.39-3.51c0.86-1.08,2.43-1.25,3.51-0.39l28.57,22.86c0.59,0.47,0.94,1.19,0.94,1.95s-0.35,1.48-0.94,1.95
L92.99,71.67C92.53,72.04,91.98,72.21,91.43,72.21z"/>
</g>
<g>
<path fill="#ED6B21" d="M80,106.5H36.57C19.44,106.5,5.5,92.56,5.5,75.43s13.94-31.07,31.07-31.07H120c1.38,0,2.5,1.12,2.5,2.5
s-1.12,2.5-2.5,2.5H36.57c-14.38,0-26.07,11.7-26.07,26.07s11.7,26.07,26.07,26.07H80c1.38,0,2.5,1.12,2.5,2.5
S81.38,106.5,80,106.5z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 959 B

View file

@ -1,44 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="#FFFFFF" 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 id="remove_1_">
<g>
<path fill="#FFFFFF" d="M98.71,29.29c0.49,0.49,1.13,0.73,1.77,0.73s1.28-0.24,1.77-0.73l7.05-7.05c0.98-0.98,0.98-2.56,0-3.54
c-0.98-0.98-2.56-0.98-3.54,0l-7.05,7.05C97.73,26.74,97.73,28.32,98.71,29.29z"/>
<path fill="#FFFFFF" d="M82,42.5h3.5V46c0,1.38,1.12,2.5,2.5,2.5s2.5-1.12,2.5-2.5v-4.96l3.51-3.51c0.98-0.98,0.98-2.56,0-3.54
c-0.98-0.98-2.56-0.98-3.54,0l-3.51,3.51H82c-1.38,0-2.5,1.12-2.5,2.5S80.62,42.5,82,42.5z"/>
<path fill="#FFFFFF" d="M113.97,10.5c-0.95,0.98-0.94,2.54,0.02,3.51c0.49,0.49,1.13,0.73,1.77,0.73c0.63,0,1.26-0.24,1.75-0.71
c0.02,1.37,1.13,2.47,2.5,2.47c1.38,0,2.5-1.12,2.5-2.5V8c0-0.05-0.01-0.1-0.02-0.15c0-0.06-0.01-0.11-0.02-0.17
c-0.03-0.22-0.08-0.43-0.15-0.62c0,0,0-0.01,0-0.01c0,0,0,0,0,0c-0.01-0.03-0.03-0.05-0.04-0.08c-0.05-0.11-0.11-0.21-0.17-0.31
c-0.03-0.04-0.05-0.08-0.08-0.11c-0.06-0.08-0.13-0.16-0.2-0.24c-0.03-0.03-0.06-0.07-0.09-0.1c-0.09-0.09-0.19-0.17-0.3-0.25
c-0.01-0.01-0.02-0.02-0.04-0.03c-0.12-0.08-0.24-0.15-0.38-0.2c-0.04-0.02-0.09-0.03-0.13-0.05c-0.1-0.04-0.2-0.07-0.3-0.09
c-0.05-0.01-0.09-0.02-0.14-0.03c-0.15-0.03-0.3-0.05-0.45-0.05h-6c-1.38,0-2.5,1.12-2.5,2.5C111.5,9.37,112.6,10.48,113.97,10.5z
"/>
<path fill="#FFFFFF" d="M89.49,10.5h11.31c1.38,0,2.5-1.12,2.5-2.5s-1.12-2.5-2.5-2.5H89.49c-1.38,0-2.5,1.12-2.5,2.5
S88.11,10.5,89.49,10.5z"/>
<path fill="#FFFFFF" d="M88,57.92c-1.38,0-2.5,1.12-2.5,2.5v5.35c1.61-0.56,3.28-0.99,5-1.29v-4.06
C90.5,59.04,89.38,57.92,88,57.92z"/>
<path fill="#FFFFFF" d="M117.5,63.91c0,1.38,1.12,2.5,2.5,2.5s2.5-1.12,2.5-2.5V52.39c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5
V63.91z"/>
<path fill="#FFFFFF" d="M64.99,10.5H76.3c1.38,0,2.5-1.12,2.5-2.5s-1.12-2.5-2.5-2.5H64.99c-1.38,0-2.5,1.12-2.5,2.5
S63.6,10.5,64.99,10.5z"/>
<path fill="#FFFFFF" d="M120,24.94c-1.38,0-2.5,1.12-2.5,2.5v11.52c0,1.38,1.12,2.5,2.5,2.5s2.5-1.12,2.5-2.5V27.44
C122.5,26.06,121.38,24.94,120,24.94z"/>
<path fill="#FFFFFF" d="M14.76,37.63c0.59-0.88,0.58-2.07-0.12-2.94c-0.86-1.08-2.44-1.25-3.51-0.39l-4.69,3.75
c-0.03,0.03-0.06,0.06-0.09,0.09c-0.07,0.06-0.13,0.12-0.19,0.19c-0.05,0.06-0.1,0.12-0.15,0.18c-0.05,0.07-0.09,0.13-0.14,0.2
c-0.04,0.07-0.08,0.14-0.12,0.21c-0.03,0.07-0.07,0.15-0.09,0.22c-0.03,0.08-0.05,0.15-0.07,0.23c-0.02,0.08-0.04,0.15-0.05,0.23
c-0.01,0.09-0.02,0.17-0.03,0.26c0,0.04-0.01,0.09-0.01,0.13v6c0,1.38,1.12,2.5,2.5,2.5s2.5-1.12,2.5-2.5v-3.5H14
c1.38,0,2.5-1.12,2.5-2.5C16.5,38.89,15.77,37.95,14.76,37.63z"/>
<path fill="#FFFFFF" d="M40.79,37.5H28.42c-1.38,0-2.5,1.12-2.5,2.5s1.12,2.5,2.5,2.5h12.36c1.38,0,2.5-1.12,2.5-2.5
S42.17,37.5,40.79,37.5z"/>
<path fill="#FFFFFF" d="M54.29,8c0-1.38-1.12-2.5-2.5-2.5H48c-0.57,0-1.12,0.19-1.56,0.55l-5.87,4.7
c-1.08,0.86-1.25,2.44-0.39,3.51c0.49,0.62,1.22,0.94,1.95,0.94c0.55,0,1.1-0.18,1.56-0.55l5.19-4.15h2.91
C53.17,10.5,54.29,9.38,54.29,8z"/>
<path fill="#FFFFFF" d="M40.79,117.5H28.42c-1.38,0-2.5,1.12-2.5,2.5s1.12,2.5,2.5,2.5h12.36c1.38,0,2.5-1.12,2.5-2.5
S42.17,117.5,40.79,117.5z"/>
<path fill="#FFFFFF" d="M67.58,117.5H55.21c-1.38,0-2.5,1.12-2.5,2.5s1.12,2.5,2.5,2.5h12.36c1.38,0,2.5-1.12,2.5-2.5
S68.96,117.5,67.58,117.5z"/>
<path fill="#FFFFFF" d="M52.71,40c0,1.38,1.12,2.5,2.5,2.5h12.36c1.38,0,2.5-1.12,2.5-2.5s-1.12-2.5-2.5-2.5H55.21
C53.83,37.5,52.71,38.62,52.71,40z"/>
<path fill="#FFFFFF" d="M8,102.08c1.38,0,2.5-1.12,2.5-2.5V87.21c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v12.36
C5.5,100.96,6.62,102.08,8,102.08z"/>
<path fill="#FFFFFF" d="M8,75.29c1.38,0,2.5-1.12,2.5-2.5V60.42c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v12.36
C5.5,74.17,6.62,75.29,8,75.29z"/>
<path fill="#FFFFFF" d="M14,117.5h-3.5V114c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v6c0,1.38,1.12,2.5,2.5,2.5h6
c1.38,0,2.5-1.12,2.5-2.5S15.38,117.5,14,117.5z"/>
<path fill="#FFFFFF" d="M33.77,19.38c-0.86-1.08-2.44-1.25-3.51-0.39l-8.83,7.07c-1.08,0.86-1.25,2.44-0.39,3.51
c0.49,0.62,1.22,0.94,1.95,0.94c0.55,0,1.1-0.18,1.56-0.55l8.83-7.07C34.46,22.03,34.64,20.46,33.77,19.38z"/>
</g>
<g>
<path fill="#ED6B21" d="M96,69.5c-14.61,0-26.5,11.89-26.5,26.5s11.89,26.5,26.5,26.5s26.5-11.89,26.5-26.5S110.61,69.5,96,69.5z
M96,117.5c-11.86,0-21.5-9.64-21.5-21.5S84.14,74.5,96,74.5s21.5,9.64,21.5,21.5S107.86,117.5,96,117.5z"/>
<path fill="#ED6B21" d="M112,93.5H80c-1.38,0-2.5,1.12-2.5,2.5s1.12,2.5,2.5,2.5h32c1.38,0,2.5-1.12,2.5-2.5S113.38,93.5,112,93.5
z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

@ -1,42 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="SLA_supports">
<g>
<path fill="#FFFFFF" d="M117.02,121.54H11.12c-1.93,0-3.5-1.57-3.5-3.5v-3.99c0-1.93,1.57-3.5,3.5-3.5h105.9
c1.93,0,3.5,1.57,3.5,3.5v3.99C120.52,119.97,118.95,121.54,117.02,121.54z M11.12,113.55c-0.27,0-0.5,0.23-0.5,0.5v3.99
c0,0.27,0.23,0.5,0.5,0.5h105.9c0.27,0,0.5-0.23,0.5-0.5v-3.99c0-0.27-0.23-0.5-0.5-0.5H11.12z"/>
</g>
<g>
<path fill="#ED6B21" d="M32.08,108.06c-0.83,0-1.5-0.67-1.5-1.5v-18.8c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v18.8
C33.58,107.39,32.9,108.06,32.08,108.06z"/>
</g>
<g>
<path fill="#ED6B21" d="M48.02,108.06c-0.83,0-1.5-0.67-1.5-1.5v-8.14c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v8.14
C49.52,107.39,48.85,108.06,48.02,108.06z"/>
</g>
<g>
<path fill="#ED6B21" d="M88.04,108.06c-0.83,0-1.5-0.67-1.5-1.5V93.09c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v13.47
C89.54,107.39,88.87,108.06,88.04,108.06z"/>
</g>
<path fill="#FFFFFF" d="M70.36,95.12l-6.29,4.2l-14.45-9.63l-2.5,2.6l15.96,10.64c0.3,0.2,0.64,0.3,0.99,0.3s0.69-0.1,0.99-0.3
l7.9-5.27L70.36,95.12z"/>
<polygon fill="#FFFFFF" points="88.97,86.99 86.35,84.46 77.91,90.09 80.5,92.63 "/>
<path fill="#FFFFFF" d="M103.99,35.1L65.05,9.14c-0.6-0.4-1.37-0.4-1.97,0L24.14,35.1c-0.49,0.33-0.79,0.88-0.79,1.48v38.91
c0,0.59,0.3,1.15,0.79,1.48l15.47,10.32l2.5-2.6L26.9,74.54V37.53l37.16-24.78l37.16,24.78v37.01l-7.32,4.88l2.61,2.53l7.46-4.98
c0.49-0.33,0.79-0.88,0.79-1.48V36.58C104.78,35.99,104.49,35.43,103.99,35.1z"/>
<g>
<path fill="#ED6B21" d="M96.16,108.06c-0.83,0-1.5-0.67-1.5-1.5V87.93L79,73.22c-0.6-0.57-0.63-1.52-0.07-2.12
c0.57-0.6,1.52-0.63,2.12-0.07l16.13,15.15c0.3,0.28,0.47,0.68,0.47,1.09v19.27C97.66,107.39,96.99,108.06,96.16,108.06z"/>
</g>
<g>
<path fill="#ED6B21" d="M40.08,108.06c-0.83,0-1.5-0.67-1.5-1.5V93.29c0-0.39,0.15-0.76,0.41-1.04l16.13-16.91
c0.57-0.6,1.52-0.62,2.12-0.05c0.6,0.57,0.62,1.52,0.05,2.12L41.58,93.89v12.67C41.58,107.39,40.91,108.06,40.08,108.06z"/>
</g>
<g>
<path fill="#ED6B21" d="M80.13,108.06c-0.83,0-1.5-0.67-1.5-1.5v-7.65L62.94,83.19c-0.59-0.59-0.58-1.54,0-2.12
c0.59-0.58,1.54-0.59,2.12,0l16.13,16.15c0.28,0.28,0.44,0.66,0.44,1.06v8.27C81.63,107.39,80.96,108.06,80.13,108.06z"/>
</g>
<g id="paint_x5F_seams_2_">
<polyline fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
120,32 64,8 8,32 8,96 64,120 "/>
<path fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="
M120,96"/>
<polyline fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
8,32 64,56 64,120 "/>
<line fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="64" y1="56" x2="120" y2="32"/>
<line fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="64" y1="120" x2="120" y2="96"/>
<line fill="none" stroke="#FFFFFF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="120" y1="96" x2="120" y2="32"/>
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="88.05" y1="53.69" x2="95.96" y2="50.3"/>
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="95.96" y1="58.3" x2="103.99" y2="54.86"/>
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="88.05" y1="69.69" x2="95.96" y2="66.3"/>
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="80.05" y1="81.12" x2="88.05" y2="77.69"/>
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="71.94" y1="92.6" x2="80.05" y2="89.12"/>
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="80.05" y1="97.12" x2="88.05" y2="93.69"/>
<line fill="none" stroke="#ED6B21" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="88.05" y1="101.69" x2="96.13" y2="98.23"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -1,4 +1,26 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24px" height="24px">
<path fill="#FFFFFF" d="M 13.261719 14.867188 L 15.742188 17.347656 C 15.363281 18.070313 15.324219 18.789063 15.722656 19.1875 L 20.25 23.714844 C 20.820313 24.285156 22.0625 23.972656 23.015625 23.015625 C 23.972656 22.058594 24.285156 20.820313 23.714844 20.25 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 L 14.867188 13.261719 Z M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
<path fill="#ED6B21" d="M 13.261719 14.867188 L 19.191406 15.722656 C 18.789063 15.324219 18.070313 15.363281 17.347656 15.738281 M 8.5 0 C 3.804688 0 0 3.804688 0 8.5 C 0 13.195313 3.804688 17 8.5 17 C 13.195313 17 17 13.195313 17 8.5 C 17 3.804688 13.195313 0 8.5 0 Z M 8.5 15 C 4.910156 15 2 12.089844 2 8.5 C 2 4.910156 4.910156 2 8.5 2 C 12.089844 2 15 4.910156 15 8.5 C 15 12.089844 12.089844 15 8.5 15 Z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, 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="search">
<g>
<path fill="#ED6B21" d="M52,98.5C26.36,98.5,5.5,77.64,5.5,52C5.5,26.36,26.36,5.5,52,5.5c25.64,0,46.5,20.86,46.5,46.5
C98.5,77.64,77.64,98.5,52,98.5z M52,10.5c-22.88,0-41.5,18.62-41.5,41.5c0,22.88,18.62,41.5,41.5,41.5
c22.88,0,41.5-18.62,41.5-41.5C93.5,29.12,74.88,10.5,52,10.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M117.47,119.97c-0.64,0-1.28-0.24-1.77-0.73L81.34,84.88c-0.98-0.98-0.98-2.56,0-3.54s2.56-0.98,3.54,0
l34.36,34.36c0.98,0.98,0.98,2.56,0,3.54C118.75,119.72,118.11,119.97,117.47,119.97z"/>
</g>
<g>
<path fill="#ED6B21" d="M117.47,122.47c-1.28,0-2.56-0.49-3.54-1.46L92.46,99.54c-1.95-1.95-1.95-5.12,0-7.07
c1.95-1.95,5.12-1.95,7.07,0L121,113.93c1.95,1.95,1.95,5.12,0,7.07C120.03,121.98,118.75,122.47,117.47,122.47z"/>
</g>
<g>
<path fill="#FFFFFF" d="M52,77.59c-0.43,0-0.86-0.11-1.25-0.33l-20-11.55c-0.77-0.45-1.25-1.27-1.25-2.17V40.45
c0-0.89,0.48-1.72,1.25-2.17l20-11.55c0.77-0.45,1.73-0.45,2.5,0l20,11.55c0.77,0.45,1.25,1.27,1.25,2.17v23.09
c0,0.89-0.48,1.72-1.25,2.17l-20,11.55C52.86,77.48,52.43,77.59,52,77.59z M34.5,62.1L52,72.21l17.5-10.1V41.9L52,31.79L34.5,41.9
V62.1z M72,63.55L72,63.55L72,63.55z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, 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">
<path id="undo_1_" fill="#ED6B21" d="M1.95,7.01h10.24L8.86,2.51c-0.31-0.42-0.22-1.01,0.2-1.32c0.42-0.31,1.01-0.22,1.32,0.2
l4.44,6.01c0,0.01,0.01,0.01,0.01,0.02c0.01,0.01,0.02,0.03,0.03,0.04c0.01,0.02,0.03,0.05,0.04,0.07c0.01,0.02,0.02,0.03,0.03,0.05
c0.01,0.01,0.01,0.03,0.02,0.04c0.01,0.02,0.02,0.05,0.02,0.07c0.01,0.02,0.01,0.04,0.02,0.06c0,0.01,0,0.03,0.01,0.04
c0,0.02,0.01,0.05,0.01,0.07c0,0.02,0.01,0.05,0.01,0.07c0,0.01,0,0.01,0,0.02c0,0.01,0,0.01,0,0.02c0,0.02,0,0.05-0.01,0.07
c0,0.02,0,0.05-0.01,0.07c0,0.01,0,0.03-0.01,0.04c0,0.02-0.01,0.04-0.02,0.06c-0.01,0.02-0.01,0.05-0.02,0.07
c-0.01,0.01-0.01,0.03-0.02,0.04c-0.01,0.02-0.02,0.04-0.03,0.05c-0.01,0.02-0.02,0.04-0.04,0.07c-0.01,0.01-0.02,0.03-0.03,0.04
c0,0.01-0.01,0.01-0.01,0.02l-4.54,6.05c-0.19,0.25-0.47,0.38-0.76,0.38c-0.2,0-0.4-0.06-0.57-0.19c-0.42-0.31-0.5-0.91-0.19-1.32
l3.41-4.54H1.95C1.42,8.91,1,8.48,1,7.96C1,7.44,1.42,7.01,1.95,7.01z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, 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="settings">
<g>
<g>
<path fill="#ED6B21" d="M51.99,81.99c-0.56,0-1.12-0.11-1.66-0.33c-1.06-0.44-1.88-1.27-2.32-2.33l-1.69-4.1
c-1.61,0.12-3.24,0.11-4.86-0.02l-1.71,4.1c-0.91,2.19-3.44,3.22-5.62,2.31l-9.97-4.17c-2.19-0.91-3.22-3.44-2.31-5.62l1.71-4.1
c-1.23-1.06-2.38-2.21-3.43-3.44l-4.1,1.69c-1.06,0.43-2.23,0.43-3.29-0.01c-1.06-0.44-1.88-1.27-2.32-2.33l-4.1-10
c-0.9-2.19,0.15-4.71,2.34-5.61l4.1-1.69c-0.12-1.61-0.11-3.24,0.02-4.86l-4.1-1.71c-1.06-0.44-1.88-1.27-2.32-2.33
c-0.44-1.06-0.43-2.23,0.01-3.29l4.17-9.97c0.44-1.06,1.27-1.88,2.33-2.32c1.06-0.44,2.23-0.43,3.29,0.01l4.1,1.71
c1.06-1.23,2.21-2.38,3.44-3.43l-1.69-4.1c-0.44-1.06-0.43-2.23,0.01-3.29s1.27-1.88,2.33-2.32l10-4.1
c2.19-0.9,4.71,0.15,5.61,2.34l1.69,4.1c1.61-0.12,3.24-0.11,4.86,0.02l1.71-4.1c0.44-1.06,1.27-1.88,2.33-2.32
c1.06-0.44,2.23-0.43,3.29,0.01l9.97,4.17c1.06,0.44,1.88,1.27,2.32,2.33c0.44,1.06,0.43,2.23-0.01,3.29l-1.71,4.1
c1.23,1.06,2.38,2.21,3.43,3.44l4.1-1.69c1.06-0.44,2.23-0.43,3.29,0.01c1.06,0.44,1.88,1.27,2.32,2.33l4.1,9.99
c0.44,1.06,0.43,2.23-0.01,3.29s-1.27,1.88-2.33,2.32l-4.1,1.69c0.12,1.61,0.11,3.24-0.02,4.86l4.1,1.71
c2.19,0.91,3.22,3.44,2.31,5.62l-4.17,9.97c-0.91,2.19-3.44,3.22-5.62,2.31l-4.1-1.71c-1.06,1.23-2.21,2.38-3.44,3.43l1.69,4.1
c0.44,1.06,0.43,2.23-0.01,3.29c-0.44,1.06-1.27,1.88-2.33,2.32l-10,4.1C53.1,81.88,52.54,81.99,51.99,81.99z M46.77,70.18
c1.75,0,3.33,1.03,4,2.66l1.61,3.93l8.7-3.57l-1.61-3.93c-0.72-1.75-0.21-3.75,1.27-4.97c1.25-1.03,2.42-2.2,3.47-3.46
c1.22-1.47,3.2-1.97,4.95-1.24l3.95,1.65l3.62-8.67l-3.95-1.65c-1.74-0.73-2.78-2.49-2.59-4.39c0.16-1.63,0.17-3.28,0.02-4.9
c-0.17-1.91,0.89-3.68,2.64-4.4l3.93-1.61l-3.57-8.7l-3.93,1.61c-1.75,0.72-3.75,0.21-4.97-1.27c-1.03-1.25-2.2-2.42-3.46-3.47
c-1.47-1.22-1.97-3.21-1.24-4.94l1.65-3.95l-8.67-3.62l-1.65,3.95c-0.73,1.74-2.49,2.78-4.39,2.59c-1.63-0.16-3.28-0.17-4.9-0.02
c-1.91,0.16-3.68-0.89-4.4-2.64l-1.61-3.93l-8.7,3.57l1.61,3.93c0.72,1.75,0.21,3.75-1.27,4.97c-1.25,1.04-2.42,2.2-3.47,3.46
c-1.22,1.47-3.21,1.97-4.95,1.24l-3.95-1.65l-3.62,8.67l3.95,1.65c1.74,0.73,2.78,2.49,2.59,4.39c-0.16,1.63-0.17,3.28-0.02,4.9
c0.17,1.91-0.89,3.68-2.64,4.4l-3.93,1.61l3.57,8.7l3.93-1.61c1.75-0.72,3.75-0.21,4.97,1.27c1.04,1.25,2.2,2.42,3.46,3.47
c1.47,1.22,1.97,3.21,1.24,4.95l-1.65,3.95l8.67,3.62l1.65-3.95c0.73-1.74,2.49-2.79,4.39-2.59c1.63,0.16,3.28,0.17,4.9,0.02
C46.5,70.19,46.63,70.18,46.77,70.18z M77.04,36.27C77.04,36.27,77.04,36.28,77.04,36.27L77.04,36.27z"/>
</g>
<g>
<path fill="#ED6B21" d="M44,60.91c-2.21,0-4.42-0.44-6.52-1.32c-4.17-1.74-7.4-5-9.12-9.17c-1.71-4.18-1.7-8.77,0.04-12.93
s5-7.4,9.17-9.12c4.18-1.71,8.77-1.7,12.93,0.04c4.17,1.74,7.4,5,9.12,9.17c1.71,4.18,1.7,8.77-0.04,12.93s-5,7.4-9.17,9.12
C48.35,60.48,46.17,60.91,44,60.91z M44,32.09c-1.53,0-3.06,0.3-4.52,0.9c-2.94,1.21-5.23,3.49-6.46,6.42s-1.24,6.17-0.03,9.11
c1.21,2.94,3.49,5.23,6.42,6.46c2.93,1.23,6.17,1.23,9.11,0.03c2.94-1.21,5.23-3.49,6.46-6.42s1.24-6.17,0.03-9.11l0,0
c-1.21-2.94-3.49-5.23-6.42-6.46C47.11,32.4,45.56,32.09,44,32.09z"/>
</g>
</g>
<g>
<g>
<path fill="#FFFFFF" d="M97.4,122.5h-7.98c-2.11,0-3.83-1.72-3.83-3.83v-2.81c-0.86-0.3-1.71-0.65-2.53-1.05l-1.99,1.99
c-1.49,1.49-3.92,1.49-5.41,0l-5.64-5.65c-0.72-0.72-1.12-1.68-1.12-2.71c0-1.02,0.4-1.98,1.12-2.71l1.99-1.99
c-0.4-0.82-0.75-1.67-1.05-2.53h-2.81c-2.11,0-3.83-1.72-3.83-3.83v-7.98c0-2.11,1.72-3.83,3.83-3.83h2.81
c0.3-0.86,0.65-1.71,1.05-2.53l-1.99-1.99c-1.49-1.49-1.49-3.92,0-5.41l5.64-5.64c1.49-1.49,3.92-1.49,5.41,0L83.06,72
c0.82-0.4,1.67-0.75,2.53-1.05v-2.81c0-2.11,1.72-3.83,3.83-3.83h7.98c2.11,0,3.83,1.72,3.83,3.83v2.81
c0.86,0.3,1.71,0.65,2.53,1.05l1.99-1.99c1.45-1.45,3.97-1.45,5.41,0l5.64,5.64c1.49,1.49,1.49,3.92,0,5.41l-1.99,1.99
c0.4,0.83,0.75,1.67,1.05,2.53h2.81c2.11,0,3.83,1.72,3.83,3.83v7.98c0,2.11-1.72,3.83-3.83,3.83h-2.81
c-0.3,0.86-0.65,1.71-1.05,2.53l1.99,1.99c0.72,0.72,1.12,1.68,1.12,2.71c0,1.02-0.4,1.99-1.12,2.71l-5.64,5.64
c-1.44,1.44-3.97,1.45-5.41,0l-1.99-1.99c-0.83,0.4-1.67,0.75-2.53,1.05v2.81C101.22,120.78,99.51,122.5,97.4,122.5z
M90.59,117.5h5.64v-2.49c0-1.69,1.1-3.16,2.73-3.67c1.11-0.34,2.19-0.79,3.23-1.34c1.5-0.8,3.3-0.53,4.49,0.65l1.78,1.78
l3.99-3.99l-1.78-1.77c-1.19-1.19-1.45-3-0.66-4.5c0.55-1.04,1-2.12,1.34-3.23c0.51-1.63,1.98-2.73,3.67-2.73h2.49v-5.64h-2.49
c-1.69,0-3.16-1.1-3.67-2.73c-0.34-1.11-0.79-2.19-1.34-3.23c-0.8-1.5-0.53-3.31,0.66-4.49l1.78-1.78l-3.99-3.99l-1.78,1.78
c-1.19,1.19-3,1.45-4.5,0.65c-1.03-0.55-2.12-1-3.23-1.34c-1.63-0.51-2.73-1.98-2.73-3.67v-2.49h-5.64v2.49
c0,1.69-1.1,3.16-2.73,3.67c-1.11,0.34-2.19,0.79-3.23,1.34c-1.5,0.8-3.31,0.53-4.5-0.66l-1.77-1.77l-3.99,3.99l1.78,1.78
c1.19,1.19,1.45,2.99,0.65,4.5c-0.55,1.03-1,2.12-1.34,3.23c-0.51,1.63-1.98,2.73-3.67,2.73h-2.49v5.64h2.49
c1.69,0,3.16,1.1,3.67,2.73c0.34,1.11,0.8,2.2,1.34,3.23c0.8,1.5,0.53,3.3-0.66,4.49l-1.78,1.78l3.99,3.99l1.78-1.78
c1.19-1.19,2.99-1.45,4.49-0.66c1.04,0.55,2.13,1,3.23,1.34c1.63,0.51,2.73,1.98,2.73,3.67V117.5z M72.39,104.52
C72.39,104.52,72.39,104.53,72.39,104.52C72.39,104.53,72.39,104.52,72.39,104.52z M72.62,83.67
C72.62,83.67,72.62,83.67,72.62,83.67L72.62,83.67z M104.52,72.39C104.52,72.39,104.52,72.39,104.52,72.39
C104.52,72.39,104.52,72.39,104.52,72.39z"/>
</g>
<g>
<path fill="#FFFFFF" d="M93.41,106.54c-7.24,0-13.14-5.89-13.14-13.14s5.89-13.14,13.14-13.14s13.14,5.89,13.14,13.14
S100.65,106.54,93.41,106.54z M93.41,85.27c-4.49,0-8.14,3.65-8.14,8.14s3.65,8.14,8.14,8.14s8.14-3.65,8.14-8.14
S97.89,85.27,93.41,85.27z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

@ -1,19 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="OBJECTS">
<g id="split_x5F_objects">
<g>
<path fill="#FFFFFF" d="M34.63,91.95h-17.3c-4.96,0-9-4.04-9-9V17.28c0-4.96,4.04-9,9-9H83c4.96,0,9,4.04,9,9v17.3
c0,1.66-1.34,3-3,3s-3-1.34-3-3v-17.3c0-1.65-1.35-3-3-3H17.32c-1.65,0-3,1.35-3,3v65.67c0,1.65,1.35,3,3,3h17.3
c1.66,0,3,1.34,3,3S36.28,91.95,34.63,91.95z"/>
<path fill="#FFFFFF" d="M32,90.5H8c-1.38,0-2.5-1.12-2.5-2.5V8c0-1.38,1.12-2.5,2.5-2.5h80c1.38,0,2.5,1.12,2.5,2.5v24
c0,1.38-1.12,2.5-2.5,2.5s-2.5-1.12-2.5-2.5V10.5h-75v75H32c1.38,0,2.5,1.12,2.5,2.5S33.38,90.5,32,90.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M114.89,42.35H47.57c-2.85,0-5.18,2.33-5.18,5.18v67.32c0,2.85,2.33,5.18,5.18,5.18h67.32
c2.85,0,5.18-2.33,5.18-5.18V47.52C120.07,44.68,117.74,42.35,114.89,42.35z M101.82,94.28c0,12.63-6.35,18.27-20.89,18.27
s-20.42-5.64-20.42-18.27v-25.9c0-12.95,5.64-18.27,20.42-18.27c14.77,0,20.89,5.32,20.89,18.27V94.28z"/>
<path fill="#ED6B21" d="M80.93,59.8c-7.94,0-9.45,3.58-9.45,9.14v24.78c0,5.8,1.51,9.13,9.45,9.13s9.93-3.33,9.93-9.13V68.94
C90.86,63.38,89.43,59.8,80.93,59.8z"/>
<path fill="#ED6B21" d="M120,122.5H40c-1.38,0-2.5-1.12-2.5-2.5V40c0-1.38,1.12-2.5,2.5-2.5h80c1.38,0,2.5,1.12,2.5,2.5v80
C122.5,121.38,121.38,122.5,120,122.5z M42.5,117.5h75v-75h-75V117.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M86,106.5H74c-6.89,0-12.5-5.61-12.5-12.5V66c0-6.89,5.61-12.5,12.5-12.5h12c6.89,0,12.5,5.61,12.5,12.5
v28C98.5,100.89,92.89,106.5,86,106.5z M74,58.5c-4.14,0-7.5,3.36-7.5,7.5v28c0,4.14,3.36,7.5,7.5,7.5h12c4.14,0,7.5-3.36,7.5-7.5
V66c0-4.14-3.36-7.5-7.5-7.5H74z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,18 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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="PARTS">
<g id="split_x5F_parts_1_">
<g>
<path fill="#FFFFFF" d="M34.63,91.95h-17.3c-4.96,0-9-4.04-9-9V17.28c0-4.96,4.04-9,9-9H83c4.96,0,9,4.04,9,9v17.3
c0,1.66-1.34,3-3,3s-3-1.34-3-3v-17.3c0-1.65-1.35-3-3-3H17.32c-1.65,0-3,1.35-3,3v65.67c0,1.65,1.35,3,3,3h17.3
c1.66,0,3,1.34,3,3S36.28,91.95,34.63,91.95z"/>
<path fill="#FFFFFF" d="M32,90.5H8c-1.38,0-2.5-1.12-2.5-2.5V8c0-1.38,1.12-2.5,2.5-2.5h80c1.38,0,2.5,1.12,2.5,2.5v24
c0,1.38-1.12,2.5-2.5,2.5s-2.5-1.12-2.5-2.5V10.5h-75v75H32c1.38,0,2.5,1.12,2.5,2.5S33.38,90.5,32,90.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M114.91,42.32H47.57c-2.85,0-5.18,2.33-5.18,5.18v67.34c0,2.85,2.33,5.18,5.18,5.18h67.34
c2.85,0,5.18-2.33,5.18-5.18V47.5C120.09,44.65,117.76,42.32,114.91,42.32z M99.95,74.39c0,12.84-7.27,18.81-22.04,18.81h-4.28
v19.05H62.25V50.09h15.66c15.02,0,22.04,5.41,22.04,18.57C99.95,68.66,99.95,74.39,99.95,74.39z"/>
<path fill="#ED6B21" d="M78.07,60.26h-4.52v22.2h4.36c8.08,0,10.74-2.74,10.74-8.64v-4.6C88.65,63.33,86.71,60.26,78.07,60.26z"/>
<path fill="#ED6B21" d="M120,122.5H40c-1.38,0-2.5-1.12-2.5-2.5V40c0-1.38,1.12-2.5,2.5-2.5h80c1.38,0,2.5,1.12,2.5,2.5v80
C122.5,121.38,121.38,122.5,120,122.5z M42.5,117.5h75v-75h-75V117.5z"/>
</g>
<g>
<path fill="#ED6B21" d="M64,106.5c-1.38,0-2.5-1.12-2.5-2.5V61c0-4.14,3.36-7.5,7.5-7.5h17c6.89,0,12.5,5.61,12.5,12.5v4
c0,6.89-5.61,12.5-12.5,12.5H66.5V104C66.5,105.38,65.38,106.5,64,106.5z M66.5,77.5H86c4.14,0,7.5-3.36,7.5-7.5v-4
c0-4.14-3.36-7.5-7.5-7.5H69c-1.38,0-2.5,1.12-2.5,2.5V77.5z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,13 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!-- Generator: Adobe Illustrator 24.3.0, 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">
<path id="undo_1_" fill="#ED6B21" d="M14.05,7.01H3.82l3.32-4.51c0.31-0.42,0.22-1.01-0.2-1.32c-0.42-0.31-1.01-0.22-1.32,0.2
L1.18,7.4c0,0.01-0.01,0.01-0.01,0.02C1.17,7.43,1.16,7.44,1.15,7.46C1.13,7.48,1.12,7.5,1.11,7.53C1.1,7.54,1.09,7.56,1.08,7.58
C1.08,7.59,1.07,7.61,1.06,7.62C1.06,7.65,1.05,7.67,1.04,7.69C1.04,7.71,1.03,7.73,1.02,7.75c0,0.01,0,0.03-0.01,0.04
c0,0.02-0.01,0.05-0.01,0.07C1.01,7.89,1,7.92,1,7.94c0,0.01,0,0.01,0,0.02c0,0.01,0,0.01,0,0.02c0,0.02,0,0.05,0.01,0.07
c0,0.02,0,0.05,0.01,0.07c0,0.01,0,0.03,0.01,0.04c0,0.02,0.01,0.04,0.02,0.06C1.05,8.26,1.06,8.28,1.07,8.3
c0.01,0.01,0.01,0.03,0.02,0.04C1.09,8.36,1.1,8.38,1.11,8.4c0.01,0.02,0.02,0.04,0.04,0.07c0.01,0.01,0.02,0.03,0.03,0.04
c0,0.01,0.01,0.01,0.01,0.02l4.54,6.05c0.19,0.25,0.47,0.38,0.76,0.38c0.2,0,0.4-0.06,0.57-0.19c0.42-0.31,0.5-0.91,0.19-1.32
L3.84,8.91h10.22c0.52,0,0.95-0.42,0.95-0.95C15,7.44,14.58,7.01,14.05,7.01z"/>
viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<g id="redo">
<g>
<path fill="#ED6B21" d="M36.57,72.21c0.73,0,1.46-0.32,1.95-0.94c0.86-1.08,0.69-2.65-0.39-3.51L12,46.86l26.13-20.9
c1.08-0.86,1.25-2.44,0.39-3.51c-0.86-1.08-2.43-1.25-3.51-0.39L6.44,44.9C5.85,45.38,5.5,46.1,5.5,46.86s0.35,1.48,0.94,1.95
l28.57,22.86C35.47,72.04,36.02,72.21,36.57,72.21z"/>
</g>
<g>
<path fill="#ED6B21" d="M48,106.5h43.43c17.13,0,31.07-13.94,31.07-31.07s-13.94-31.07-31.07-31.07H8c-1.38,0-2.5,1.12-2.5,2.5
s1.12,2.5,2.5,2.5h83.43c14.38,0,26.07,11.7,26.07,26.07s-11.7,26.07-26.07,26.07H48c-1.38,0-2.5,1.12-2.5,2.5
S46.62,106.5,48,106.5z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 952 B

View file

@ -589,7 +589,7 @@ int CLI::run(int argc, char **argv)
#if ENABLE_GCODE_VIEWER
if (start_as_gcodeviewer) {
if (!m_input_files.empty())
gui->plater()->load_gcode(wxString::FromUTF8(m_input_files[0]));
gui->plater()->load_gcode(wxString::FromUTF8(m_input_files[0].c_str()));
} else {
#endif // ENABLE_GCODE_VIEWER_AS
#if 0

View file

@ -255,18 +255,24 @@ extern void its_transform(indexed_triangle_set &its, T *trafo3x4)
}
template<typename T>
inline void its_transform(indexed_triangle_set &its, const Eigen::Transform<T, 3, Eigen::Affine, Eigen::DontAlign>& t)
inline void its_transform(indexed_triangle_set &its, const Eigen::Transform<T, 3, Eigen::Affine, Eigen::DontAlign>& t, bool fix_left_handed = false)
{
//const Eigen::Matrix<double, 3, 3, Eigen::DontAlign> r = t.matrix().template block<3, 3>(0, 0);
for (stl_vertex &v : its.vertices)
v = (t * v.template cast<T>()).template cast<float>().eval();
if (fix_left_handed && t.matrix().block(0, 0, 3, 3).determinant() < 0.)
for (stl_triangle_vertex_indices &i : its.indices)
std::swap(i[0], i[1]);
}
template<typename T>
inline void its_transform(indexed_triangle_set &its, const Eigen::Matrix<T, 3, 3, Eigen::DontAlign>& m)
inline void its_transform(indexed_triangle_set &its, const Eigen::Matrix<T, 3, 3, Eigen::DontAlign>& m, bool fix_left_handed = false)
{
for (stl_vertex &v : its.vertices)
for (stl_vertex &v : its.vertices)
v = (m * v.template cast<T>()).template cast<float>().eval();
if (fix_left_handed && m.determinant() < 0.)
for (stl_triangle_vertex_indices &i : its.indices)
std::swap(i[0], i[1]);
}
extern void its_rotate_x(indexed_triangle_set &its, float angle);

View file

@ -283,7 +283,7 @@ namespace detail {
template<typename V, typename W>
std::enable_if_t<std::is_same<typename V::Scalar, double>::value && std::is_same<typename W::Scalar, double>::value, bool>
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W v2, double &t, double &u, double &v) {
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W &v2, double &t, double &u, double &v) {
return intersect_triangle1(const_cast<double*>(origin.data()), const_cast<double*>(dir.data()),
const_cast<double*>(v0.data()), const_cast<double*>(v1.data()), const_cast<double*>(v2.data()),
&t, &u, &v);
@ -291,7 +291,7 @@ namespace detail {
template<typename V, typename W>
std::enable_if_t<std::is_same<typename V::Scalar, double>::value && !std::is_same<typename W::Scalar, double>::value, bool>
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W v2, double &t, double &u, double &v) {
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W &v2, double &t, double &u, double &v) {
using Vector = Eigen::Matrix<double, 3, 1>;
Vector w0 = v0.template cast<double>();
Vector w1 = v1.template cast<double>();
@ -302,7 +302,7 @@ namespace detail {
template<typename V, typename W>
std::enable_if_t<! std::is_same<typename V::Scalar, double>::value && std::is_same<typename W::Scalar, double>::value, bool>
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W v2, double &t, double &u, double &v) {
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W &v2, double &t, double &u, double &v) {
using Vector = Eigen::Matrix<double, 3, 1>;
Vector o = origin.template cast<double>();
Vector d = dir.template cast<double>();
@ -311,7 +311,7 @@ namespace detail {
template<typename V, typename W>
std::enable_if_t<! std::is_same<typename V::Scalar, double>::value && ! std::is_same<typename W::Scalar, double>::value, bool>
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W v2, double &t, double &u, double &v) {
intersect_triangle(const V &origin, const V &dir, const W &v0, const W &v1, const W &v2, double &t, double &u, double &v) {
using Vector = Eigen::Matrix<double, 3, 1>;
Vector o = origin.template cast<double>();
Vector d = dir.template cast<double>();

View file

@ -1,6 +1,7 @@
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include "AppConfig.hpp"
#include "Exception.hpp"
#include <utility>
#include <vector>
@ -126,7 +127,7 @@ std::string AppConfig::load()
// ! But to avoid the use of _utf8 (related to use of wxWidgets)
// we will rethrow this exception from the place of load() call, if returned value wouldn't be empty
/*
throw std::runtime_error(
throw Slic3r::RuntimeError(
_utf8(L("Error parsing PrusaSlicer config file, it is probably corrupted. "
"Try to manually delete the file to recover from the error. Your user profiles will not be affected.")) +
"\n\n" + AppConfig::config_path() + "\n\n" + ex.what());

View file

@ -75,6 +75,7 @@ BoundingBoxBase<PointClass>::merge(const PointClass &point)
}
}
template void BoundingBoxBase<Point>::merge(const Point &point);
template void BoundingBoxBase<Vec2f>::merge(const Vec2f &point);
template void BoundingBoxBase<Vec2d>::merge(const Vec2d &point);
template <class PointClass> void
@ -101,6 +102,7 @@ BoundingBoxBase<PointClass>::merge(const BoundingBoxBase<PointClass> &bb)
}
}
template void BoundingBoxBase<Point>::merge(const BoundingBoxBase<Point> &bb);
template void BoundingBoxBase<Vec2f>::merge(const BoundingBoxBase<Vec2f> &bb);
template void BoundingBoxBase<Vec2d>::merge(const BoundingBoxBase<Vec2d> &bb);
template <class PointClass> void
@ -115,6 +117,7 @@ BoundingBox3Base<PointClass>::merge(const PointClass &point)
this->defined = true;
}
}
template void BoundingBox3Base<Vec3f>::merge(const Vec3f &point);
template void BoundingBox3Base<Vec3d>::merge(const Vec3d &point);
template <class PointClass> void
@ -147,6 +150,7 @@ BoundingBoxBase<PointClass>::size() const
return PointClass(this->max(0) - this->min(0), this->max(1) - this->min(1));
}
template Point BoundingBoxBase<Point>::size() const;
template Vec2f BoundingBoxBase<Vec2f>::size() const;
template Vec2d BoundingBoxBase<Vec2d>::size() const;
template <class PointClass> PointClass
@ -154,6 +158,7 @@ BoundingBox3Base<PointClass>::size() const
{
return PointClass(this->max(0) - this->min(0), this->max(1) - this->min(1), this->max(2) - this->min(2));
}
template Vec3f BoundingBox3Base<Vec3f>::size() const;
template Vec3d BoundingBox3Base<Vec3d>::size() const;
template <class PointClass> double BoundingBoxBase<PointClass>::radius() const
@ -200,6 +205,7 @@ BoundingBoxBase<PointClass>::center() const
return (this->min + this->max) / 2;
}
template Point BoundingBoxBase<Point>::center() const;
template Vec2f BoundingBoxBase<Vec2f>::center() const;
template Vec2d BoundingBoxBase<Vec2d>::center() const;
template <class PointClass> PointClass
@ -207,6 +213,7 @@ BoundingBox3Base<PointClass>::center() const
{
return (this->min + this->max) / 2;
}
template Vec3f BoundingBox3Base<Vec3f>::center() const;
template Vec3d BoundingBox3Base<Vec3d>::center() const;
template <class PointClass> coordf_t
@ -215,6 +222,7 @@ BoundingBox3Base<PointClass>::max_size() const
PointClass s = size();
return std::max(s(0), std::max(s(1), s(2)));
}
template coordf_t BoundingBox3Base<Vec3f>::max_size() const;
template coordf_t BoundingBox3Base<Vec3d>::max_size() const;
// Align a coordinate to a grid. The coordinate may be negative,

View file

@ -2,6 +2,7 @@
#define slic3r_BoundingBox_hpp_
#include "libslic3r.h"
#include "Exception.hpp"
#include "Point.hpp"
#include "Polygon.hpp"
@ -18,11 +19,13 @@ public:
BoundingBoxBase() : min(PointClass::Zero()), max(PointClass::Zero()), defined(false) {}
BoundingBoxBase(const PointClass &pmin, const PointClass &pmax) :
min(pmin), max(pmax), defined(pmin(0) < pmax(0) && pmin(1) < pmax(1)) {}
BoundingBoxBase(const PointClass &p1, const PointClass &p2, const PointClass &p3) :
min(p1), max(p1), defined(false) { merge(p2); merge(p3); }
BoundingBoxBase(const std::vector<PointClass>& points) : min(PointClass::Zero()), max(PointClass::Zero())
{
if (points.empty()) {
this->defined = false;
// throw std::invalid_argument("Empty point set supplied to BoundingBoxBase constructor");
// throw Slic3r::InvalidArgument("Empty point set supplied to BoundingBoxBase constructor");
} else {
typename std::vector<PointClass>::const_iterator it = points.begin();
this->min = *it;
@ -65,10 +68,12 @@ public:
BoundingBox3Base(const PointClass &pmin, const PointClass &pmax) :
BoundingBoxBase<PointClass>(pmin, pmax)
{ if (pmin(2) >= pmax(2)) BoundingBoxBase<PointClass>::defined = false; }
BoundingBox3Base(const PointClass &p1, const PointClass &p2, const PointClass &p3) :
BoundingBoxBase<PointClass>(p1, p1) { merge(p2); merge(p3); }
BoundingBox3Base(const std::vector<PointClass>& points)
{
if (points.empty())
throw std::invalid_argument("Empty point set supplied to BoundingBox3Base constructor");
throw Slic3r::InvalidArgument("Empty point set supplied to BoundingBox3Base constructor");
typename std::vector<PointClass>::const_iterator it = points.begin();
this->min = *it;
this->max = *it;
@ -109,24 +114,32 @@ extern template void BoundingBoxBase<Vec3d>::scale(double factor);
extern template void BoundingBoxBase<Point>::offset(coordf_t delta);
extern template void BoundingBoxBase<Vec2d>::offset(coordf_t delta);
extern template void BoundingBoxBase<Point>::merge(const Point &point);
extern template void BoundingBoxBase<Vec2f>::merge(const Vec2f &point);
extern template void BoundingBoxBase<Vec2d>::merge(const Vec2d &point);
extern template void BoundingBoxBase<Point>::merge(const Points &points);
extern template void BoundingBoxBase<Vec2d>::merge(const Pointfs &points);
extern template void BoundingBoxBase<Point>::merge(const BoundingBoxBase<Point> &bb);
extern template void BoundingBoxBase<Vec2f>::merge(const BoundingBoxBase<Vec2f> &bb);
extern template void BoundingBoxBase<Vec2d>::merge(const BoundingBoxBase<Vec2d> &bb);
extern template Point BoundingBoxBase<Point>::size() const;
extern template Vec2f BoundingBoxBase<Vec2f>::size() const;
extern template Vec2d BoundingBoxBase<Vec2d>::size() const;
extern template double BoundingBoxBase<Point>::radius() const;
extern template double BoundingBoxBase<Vec2d>::radius() const;
extern template Point BoundingBoxBase<Point>::center() const;
extern template Vec2f BoundingBoxBase<Vec2f>::center() const;
extern template Vec2d BoundingBoxBase<Vec2d>::center() const;
extern template void BoundingBox3Base<Vec3f>::merge(const Vec3f &point);
extern template void BoundingBox3Base<Vec3d>::merge(const Vec3d &point);
extern template void BoundingBox3Base<Vec3d>::merge(const Pointf3s &points);
extern template void BoundingBox3Base<Vec3d>::merge(const BoundingBox3Base<Vec3d> &bb);
extern template Vec3f BoundingBox3Base<Vec3f>::size() const;
extern template Vec3d BoundingBox3Base<Vec3d>::size() const;
extern template double BoundingBox3Base<Vec3d>::radius() const;
extern template void BoundingBox3Base<Vec3d>::offset(coordf_t delta);
extern template Vec3f BoundingBox3Base<Vec3f>::center() const;
extern template Vec3d BoundingBox3Base<Vec3d>::center() const;
extern template coordf_t BoundingBox3Base<Vec3f>::max_size() const;
extern template coordf_t BoundingBox3Base<Vec3d>::max_size() const;
class BoundingBox : public BoundingBoxBase<Point>

View file

@ -97,6 +97,8 @@ add_library(libslic3r STATIC
GCode/PrintExtents.hpp
GCode/SpiralVase.cpp
GCode/SpiralVase.hpp
GCode/SeamPlacer.cpp
GCode/SeamPlacer.hpp
GCode/ToolOrdering.cpp
GCode/ToolOrdering.hpp
GCode/WipeTower.cpp

View file

@ -5,7 +5,6 @@
#include <fstream>
#include <iostream>
#include <iomanip>
#include <exception> // std::runtime_error
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/erase.hpp>
@ -218,7 +217,7 @@ ConfigOption* ConfigOptionDef::create_empty_option() const
case coInts: return new ConfigOptionIntsNullable();
case coPercents: return new ConfigOptionPercentsNullable();
case coBools: return new ConfigOptionBoolsNullable();
default: throw std::runtime_error(std::string("Unknown option type for nullable option ") + this->label);
default: throw Slic3r::RuntimeError(std::string("Unknown option type for nullable option ") + this->label);
}
} else {
switch (this->type) {
@ -238,7 +237,7 @@ ConfigOption* ConfigOptionDef::create_empty_option() const
case coBool: return new ConfigOptionBool();
case coBools: return new ConfigOptionBools();
case coEnum: return new ConfigOptionEnumGeneric(this->enum_keys_map);
default: throw std::runtime_error(std::string("Unknown option type for option ") + this->label);
default: throw Slic3r::RuntimeError(std::string("Unknown option type for option ") + this->label);
}
}
}
@ -535,7 +534,7 @@ double ConfigBase::get_abs_value(const t_config_option_key &opt_key) const
return opt_def->ratio_over.empty() ? 0. :
static_cast<const ConfigOptionFloatOrPercent*>(raw_opt)->get_abs_value(this->get_abs_value(opt_def->ratio_over));
}
throw std::runtime_error("ConfigBase::get_abs_value(): Not a valid option type for get_abs_value()");
throw Slic3r::RuntimeError("ConfigBase::get_abs_value(): Not a valid option type for get_abs_value()");
}
// Return an absolute value of a possibly relative config variable.
@ -546,7 +545,7 @@ double ConfigBase::get_abs_value(const t_config_option_key &opt_key, double rati
const ConfigOption *raw_opt = this->option(opt_key);
assert(raw_opt != nullptr);
if (raw_opt->type() != coFloatOrPercent)
throw std::runtime_error("ConfigBase::get_abs_value(): opt_key is not of coFloatOrPercent");
throw Slic3r::RuntimeError("ConfigBase::get_abs_value(): opt_key is not of coFloatOrPercent");
// Compute absolute value.
return static_cast<const ConfigOptionFloatOrPercent*>(raw_opt)->get_abs_value(ratio_over);
}
@ -609,7 +608,7 @@ void ConfigBase::load_from_gcode_file(const std::string &file)
std::getline(ifs, firstline);
if (strncmp(slic3r_gcode_header, firstline.c_str(), strlen(slic3r_gcode_header)) != 0 &&
strncmp(prusaslicer_gcode_header, firstline.c_str(), strlen(prusaslicer_gcode_header)) != 0)
throw std::runtime_error("Not a PrusaSlicer / Slic3r PE generated g-code.");
throw Slic3r::RuntimeError("Not a PrusaSlicer / Slic3r PE generated g-code.");
}
ifs.seekg(0, ifs.end);
auto file_length = ifs.tellg();
@ -621,7 +620,7 @@ void ConfigBase::load_from_gcode_file(const std::string &file)
size_t key_value_pairs = load_from_gcode_string(data.data());
if (key_value_pairs < 80)
throw std::runtime_error(format("Suspiciously low number of configuration values extracted from %1%: %2%", file, key_value_pairs));
throw Slic3r::RuntimeError(format("Suspiciously low number of configuration values extracted from %1%: %2%", file, key_value_pairs));
}
// Load the config keys from the given string.
@ -750,7 +749,7 @@ ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool cre
throw NoDefinitionException(opt_key);
const ConfigOptionDef *optdef = def->get(opt_key);
if (optdef == nullptr)
// throw std::runtime_error(std::string("Invalid option name: ") + opt_key);
// throw Slic3r::RuntimeError(std::string("Invalid option name: ") + opt_key);
// Let the parent decide what to do if the opt_key is not defined by this->def().
return nullptr;
ConfigOption *opt = optdef->create_default_option();

View file

@ -13,6 +13,7 @@
#include <vector>
#include "libslic3r.h"
#include "clonable_ptr.hpp"
#include "Exception.hpp"
#include "Point.hpp"
#include <boost/algorithm/string/trim.hpp>
@ -34,31 +35,31 @@ extern bool unescape_string_cstyle(const std::string &str, std::string &
extern bool unescape_strings_cstyle(const std::string &str, std::vector<std::string> &out);
/// Specialization of std::exception to indicate that an unknown config option has been encountered.
class UnknownOptionException : public std::runtime_error {
class UnknownOptionException : public Slic3r::RuntimeError {
public:
UnknownOptionException() :
std::runtime_error("Unknown option exception") {}
Slic3r::RuntimeError("Unknown option exception") {}
UnknownOptionException(const std::string &opt_key) :
std::runtime_error(std::string("Unknown option exception: ") + opt_key) {}
Slic3r::RuntimeError(std::string("Unknown option exception: ") + opt_key) {}
};
/// Indicate that the ConfigBase derived class does not provide config definition (the method def() returns null).
class NoDefinitionException : public std::runtime_error
class NoDefinitionException : public Slic3r::RuntimeError
{
public:
NoDefinitionException() :
std::runtime_error("No definition exception") {}
Slic3r::RuntimeError("No definition exception") {}
NoDefinitionException(const std::string &opt_key) :
std::runtime_error(std::string("No definition exception: ") + opt_key) {}
Slic3r::RuntimeError(std::string("No definition exception: ") + opt_key) {}
};
/// Indicate that an unsupported accessor was called on a config option.
class BadOptionTypeException : public std::runtime_error
class BadOptionTypeException : public Slic3r::RuntimeError
{
public:
BadOptionTypeException() : std::runtime_error("Bad option type exception") {}
BadOptionTypeException(const std::string &message) : std::runtime_error(message) {}
BadOptionTypeException(const char* message) : std::runtime_error(message) {}
BadOptionTypeException() : Slic3r::RuntimeError("Bad option type exception") {}
BadOptionTypeException(const std::string &message) : Slic3r::RuntimeError(message) {}
BadOptionTypeException(const char* message) : Slic3r::RuntimeError(message) {}
};
// Type of a configuration value.
@ -167,7 +168,7 @@ public:
void set(const ConfigOption *rhs) override
{
if (rhs->type() != this->type())
throw std::runtime_error("ConfigOptionSingle: Assigning an incompatible type");
throw Slic3r::RuntimeError("ConfigOptionSingle: Assigning an incompatible type");
assert(dynamic_cast<const ConfigOptionSingle<T>*>(rhs));
this->value = static_cast<const ConfigOptionSingle<T>*>(rhs)->value;
}
@ -175,7 +176,7 @@ public:
bool operator==(const ConfigOption &rhs) const override
{
if (rhs.type() != this->type())
throw std::runtime_error("ConfigOptionSingle: Comparing incompatible types");
throw Slic3r::RuntimeError("ConfigOptionSingle: Comparing incompatible types");
assert(dynamic_cast<const ConfigOptionSingle<T>*>(&rhs));
return this->value == static_cast<const ConfigOptionSingle<T>*>(&rhs)->value;
}
@ -239,7 +240,7 @@ public:
void set(const ConfigOption *rhs) override
{
if (rhs->type() != this->type())
throw std::runtime_error("ConfigOptionVector: Assigning an incompatible type");
throw Slic3r::RuntimeError("ConfigOptionVector: Assigning an incompatible type");
assert(dynamic_cast<const ConfigOptionVector<T>*>(rhs));
this->values = static_cast<const ConfigOptionVector<T>*>(rhs)->values;
}
@ -256,12 +257,12 @@ public:
if (opt->type() == this->type()) {
auto other = static_cast<const ConfigOptionVector<T>*>(opt);
if (other->values.empty())
throw std::runtime_error("ConfigOptionVector::set(): Assigning from an empty vector");
throw Slic3r::RuntimeError("ConfigOptionVector::set(): Assigning from an empty vector");
this->values.emplace_back(other->values.front());
} else if (opt->type() == this->scalar_type())
this->values.emplace_back(static_cast<const ConfigOptionSingle<T>*>(opt)->value);
else
throw std::runtime_error("ConfigOptionVector::set():: Assigning an incompatible type");
throw Slic3r::RuntimeError("ConfigOptionVector::set():: Assigning an incompatible type");
}
}
@ -280,12 +281,12 @@ public:
// Assign the first value of the rhs vector.
auto other = static_cast<const ConfigOptionVector<T>*>(rhs);
if (other->values.empty())
throw std::runtime_error("ConfigOptionVector::set_at(): Assigning from an empty vector");
throw Slic3r::RuntimeError("ConfigOptionVector::set_at(): Assigning from an empty vector");
this->values[i] = other->get_at(j);
} else if (rhs->type() == this->scalar_type())
this->values[i] = static_cast<const ConfigOptionSingle<T>*>(rhs)->value;
else
throw std::runtime_error("ConfigOptionVector::set_at(): Assigning an incompatible type");
throw Slic3r::RuntimeError("ConfigOptionVector::set_at(): Assigning an incompatible type");
}
const T& get_at(size_t i) const
@ -310,9 +311,9 @@ public:
else if (n > this->values.size()) {
if (this->values.empty()) {
if (opt_default == nullptr)
throw std::runtime_error("ConfigOptionVector::resize(): No default value provided.");
throw Slic3r::RuntimeError("ConfigOptionVector::resize(): No default value provided.");
if (opt_default->type() != this->type())
throw std::runtime_error("ConfigOptionVector::resize(): Extending with an incompatible type.");
throw Slic3r::RuntimeError("ConfigOptionVector::resize(): Extending with an incompatible type.");
this->values.resize(n, static_cast<const ConfigOptionVector<T>*>(opt_default)->values.front());
} else {
// Resize by duplicating the last value.
@ -329,7 +330,7 @@ public:
bool operator==(const ConfigOption &rhs) const override
{
if (rhs.type() != this->type())
throw std::runtime_error("ConfigOptionVector: Comparing incompatible types");
throw Slic3r::RuntimeError("ConfigOptionVector: Comparing incompatible types");
assert(dynamic_cast<const ConfigOptionVector<T>*>(&rhs));
return this->values == static_cast<const ConfigOptionVector<T>*>(&rhs)->values;
}
@ -341,9 +342,9 @@ public:
// An option overrides another option if it is not nil and not equal.
bool overriden_by(const ConfigOption *rhs) const override {
if (this->nullable())
throw std::runtime_error("Cannot override a nullable ConfigOption.");
throw Slic3r::RuntimeError("Cannot override a nullable ConfigOption.");
if (rhs->type() != this->type())
throw std::runtime_error("ConfigOptionVector.overriden_by() applied to different types.");
throw Slic3r::RuntimeError("ConfigOptionVector.overriden_by() applied to different types.");
auto rhs_vec = static_cast<const ConfigOptionVector<T>*>(rhs);
if (! rhs->nullable())
// Overridding a non-nullable object with another non-nullable object.
@ -361,9 +362,9 @@ public:
// Apply an override option, possibly a nullable one.
bool apply_override(const ConfigOption *rhs) override {
if (this->nullable())
throw std::runtime_error("Cannot override a nullable ConfigOption.");
throw Slic3r::RuntimeError("Cannot override a nullable ConfigOption.");
if (rhs->type() != this->type())
throw std::runtime_error("ConfigOptionVector.apply_override() applied to different types.");
throw Slic3r::RuntimeError("ConfigOptionVector.apply_override() applied to different types.");
auto rhs_vec = static_cast<const ConfigOptionVector<T>*>(rhs);
if (! rhs->nullable()) {
// Overridding a non-nullable object with another non-nullable object.
@ -452,7 +453,7 @@ public:
bool operator==(const ConfigOptionFloatsTempl &rhs) const { return vectors_equal(this->values, rhs.values); }
bool operator==(const ConfigOption &rhs) const override {
if (rhs.type() != this->type())
throw std::runtime_error("ConfigOptionFloatsTempl: Comparing incompatible types");
throw Slic3r::RuntimeError("ConfigOptionFloatsTempl: Comparing incompatible types");
assert(dynamic_cast<const ConfigOptionVector<double>*>(&rhs));
return vectors_equal(this->values, static_cast<const ConfigOptionVector<double>*>(&rhs)->values);
}
@ -499,7 +500,7 @@ public:
if (NULLABLE)
this->values.push_back(nil_value());
else
throw std::runtime_error("Deserializing nil into a non-nullable object");
throw Slic3r::RuntimeError("Deserializing nil into a non-nullable object");
} else {
std::istringstream iss(item_str);
double value;
@ -524,9 +525,9 @@ protected:
if (NULLABLE)
ss << "nil";
else
throw std::runtime_error("Serializing NaN");
throw Slic3r::RuntimeError("Serializing NaN");
} else
throw std::runtime_error("Serializing invalid number");
throw Slic3r::RuntimeError("Serializing invalid number");
}
static bool vectors_equal(const std::vector<double> &v1, const std::vector<double> &v2) {
if (NULLABLE) {
@ -645,7 +646,7 @@ public:
if (NULLABLE)
this->values.push_back(nil_value());
else
throw std::runtime_error("Deserializing nil into a non-nullable object");
throw Slic3r::RuntimeError("Deserializing nil into a non-nullable object");
} else {
std::istringstream iss(item_str);
int value;
@ -662,7 +663,7 @@ private:
if (NULLABLE)
ss << "nil";
else
throw std::runtime_error("Serializing NaN");
throw Slic3r::RuntimeError("Serializing NaN");
} else
ss << v;
}
@ -847,7 +848,7 @@ public:
bool operator==(const ConfigOption &rhs) const override
{
if (rhs.type() != this->type())
throw std::runtime_error("ConfigOptionFloatOrPercent: Comparing incompatible types");
throw Slic3r::RuntimeError("ConfigOptionFloatOrPercent: Comparing incompatible types");
assert(dynamic_cast<const ConfigOptionFloatOrPercent*>(&rhs));
return *this == *static_cast<const ConfigOptionFloatOrPercent*>(&rhs);
}
@ -858,7 +859,7 @@ public:
void set(const ConfigOption *rhs) override {
if (rhs->type() != this->type())
throw std::runtime_error("ConfigOptionFloatOrPercent: Assigning an incompatible type");
throw Slic3r::RuntimeError("ConfigOptionFloatOrPercent: Assigning an incompatible type");
assert(dynamic_cast<const ConfigOptionFloatOrPercent*>(rhs));
*this = *static_cast<const ConfigOptionFloatOrPercent*>(rhs);
}
@ -1126,7 +1127,7 @@ public:
if (NULLABLE)
this->values.push_back(nil_value());
else
throw std::runtime_error("Deserializing nil into a non-nullable object");
throw Slic3r::RuntimeError("Deserializing nil into a non-nullable object");
} else
this->values.push_back(item_str.compare("1") == 0);
}
@ -1139,7 +1140,7 @@ protected:
if (NULLABLE)
ss << "nil";
else
throw std::runtime_error("Serializing NaN");
throw Slic3r::RuntimeError("Serializing NaN");
} else
ss << (v ? "1" : "0");
}
@ -1175,14 +1176,14 @@ public:
bool operator==(const ConfigOption &rhs) const override
{
if (rhs.type() != this->type())
throw std::runtime_error("ConfigOptionEnum<T>: Comparing incompatible types");
throw Slic3r::RuntimeError("ConfigOptionEnum<T>: Comparing incompatible types");
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
return this->value == (T)rhs.getInt();
}
void set(const ConfigOption *rhs) override {
if (rhs->type() != this->type())
throw std::runtime_error("ConfigOptionEnum<T>: Assigning an incompatible type");
throw Slic3r::RuntimeError("ConfigOptionEnum<T>: Assigning an incompatible type");
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
this->value = (T)rhs->getInt();
}
@ -1259,14 +1260,14 @@ public:
bool operator==(const ConfigOption &rhs) const override
{
if (rhs.type() != this->type())
throw std::runtime_error("ConfigOptionEnumGeneric: Comparing incompatible types");
throw Slic3r::RuntimeError("ConfigOptionEnumGeneric: Comparing incompatible types");
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
return this->value == rhs.getInt();
}
void set(const ConfigOption *rhs) override {
if (rhs->type() != this->type())
throw std::runtime_error("ConfigOptionEnumGeneric: Assigning an incompatible type");
throw Slic3r::RuntimeError("ConfigOptionEnumGeneric: Assigning an incompatible type");
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
this->value = rhs->getInt();
}
@ -1321,7 +1322,7 @@ public:
case coInts: { auto opt = new ConfigOptionIntsNullable(); archive(*opt); return opt; }
case coPercents: { auto opt = new ConfigOptionPercentsNullable();archive(*opt); return opt; }
case coBools: { auto opt = new ConfigOptionBoolsNullable(); archive(*opt); return opt; }
default: throw std::runtime_error(std::string("ConfigOptionDef::load_option_from_archive(): Unknown nullable option type for option ") + this->opt_key);
default: throw Slic3r::RuntimeError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown nullable option type for option ") + this->opt_key);
}
} else {
switch (this->type) {
@ -1340,7 +1341,7 @@ public:
case coBool: { auto opt = new ConfigOptionBool(); archive(*opt); return opt; }
case coBools: { auto opt = new ConfigOptionBools(); archive(*opt); return opt; }
case coEnum: { auto opt = new ConfigOptionEnumGeneric(this->enum_keys_map); archive(*opt); return opt; }
default: throw std::runtime_error(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
default: throw Slic3r::RuntimeError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown option type for option ") + this->opt_key);
}
}
}
@ -1352,7 +1353,7 @@ public:
case coInts: archive(*static_cast<const ConfigOptionIntsNullable*>(opt)); break;
case coPercents: archive(*static_cast<const ConfigOptionPercentsNullable*>(opt));break;
case coBools: archive(*static_cast<const ConfigOptionBoolsNullable*>(opt)); break;
default: throw std::runtime_error(std::string("ConfigOptionDef::save_option_to_archive(): Unknown nullable option type for option ") + this->opt_key);
default: throw Slic3r::RuntimeError(std::string("ConfigOptionDef::save_option_to_archive(): Unknown nullable option type for option ") + this->opt_key);
}
} else {
switch (this->type) {
@ -1371,7 +1372,7 @@ public:
case coBool: archive(*static_cast<const ConfigOptionBool*>(opt)); break;
case coBools: archive(*static_cast<const ConfigOptionBools*>(opt)); break;
case coEnum: archive(*static_cast<const ConfigOptionEnumGeneric*>(opt)); break;
default: throw std::runtime_error(std::string("ConfigOptionDef::save_option_to_archive(): Unknown option type for option ") + this->opt_key);
default: throw Slic3r::RuntimeError(std::string("ConfigOptionDef::save_option_to_archive(): Unknown option type for option ") + this->opt_key);
}
}
// Make the compiler happy, shut up the warnings.

View file

@ -1,5 +1,6 @@
#include "BoundingBox.hpp"
#include "ExPolygon.hpp"
#include "Exception.hpp"
#include "Geometry.hpp"
#include "Polygon.hpp"
#include "Line.hpp"
@ -435,7 +436,7 @@ void ExPolygon::triangulate_pp(Polygons* polygons) const
std::list<TPPLPoly> output;
int res = TPPLPartition().Triangulate_MONO(&input, &output);
if (res != 1)
throw std::runtime_error("Triangulation failed");
throw Slic3r::RuntimeError("Triangulation failed");
// convert output polygons
for (std::list<TPPLPoly>::iterator poly = output.begin(); poly != output.end(); ++poly) {
@ -548,7 +549,7 @@ void ExPolygon::triangulate_pp(Points *triangles) const
int res = TPPLPartition().Triangulate_MONO(&input, &output);
// int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
if (res != 1)
throw std::runtime_error("Triangulation failed");
throw Slic3r::RuntimeError("Triangulation failed");
*triangles = polypartition_output_to_triangles(output);
}
@ -591,7 +592,7 @@ void ExPolygon::triangulate_p2t(Polygons* polygons) const
}
polygons->push_back(p);
}
} catch (const std::runtime_error & /* err */) {
} catch (const Slic3r::RuntimeError & /* err */) {
assert(false);
// just ignore, don't triangulate
}

View file

@ -0,0 +1,28 @@
#ifndef _libslic3r_Exception_h_
#define _libslic3r_Exception_h_
#include <stdexcept>
namespace Slic3r {
// PrusaSlicer's own exception hierarchy is derived from std::runtime_error.
// Base for Slicer's own exceptions.
class Exception : public std::runtime_error { using std::runtime_error::runtime_error; };
#define SLIC3R_DERIVE_EXCEPTION(DERIVED_EXCEPTION, PARENT_EXCEPTION) \
class DERIVED_EXCEPTION : public PARENT_EXCEPTION { using PARENT_EXCEPTION::PARENT_EXCEPTION; }
// Critical exception produced by Slicer, such exception shall never propagate up to the UI thread.
// If that happens, an ugly fat message box with an ugly fat exclamation mark is displayed.
SLIC3R_DERIVE_EXCEPTION(CriticalException, Exception);
SLIC3R_DERIVE_EXCEPTION(RuntimeError, CriticalException);
SLIC3R_DERIVE_EXCEPTION(LogicError, CriticalException);
SLIC3R_DERIVE_EXCEPTION(InvalidArgument, LogicError);
SLIC3R_DERIVE_EXCEPTION(OutOfRange, LogicError);
SLIC3R_DERIVE_EXCEPTION(IOError, CriticalException);
SLIC3R_DERIVE_EXCEPTION(FileIOError, IOError);
// Runtime exception produced by Slicer. Such exception cancels the slicing process and it shall be shown in notifications.
SLIC3R_DERIVE_EXCEPTION(SlicingError, Exception);
#undef SLIC3R_DERIVE_EXCEPTION
} // namespace Slic3r
#endif // _libslic3r_Exception_h_

View file

@ -2,6 +2,7 @@
#define slic3r_ExtrusionEntityCollection_hpp_
#include "libslic3r.h"
#include "Exception.hpp"
#include "ExtrusionEntity.hpp"
namespace Slic3r {
@ -107,7 +108,7 @@ public:
// Following methods shall never be called on an ExtrusionEntityCollection.
Polyline as_polyline() const override {
throw std::runtime_error("Calling as_polyline() on a ExtrusionEntityCollection");
throw Slic3r::RuntimeError("Calling as_polyline() on a ExtrusionEntityCollection");
return Polyline();
};
@ -117,7 +118,7 @@ public:
}
double length() const override {
throw std::runtime_error("Calling length() on a ExtrusionEntityCollection");
throw Slic3r::RuntimeError("Calling length() on a ExtrusionEntityCollection");
return 0.;
}
};

View file

@ -10,14 +10,14 @@
namespace Slic3r {
// Generic file parser error, mostly copied from boost::property_tree::file_parser_error
class file_parser_error: public std::runtime_error
class file_parser_error: public Slic3r::RuntimeError
{
public:
file_parser_error(const std::string &msg, const std::string &file, unsigned long line = 0) :
std::runtime_error(format_what(msg, file, line)),
Slic3r::RuntimeError(format_what(msg, file, line)),
m_message(msg), m_filename(file), m_line(line) {}
file_parser_error(const std::string &msg, const boost::filesystem::path &file, unsigned long line = 0) :
std::runtime_error(format_what(msg, file.string(), line)),
Slic3r::RuntimeError(format_what(msg, file.string(), line)),
m_message(msg), m_filename(file.string()), m_line(line) {}
// gcc 3.4.2 complains about lack of throw specifier on compiler
// generated dtor
@ -35,7 +35,7 @@ private:
std::string m_filename;
unsigned long m_line;
// Format error message to be returned by std::runtime_error::what()
// Format error message to be returned by Slic3r::RuntimeError::what()
static std::string format_what(const std::string &msg, const std::string &file, unsigned long l)
{
std::stringstream stream;

View file

@ -318,7 +318,7 @@ void export_group_fills_to_svg(const char *path, const std::vector<SurfaceFill>
#endif
// friend to Layer
void Layer::make_fills(FillAdaptive_Internal::Octree* adaptive_fill_octree, FillAdaptive_Internal::Octree* support_fill_octree)
void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree)
{
for (LayerRegion *layerm : m_regions)
layerm->fills.clear();
@ -345,8 +345,7 @@ void Layer::make_fills(FillAdaptive_Internal::Octree* adaptive_fill_octree, Fill
f->layer_id = this->id();
f->z = this->print_z;
f->angle = surface_fill.params.angle;
f->adapt_fill_octree = adaptive_fill_octree;
f->support_fill_octree = support_fill_octree;
f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
// calculate flow spacing for infill pattern generation
bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.flow.bridge;

File diff suppressed because it is too large Load diff

View file

@ -1,138 +1,75 @@
// Adaptive cubic infill was inspired by the work of @mboerwinkle
// as implemented for Cura.
// https://github.com/Ultimaker/CuraEngine/issues/381
// https://github.com/Ultimaker/CuraEngine/pull/401
//
// Our implementation is more accurate (discretizes a bit less cubes than Cura's)
// by splitting only such cubes which contain a triangle.
// Our line extraction is time optimal instead of O(n^2) when connecting extracted lines,
// and we also implemented adaptivity for supporting internal overhangs only.
#ifndef slic3r_FillAdaptive_hpp_
#define slic3r_FillAdaptive_hpp_
#include "../AABBTreeIndirect.hpp"
#include "FillBase.hpp"
struct indexed_triangle_set;
namespace Slic3r {
class PrintObject;
namespace FillAdaptive_Internal
namespace FillAdaptive
{
struct CubeProperties
{
double edge_length; // Lenght of edge of a cube
double height; // Height of rotated cube (standing on the corner)
double diagonal_length; // Length of diagonal of a cube a face
double line_z_distance; // Defines maximal distance from a center of a cube on Z axis on which lines will be created
double line_xy_distance;// Defines maximal distance from a center of a cube on X and Y axis on which lines will be created
};
struct Cube
{
Vec3d center;
std::unique_ptr<Cube> children[8] = {};
Cube(const Vec3d &center) : center(center) {}
};
struct Octree;
// To keep the definition of Octree opaque, we have to define a custom deleter.
struct OctreeDeleter { void operator()(Octree *p); };
using OctreePtr = std::unique_ptr<Octree, OctreeDeleter>;
struct Octree
{
std::unique_ptr<Cube> root_cube;
Vec3d origin;
std::vector<CubeProperties> cubes_properties;
// Calculate line spacing for
// 1) adaptive cubic infill
// 2) adaptive internal support cubic infill
// Returns zero for a particular infill type if no such infill is to be generated.
std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object);
Octree(std::unique_ptr<Cube> rootCube, const Vec3d &origin, const std::vector<CubeProperties> &cubes_properties)
: root_cube(std::move(rootCube)), origin(origin), cubes_properties(cubes_properties) {}
// Rotation of the octree to stand on one of its corners.
Eigen::Quaterniond transform_to_world();
// Inverse roation of the above.
Eigen::Quaterniond transform_to_octree();
inline static int find_octant(const Vec3d &i_cube, const Vec3d &current)
{
return (i_cube.z() > current.z()) * 4 + (i_cube.y() > current.y()) * 2 + (i_cube.x() > current.x());
}
static void propagate_point(
Vec3d point,
FillAdaptive_Internal::Cube *current_cube,
int depth,
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties);
};
}; // namespace FillAdaptive_Internal
FillAdaptive::OctreePtr build_octree(
// Mesh is rotated to the coordinate system of the octree.
const indexed_triangle_set &triangle_mesh,
// Overhang triangles extracted from fill surfaces with stInternalBridge type,
// rotated to the coordinate system of the octree.
const std::vector<Vec3d> &overhang_triangles,
coordf_t line_spacing,
// If true, octree is densified below internal overhangs only.
bool support_overhangs_only);
//
// Some of the algorithms used by class FillAdaptive were inspired by
// Cura Engine's class SubDivCube
// https://github.com/Ultimaker/CuraEngine/blob/master/src/infill/SubDivCube.h
//
class FillAdaptive : public Fill
class Filler : public Slic3r::Fill
{
public:
virtual ~FillAdaptive() {}
virtual ~Filler() {}
protected:
virtual Fill* clone() const { return new FillAdaptive(*this); };
virtual Fill* clone() const { return new Filler(*this); };
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
Polylines &polylines_out);
virtual bool no_sort() const { return true; }
void generate_infill_lines(
FillAdaptive_Internal::Cube *cube,
double z_position,
const Vec3d & origin,
const Transform3d & rotation_matrix,
std::vector<Lines> & dir_lines_out,
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties,
int depth);
static void connect_lines(Lines &lines, Line new_line);
void generate_infill(const FillParams & params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon & expolygon,
Polylines & polylines_out,
FillAdaptive_Internal::Octree *octree);
public:
static std::unique_ptr<FillAdaptive_Internal::Octree> build_octree(
TriangleMesh &triangle_mesh,
coordf_t line_spacing,
const Vec3d & cube_center);
static void expand_cube(
FillAdaptive_Internal::Cube *cube,
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties,
const AABBTreeIndirect::Tree3f &distance_tree,
const TriangleMesh & triangle_mesh,
int depth);
};
class FillSupportCubic : public FillAdaptive
{
public:
virtual ~FillSupportCubic() = default;
protected:
virtual Fill* clone() const { return new FillSupportCubic(*this); };
virtual bool no_sort() const { return true; }
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon &expolygon,
Polylines &polylines_out);
public:
static std::unique_ptr<FillAdaptive_Internal::Octree> build_octree(
TriangleMesh & triangle_mesh,
coordf_t line_spacing,
const Vec3d & cube_center,
const Transform3d &rotation_matrix);
};
// Calculate line spacing for
// 1) adaptive cubic infill
// 2) adaptive internal support cubic infill
// Returns zero for a particular infill type if no such infill is to be generated.
std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object);
}; // namespace FillAdaptive
} // namespace Slic3r
#endif // slic3r_FillAdaptive_hpp_

View file

@ -38,9 +38,9 @@ Fill* Fill::new_from_type(const InfillPattern type)
case ipArchimedeanChords: return new FillArchimedeanChords();
case ipHilbertCurve: return new FillHilbertCurve();
case ipOctagramSpiral: return new FillOctagramSpiral();
case ipAdaptiveCubic: return new FillAdaptive();
case ipSupportCubic: return new FillSupportCubic();
default: throw std::invalid_argument("unknown type");
case ipAdaptiveCubic: return new FillAdaptive::Filler();
case ipSupportCubic: return new FillAdaptive::Filler();
default: throw Slic3r::InvalidArgument("unknown type");
}
}
@ -847,8 +847,9 @@ void Fill::connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary_
boundary.assign(boundary_src.holes.size() + 1, Points());
boundary_data.assign(boundary_src.holes.size() + 1, std::vector<ContourPointData>());
// Mapping the infill_ordered end point to a (contour, point) of boundary.
std::vector<std::pair<size_t, size_t>> map_infill_end_point_to_boundary;
map_infill_end_point_to_boundary.assign(infill_ordered.size() * 2, std::pair<size_t, size_t>(std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max()));
std::vector<std::pair<size_t, size_t>> map_infill_end_point_to_boundary;
static constexpr auto boundary_idx_unconnected = std::numeric_limits<size_t>::max();
map_infill_end_point_to_boundary.assign(infill_ordered.size() * 2, std::pair<size_t, size_t>(boundary_idx_unconnected, boundary_idx_unconnected));
{
// Project the infill_ordered end points onto boundary_src.
std::vector<std::pair<EdgeGrid::Grid::ClosestPointResult, size_t>> intersection_points;
@ -898,13 +899,14 @@ void Fill::connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary_
contour_data.front().param = contour_data.back().param + (contour_dst.back().cast<float>() - contour_dst.front().cast<float>()).norm();
}
#ifndef NDEBUG
assert(boundary.size() == boundary_src.num_contours());
assert(std::all_of(map_infill_end_point_to_boundary.begin(), map_infill_end_point_to_boundary.end(),
#if 0
// Adaptive Cubic Infill produces infill lines, which not always end at the outer boundary.
assert(std::all_of(map_infill_end_point_to_boundary.begin(), map_infill_end_point_to_boundary.end(),
[&boundary](const std::pair<size_t, size_t> &contour_point) {
return contour_point.first < boundary.size() && contour_point.second < boundary[contour_point.first].size();
}));
#endif /* NDEBUG */
#endif
}
// Mark the points and segments of split boundary as consumed if they are very close to some of the infill line.
@ -935,9 +937,9 @@ void Fill::connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary_
const Polyline &pl2 = infill_ordered[idx_chain];
const std::pair<size_t, size_t> *cp1 = &map_infill_end_point_to_boundary[(idx_chain - 1) * 2 + 1];
const std::pair<size_t, size_t> *cp2 = &map_infill_end_point_to_boundary[idx_chain * 2];
const std::vector<ContourPointData> &contour_data = boundary_data[cp1->first];
if (cp1->first == cp2->first) {
if (cp1->first != boundary_idx_unconnected && cp1->first == cp2->first) {
// End points on the same contour. Try to connect them.
const std::vector<ContourPointData> &contour_data = boundary_data[cp1->first];
float param_lo = (cp1->second == 0) ? 0.f : contour_data[cp1->second].param;
float param_hi = (cp2->second == 0) ? 0.f : contour_data[cp2->second].param;
float param_end = contour_data.front().param;
@ -964,7 +966,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary_
const std::pair<size_t, size_t> *cp1prev = cp1 - 1;
const std::pair<size_t, size_t> *cp2 = &map_infill_end_point_to_boundary[(connection_cost.idx_first + 1) * 2];
const std::pair<size_t, size_t> *cp2next = cp2 + 1;
assert(cp1->first == cp2->first);
assert(cp1->first == cp2->first && cp1->first != boundary_idx_unconnected);
std::vector<ContourPointData> &contour_data = boundary_data[cp1->first];
if (connection_cost.reversed)
std::swap(cp1, cp2);

View file

@ -11,6 +11,7 @@
#include "../libslic3r.h"
#include "../BoundingBox.hpp"
#include "../Exception.hpp"
#include "../Utils.hpp"
namespace Slic3r {
@ -19,13 +20,14 @@ class ExPolygon;
class Surface;
enum InfillPattern : int;
namespace FillAdaptive_Internal {
namespace FillAdaptive {
struct Octree;
};
class InfillFailedException : public std::runtime_error {
// Infill shall never fail, therefore the error is classified as RuntimeError, not SlicingError.
class InfillFailedException : public Slic3r::RuntimeError {
public:
InfillFailedException() : std::runtime_error("Infill failed") {}
InfillFailedException() : Slic3r::RuntimeError("Infill failed") {}
};
struct FillParams
@ -74,9 +76,7 @@ public:
BoundingBox bounding_box;
// Octree builds on mesh for usage in the adaptive cubic infill
FillAdaptive_Internal::Octree* adapt_fill_octree = nullptr;
// Octree builds on mesh for usage in the support cubic infill
FillAdaptive_Internal::Octree* support_fill_octree = nullptr;
FillAdaptive::Octree* adapt_fill_octree = nullptr;
public:
virtual ~Fill() {}

View file

@ -53,7 +53,7 @@ static inline FlowRole opt_key_to_flow_role(const std::string &opt_key)
else if (opt_key == "support_material_extrusion_width")
return frSupportMaterial;
else
throw std::runtime_error("opt_key_to_flow_role: invalid argument");
throw Slic3r::RuntimeError("opt_key_to_flow_role: invalid argument");
};
static inline void throw_on_missing_variable(const std::string &opt_key, const char *dependent_opt_key)
@ -126,7 +126,7 @@ Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent
{
// we need layer height unless it's a bridge
if (height <= 0 && bridge_flow_ratio == 0)
throw std::invalid_argument("Invalid flow height supplied to new_from_config_width()");
throw Slic3r::InvalidArgument("Invalid flow height supplied to new_from_config_width()");
float w;
if (bridge_flow_ratio > 0) {
@ -151,7 +151,7 @@ Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height,
{
// we need layer height unless it's a bridge
if (height <= 0 && !bridge)
throw std::invalid_argument("Invalid flow height supplied to new_from_spacing()");
throw Slic3r::InvalidArgument("Invalid flow height supplied to new_from_spacing()");
// Calculate width from spacing.
// For normal extrusons, extrusion width is wider than the spacing due to the rounding and squishing of the extrusions.
// For bridge extrusions, the extrusions are placed with a tiny BRIDGE_EXTRA_SPACING gaps between the threads.

View file

@ -3,6 +3,7 @@
#include "libslic3r.h"
#include "Config.hpp"
#include "Exception.hpp"
#include "ExtrusionEntity.hpp"
namespace Slic3r {
@ -27,11 +28,11 @@ enum FlowRole {
frSupportMaterialInterface,
};
class FlowError : public std::invalid_argument
class FlowError : public Slic3r::InvalidArgument
{
public:
FlowError(const std::string& what_arg) : invalid_argument(what_arg) {}
FlowError(const char* what_arg) : invalid_argument(what_arg) {}
FlowError(const std::string& what_arg) : Slic3r::InvalidArgument(what_arg) {}
FlowError(const char* what_arg) : Slic3r::InvalidArgument(what_arg) {}
};
class FlowErrorNegativeSpacing : public FlowError

View file

@ -1,4 +1,5 @@
#include "../libslic3r.h"
#include "../Exception.hpp"
#include "../Model.hpp"
#include "../Utils.hpp"
#include "../GCode.hpp"
@ -123,11 +124,11 @@ const char* INVALID_OBJECT_TYPES[] =
"other"
};
class version_error : public std::runtime_error
class version_error : public Slic3r::FileIOError
{
public:
version_error(const std::string& what_arg) : std::runtime_error(what_arg) {}
version_error(const char* what_arg) : std::runtime_error(what_arg) {}
version_error(const std::string& what_arg) : Slic3r::FileIOError(what_arg) {}
version_error(const char* what_arg) : Slic3r::FileIOError(what_arg) {}
};
const char* get_attribute_value_charptr(const char** attributes, unsigned int attributes_size, const char* attribute_key)
@ -607,7 +608,7 @@ namespace Slic3r {
{
// ensure the zip archive is closed and rethrow the exception
close_zip_reader(&archive);
throw std::runtime_error(e.what());
throw Slic3r::FileIOError(e.what());
}
}
}
@ -780,7 +781,7 @@ namespace Slic3r {
{
char error_buf[1024];
::sprintf(error_buf, "Error (%s) while parsing '%s' at line %d", XML_ErrorString(XML_GetErrorCode(data->parser)), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser));
throw std::runtime_error(error_buf);
throw Slic3r::FileIOError(error_buf);
}
return n;
@ -789,7 +790,7 @@ namespace Slic3r {
catch (const version_error& e)
{
// rethrow the exception
throw std::runtime_error(e.what());
throw Slic3r::FileIOError(e.what());
}
catch (std::exception& e)
{
@ -2360,9 +2361,9 @@ namespace Slic3r {
continue;
if (!volume->mesh().repaired)
throw std::runtime_error("store_3mf() requires repair()");
throw Slic3r::FileIOError("store_3mf() requires repair()");
if (!volume->mesh().has_shared_vertices())
throw std::runtime_error("store_3mf() requires shared vertices");
throw Slic3r::FileIOError("store_3mf() requires shared vertices");
volumes_offsets.insert(VolumeToOffsetsMap::value_type(volume, Offsets(vertices_count))).first;

View file

@ -7,6 +7,7 @@
#include <boost/nowide/cstdio.hpp>
#include "../libslic3r.h"
#include "../Exception.hpp"
#include "../Model.hpp"
#include "../GCode.hpp"
#include "../PrintConfig.hpp"
@ -923,7 +924,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
{
char error_buf[1024];
::sprintf(error_buf, "Error (%s) while parsing '%s' at line %d", XML_ErrorString(XML_GetErrorCode(data->parser)), data->stat.m_filename, (int)XML_GetCurrentLineNumber(data->parser));
throw std::runtime_error(error_buf);
throw Slic3r::FileIOError(error_buf);
}
return n;
@ -948,9 +949,9 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi
if (check_version && (ctx.m_version > VERSION_AMF_COMPATIBLE))
{
// std::string msg = _(L("The selected amf file has been saved with a newer version of " + std::string(SLIC3R_APP_NAME) + " and is not compatible."));
// throw std::runtime_error(msg.c_str());
// throw Slic3r::FileIOError(msg.c_str());
const std::string msg = (boost::format(_(L("The selected amf file has been saved with a newer version of %1% and is not compatible."))) % std::string(SLIC3R_APP_NAME)).str();
throw std::runtime_error(msg);
throw Slic3r::FileIOError(msg);
}
return true;
@ -994,7 +995,7 @@ bool load_amf_archive(const char* path, DynamicPrintConfig* config, Model* model
{
// ensure the zip archive is closed and rethrow the exception
close_zip_reader(&archive);
throw std::runtime_error(e.what());
throw Slic3r::FileIOError(e.what());
}
break;
@ -1147,9 +1148,9 @@ bool store_amf(const char* path, Model* model, const DynamicPrintConfig* config,
for (ModelVolume *volume : object->volumes) {
vertices_offsets.push_back(num_vertices);
if (! volume->mesh().repaired)
throw std::runtime_error("store_amf() requires repair()");
throw Slic3r::FileIOError("store_amf() requires repair()");
if (! volume->mesh().has_shared_vertices())
throw std::runtime_error("store_amf() requires shared vertices");
throw Slic3r::FileIOError("store_amf() requires shared vertices");
const indexed_triangle_set &its = volume->mesh().its;
const Transform3d& matrix = volume->get_matrix();
for (size_t i = 0; i < its.vertices.size(); ++i) {

View file

@ -147,7 +147,7 @@ static void extract_model_from_archive(
}
}
if (! trafo_set)
throw std::runtime_error(std::string("Archive ") + path + " does not contain a valid entry in scene.xml for " + name);
throw Slic3r::FileIOError(std::string("Archive ") + path + " does not contain a valid entry in scene.xml for " + name);
// Extract the STL.
StlHeader header;
@ -266,7 +266,7 @@ static void extract_model_from_archive(
}
if (! mesh_valid)
throw std::runtime_error(std::string("Archive ") + path + " does not contain a valid mesh for " + name);
throw Slic3r::FileIOError(std::string("Archive ") + path + " does not contain a valid mesh for " + name);
// Add this mesh to the model.
ModelVolume *volume = nullptr;
@ -303,7 +303,7 @@ bool load_prus(const char *path, Model *model)
mz_bool res = MZ_FALSE;
try {
if (!open_zip_reader(&archive, path))
throw std::runtime_error(std::string("Unable to init zip reader for ") + path);
throw Slic3r::FileIOError(std::string("Unable to init zip reader for ") + path);
std::vector<char> scene_xml_data;
// For grouping multiple STLs into a single ModelObject for multi-material prints.
std::map<int, ModelObject*> group_to_model_object;
@ -316,10 +316,10 @@ bool load_prus(const char *path, Model *model)
buffer.assign((size_t)stat.m_uncomp_size, 0);
res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (char*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == MZ_FALSE)
std::runtime_error(std::string("Error while extracting a file from ") + path);
throw Slic3r::FileIOError(std::string("Error while extracting a file from ") + path);
if (strcmp(stat.m_filename, "scene.xml") == 0) {
if (! scene_xml_data.empty())
throw std::runtime_error(std::string("Multiple scene.xml were found in the archive.") + path);
throw Slic3r::FileIOError(std::string("Multiple scene.xml were found in the archive.") + path);
scene_xml_data = std::move(buffer);
} else if (boost::iends_with(stat.m_filename, ".stl")) {
// May throw std::exception

View file

@ -10,6 +10,7 @@
#include <sstream>
#include "libslic3r/Exception.hpp"
#include "libslic3r/SlicesToTriangleMesh.hpp"
#include "libslic3r/MarchingSquares.hpp"
#include "libslic3r/ClipperUtils.hpp"
@ -64,7 +65,7 @@ boost::property_tree::ptree read_ini(const mz_zip_archive_file_stat &entry,
if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename,
buf.data(), buf.size(), 0))
throw std::runtime_error(zip.get_errorstr());
throw Slic3r::FileIOError(zip.get_errorstr());
boost::property_tree::ptree tree;
std::stringstream ss(buf);
@ -80,7 +81,7 @@ PNGBuffer read_png(const mz_zip_archive_file_stat &entry,
if (!mz_zip_reader_extract_file_to_mem(&zip.arch, entry.m_filename,
buf.data(), buf.size(), 0))
throw std::runtime_error(zip.get_errorstr());
throw Slic3r::FileIOError(zip.get_errorstr());
return {std::move(buf), (name.empty() ? entry.m_filename : name)};
}
@ -94,7 +95,7 @@ ArchiveData extract_sla_archive(const std::string &zipfname,
struct Arch: public MZ_Archive {
Arch(const std::string &fname) {
if (!open_zip_reader(&arch, fname))
throw std::runtime_error(get_errorstr());
throw Slic3r::FileIOError(get_errorstr());
}
~Arch() { close_zip_reader(&arch); }
@ -202,7 +203,7 @@ RasterParams get_raster_params(const DynamicPrintConfig &cfg)
if (!opt_disp_cols || !opt_disp_rows || !opt_disp_w || !opt_disp_h ||
!opt_mirror_x || !opt_mirror_y || !opt_orient)
throw std::runtime_error("Invalid SL1 file");
throw Slic3r::FileIOError("Invalid SL1 file");
RasterParams rstp;
@ -228,7 +229,7 @@ SliceParams get_slice_params(const DynamicPrintConfig &cfg)
auto *opt_init_layerh = cfg.option<ConfigOptionFloat>("initial_layer_height");
if (!opt_layerh || !opt_init_layerh)
throw std::runtime_error("Invalid SL1 file");
throw Slic3r::FileIOError("Invalid SL1 file");
return SliceParams{opt_layerh->getFloat(), opt_init_layerh->getFloat()};
}

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,7 @@
#include "GCode/SpiralVase.hpp"
#include "GCode/ToolOrdering.hpp"
#include "GCode/WipeTower.hpp"
#include "GCode/SeamPlacer.hpp"
#if ENABLE_GCODE_VIEWER
#include "GCode/GCodeProcessor.hpp"
#else
@ -69,6 +70,7 @@ private:
std::unique_ptr<MotionPlanner> m_layer_mp;
};
class OozePrevention {
public:
bool enable;
@ -338,6 +340,9 @@ private:
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
std::string set_extruder(unsigned int extruder_id, double print_z);
// Cache for custom seam enforcers/blockers for each layer.
SeamPlacer m_seam_placer;
/* Origin of print coordinates expressed in unscaled G-code coordinates.
This affects the input arguments supplied to the extrude*() and travel_to()
methods. */
@ -376,7 +381,6 @@ private:
// Current layer processed. Insequential printing mode, only a single copy will be printed.
// In non-sequential mode, all its copies will be printed.
const Layer* m_layer;
std::map<const PrintObject*,Point> m_seam_position;
double m_volumetric_speed;
// Support for the extrusion role markers. Which marker is active?
ExtrusionRole m_last_extrusion_role;

View file

@ -319,13 +319,13 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
{
boost::nowide::ifstream in(filename);
if (!in.good())
throw std::runtime_error(std::string("Time estimator post process export failed.\nCannot open file for reading.\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for reading.\n"));
// temporary file to contain modified gcode
std::string out_path = filename + ".postprocess";
FILE* out = boost::nowide::fopen(out_path.c_str(), "wb");
if (out == nullptr)
throw std::runtime_error(std::string("Time estimator post process export failed.\nCannot open file for writing.\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for writing.\n"));
auto time_in_minutes = [](float time_in_seconds) {
return int(::roundf(time_in_seconds / 60.0f));
@ -418,7 +418,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
in.close();
fclose(out);
boost::nowide::remove(out_path.c_str());
throw std::runtime_error(std::string("Time estimator post process export failed.\nIs the disk full?\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nIs the disk full?\n"));
}
export_line.clear();
};
@ -426,7 +426,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
while (std::getline(in, gcode_line)) {
if (!in.good()) {
fclose(out);
throw std::runtime_error(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
}
gcode_line += "\n";
@ -460,7 +460,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
in.close();
if (rename_file(out_path, filename))
throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + out_path + " to " + filename + '\n' +
throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + filename + '\n' +
"Is " + out_path + " locked?" + '\n');
}

View file

@ -79,7 +79,7 @@ static DWORD execute_process_winapi(const std::wstring &command_line)
if (! ::CreateProcessW(
nullptr /* lpApplicationName */, (LPWSTR)command_line.c_str(), nullptr /* lpProcessAttributes */, nullptr /* lpThreadAttributes */, false /* bInheritHandles */,
CREATE_UNICODE_ENVIRONMENT /* | CREATE_NEW_CONSOLE */ /* dwCreationFlags */, (LPVOID)envstr.c_str(), nullptr /* lpCurrentDirectory */, &startup_info, &process_info))
throw std::runtime_error(std::string("Failed starting the script ") + boost::nowide::narrow(command_line) + ", Win32 error: " + std::to_string(int(::GetLastError())));
throw Slic3r::RuntimeError(std::string("Failed starting the script ") + boost::nowide::narrow(command_line) + ", Win32 error: " + std::to_string(int(::GetLastError())));
::WaitForSingleObject(process_info.hProcess, INFINITE);
ULONG rc = 0;
::GetExitCodeProcess(process_info.hProcess, &rc);
@ -98,13 +98,13 @@ static int run_script(const std::string &script, const std::string &gcode, std::
LPWSTR *szArglist = CommandLineToArgvW(boost::nowide::widen(script).c_str(), &nArgs);
if (szArglist == nullptr || nArgs <= 0) {
// CommandLineToArgvW failed. Maybe the command line escapment is invalid?
throw std::runtime_error(std::string("Post processing script ") + script + " on file " + gcode + " failed. CommandLineToArgvW() refused to parse the command line path.");
throw Slic3r::RuntimeError(std::string("Post processing script ") + script + " on file " + gcode + " failed. CommandLineToArgvW() refused to parse the command line path.");
}
std::wstring command_line;
std::wstring command = szArglist[0];
if (! boost::filesystem::exists(boost::filesystem::path(command)))
throw std::runtime_error(std::string("The configured post-processing script does not exist: ") + boost::nowide::narrow(command));
throw Slic3r::RuntimeError(std::string("The configured post-processing script does not exist: ") + boost::nowide::narrow(command));
if (boost::iends_with(command, L".pl")) {
// This is a perl script. Run it through the perl interpreter.
// The current process may be slic3r.exe or slic3r-console.exe.
@ -115,7 +115,7 @@ static int run_script(const std::string &script, const std::string &gcode, std::
boost::filesystem::path path_perl = path_exe.parent_path() / "perl" / "perl.exe";
if (! boost::filesystem::exists(path_perl)) {
LocalFree(szArglist);
throw std::runtime_error(std::string("Perl interpreter ") + path_perl.string() + " does not exist.");
throw Slic3r::RuntimeError(std::string("Perl interpreter ") + path_perl.string() + " does not exist.");
}
// Replace it with the current perl interpreter.
quote_argv_winapi(boost::nowide::widen(path_perl.string()), command_line);
@ -187,7 +187,7 @@ void run_post_process_scripts(const std::string &path, const PrintConfig &config
config.setenv_();
auto gcode_file = boost::filesystem::path(path);
if (! boost::filesystem::exists(gcode_file))
throw std::runtime_error(std::string("Post-processor can't find exported gcode file"));
throw Slic3r::RuntimeError(std::string("Post-processor can't find exported gcode file"));
for (const std::string &scripts : config.post_process.values) {
std::vector<std::string> lines;
@ -205,7 +205,7 @@ void run_post_process_scripts(const std::string &path, const PrintConfig &config
const std::string msg = std_err.empty() ? (boost::format("Post-processing script %1% on file %2% failed.\nError code: %3%") % script % path % result).str()
: (boost::format("Post-processing script %1% on file %2% failed.\nError code: %3%\nOutput:\n%4%") % script % path % result % std_err).str();
BOOST_LOG_TRIVIAL(error) << msg;
throw std::runtime_error(msg);
throw Slic3r::RuntimeError(msg);
}
}
}

View file

@ -148,7 +148,7 @@ static inline int parse_int(const char *&line)
char *endptr = NULL;
long result = strtol(line, &endptr, 10);
if (endptr == NULL || !is_ws_or_eol(*endptr))
throw std::runtime_error("PressureEqualizer: Error parsing an int");
throw Slic3r::RuntimeError("PressureEqualizer: Error parsing an int");
line = endptr;
return int(result);
};
@ -160,7 +160,7 @@ static inline float parse_float(const char *&line)
char *endptr = NULL;
float result = strtof(line, &endptr);
if (endptr == NULL || !is_ws_or_eol(*endptr))
throw std::runtime_error("PressureEqualizer: Error parsing a float");
throw Slic3r::RuntimeError("PressureEqualizer: Error parsing a float");
line = endptr;
return result;
};
@ -229,7 +229,7 @@ bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLi
assert(false);
}
if (i == -1)
throw std::runtime_error(std::string("GCode::PressureEqualizer: Invalid axis for G0/G1: ") + axis);
throw Slic3r::RuntimeError(std::string("GCode::PressureEqualizer: Invalid axis for G0/G1: ") + axis);
buf.pos_provided[i] = true;
new_pos[i] = parse_float(line);
if (i == 3 && m_config->use_relative_e_distances.value)
@ -298,7 +298,7 @@ bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLi
set = true;
break;
default:
throw std::runtime_error(std::string("GCode::PressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
throw Slic3r::RuntimeError(std::string("GCode::PressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
}
eatws(line);
}

View file

@ -94,7 +94,7 @@ static BoundingBoxf extrusionentity_extents(const ExtrusionEntity *extrusion_ent
auto *extrusion_entity_collection = dynamic_cast<const ExtrusionEntityCollection*>(extrusion_entity);
if (extrusion_entity_collection != nullptr)
return extrusionentity_extents(*extrusion_entity_collection);
throw std::runtime_error("Unexpected extrusion_entity type in extrusionentity_extents()");
throw Slic3r::RuntimeError("Unexpected extrusion_entity type in extrusionentity_extents()");
return BoundingBoxf();
}

View file

@ -0,0 +1,672 @@
#include "SeamPlacer.hpp"
#include "libslic3r/ExtrusionEntity.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/BoundingBox.hpp"
#include "libslic3r/EdgeGrid.hpp"
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/SVG.hpp"
namespace Slic3r {
// This penalty is added to all points inside custom blockers (subtracted from pts inside enforcers).
static constexpr float ENFORCER_BLOCKER_PENALTY = 100;
// In case there are custom enforcers/blockers, the loop polygon shall always have
// sides smaller than this (so it isn't limited to original resolution).
static constexpr float MINIMAL_POLYGON_SIDE = scale_(0.2f);
// When spAligned is active and there is a support enforcer,
// add this penalty to its center.
static constexpr float ENFORCER_CENTER_PENALTY = -10.f;
static float extrudate_overlap_penalty(float nozzle_r, float weight_zero, float overlap_distance)
{
// The extrudate is not fully supported by the lower layer. Fit a polynomial penalty curve.
// Solved by sympy package:
/*
from sympy import *
(x,a,b,c,d,r,z)=symbols('x a b c d r z')
p = a + b*x + c*x*x + d*x*x*x
p2 = p.subs(solve([p.subs(x, -r), p.diff(x).subs(x, -r), p.diff(x,x).subs(x, -r), p.subs(x, 0)-z], [a, b, c, d]))
from sympy.plotting import plot
plot(p2.subs(r,0.2).subs(z,1.), (x, -1, 3), adaptive=False, nb_of_points=400)
*/
if (overlap_distance < - nozzle_r) {
// The extrudate is fully supported by the lower layer. This is the ideal case, therefore zero penalty.
return 0.f;
} else {
float x = overlap_distance / nozzle_r;
float x2 = x * x;
float x3 = x2 * x;
return weight_zero * (1.f + 3.f * x + 3.f * x2 + x3);
}
}
// Return a value in <0, 1> of a cubic B-spline kernel centered around zero.
// The B-spline is re-scaled so it has value 1 at zero.
static inline float bspline_kernel(float x)
{
x = std::abs(x);
if (x < 1.f) {
return 1.f - (3.f / 2.f) * x * x + (3.f / 4.f) * x * x * x;
}
else if (x < 2.f) {
x -= 1.f;
float x2 = x * x;
float x3 = x2 * x;
return (1.f / 4.f) - (3.f / 4.f) * x + (3.f / 4.f) * x2 - (1.f / 4.f) * x3;
}
else
return 0;
}
static Points::const_iterator project_point_to_polygon_and_insert(Polygon &polygon, const Point &pt, double eps)
{
assert(polygon.points.size() >= 2);
if (polygon.points.size() <= 1)
if (polygon.points.size() == 1)
return polygon.points.begin();
Point pt_min;
double d_min = std::numeric_limits<double>::max();
size_t i_min = size_t(-1);
for (size_t i = 0; i < polygon.points.size(); ++ i) {
size_t j = i + 1;
if (j == polygon.points.size())
j = 0;
const Point &p1 = polygon.points[i];
const Point &p2 = polygon.points[j];
const Slic3r::Point v_seg = p2 - p1;
const Slic3r::Point v_pt = pt - p1;
const int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
if (t_pt < 0) {
// Closest to p1.
double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
if (dabs < d_min) {
d_min = dabs;
i_min = i;
pt_min = p1;
}
}
else if (t_pt > l2_seg) {
// Closest to p2. Then p2 is the starting point of another segment, which shall be discovered in the next step.
continue;
} else {
// Closest to the segment.
assert(t_pt >= 0 && t_pt <= l2_seg);
int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
double d = double(d_seg) / sqrt(double(l2_seg));
double dabs = std::abs(d);
if (dabs < d_min) {
d_min = dabs;
i_min = i;
// Evaluate the foot point.
pt_min = p1;
double linv = double(d_seg) / double(l2_seg);
pt_min(0) = pt(0) - coord_t(floor(double(v_seg(1)) * linv + 0.5));
pt_min(1) = pt(1) + coord_t(floor(double(v_seg(0)) * linv + 0.5));
assert(Line(p1, p2).distance_to(pt_min) < scale_(1e-5));
}
}
}
assert(i_min != size_t(-1));
if ((pt_min - polygon.points[i_min]).cast<double>().norm() > eps) {
// Insert a new point on the segment i_min, i_min+1.
return polygon.points.insert(polygon.points.begin() + (i_min + 1), pt_min);
}
return polygon.points.begin() + i_min;
}
static std::vector<float> polygon_angles_at_vertices(const Polygon &polygon, const std::vector<float> &lengths, float min_arm_length)
{
assert(polygon.points.size() + 1 == lengths.size());
if (min_arm_length > 0.25f * lengths.back())
min_arm_length = 0.25f * lengths.back();
// Find the initial prev / next point span.
size_t idx_prev = polygon.points.size();
size_t idx_curr = 0;
size_t idx_next = 1;
while (idx_prev > idx_curr && lengths.back() - lengths[idx_prev] < min_arm_length)
-- idx_prev;
while (idx_next < idx_prev && lengths[idx_next] < min_arm_length)
++ idx_next;
std::vector<float> angles(polygon.points.size(), 0.f);
for (; idx_curr < polygon.points.size(); ++ idx_curr) {
// Move idx_prev up until the distance between idx_prev and idx_curr is lower than min_arm_length.
if (idx_prev >= idx_curr) {
while (idx_prev < polygon.points.size() && lengths.back() - lengths[idx_prev] + lengths[idx_curr] > min_arm_length)
++ idx_prev;
if (idx_prev == polygon.points.size())
idx_prev = 0;
}
while (idx_prev < idx_curr && lengths[idx_curr] - lengths[idx_prev] > min_arm_length)
++ idx_prev;
// Move idx_prev one step back.
if (idx_prev == 0)
idx_prev = polygon.points.size() - 1;
else
-- idx_prev;
// Move idx_next up until the distance between idx_curr and idx_next is greater than min_arm_length.
if (idx_curr <= idx_next) {
while (idx_next < polygon.points.size() && lengths[idx_next] - lengths[idx_curr] < min_arm_length)
++ idx_next;
if (idx_next == polygon.points.size())
idx_next = 0;
}
while (idx_next < idx_curr && lengths.back() - lengths[idx_curr] + lengths[idx_next] < min_arm_length)
++ idx_next;
// Calculate angle between idx_prev, idx_curr, idx_next.
const Point &p0 = polygon.points[idx_prev];
const Point &p1 = polygon.points[idx_curr];
const Point &p2 = polygon.points[idx_next];
const Point v1 = p1 - p0;
const Point v2 = p2 - p1;
int64_t dot = int64_t(v1(0))*int64_t(v2(0)) + int64_t(v1(1))*int64_t(v2(1));
int64_t cross = int64_t(v1(0))*int64_t(v2(1)) - int64_t(v1(1))*int64_t(v2(0));
float angle = float(atan2(double(cross), double(dot)));
angles[idx_curr] = angle;
}
return angles;
}
void SeamPlacer::init(const Print& print)
{
m_enforcers.clear();
m_blockers.clear();
//m_last_seam_position.clear();
m_seam_history.clear();
for (const PrintObject* po : print.objects()) {
po->project_and_append_custom_facets(true, EnforcerBlockerType::ENFORCER, m_enforcers);
po->project_and_append_custom_facets(true, EnforcerBlockerType::BLOCKER, m_blockers);
}
const std::vector<double>& nozzle_dmrs = print.config().nozzle_diameter.values;
float max_nozzle_dmr = *std::max_element(nozzle_dmrs.begin(), nozzle_dmrs.end());
for (ExPolygons& explgs : m_enforcers)
explgs = Slic3r::offset_ex(explgs, scale_(max_nozzle_dmr));
for (ExPolygons& explgs : m_blockers)
explgs = Slic3r::offset_ex(explgs, scale_(max_nozzle_dmr));
}
Point SeamPlacer::get_seam(const size_t layer_idx, const SeamPosition seam_position,
const ExtrusionLoop& loop, Point last_pos, coordf_t nozzle_dmr,
const PrintObject* po, bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid)
{
Polygon polygon = loop.polygon();
BoundingBox polygon_bb = polygon.bounding_box();
const coord_t nozzle_r = coord_t(scale_(0.5 * nozzle_dmr) + 0.5);
if (this->is_custom_seam_on_layer(layer_idx)) {
// Seam enf/blockers can begin and end in between the original vertices.
// Let add extra points in between and update the leghths.
polygon.densify(MINIMAL_POLYGON_SIDE);
}
if (seam_position != spRandom) {
// Retrieve the last start position for this object.
float last_pos_weight = 1.f;
if (seam_position == spAligned) {
// Seam is aligned to the seam at the preceding layer.
if (po != nullptr) {
std::optional<Point> pos = m_seam_history.get_last_seam(po, layer_idx, polygon_bb);
if (pos.has_value()) {
//last_pos = m_last_seam_position[po];
last_pos = *pos;
last_pos_weight = is_custom_enforcer_on_layer(layer_idx) ? 0.f : 1.f;
}
}
}
else if (seam_position == spRear) {
// Object is centered around (0,0) in its current coordinate system.
last_pos.x() = 0;
last_pos.y() += coord_t(3. * po->bounding_box().radius());
last_pos_weight = 5.f;
} if (seam_position == spNearest) {
// last_pos already contains current nozzle position
}
// Insert a projection of last_pos into the polygon.
size_t last_pos_proj_idx;
{
auto it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r);
last_pos_proj_idx = it - polygon.points.begin();
}
// Parametrize the polygon by its length.
std::vector<float> lengths = polygon.parameter_by_length();
// For each polygon point, store a penalty.
// First calculate the angles, store them as penalties. The angles are caluculated over a minimum arm length of nozzle_r.
std::vector<float> penalties = polygon_angles_at_vertices(polygon, lengths, float(nozzle_r));
// No penalty for reflex points, slight penalty for convex points, high penalty for flat surfaces.
const float penaltyConvexVertex = 1.f;
const float penaltyFlatSurface = 5.f;
const float penaltyOverhangHalf = 10.f;
// Penalty for visible seams.
for (size_t i = 0; i < polygon.points.size(); ++ i) {
float ccwAngle = penalties[i];
if (was_clockwise)
ccwAngle = - ccwAngle;
float penalty = 0;
if (ccwAngle <- float(0.6 * PI))
// Sharp reflex vertex. We love that, it hides the seam perfectly.
penalty = 0.f;
else if (ccwAngle > float(0.6 * PI))
// Seams on sharp convex vertices are more visible than on reflex vertices.
penalty = penaltyConvexVertex;
else if (ccwAngle < 0.f) {
// Interpolate penalty between maximum and zero.
penalty = penaltyFlatSurface * bspline_kernel(ccwAngle * float(PI * 2. / 3.));
} else {
assert(ccwAngle >= 0.f);
// Interpolate penalty between maximum and the penalty for a convex vertex.
penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle * float(PI * 2. / 3.));
}
// Give a negative penalty for points close to the last point or the prefered seam location.
float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
float dist_max = 0.1f * lengths.back(); // 5.f * nozzle_dmr
penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
penalties[i] = std::max(0.f, penalty);
}
// Penalty for overhangs.
if (lower_layer_edge_grid) {
// Use the edge grid distance field structure over the lower layer to calculate overhangs.
coord_t nozzle_r = coord_t(std::floor(scale_(0.5 * nozzle_dmr) + 0.5));
coord_t search_r = coord_t(std::floor(scale_(0.8 * nozzle_dmr) + 0.5));
for (size_t i = 0; i < polygon.points.size(); ++ i) {
const Point &p = polygon.points[i];
coordf_t dist;
// Signed distance is positive outside the object, negative inside the object.
// The point is considered at an overhang, if it is more than nozzle radius
// outside of the lower layer contour.
[[maybe_unused]] bool found = lower_layer_edge_grid->signed_distance(p, search_r, dist);
// If the approximate Signed Distance Field was initialized over lower_layer_edge_grid,
// then the signed distnace shall always be known.
assert(found);
penalties[i] += extrudate_overlap_penalty(float(nozzle_r), penaltyOverhangHalf, float(dist));
}
}
// Custom seam. Huge (negative) constant penalty is applied inside
// blockers (enforcers) to rule out points that should not win.
this->apply_custom_seam(polygon, penalties, lengths, layer_idx, seam_position);
// Find a point with a minimum penalty.
size_t idx_min = std::min_element(penalties.begin(), penalties.end()) - penalties.begin();
if (seam_position != spAligned || ! is_custom_enforcer_on_layer(layer_idx)) {
// Very likely the weight of idx_min is very close to the weight of last_pos_proj_idx.
// In that case use last_pos_proj_idx instead.
float penalty_aligned = penalties[last_pos_proj_idx];
float penalty_min = penalties[idx_min];
float penalty_diff_abs = std::abs(penalty_min - penalty_aligned);
float penalty_max = std::max(penalty_min, penalty_aligned);
float penalty_diff_rel = (penalty_max == 0.f) ? 0.f : penalty_diff_abs / penalty_max;
// printf("Align seams, penalty aligned: %f, min: %f, diff abs: %f, diff rel: %f\n", penalty_aligned, penalty_min, penalty_diff_abs, penalty_diff_rel);
if (std::abs(penalty_diff_rel) < 0.05) {
// Penalty of the aligned point is very close to the minimum penalty.
// Align the seams as accurately as possible.
idx_min = last_pos_proj_idx;
}
}
if (seam_position == spAligned && loop.role() == erExternalPerimeter)
m_seam_history.add_seam(po, polygon.points[idx_min], polygon_bb);
// Export the contour into a SVG file.
#if 0
{
static int iRun = 0;
SVG svg(debug_out_path("GCode_extrude_loop-%d.svg", iRun ++));
if (m_layer->lower_layer != NULL)
svg.draw(m_layer->lower_layer->slices);
for (size_t i = 0; i < loop.paths.size(); ++ i)
svg.draw(loop.paths[i].as_polyline(), "red");
Polylines polylines;
for (size_t i = 0; i < loop.paths.size(); ++ i)
polylines.push_back(loop.paths[i].as_polyline());
Slic3r::Polygons polygons;
coordf_t nozzle_dmr = EXTRUDER_CONFIG(nozzle_diameter);
coord_t delta = scale_(0.5*nozzle_dmr);
Slic3r::offset(polylines, &polygons, delta);
// for (size_t i = 0; i < polygons.size(); ++ i) svg.draw((Polyline)polygons[i], "blue");
svg.draw(last_pos, "green", 3);
svg.draw(polygon.points[idx_min], "yellow", 3);
svg.Close();
}
#endif
return polygon.points[idx_min];
} else { // spRandom
if (loop.loop_role() == elrContourInternalPerimeter && loop.role() != erExternalPerimeter) {
// This loop does not contain any other loop. Set a random position.
// The other loops will get a seam close to the random point chosen
// on the innermost contour.
//FIXME This works correctly for inner contours first only.
last_pos = this->get_random_seam(layer_idx, polygon);
}
if (loop.role() == erExternalPerimeter && is_custom_seam_on_layer(layer_idx)) {
// There is a possibility that the loop will be influenced by custom
// seam enforcer/blocker. In this case do not inherit the seam
// from internal loops (which may conflict with the custom selection
// and generate another random one.
bool saw_custom = false;
Point candidate = this->get_random_seam(layer_idx, polygon, &saw_custom);
if (saw_custom)
last_pos = candidate;
}
return last_pos;
}
}
Point SeamPlacer::get_random_seam(size_t layer_idx, const Polygon& polygon,
bool* saw_custom) const
{
// Parametrize the polygon by its length.
std::vector<float> lengths = polygon.parameter_by_length();
// Which of the points are inside enforcers/blockers?
std::vector<size_t> enforcers_idxs;
std::vector<size_t> blockers_idxs;
this->get_enforcers_and_blockers(layer_idx, polygon, enforcers_idxs, blockers_idxs);
bool has_enforcers = ! enforcers_idxs.empty();
bool has_blockers = ! blockers_idxs.empty();
if (saw_custom)
*saw_custom = has_enforcers || has_blockers;
// FIXME FIXME FIXME: This is just to test the outcome and whether it is
// reasonable. The algorithm should really sum the length of all available
// pieces, get a random length and find the respective point.
float rand_len = 0.f;
size_t pt_idx = 0;
do {
rand_len = lengths.back() * (rand()/float(RAND_MAX));
auto it = std::lower_bound(lengths.begin(), lengths.end(), rand_len);
pt_idx = it == lengths.end() ? 0 : (it-lengths.begin()-1);
// If there are blockers and the point is inside, repeat.
// If there are enforcers and the point is NOT inside, repeat.
} while ((has_blockers && std::binary_search(blockers_idxs.begin(), blockers_idxs.end(), pt_idx))
|| (has_enforcers && ! std::binary_search(enforcers_idxs.begin(), enforcers_idxs.end(), pt_idx)));
if (! has_enforcers && ! has_blockers) {
// The polygon may be too coarse, calculate the point exactly.
bool last_seg = pt_idx == polygon.points.size()-1;
size_t next_idx = last_seg ? 0 : pt_idx+1;
const Point& prev = polygon.points[pt_idx];
const Point& next = polygon.points[next_idx];
assert(next_idx == 0 || pt_idx+1 == next_idx);
coordf_t diff_x = next.x() - prev.x();
coordf_t diff_y = next.y() - prev.y();
coordf_t dist = lengths[last_seg ? pt_idx+1 : next_idx] - lengths[pt_idx];
return Point(prev.x() + (rand_len - lengths[pt_idx]) * (diff_x/dist),
prev.y() + (rand_len - lengths[pt_idx]) * (diff_y/dist));
} else {
// The polygon should be dense enough.
return polygon.points[pt_idx];
}
}
void SeamPlacer::get_enforcers_and_blockers(size_t layer_id,
const Polygon& polygon,
std::vector<size_t>& enforcers_idxs,
std::vector<size_t>& blockers_idxs) const
{
enforcers_idxs.clear();
blockers_idxs.clear();
// FIXME: This is quadratic and it should be improved, maybe by building
// an AABB tree (or at least utilize bounding boxes).
for (size_t i=0; i<polygon.points.size(); ++i) {
if (! m_enforcers.empty()) {
assert(layer_id < m_enforcers.size());
for (const ExPolygon& explg : m_enforcers[layer_id]) {
if (explg.contains(polygon.points[i]))
enforcers_idxs.push_back(i);
}
}
if (! m_blockers.empty()) {
assert(layer_id < m_blockers.size());
for (const ExPolygon& explg : m_blockers[layer_id]) {
if (explg.contains(polygon.points[i]))
blockers_idxs.push_back(i);
}
}
}
}
// Go through the polygon, identify points inside support enforcers and return
// indices of points in the middle of each enforcer (measured along the contour).
static std::vector<size_t> find_enforcer_centers(const Polygon& polygon,
const std::vector<float>& lengths,
const std::vector<size_t>& enforcers_idxs)
{
std::vector<size_t> out;
assert(polygon.points.size()+1 == lengths.size());
assert(std::is_sorted(enforcers_idxs.begin(), enforcers_idxs.end()));
if (polygon.size() < 2 || enforcers_idxs.empty())
return out;
auto get_center_idx = [&polygon, &lengths](size_t start_idx, size_t end_idx) -> size_t {
assert(end_idx >= start_idx);
if (start_idx == end_idx)
return start_idx;
float t_c = lengths[start_idx] + 0.5f * (lengths[end_idx] - lengths[start_idx]);
auto it = std::lower_bound(lengths.begin() + start_idx, lengths.begin() + end_idx, t_c);
int ret = it - lengths.begin();
return ret;
};
int last_enforcer_start_idx = enforcers_idxs.front();
bool first_pt_in_list = enforcers_idxs.front() != 0;
bool last_pt_in_list = enforcers_idxs.back() == polygon.points.size() - 1;
bool wrap_around = last_pt_in_list && first_pt_in_list;
for (size_t i=0; i<enforcers_idxs.size(); ++i) {
if (i != enforcers_idxs.size() - 1) {
if (enforcers_idxs[i+1] != enforcers_idxs[i] + 1) {
// i is last point of current enforcer
out.push_back(get_center_idx(last_enforcer_start_idx, enforcers_idxs[i]));
last_enforcer_start_idx = enforcers_idxs[i+1];
}
} else {
if (! wrap_around) {
// we can safely use the last enforcer point.
out.push_back(get_center_idx(last_enforcer_start_idx, enforcers_idxs[i]));
}
}
}
if (wrap_around) {
// Update first center already found.
if (out.empty()) {
// Probably an enforcer around the whole contour. Return nothing.
return out;
}
// find last point of the enforcer at the beginning:
size_t idx = 0;
while (enforcers_idxs[idx]+1 == enforcers_idxs[idx+1])
++idx;
float t_s = lengths[last_enforcer_start_idx];
float t_e = lengths[idx];
float half_dist = 0.5f * (t_e + lengths.back() - t_s);
float t_c = (half_dist > t_e) ? t_s + half_dist : t_e - half_dist;
auto it = std::lower_bound(lengths.begin(), lengths.end(), t_c);
out[0] = it - lengths.begin();
if (out[0] == lengths.size() - 1)
--out[0];
assert(out[0] < lengths.size() - 1);
}
return out;
}
void SeamPlacer::apply_custom_seam(const Polygon& polygon,
std::vector<float>& penalties,
const std::vector<float>& lengths,
int layer_id, SeamPosition seam_position) const
{
if (! is_custom_seam_on_layer(layer_id))
return;
std::vector<size_t> enforcers_idxs;
std::vector<size_t> blockers_idxs;
this->get_enforcers_and_blockers(layer_id, polygon, enforcers_idxs, blockers_idxs);
for (size_t i : enforcers_idxs) {
assert(i < penalties.size());
penalties[i] -= float(ENFORCER_BLOCKER_PENALTY);
}
for (size_t i : blockers_idxs) {
assert(i < penalties.size());
penalties[i] += float(ENFORCER_BLOCKER_PENALTY);
}
if (seam_position == spAligned) {
std::vector<size_t> enf_centers = find_enforcer_centers(polygon, lengths, enforcers_idxs);
for (size_t idx : enf_centers) {
assert(idx < penalties.size());
penalties[idx] += ENFORCER_CENTER_PENALTY;
}
}
////////////////////////
// std::ostringstream os;
// os << std::setw(3) << std::setfill('0') << layer_id;
// int a = scale_(20.);
// SVG svg("custom_seam" + os.str() + ".svg", BoundingBox(Point(-a, -a), Point(a, a)));
// /*if (! m_enforcers.empty())
// svg.draw(m_enforcers[layer_id], "blue");
// if (! m_blockers.empty())
// svg.draw(m_blockers[layer_id], "red");*/
// size_t min_idx = std::min_element(penalties.begin(), penalties.end()) - penalties.begin();
// //svg.draw(polygon.points[idx_min], "red", 6e5);
// for (size_t i=0; i<polygon.points.size(); ++i) {
// std::string fill;
// coord_t size = 0;
// if (min_idx == i) {
// fill = "yellow";
// size = 5e5;
// } else {
// fill = (std::find(enforcers_idxs.begin(), enforcers_idxs.end(), i) != enforcers_idxs.end() ? "green" : "black");
// if (std::find(enf_centers.begin(), enf_centers.end(), i) != enf_centers.end()) {
// size = 5e5;
// fill = "blue";
// }
// }
// if (i != 0)
// svg.draw(polygon.points[i], fill, size);
// else
// svg.draw(polygon.points[i], "red", 5e5);
// }
//////////////////////
}
std::optional<Point> SeamHistory::get_last_seam(const PrintObject* po, size_t layer_id, const BoundingBox& island_bb)
{
assert(layer_id >= m_layer_id);
if (layer_id > m_layer_id) {
// Get seam was called for different layer than last time.
m_data_last_layer = m_data_this_layer;
m_data_this_layer.clear();
m_layer_id = layer_id;
}
std::optional<Point> out;
auto seams_it = m_data_last_layer.find(po);
if (seams_it == m_data_last_layer.end())
return out;
const std::vector<SeamPoint>& seam_data_po = seams_it->second;
// Find a bounding-box on the last layer that is close to one we see now.
double min_score = std::numeric_limits<double>::max();
for (const SeamPoint& sp : seam_data_po) {
const BoundingBox& bb = sp.m_island_bb;
if (! bb.overlap(island_bb)) {
// This bb does not even overlap. It is likely unrelated.
continue;
}
double score = std::pow(bb.min(0) - island_bb.min(0), 2.)
+ std::pow(bb.min(1) - island_bb.min(1), 2.)
+ std::pow(bb.max(0) - island_bb.max(0), 2.)
+ std::pow(bb.max(1) - island_bb.max(1), 2.);
if (score < min_score) {
min_score = score;
out = sp.m_pos;
}
}
return out;
}
void SeamHistory::add_seam(const PrintObject* po, const Point& pos, const BoundingBox& island_bb)
{
m_data_this_layer[po].push_back({pos, island_bb});;
}
void SeamHistory::clear()
{
m_layer_id = 0;
m_data_last_layer.clear();
m_data_this_layer.clear();
}
}

View file

@ -0,0 +1,89 @@
#ifndef libslic3r_SeamPlacer_hpp_
#define libslic3r_SeamPlacer_hpp_
#include <optional>
#include "libslic3r/ExPolygon.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/BoundingBox.hpp"
namespace Slic3r {
class PrintObject;
class ExtrusionLoop;
class Print;
namespace EdgeGrid { class Grid; }
class SeamHistory {
public:
SeamHistory() { clear(); }
std::optional<Point> get_last_seam(const PrintObject* po, size_t layer_id, const BoundingBox& island_bb);
void add_seam(const PrintObject* po, const Point& pos, const BoundingBox& island_bb);
void clear();
private:
struct SeamPoint {
Point m_pos;
BoundingBox m_island_bb;
};
std::map<const PrintObject*, std::vector<SeamPoint>> m_data_last_layer;
std::map<const PrintObject*, std::vector<SeamPoint>> m_data_this_layer;
size_t m_layer_id;
};
class SeamPlacer {
public:
void init(const Print& print);
Point get_seam(const size_t layer_idx, const SeamPosition seam_position,
const ExtrusionLoop& loop, Point last_pos,
coordf_t nozzle_diameter, const PrintObject* po,
bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid);
private:
std::vector<ExPolygons> m_enforcers;
std::vector<ExPolygons> m_blockers;
//std::map<const PrintObject*, Point> m_last_seam_position;
SeamHistory m_seam_history;
// Get indices of points inside enforcers and blockers.
void get_enforcers_and_blockers(size_t layer_id,
const Polygon& polygon,
std::vector<size_t>& enforcers_idxs,
std::vector<size_t>& blockers_idxs) const;
// Apply penalties to points inside enforcers/blockers.
void apply_custom_seam(const Polygon& polygon,
std::vector<float>& penalties,
const std::vector<float>& lengths,
int layer_id, SeamPosition seam_position) const;
// Return random point of a polygon. The distribution will be uniform
// along the contour and account for enforcers and blockers.
Point get_random_seam(size_t layer_idx, const Polygon& polygon,
bool* saw_custom = nullptr) const;
// Is there any enforcer/blocker on this layer?
bool is_custom_seam_on_layer(size_t layer_id) const {
return is_custom_enforcer_on_layer(layer_id)
|| is_custom_blocker_on_layer(layer_id);
}
bool is_custom_enforcer_on_layer(size_t layer_id) const {
return (! m_enforcers.empty() && ! m_enforcers[layer_id].empty());
}
bool is_custom_blocker_on_layer(size_t layer_id) const {
return (! m_blockers.empty() && ! m_blockers[layer_id].empty());
}
};
}
#endif // libslic3r_SeamPlacer_hpp_

View file

@ -1,22 +1,6 @@
/*
TODO LIST
---------
1. cooling moves - DONE
2. account for perimeter and finish_layer extrusions and subtract it from last wipe - DONE
3. priming extrusions (last wipe must clear the color) - DONE
4. Peter's wipe tower - layer's are not exactly square
5. Peter's wipe tower - variable width for higher levels
6. Peter's wipe tower - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer)
7. Peter's wipe tower - enable enhanced first layer adhesion
*/
#include "WipeTower.hpp"
#include <assert.h>
#include <math.h>
#include <cassert>
#include <iostream>
#include <vector>
#include <numeric>
@ -28,13 +12,16 @@ TODO LIST
#endif // ENABLE_GCODE_VIEWER
#include "BoundingBox.hpp"
#if defined(__linux) || defined(__GNUC__ )
#include <strings.h>
#endif /* __linux */
#ifdef _MSC_VER
#define strcasecmp _stricmp
#endif
// Experimental "Peter's wipe tower" feature was partially implemented, inspired by
// PJR's idea of alternating two perpendicular wiping directions on a square tower.
// It is probably never going to be finished, there are multiple remaining issues
// and there is probably no need to go down this way. m_peters_wipe_tower variable
// turns this on, maybe it should just be removed. Anyway, the issues are
// - layer's are not exactly square
// - variable width for higher levels
// - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer)
// - enable enhanced first layer adhesion
namespace Slic3r
@ -441,9 +428,26 @@ public:
WipeTowerWriter& append(const std::string& text) { m_gcode += text; return *this; }
std::vector<Vec2f> wipe_path() const
{
return m_wipe_path;
}
WipeTowerWriter& add_wipe_point(const Vec2f& pt)
{
m_wipe_path.push_back(rotate(pt));
return *this;
}
WipeTowerWriter& add_wipe_point(float x, float y)
{
return add_wipe_point(Vec2f(x, y));
}
private:
Vec2f m_start_pos;
Vec2f m_current_pos;
std::vector<Vec2f> m_wipe_path;
float m_current_z;
float m_current_feedrate;
size_t m_current_tool;
@ -713,7 +717,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
return results;
}
WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_layer)
WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool)
{
if ( m_print_brim )
return toolchange_Brim();
@ -790,7 +794,9 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_lay
else {
writer.rectangle(Vec2f::Zero(), m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
if (layer_finished()) { // no finish_layer will be called, we must wipe the nozzle
writer.travel(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
}
}
}
@ -820,6 +826,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_lay
result.extrusions = writer.extrusions();
result.start_pos = writer.start_pos_rotated();
result.end_pos = writer.pos_rotated();
result.wipe_path = writer.wipe_path();
return result;
}
@ -853,13 +860,15 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
for (size_t i = 0; i < 4; ++ i) {
box.expand(spacing);
writer.travel (box.ld, 7000)
.extrude(box.lu, 2100).extrude(box.ru)
.extrude(box.rd ).extrude(box.ld);
.extrude(box.lu, 2100).extrude(box.ru)
.extrude(box.rd ).extrude(box.ld);
}
writer.travel(wipeTower_box.ld, 7000); // Move to the front left corner.
writer.travel(wipeTower_box.rd) // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower.
.travel(wipeTower_box.ld);
box.expand(-spacing);
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(box.ld)
.add_wipe_point(box.rd);
writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n"
";-----------------------------------\n");
@ -884,6 +893,7 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
result.extrusions = writer.extrusions();
result.start_pos = writer.start_pos_rotated();
result.end_pos = writer.pos_rotated();
result.wipe_path = writer.wipe_path();
return result;
}
@ -927,13 +937,6 @@ void WipeTower::toolchange_Unload(
else
sparse_beginning_y += (m_layer_info-1)->toolchanges_depth() + m_perimeter_width;
//debugging:
/* float oldx = writer.x();
float oldy = writer.y();
writer.travel(xr,sparse_beginning_y);
writer.extrude(xr+5,writer.y());
writer.travel(oldx,oldy);*/
float sum_of_depths = 0.f;
for (const auto& tch : m_layer_info->tool_changes) { // let's find this toolchange
if (tch.old_tool == m_current_tool) {
@ -941,13 +944,6 @@ void WipeTower::toolchange_Unload(
float ramming_end_y = sum_of_depths;
ramming_end_y -= (y_step/m_extra_spacing-m_perimeter_width) / 2.f; // center of final ramming line
// debugging:
/*float oldx = writer.x();
float oldy = writer.y();
writer.travel(xl,ramming_end_y);
writer.extrude(xl-15,writer.y());
writer.travel(oldx,oldy);*/
if ( (m_current_shape == SHAPE_REVERSED && ramming_end_y < sparse_beginning_y - 0.5f*m_perimeter_width ) ||
(m_current_shape == SHAPE_NORMAL && ramming_end_y > sparse_beginning_y + 0.5f*m_perimeter_width ) )
{
@ -998,12 +994,6 @@ void WipeTower::toolchange_Unload(
.retract(0.70f * total_retraction_distance, 1.0f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(0.20f * total_retraction_distance, 0.5f * m_filpar[m_current_tool].unloading_speed * 60.f)
.retract(0.10f * total_retraction_distance, 0.3f * m_filpar[m_current_tool].unloading_speed * 60.f)
/*.load_move_x_advanced(turning_point, -15.f, 83.f, 50.f) // this is done at fixed speed
.load_move_x_advanced(old_x, -0.70f * total_retraction_distance, 1.0f * m_filpar[m_current_tool].unloading_speed)
.load_move_x_advanced(turning_point, -0.20f * total_retraction_distance, 0.5f * m_filpar[m_current_tool].unloading_speed)
.load_move_x_advanced(old_x, -0.10f * total_retraction_distance, 0.3f * m_filpar[m_current_tool].unloading_speed)
.travel(old_x, writer.y()) // in case previous move was shortened to limit feedrate*/
.resume_preview();
}
// Wipe tower should only change temperature with single extruder MM. Otherwise, all temperatures should
@ -1096,11 +1086,6 @@ void WipeTower::toolchange_Load(
writer.append("; CP TOOLCHANGE LOAD\n")
.suppress_preview()
/*.load_move_x_advanced(turning_point, 0.2f * edist, 0.3f * m_filpar[m_current_tool].loading_speed) // Acceleration
.load_move_x_advanced(oldx, 0.5f * edist, m_filpar[m_current_tool].loading_speed) // Fast phase
.load_move_x_advanced(turning_point, 0.2f * edist, 0.3f * m_filpar[m_current_tool].loading_speed) // Slowing down
.load_move_x_advanced(oldx, 0.1f * edist, 0.1f * m_filpar[m_current_tool].loading_speed) // Super slow*/
.load(0.2f * edist, 60.f * m_filpar[m_current_tool].loading_speed_start)
.load_move_x_advanced(turning_point, 0.7f * edist, m_filpar[m_current_tool].loading_speed) // Fast phase
.load_move_x_advanced(oldx, 0.1f * edist, 0.1f * m_filpar[m_current_tool].loading_speed) // Super slow*/
@ -1170,11 +1155,14 @@ void WipeTower::toolchange_Wipe(
m_left_to_right = !m_left_to_right;
}
// this is neither priming nor not the last toolchange on this layer - we are going back to the model - wipe the nozzle
// this is neither priming nor not the last toolchange on this layer - we are
// going back to the model - wipe the nozzle.
if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool) {
m_left_to_right = !m_left_to_right;
writer.travel(writer.x(), writer.y() - dy)
.travel(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y());
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(writer.x(), writer.y() - dy)
.add_wipe_point(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y() - dy);
}
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
@ -1238,7 +1226,8 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
writer.extrude(box.rd.x() - m_perimeter_width / 2.f, writer.y() + 0.5f * step);
writer.extrude(box.ld.x() + m_perimeter_width / 2.f, writer.y());
}
writer.travel(box.rd.x()-m_perimeter_width/2.f,writer.y()); // wipe the nozzle
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(box.rd.x()-m_perimeter_width/2.f,writer.y());
}
else { // Extrude a sparse infill to support the material to be printed above.
const float dy = (fill_box.lu.y() - fill_box.ld.y() - m_perimeter_width);
@ -1257,10 +1246,13 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
writer.travel(x,writer.y());
writer.extrude(x,i%2 ? fill_box.rd.y() : fill_box.ru.y());
}
writer.travel(left,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
writer.add_wipe_point(Vec2f(writer.x(), writer.y()))
.add_wipe_point(Vec2f(left, writer.y()));
}
else {
writer.add_wipe_point(Vec2f(writer.x(), writer.y()))
.add_wipe_point(Vec2f(right, writer.y()));
}
else
writer.travel(right,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
}
writer.append("; CP EMPTY GRID END\n"
";------------------\n\n\n\n\n\n\n");
@ -1285,6 +1277,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
result.extrusions = writer.extrusions();
result.start_pos = writer.start_pos_rotated();
result.end_pos = writer.pos_rotated();
result.wipe_path = writer.wipe_path();
return result;
}
@ -1356,7 +1349,7 @@ void WipeTower::save_on_last_wipe()
continue;
for (const auto &toolchange : m_layer_info->tool_changes)
tool_change(toolchange.new_tool, false);
tool_change(toolchange.new_tool);
float width = m_wipe_tower_width - 3*m_perimeter_width; // width we draw into
float length_to_save = 2*(m_wipe_tower_width+m_wipe_tower_depth) + (!layer_finished() ? finish_layer().total_extrusion_length_in_plane() : 0.f);
@ -1418,7 +1411,7 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f;
for (const auto &toolchange : layer.tool_changes)
layer_result.emplace_back(tool_change(toolchange.new_tool, false));
layer_result.emplace_back(tool_change(toolchange.new_tool));
if (! layer_finished()) {
auto finish_layer_toolchange = finish_layer();
@ -1432,6 +1425,7 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
last_toolchange.gcode += finish_layer_toolchange.gcode;
last_toolchange.extrusions.insert(last_toolchange.extrusions.end(), finish_layer_toolchange.extrusions.begin(), finish_layer_toolchange.extrusions.end());
last_toolchange.end_pos = finish_layer_toolchange.end_pos;
last_toolchange.wipe_path = finish_layer_toolchange.wipe_path;
}
else
layer_result.emplace_back(std::move(finish_layer_toolchange));
@ -1467,4 +1461,4 @@ void WipeTower::make_wipe_tower_square()
lay.extra_spacing = lay.depth / lay.toolchanges_depth();
}
}; // namespace Slic3r
} // namespace Slic3r

View file

@ -57,6 +57,13 @@ public:
// Is this a priming extrusion? (If so, the wipe tower rotation & translation will not be applied later)
bool priming;
// Pass a polyline so that normal G-code generator can do a wipe for us.
// The wipe cannot be done by the wipe tower because it has to pass back
// a loaded extruder, so it would have to either do a wipe with no retraction
// (leading to https://github.com/prusa3d/PrusaSlicer/issues/2834) or do
// an extra retraction-unretraction pair.
std::vector<Vec2f> wipe_path;
// Initial tool
int initial_tool;
@ -154,7 +161,7 @@ public:
// Returns gcode for a toolchange and a final print head position.
// On the first layer, extrude a brim around the future wipe tower first.
ToolChangeResult tool_change(size_t new_tool, bool last_in_layer);
ToolChangeResult tool_change(size_t new_tool);
// Fill the unfilled space with a sparse infill.
// Call this method only if layer_finished() is false.

View file

@ -153,7 +153,7 @@ GCodeSender::set_baud_rate(unsigned int baud_rate)
if (::tcsetattr(handle, TCSAFLUSH, &ios) != 0)
printf("Failed to set baud rate: %s\n", strerror(errno));
#else
//throw invalid_argument ("OS does not currently support custom bauds");
//throw Slic3r::InvalidArgument("OS does not currently support custom bauds");
#endif
}
}

View file

@ -1,3 +1,4 @@
#include "Exception.hpp"
#include "GCodeTimeEstimator.hpp"
#include "Utils.hpp"
#include <boost/bind.hpp>
@ -254,13 +255,13 @@ namespace Slic3r {
{
boost::nowide::ifstream in(filename);
if (!in.good())
throw std::runtime_error(std::string("Time estimator post process export failed.\nCannot open file for reading.\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for reading.\n"));
std::string path_tmp = filename + ".postprocess";
FILE* out = boost::nowide::fopen(path_tmp.c_str(), "wb");
if (out == nullptr)
throw std::runtime_error(std::string("Time estimator post process export failed.\nCannot open file for writing.\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nCannot open file for writing.\n"));
std::string normal_time_mask = "M73 P%s R%s\n";
std::string silent_time_mask = "M73 Q%s S%s\n";
@ -278,7 +279,7 @@ namespace Slic3r {
in.close();
fclose(out);
boost::nowide::remove(path_tmp.c_str());
throw std::runtime_error(std::string("Time estimator post process export failed.\nIs the disk full?\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nIs the disk full?\n"));
}
export_line.clear();
};
@ -326,7 +327,7 @@ namespace Slic3r {
if (!in.good())
{
fclose(out);
throw std::runtime_error(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
}
// check tags
@ -383,7 +384,7 @@ namespace Slic3r {
in.close();
if (rename_file(path_tmp, filename))
throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + filename + '\n' +
throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + filename + '\n' +
"Is " + path_tmp + " locked?" + '\n');
return true;

View file

@ -1,4 +1,5 @@
#include "libslic3r.h"
#include "Exception.hpp"
#include "Geometry.hpp"
#include "ClipperUtils.hpp"
#include "ExPolygon.hpp"
@ -471,7 +472,7 @@ Pointfs arrange(size_t num_parts, const Vec2d &part_size, coordf_t gap, const Bo
size_t cellw = size_t(floor((bed_bbox.size()(0) + gap) / cell_size(0)));
size_t cellh = size_t(floor((bed_bbox.size()(1) + gap) / cell_size(1)));
if (num_parts > cellw * cellh)
throw std::invalid_argument("%zu parts won't fit in your print area!\n", num_parts);
throw Slic3r::InvalidArgument("%zu parts won't fit in your print area!\n", num_parts);
// Get a bounding box of cellw x cellh cells, centered at the center of the bed.
Vec2d cells_size(cellw * cell_size(0) - gap, cellh * cell_size(1) - gap);

View file

@ -281,7 +281,7 @@ bool directions_parallel(double angle1, double angle2, double max_diff = 0);
template<class T> bool contains(const std::vector<T> &vector, const Point &point);
template<typename T> T rad2deg(T angle) { return T(180.0) * angle / T(PI); }
double rad2deg_dir(double angle);
template<typename T> T deg2rad(T angle) { return T(PI) * angle / T(180.0); }
template<typename T> constexpr T deg2rad(const T angle) { return T(PI) * angle / T(180.0); }
template<typename T> T angle_to_0_2PI(T angle)
{
static const T TWO_PI = T(2) * T(PI);

View file

@ -13,7 +13,7 @@ class Layer;
class PrintRegion;
class PrintObject;
namespace FillAdaptive_Internal {
namespace FillAdaptive {
struct Octree;
};
@ -139,7 +139,7 @@ public:
}
void make_perimeters();
void make_fills() { this->make_fills(nullptr, nullptr); };
void make_fills(FillAdaptive_Internal::Octree* adaptive_fill_octree, FillAdaptive_Internal::Octree* support_fill_octree);
void make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree);
void make_ironing();
void export_region_slices_to_svg(const char *path) const;

View file

@ -1,3 +1,4 @@
#include "Exception.hpp"
#include "MeshBoolean.hpp"
#include "libslic3r/TriangleMesh.hpp"
#undef PI
@ -136,7 +137,7 @@ template<class _Mesh> void triangle_mesh_to_cgal(const TriangleMesh &M, _Mesh &o
if(CGAL::is_closed(out))
CGALProc::orient_to_bound_a_volume(out);
else
std::runtime_error("Mesh not watertight");
throw Slic3r::RuntimeError("Mesh not watertight");
}
inline Vec3d to_vec3d(const _EpicMesh::Point &v)
@ -222,7 +223,7 @@ template<class Op> void _cgal_do(Op &&op, CGALMesh &A, CGALMesh &B)
}
if (! success)
throw std::runtime_error("CGAL mesh boolean operation failed.");
throw Slic3r::RuntimeError("CGAL mesh boolean operation failed.");
}
void minus(CGALMesh &A, CGALMesh &B) { _cgal_do(_cgal_diff, A, B); }

View file

@ -1,3 +1,4 @@
#include "Exception.hpp"
#include "Model.hpp"
#include "ModelArrange.hpp"
#include "Geometry.hpp"
@ -116,13 +117,13 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c
else if (boost::algorithm::iends_with(input_file, ".prusa"))
result = load_prus(input_file.c_str(), &model);
else
throw std::runtime_error("Unknown file format. Input file must have .stl, .obj, .amf(.xml) or .prusa extension.");
throw Slic3r::RuntimeError("Unknown file format. Input file must have .stl, .obj, .amf(.xml) or .prusa extension.");
if (! result)
throw std::runtime_error("Loading of a model file failed.");
throw Slic3r::RuntimeError("Loading of a model file failed.");
if (model.objects.empty())
throw std::runtime_error("The supplied file couldn't be read because it's empty");
throw Slic3r::RuntimeError("The supplied file couldn't be read because it's empty");
for (ModelObject *o : model.objects)
o->input_file = input_file;
@ -146,13 +147,13 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig
else if (boost::algorithm::iends_with(input_file, ".zip.amf"))
result = load_amf(input_file.c_str(), config, &model, check_version);
else
throw std::runtime_error("Unknown file format. Input file must have .3mf or .zip.amf extension.");
throw Slic3r::RuntimeError("Unknown file format. Input file must have .3mf or .zip.amf extension.");
if (!result)
throw std::runtime_error("Loading of a model file failed.");
throw Slic3r::RuntimeError("Loading of a model file failed.");
if (model.objects.empty())
throw std::runtime_error("The supplied file couldn't be read because it's empty");
throw Slic3r::RuntimeError("The supplied file couldn't be read because it's empty");
for (ModelObject *o : model.objects)
{
@ -776,6 +777,38 @@ TriangleMesh ModelObject::raw_mesh() const
return mesh;
}
// Non-transformed (non-rotated, non-scaled, non-translated) sum of non-modifier object volumes.
// Currently used by ModelObject::mesh(), to calculate the 2D envelope for 2D plater
// and to display the object statistics at ModelObject::print_info().
indexed_triangle_set ModelObject::raw_indexed_triangle_set() const
{
size_t num_vertices = 0;
size_t num_faces = 0;
for (const ModelVolume *v : this->volumes)
if (v->is_model_part()) {
num_vertices += v->mesh().its.vertices.size();
num_faces += v->mesh().its.indices.size();
}
indexed_triangle_set out;
out.vertices.reserve(num_vertices);
out.indices.reserve(num_faces);
for (const ModelVolume *v : this->volumes)
if (v->is_model_part()) {
size_t i = out.vertices.size();
size_t j = out.indices.size();
append(out.vertices, v->mesh().its.vertices);
append(out.indices, v->mesh().its.indices);
auto m = v->get_matrix();
for (; i < out.vertices.size(); ++ i)
out.vertices[i] = (m * out.vertices[i].cast<double>()).cast<float>().eval();
if (v->is_left_handed()) {
for (; j < out.indices.size(); ++ j)
std::swap(out.indices[j][0], out.indices[j][1]);
}
}
return out;
}
// Non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
TriangleMesh ModelObject::full_raw_mesh() const
{
@ -817,7 +850,7 @@ const BoundingBoxf3& ModelObject::raw_bounding_box() const
m_raw_bounding_box_valid = true;
m_raw_bounding_box.reset();
if (this->instances.empty())
throw std::invalid_argument("Can't call raw_bounding_box() with no instances");
throw Slic3r::InvalidArgument("Can't call raw_bounding_box() with no instances");
const Transform3d& inst_matrix = this->instances.front()->get_transformation().get_matrix(true);
for (const ModelVolume *v : this->volumes)

View file

@ -244,6 +244,8 @@ public:
// Non-transformed (non-rotated, non-scaled, non-translated) sum of non-modifier object volumes.
// Currently used by ModelObject::mesh() and to calculate the 2D envelope for 2D plater.
TriangleMesh raw_mesh() const;
// The same as above, but producing a lightweight indexed_triangle_set.
indexed_triangle_set raw_indexed_triangle_set() const;
// Non-transformed (non-rotated, non-scaled, non-translated) sum of all object volumes.
TriangleMesh full_raw_mesh() const;
// A transformed snug bounding box around the non-modifier object volumes, without the translation applied.

View file

@ -20,7 +20,7 @@ using VirtualBedFn = std::function<void(arrangement::ArrangePolygon&)>;
[[noreturn]] inline void throw_if_out_of_bed(arrangement::ArrangePolygon&)
{
throw std::runtime_error("Objects could not fit on the bed");
throw Slic3r::RuntimeError("Objects could not fit on the bed");
}
ArrangePolygons get_arrange_polys(const Model &model, ModelInstancePtrs &instances);

View file

@ -64,11 +64,6 @@ openvdb::FloatGrid::Ptr mesh_to_grid(const TriangleMesh &mesh,
float interiorBandWidth,
int flags)
{
// openvdb::initialize();
// return openvdb::tools::meshToVolume<openvdb::FloatGrid>(
// TriangleMeshDataAdapter{mesh}, tr, exteriorBandWidth,
// interiorBandWidth, flags);
openvdb::initialize();
TriangleMeshPtrs meshparts = mesh.split();
@ -83,15 +78,23 @@ openvdb::FloatGrid::Ptr mesh_to_grid(const TriangleMesh &mesh,
openvdb::FloatGrid::Ptr grid;
for (TriangleMesh *m : meshparts) {
auto gridptr = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
auto subgrid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
TriangleMeshDataAdapter{*m}, tr, exteriorBandWidth,
interiorBandWidth, flags);
if (grid && gridptr) openvdb::tools::csgUnion(*grid, *gridptr);
else if (gridptr) grid = std::move(gridptr);
if (grid && subgrid) openvdb::tools::csgUnion(*grid, *subgrid);
else if (subgrid) grid = std::move(subgrid);
}
grid = openvdb::tools::levelSetRebuild(*grid, 0., exteriorBandWidth, interiorBandWidth);
if (grid) {
grid = openvdb::tools::levelSetRebuild(*grid, 0., exteriorBandWidth,
interiorBandWidth);
} else if(meshparts.empty()) {
// Splitting failed, fall back to hollow the original mesh
grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
TriangleMeshDataAdapter{mesh}, tr, exteriorBandWidth,
interiorBandWidth, flags);
}
return grid;
}

View file

@ -1,4 +1,5 @@
#include "PlaceholderParser.hpp"
#include "Exception.hpp"
#include "Flow.hpp"
#include <cstring>
#include <ctime>
@ -1303,7 +1304,7 @@ static std::string process_macro(const std::string &templ, client::MyContext &co
if (!context.error_message.empty()) {
if (context.error_message.back() != '\n' && context.error_message.back() != '\r')
context.error_message += '\n';
throw std::runtime_error(context.error_message);
throw Slic3r::RuntimeError(context.error_message);
}
return output;
}
@ -1319,7 +1320,7 @@ std::string PlaceholderParser::process(const std::string &templ, unsigned int cu
}
// Evaluate a boolean expression using the full expressive power of the PlaceholderParser boolean expression syntax.
// Throws std::runtime_error on syntax or runtime error.
// Throws Slic3r::RuntimeError on syntax or runtime error.
bool PlaceholderParser::evaluate_boolean_expression(const std::string &templ, const DynamicConfig &config, const DynamicConfig *config_override)
{
client::MyContext context;

View file

@ -40,11 +40,11 @@ public:
const DynamicConfig* external_config() const { return m_external_config; }
// Fill in the template using a macro processing language.
// Throws std::runtime_error on syntax or runtime error.
// Throws Slic3r::RuntimeError on syntax or runtime error.
std::string process(const std::string &templ, unsigned int current_extruder_id = 0, const DynamicConfig *config_override = nullptr) const;
// Evaluate a boolean expression using the full expressive power of the PlaceholderParser boolean expression syntax.
// Throws std::runtime_error on syntax or runtime error.
// Throws Slic3r::RuntimeError on syntax or runtime error.
static bool evaluate_boolean_expression(const std::string &templ, const DynamicConfig &config, const DynamicConfig *config_override = nullptr);
// Update timestamp, year, month, day, hour, minute, second variables at the provided config.

View file

@ -44,16 +44,6 @@ Pointf3s transform(const Pointf3s& points, const Transform3d& t)
return ret_points;
}
void Point::rotate(double angle)
{
double cur_x = (double)(*this)(0);
double cur_y = (double)(*this)(1);
double s = ::sin(angle);
double c = ::cos(angle);
(*this)(0) = (coord_t)round(c * cur_x - s * cur_y);
(*this)(1) = (coord_t)round(c * cur_y + s * cur_x);
}
void Point::rotate(double angle, const Point &center)
{
double cur_x = (double)(*this)(0);

View file

@ -105,6 +105,7 @@ public:
template<typename OtherDerived>
Point(const Eigen::MatrixBase<OtherDerived> &other) : Vec2crd(other) {}
static Point new_scale(coordf_t x, coordf_t y) { return Point(coord_t(scale_(x)), coord_t(scale_(y))); }
static Point new_scale(const Vec2d &v) { return Point(coord_t(scale_(v.x())), coord_t(scale_(v.y()))); }
// This method allows you to assign Eigen expressions to MyVectorType
template<typename OtherDerived>
@ -121,7 +122,14 @@ public:
Point& operator*=(const double &rhs) { (*this)(0) = coord_t((*this)(0) * rhs); (*this)(1) = coord_t((*this)(1) * rhs); return *this; }
Point operator*(const double &rhs) { return Point((*this)(0) * rhs, (*this)(1) * rhs); }
void rotate(double angle);
void rotate(double angle) { this->rotate(std::cos(angle), std::sin(angle)); }
void rotate(double cos_a, double sin_a) {
double cur_x = (double)(*this)(0);
double cur_y = (double)(*this)(1);
(*this)(0) = (coord_t)round(cos_a * cur_x - sin_a * cur_y);
(*this)(1) = (coord_t)round(cos_a * cur_y + sin_a * cur_x);
}
void rotate(double angle, const Point &center);
Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
Point rotated(double angle, const Point &center) const { Point res(*this); res.rotate(angle, center); return res; }

View file

@ -1,5 +1,6 @@
#include "BoundingBox.hpp"
#include "ClipperUtils.hpp"
#include "Exception.hpp"
#include "Polygon.hpp"
#include "Polyline.hpp"
@ -16,7 +17,7 @@ Polyline Polygon::split_at_vertex(const Point &point) const
for (const Point &pt : this->points)
if (pt == point)
return this->split_at_index(int(&pt - &this->points.front()));
throw std::invalid_argument("Point not found");
throw Slic3r::InvalidArgument("Point not found");
return Polyline();
}
@ -259,6 +260,44 @@ Point Polygon::point_projection(const Point &point) const
return proj;
}
std::vector<float> Polygon::parameter_by_length() const
{
// Parametrize the polygon by its length.
std::vector<float> lengths(points.size()+1, 0.);
for (size_t i = 1; i < points.size(); ++ i)
lengths[i] = lengths[i-1] + (points[i] - points[i-1]).cast<float>().norm();
lengths.back() = lengths[lengths.size()-2] + (points.front() - points.back()).cast<float>().norm();
return lengths;
}
void Polygon::densify(float min_length, std::vector<float>* lengths_ptr)
{
std::vector<float> lengths_local;
std::vector<float>& lengths = lengths_ptr ? *lengths_ptr : lengths_local;
if (! lengths_ptr) {
// Length parametrization has not been provided. Calculate our own.
lengths = this->parameter_by_length();
}
assert(points.size() == lengths.size() - 1);
for (size_t j=1; j<=points.size(); ++j) {
bool last = j == points.size();
int i = last ? 0 : j;
if (lengths[j] - lengths[j-1] > min_length) {
Point diff = points[i] - points[j-1];
float diff_len = lengths[j] - lengths[j-1];
float r = (min_length/diff_len);
Point new_pt = points[j-1] + Point(r*diff[0], r*diff[1]);
points.insert(points.begin() + j, new_pt);
lengths.insert(lengths.begin() + j, lengths[j-1] + min_length);
}
}
assert(points.size() == lengths.size() - 1);
}
BoundingBox get_extents(const Points &points)
{
return BoundingBox(points);

View file

@ -61,12 +61,14 @@ public:
bool contains(const Point &point) const;
Polygons simplify(double tolerance) const;
void simplify(double tolerance, Polygons &polygons) const;
void densify(float min_length, std::vector<float>* lengths = nullptr);
void triangulate_convex(Polygons* polygons) const;
Point centroid() const;
Points concave_points(double angle = PI) const;
Points convex_points(double angle = PI) const;
// Projection of a point onto the polygon.
Point point_projection(const Point &point) const;
std::vector<float> parameter_by_length() const;
};
inline bool operator==(const Polygon &lhs, const Polygon &rhs) { return lhs.points == rhs.points; }

View file

@ -1,5 +1,6 @@
#include "BoundingBox.hpp"
#include "Polyline.hpp"
#include "Exception.hpp"
#include "ExPolygon.hpp"
#include "ExPolygonCollection.hpp"
#include "Line.hpp"
@ -19,7 +20,7 @@ Polyline::operator Polylines() const
Polyline::operator Line() const
{
if (this->points.size() > 2)
throw std::invalid_argument("Can't convert polyline with more than two points to a line");
throw Slic3r::InvalidArgument("Can't convert polyline with more than two points to a line");
return Line(this->points.front(), this->points.back());
}
@ -207,7 +208,7 @@ BoundingBox get_extents(const Polylines &polylines)
const Point& leftmost_point(const Polylines &polylines)
{
if (polylines.empty())
throw std::invalid_argument("leftmost_point() called on empty PolylineCollection");
throw Slic3r::InvalidArgument("leftmost_point() called on empty PolylineCollection");
Polylines::const_iterator it = polylines.begin();
const Point *p = &it->leftmost_point();
for (++ it; it != polylines.end(); ++it) {

View file

@ -1,5 +1,6 @@
#include <cassert>
#include "Exception.hpp"
#include "Preset.hpp"
#include "AppConfig.hpp"
@ -107,7 +108,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
const std::string id = path.stem().string();
if (! boost::filesystem::exists(path)) {
throw std::runtime_error((boost::format("Cannot load Vendor Config Bundle `%1%`: File not found: `%2%`.") % id % path).str());
throw Slic3r::RuntimeError((boost::format("Cannot load Vendor Config Bundle `%1%`: File not found: `%2%`.") % id % path).str());
}
VendorProfile res(id);
@ -117,7 +118,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
{
auto res = tree.find(key);
if (res == tree.not_found()) {
throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Missing secion or key: `%2%`.") % id % key).str());
throw Slic3r::RuntimeError((boost::format("Vendor Config Bundle `%1%` is not valid: Missing secion or key: `%2%`.") % id % key).str());
}
return res;
};
@ -129,7 +130,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
auto config_version_str = get_or_throw(vendor_section, "config_version")->second.data();
auto config_version = Semver::parse(config_version_str);
if (! config_version) {
throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Cannot parse config_version: `%2%`.") % id % config_version_str).str());
throw Slic3r::RuntimeError((boost::format("Vendor Config Bundle `%1%` is not valid: Cannot parse config_version: `%2%`.") % id % config_version_str).str());
} else {
res.config_version = std::move(*config_version);
}
@ -672,9 +673,9 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri
preset.file << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed";
preset.loaded = true;
} catch (const std::ifstream::failure &err) {
throw std::runtime_error(std::string("The selected preset cannot be loaded: ") + preset.file + "\n\tReason: " + err.what());
throw Slic3r::RuntimeError(std::string("The selected preset cannot be loaded: ") + preset.file + "\n\tReason: " + err.what());
} catch (const std::runtime_error &err) {
throw std::runtime_error(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what());
throw Slic3r::RuntimeError(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what());
}
presets_loaded.emplace_back(preset);
} catch (const std::runtime_error &err) {
@ -686,7 +687,7 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri
std::sort(m_presets.begin() + m_num_default_presets, m_presets.end());
this->select_preset(first_visible_idx());
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
throw Slic3r::RuntimeError(errors_cummulative);
}
// Load a preset from an already parsed config file, insert it into the sorted sequence of presets
@ -1557,10 +1558,10 @@ void PhysicalPrinterCollection::load_printers(const std::string& dir_path, const
printer.loaded = true;
}
catch (const std::ifstream::failure& err) {
throw std::runtime_error(std::string("The selected preset cannot be loaded: ") + printer.file + "\n\tReason: " + err.what());
throw Slic3r::RuntimeError(std::string("The selected preset cannot be loaded: ") + printer.file + "\n\tReason: " + err.what());
}
catch (const std::runtime_error& err) {
throw std::runtime_error(std::string("Failed loading the preset file: ") + printer.file + "\n\tReason: " + err.what());
throw Slic3r::RuntimeError(std::string("Failed loading the preset file: ") + printer.file + "\n\tReason: " + err.what());
}
printers_loaded.emplace_back(printer);
}
@ -1572,7 +1573,7 @@ void PhysicalPrinterCollection::load_printers(const std::string& dir_path, const
m_printers.insert(m_printers.end(), std::make_move_iterator(printers_loaded.begin()), std::make_move_iterator(printers_loaded.end()));
std::sort(m_printers.begin(), m_printers.end());
if (!errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
throw Slic3r::RuntimeError(errors_cummulative);
}
// if there is saved user presets, contains information about "Print Host upload",

View file

@ -157,7 +157,7 @@ void PresetBundle::setup_directories()
subdir.make_preferred();
if (! boost::filesystem::is_directory(subdir) &&
! boost::filesystem::create_directory(subdir))
throw std::runtime_error(std::string("Slic3r was unable to create its data directory at ") + subdir.string());
throw Slic3r::RuntimeError(std::string("Slic3r was unable to create its data directory at ") + subdir.string());
}
}
@ -207,7 +207,7 @@ void PresetBundle::load_presets(AppConfig &config, const std::string &preferred_
this->update_multi_material_filament_presets();
this->update_compatible(PresetSelectCompatibleType::Never);
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
throw Slic3r::RuntimeError(errors_cummulative);
this->load_selections(config, preferred_model_id);
}
@ -679,21 +679,21 @@ void PresetBundle::load_config_file(const std::string &path)
boost::nowide::ifstream ifs(path);
boost::property_tree::read_ini(ifs, tree);
} catch (const std::ifstream::failure &err) {
throw std::runtime_error(std::string("The Config Bundle cannot be loaded: ") + path + "\n\tReason: " + err.what());
throw Slic3r::RuntimeError(std::string("The Config Bundle cannot be loaded: ") + path + "\n\tReason: " + err.what());
} catch (const boost::property_tree::file_parser_error &err) {
throw std::runtime_error((boost::format("Failed loading the Config Bundle \"%1%\": %2% at line %3%")
throw Slic3r::RuntimeError((boost::format("Failed loading the Config Bundle \"%1%\": %2% at line %3%")
% err.filename() % err.message() % err.line()).str());
} catch (const std::runtime_error &err) {
throw std::runtime_error(std::string("Failed loading the preset file: ") + path + "\n\tReason: " + err.what());
throw Slic3r::RuntimeError(std::string("Failed loading the preset file: ") + path + "\n\tReason: " + err.what());
}
// 2) Continue based on the type of the configuration file.
ConfigFileType config_file_type = guess_config_file_type(tree);
switch (config_file_type) {
case CONFIG_FILE_TYPE_UNKNOWN:
throw std::runtime_error(std::string("Unknown configuration file type: ") + path);
throw Slic3r::RuntimeError(std::string("Unknown configuration file type: ") + path);
case CONFIG_FILE_TYPE_APP_CONFIG:
throw std::runtime_error(std::string("Invalid configuration file: ") + path + ". This is an application config file.");
throw Slic3r::RuntimeError(std::string("Invalid configuration file: ") + path + ". This is an application config file.");
case CONFIG_FILE_TYPE_CONFIG:
{
// Initialize a config from full defaults.

View file

@ -1,5 +1,6 @@
#include "clipper/clipper_z.hpp"
#include "Exception.hpp"
#include "Print.hpp"
#include "BoundingBox.hpp"
#include "ClipperUtils.hpp"
@ -1507,7 +1508,7 @@ BoundingBox Print::total_bounding_box() const
double Print::skirt_first_layer_height() const
{
if (m_objects.empty())
throw std::invalid_argument("skirt_first_layer_height() can't be called without PrintObjects");
throw Slic3r::InvalidArgument("skirt_first_layer_height() can't be called without PrintObjects");
return m_objects.front()->config().get_abs_value("first_layer_height");
}
@ -1583,7 +1584,7 @@ void Print::auto_assign_extruders(ModelObject* model_object) const
// Slicing process, running at a background thread.
void Print::process()
{
BOOST_LOG_TRIVIAL(info) << "Staring the slicing process." << log_memory_info();
BOOST_LOG_TRIVIAL(info) << "Starting the slicing process." << log_memory_info();
for (PrintObject *obj : m_objects)
obj->make_perimeters();
this->set_status(70, L("Infilling layers"));
@ -1603,7 +1604,7 @@ void Print::process()
// Initialize the tool ordering, so it could be used by the G-code preview slider for planning tool changes and filament switches.
m_tool_ordering = ToolOrdering(*this, -1, false);
if (m_tool_ordering.empty() || m_tool_ordering.last_extruder() == unsigned(-1))
throw std::runtime_error("The print is empty. The model is not printable with current print settings.");
throw Slic3r::SlicingError("The print is empty. The model is not printable with current print settings.");
}
this->set_done(psWipeTower);
}
@ -2173,7 +2174,7 @@ void Print::_make_wipe_tower()
wipe_tower.set_layer(float(m_wipe_tower_data.tool_ordering.back().print_z), float(layer_height), 0, false, true);
}
m_wipe_tower_data.final_purge = Slic3r::make_unique<WipeTower::ToolChangeResult>(
wipe_tower.tool_change((unsigned int)-1, false));
wipe_tower.tool_change((unsigned int)(-1)));
m_wipe_tower_data.used_filament = wipe_tower.get_used_filament();
m_wipe_tower_data.number_of_toolchanges = wipe_tower.get_number_of_toolchanges();

View file

@ -30,8 +30,10 @@ enum class SlicingMode : uint32_t;
class Layer;
class SupportLayer;
namespace FillAdaptive_Internal {
namespace FillAdaptive {
struct Octree;
struct OctreeDeleter;
using OctreePtr = std::unique_ptr<Octree, OctreeDeleter>;
};
// Print step IDs for keeping track of the print state.
@ -239,7 +241,7 @@ private:
void discover_horizontal_shells();
void combine_infill();
void _generate_support_material();
std::pair<std::unique_ptr<FillAdaptive_Internal::Octree>, std::unique_ptr<FillAdaptive_Internal::Octree>> prepare_adaptive_infill_data();
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> prepare_adaptive_infill_data();
// XYZ in scaled coordinates
Vec3crd m_size;

View file

@ -1,3 +1,4 @@
#include "Exception.hpp"
#include "PrintBase.hpp"
#include <boost/filesystem.hpp>
@ -68,7 +69,7 @@ std::string PrintBase::output_filename(const std::string &format, const std::str
filename = boost::filesystem::change_extension(filename, default_ext);
return filename.string();
} catch (std::runtime_error &err) {
throw std::runtime_error(L("Failed processing of the output_filename_format template.") + "\n" + err.what());
throw Slic3r::RuntimeError(L("Failed processing of the output_filename_format template.") + "\n" + err.what());
}
}

View file

@ -1,3 +1,4 @@
#include "Exception.hpp"
#include "Print.hpp"
#include "BoundingBox.hpp"
#include "ClipperUtils.hpp"
@ -8,6 +9,7 @@
#include "SupportMaterial.hpp"
#include "Surface.hpp"
#include "Slicing.hpp"
#include "Tesselate.hpp"
#include "Utils.hpp"
#include "AABBTreeIndirect.hpp"
#include "Fill/FillAdaptive.hpp"
@ -138,7 +140,7 @@ void PrintObject::slice()
}
});
if (m_layers.empty())
throw std::runtime_error("No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n");
throw Slic3r::SlicingError("No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n");
this->set_done(posSlice);
}
@ -426,81 +428,52 @@ void PrintObject::generate_support_material()
// therefore they cannot be printed without supports.
for (const Layer *layer : m_layers)
if (layer->empty())
throw std::runtime_error("Levitating objects cannot be printed without supports.");
throw Slic3r::SlicingError("Levitating objects cannot be printed without supports.");
#endif
}
this->set_done(posSupportMaterial);
}
}
//#define ADAPTIVE_SUPPORT_SIMPLE
std::pair<std::unique_ptr<FillAdaptive_Internal::Octree>, std::unique_ptr<FillAdaptive_Internal::Octree>> PrintObject::prepare_adaptive_infill_data()
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> PrintObject::prepare_adaptive_infill_data()
{
using namespace FillAdaptive_Internal;
using namespace FillAdaptive;
auto [adaptive_line_spacing, support_line_spacing] = adaptive_fill_line_spacing(*this);
if (adaptive_line_spacing == 0. && support_line_spacing == 0. || this->layers().empty())
return std::make_pair(OctreePtr(), OctreePtr());
std::unique_ptr<Octree> adaptive_fill_octree = {}, support_fill_octree = {};
indexed_triangle_set mesh = this->model_object()->raw_indexed_triangle_set();
// Rotate mesh and build octree on it with axis-aligned (standart base) cubes.
Transform3d m = m_trafo;
m.pretranslate(Vec3d(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0));
auto to_octree = transform_to_octree().toRotationMatrix();
its_transform(mesh, to_octree * m, true);
if (adaptive_line_spacing == 0. && support_line_spacing == 0.)
return std::make_pair(std::move(adaptive_fill_octree), std::move(support_fill_octree));
// Triangulate internal bridging surfaces.
std::vector<std::vector<Vec3d>> overhangs(this->layers().size());
tbb::parallel_for(
tbb::blocked_range<int>(0, int(m_layers.size()) - 1),
[this, &to_octree, &overhangs](const tbb::blocked_range<int> &range) {
std::vector<Vec3d> &out = overhangs[range.begin()];
for (int idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
m_print->throw_if_canceled();
const Layer *layer = this->layers()[idx_layer];
for (const LayerRegion *layerm : layer->regions())
for (const Surface &surface : layerm->fill_surfaces.surfaces)
if (surface.surface_type == stInternalBridge)
append(out, triangulate_expolygon_3d(surface.expolygon, layer->bottom_z()));
}
for (Vec3d &p : out)
p = (to_octree * p).eval();
});
// and gather them.
for (size_t i = 1; i < overhangs.size(); ++ i)
append(overhangs.front(), std::move(overhangs[i]));
TriangleMesh mesh = this->model_object()->raw_mesh();
mesh.transform(m_trafo, true);
// Apply XY shift
mesh.translate(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0);
// Center of the first cube in octree
Vec3d mesh_origin = mesh.bounding_box().center();
#ifdef ADAPTIVE_SUPPORT_SIMPLE
if (mesh.its.vertices.empty())
{
mesh.require_shared_vertices();
}
Vec3f vertical(0, 0, 1);
indexed_triangle_set its_set;
its_set.vertices = mesh.its.vertices;
// Filter out non overhanging faces
for (size_t i = 0; i < mesh.its.indices.size(); ++i) {
stl_triangle_vertex_indices vertex_idx = mesh.its.indices[i];
auto its_calculate_normal = [](const stl_triangle_vertex_indices &index, const std::vector<stl_vertex> &vertices) {
stl_normal normal = (vertices[index.y()] - vertices[index.x()]).cross(vertices[index.z()] - vertices[index.x()]);
return normal;
};
stl_normal normal = its_calculate_normal(vertex_idx, mesh.its.vertices);
stl_normalize_vector(normal);
if(normal.dot(vertical) >= 0.707) {
its_set.indices.push_back(vertex_idx);
}
}
mesh = TriangleMesh(its_set);
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
Slic3r::store_stl(debug_out_path("overhangs.stl").c_str(), &mesh, false);
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
#endif /* ADAPTIVE_SUPPORT_SIMPLE */
Vec3d rotation = Vec3d((5.0 * M_PI) / 4.0, Geometry::deg2rad(215.264), M_PI / 6.0);
Transform3d rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation, Vec3d::Ones(), Vec3d::Ones()).inverse();
if (adaptive_line_spacing != 0.) {
// Rotate mesh and build octree on it with axis-aligned (standart base) cubes
mesh.transform(rotation_matrix);
adaptive_fill_octree = FillAdaptive::build_octree(mesh, adaptive_line_spacing, rotation_matrix * mesh_origin);
}
if (support_line_spacing != 0.)
support_fill_octree = FillSupportCubic::build_octree(mesh, support_line_spacing, rotation_matrix * mesh_origin, rotation_matrix);
return std::make_pair(std::move(adaptive_fill_octree), std::move(support_fill_octree));
return std::make_pair(
adaptive_line_spacing ? build_octree(mesh, overhangs.front(), adaptive_line_spacing, false) : OctreePtr(),
support_line_spacing ? build_octree(mesh, overhangs.front(), support_line_spacing, true) : OctreePtr());
}
void PrintObject::clear_layers()
@ -2836,8 +2809,8 @@ void PrintObject::project_and_append_custom_facets(
// Calculate how to move points on triangle sides per unit z increment.
Vec2f ta(trianglef[1] - trianglef[0]);
Vec2f tb(trianglef[2] - trianglef[0]);
ta *= 1./(facet[1].z() - facet[0].z());
tb *= 1./(facet[2].z() - facet[0].z());
ta *= 1.f/(facet[1].z() - facet[0].z());
tb *= 1.f/(facet[2].z() - facet[0].z());
// Projection on current slice will be build directly in place.
LightPolygon* proj = &projections_of_triangles[idx].polygons[0];
@ -2848,7 +2821,7 @@ void PrintObject::project_and_append_custom_facets(
// Project a sub-polygon on all slices intersecting the triangle.
while (it != layers().end()) {
const float z = (*it)->slice_z;
const float z = float((*it)->slice_z);
// Projections of triangle sides intersections with slices.
// a moves along one side, b tracks the other.
@ -2860,7 +2833,7 @@ void PrintObject::project_and_append_custom_facets(
if (z > facet[1].z() && ! passed_first) {
proj->add(trianglef[1]);
ta = trianglef[2]-trianglef[1];
ta *= 1./(facet[2].z() - facet[1].z());
ta *= 1.f/(facet[2].z() - facet[1].z());
passed_first = true;
}

View file

@ -1,3 +1,4 @@
#include "Exception.hpp"
#include "Print.hpp"
namespace Slic3r {
@ -13,7 +14,7 @@ unsigned int PrintRegion::extruder(FlowRole role) const
else if (role == frSolidInfill || role == frTopSolidInfill)
extruder = m_config.solid_infill_extruder;
else
throw std::invalid_argument("Unknown role");
throw Slic3r::InvalidArgument("Unknown role");
return extruder;
}
@ -40,7 +41,7 @@ Flow PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool fir
} else if (role == frTopSolidInfill) {
config_width = m_config.top_infill_extrusion_width;
} else {
throw std::invalid_argument("Unknown role");
throw Slic3r::InvalidArgument("Unknown role");
}
}

View file

@ -1,3 +1,4 @@
#include <libslic3r/Exception.hpp>
#include <libslic3r/SLAPrintSteps.hpp>
#include <libslic3r/MeshBoolean.hpp>
@ -187,7 +188,7 @@ void SLAPrint::Steps::drill_holes(SLAPrintObject &po)
}
if (MeshBoolean::cgal::does_self_intersect(*holes_mesh_cgal))
throw std::runtime_error(L("Too much overlapping holes."));
throw Slic3r::SlicingError(L("Too many overlapping holes."));
auto hollowed_mesh_cgal = MeshBoolean::cgal::triangle_mesh_to_cgal(hollowed_mesh);
@ -195,7 +196,7 @@ void SLAPrint::Steps::drill_holes(SLAPrintObject &po)
MeshBoolean::cgal::minus(*hollowed_mesh_cgal, *holes_mesh_cgal);
hollowed_mesh = MeshBoolean::cgal::cgal_to_triangle_mesh(*hollowed_mesh_cgal);
} catch (const std::runtime_error &) {
throw std::runtime_error(L(
throw Slic3r::SlicingError(L(
"Drilling holes into the mesh failed. "
"This is usually caused by broken model. Try to fix it first."));
}
@ -241,7 +242,7 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po)
if(slindex_it == po.m_slice_index.end())
//TRN To be shown at the status bar on SLA slicing error.
throw std::runtime_error(
throw Slic3r::RuntimeError(
L("Slicing had to be stopped due to an internal error: "
"Inconsistent slice index."));
@ -445,7 +446,7 @@ void SLAPrint::Steps::generate_pad(SLAPrintObject &po) {
auto &pad_mesh = po.m_supportdata->support_tree_ptr->retrieve_mesh(sla::MeshType::Pad);
if (!validate_pad(pad_mesh, pcfg))
throw std::runtime_error(
throw Slic3r::SlicingError(
L("No pad can be generated for this model with the "
"current configuration"));
@ -613,7 +614,7 @@ void SLAPrint::Steps::initialize_printer_input()
for(const SliceRecord& slicerecord : o->get_slice_index()) {
if (!slicerecord.is_valid())
throw std::runtime_error(
throw Slic3r::SlicingError(
L("There are unprintable objects. Try to "
"adjust support settings to make the "
"objects printable."));

View file

@ -10,6 +10,8 @@
#include "semver/semver.h"
#include "Exception.hpp"
namespace Slic3r {
@ -38,7 +40,7 @@ public:
{
auto parsed = parse(str);
if (! parsed) {
throw std::runtime_error(std::string("Could not parse version string: ") + str);
throw Slic3r::RuntimeError(std::string("Could not parse version string: ") + str);
}
ver = parsed->ver;
parsed->ver = semver_zero();

View file

@ -1973,4 +1973,59 @@ std::vector<const PrintInstance*> chain_print_object_instances(const Print &prin
return out;
}
Polylines chain_lines(const std::vector<Line> &lines, const double point_distance_epsilon)
{
// Create line end point lookup.
struct LineEnd {
LineEnd(const Line *line, bool start) : line(line), start(start) {}
const Line *line;
// Is it the start or end point?
bool start;
const Point& point() const { return start ? line->a : line->b; }
const Point& other_point() const { return start ? line->b : line->a; }
LineEnd other_end() const { return LineEnd(line, ! start); }
bool operator==(const LineEnd &rhs) const { return this->line == rhs.line && this->start == rhs.start; }
};
struct LineEndAccessor {
const Point* operator()(const LineEnd &pt) const { return &pt.point(); }
};
typedef ClosestPointInRadiusLookup<LineEnd, LineEndAccessor> ClosestPointLookupType;
ClosestPointLookupType closest_end_point_lookup(point_distance_epsilon);
for (const Line &line : lines) {
closest_end_point_lookup.insert(LineEnd(&line, true));
closest_end_point_lookup.insert(LineEnd(&line, false));
}
// Chain the lines.
std::vector<char> line_consumed(lines.size(), false);
static const double point_distance_epsilon2 = point_distance_epsilon * point_distance_epsilon;
Polylines out;
for (const Line &seed : lines)
if (! line_consumed[&seed - lines.data()]) {
line_consumed[&seed - lines.data()] = true;
closest_end_point_lookup.erase(LineEnd(&seed, false));
closest_end_point_lookup.erase(LineEnd(&seed, true));
Polyline pl { seed.a, seed.b };
for (size_t round = 0; round < 2; ++ round) {
for (;;) {
auto [line_end, dist2] = closest_end_point_lookup.find(pl.last_point());
if (line_end == nullptr || dist2 >= point_distance_epsilon2)
// Cannot extent in this direction.
break;
// Average the last point.
pl.points.back() = (0.5 * (pl.points.back().cast<double>() + line_end->point().cast<double>())).cast<coord_t>();
// and extend with the new line segment.
pl.points.emplace_back(line_end->other_point());
closest_end_point_lookup.erase(*line_end);
closest_end_point_lookup.erase(line_end->other_end());
line_consumed[line_end->line - lines.data()] = true;
}
// reverse and try the oter direction.
pl.reverse();
}
out.emplace_back(std::move(pl));
}
return out;
}
} // namespace Slic3r

View file

@ -33,6 +33,8 @@ class Print;
struct PrintInstance;
std::vector<const PrintInstance*> chain_print_object_instances(const Print &print);
// Chain lines into polylines.
Polylines chain_lines(const std::vector<Line> &lines, const double point_distance_epsilon);
} // namespace Slic3r

View file

@ -1,3 +1,4 @@
#include "Exception.hpp"
#include "TriangleMesh.hpp"
#include "ClipperUtils.hpp"
#include "Geometry.hpp"
@ -420,7 +421,7 @@ std::deque<uint32_t> TriangleMesh::find_unvisited_neighbors(std::vector<unsigned
{
// Make sure we're not operating on a broken mesh.
if (!this->repaired)
throw std::runtime_error("find_unvisited_neighbors() requires repair()");
throw Slic3r::RuntimeError("find_unvisited_neighbors() requires repair()");
// If the visited list is empty, populate it with false for every facet.
if (facet_visited.empty())
@ -683,7 +684,7 @@ void TriangleMeshSlicer::init(const TriangleMesh *_mesh, throw_on_cancel_callbac
{
mesh = _mesh;
if (! mesh->has_shared_vertices())
throw std::invalid_argument("TriangleMeshSlicer was passed a mesh without shared vertices.");
throw Slic3r::InvalidArgument("TriangleMeshSlicer was passed a mesh without shared vertices.");
throw_on_cancel();
facets_edges.assign(_mesh->stl.stats.number_of_facets * 3, -1);

View file

@ -348,11 +348,11 @@ inline std::string get_time_dhm(float time_in_secs)
char buffer[64];
if (days > 0)
::sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs);
::sprintf(buffer, "%dd %dh %dm", days, hours, minutes);
else if (hours > 0)
::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs);
::sprintf(buffer, "%dh %dm", hours, minutes);
else if (minutes > 0)
::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs);
::sprintf(buffer, "%dm", minutes);
return buffer;
}

View file

@ -1,5 +1,6 @@
#include <exception>
#include "Exception.hpp"
#include "Zipper.hpp"
#include "miniz_extension.hpp"
#include <boost/log/trivial.hpp>
@ -29,7 +30,7 @@ public:
SLIC3R_NORETURN void blow_up() const
{
throw std::runtime_error(formatted_errorstr());
throw Slic3r::RuntimeError(formatted_errorstr());
}
bool is_alive()

View file

@ -12,7 +12,7 @@ PRODUCTVERSION @SLIC3R_RC_VERSION@
VALUE "ProductName", "@SLIC3R_APP_NAME@ G-code Viewer"
VALUE "ProductVersion", "@SLIC3R_BUILD_ID@"
VALUE "InternalName", "@SLIC3R_APP_NAME@ G-code Viewer"
VALUE "LegalCopyright", "Copyright \251 2016-2020 Prusa Research, \251 2011-2018 Alessandro Ranelucci"
VALUE "LegalCopyright", "Copyright \251 2016-2020 Prusa Research, \251 2011-2018 Alessandro Ranellucci"
VALUE "OriginalFilename", "prusa-gcodeviewer.exe"
}
}

View file

@ -12,7 +12,7 @@ PRODUCTVERSION @SLIC3R_RC_VERSION@
VALUE "ProductName", "@SLIC3R_APP_NAME@"
VALUE "ProductVersion", "@SLIC3R_BUILD_ID@"
VALUE "InternalName", "@SLIC3R_APP_NAME@"
VALUE "LegalCopyright", "Copyright \251 2016-2020 Prusa Research, \251 2011-2018 Alessandro Ranelucci"
VALUE "LegalCopyright", "Copyright \251 2016-2020 Prusa Research, \251 2011-2018 Alessandro Ranellucci"
VALUE "OriginalFilename", "prusa-slicer.exe"
}
}

View file

@ -315,7 +315,7 @@ size_t SnapshotDB::load_db()
// Sort the snapshots by their date/time.
std::sort(m_snapshots.begin(), m_snapshots.end(), [](const Snapshot &s1, const Snapshot &s2) { return s1.time_captured < s2.time_captured; });
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
throw Slic3r::RuntimeError(errors_cummulative);
return m_snapshots.size();
}
@ -339,7 +339,7 @@ static void copy_config_dir_single_level(const boost::filesystem::path &path_src
{
if (! boost::filesystem::is_directory(path_dst) &&
! boost::filesystem::create_directory(path_dst))
throw std::runtime_error(std::string("Slic3r was unable to create a directory at ") + path_dst.string());
throw Slic3r::RuntimeError(std::string("Slic3r was unable to create a directory at ") + path_dst.string());
for (auto &dir_entry : boost::filesystem::directory_iterator(path_src))
if (Slic3r::is_ini_file(dir_entry))
@ -429,7 +429,7 @@ const Snapshot& SnapshotDB::restore_snapshot(const std::string &id, AppConfig &a
this->restore_snapshot(snapshot, app_config);
return snapshot;
}
throw std::runtime_error(std::string("Snapshot with id " + id + " was not found."));
throw Slic3r::RuntimeError(std::string("Snapshot with id " + id + " was not found."));
}
void SnapshotDB::restore_snapshot(const Snapshot &snapshot, AppConfig &app_config)
@ -501,7 +501,7 @@ boost::filesystem::path SnapshotDB::create_db_dir()
subdir.make_preferred();
if (! boost::filesystem::is_directory(subdir) &&
! boost::filesystem::create_directory(subdir))
throw std::runtime_error(std::string("Slic3r was unable to create a directory at ") + subdir.string());
throw Slic3r::RuntimeError(std::string("Slic3r was unable to create a directory at ") + subdir.string());
}
return snapshots_dir;
}

View file

@ -324,7 +324,7 @@ std::vector<Index> Index::load_db()
}
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
throw Slic3r::RuntimeError(errors_cummulative);
return index_db;
}

View file

@ -1926,7 +1926,7 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity,
if (extrusion_entity_collection != nullptr)
extrusionentity_to_verts(*extrusion_entity_collection, print_z, copy, volume);
else {
throw std::runtime_error("Unexpected extrusion_entity type in to_verts()");
throw Slic3r::RuntimeError("Unexpected extrusion_entity type in to_verts()");
}
}
}

View file

@ -41,6 +41,36 @@
namespace Slic3r {
bool SlicingProcessCompletedEvent::critical_error() const
{
try {
this->rethrow_exception();
} catch (const Slic3r::SlicingError &ex) {
// Exception derived from SlicingError is non-critical.
return false;
} catch (...) {
}
return true;
}
std::string SlicingProcessCompletedEvent::format_error_message() const
{
std::string error;
try {
this->rethrow_exception();
} catch (const std::bad_alloc& ex) {
wxString errmsg = GUI::from_u8((boost::format(_utf8(L("%s has encountered an error. It was likely caused by running out of memory. "
"If you are sure you have enough RAM on your system, this may also be a bug and we would "
"be glad if you reported it."))) % SLIC3R_APP_NAME).str());
error = std::string(errmsg.ToUTF8()) + "\n\n" + std::string(ex.what());
} catch (std::exception &ex) {
error = ex.what();
} catch (...) {
error = "Unknown C++ exception.";
}
return error;
}
BackgroundSlicingProcess::BackgroundSlicingProcess()
{
boost::filesystem::path temp_path(wxStandardPaths::Get().GetTempDir().utf8_str().data());
@ -109,19 +139,19 @@ void BackgroundSlicingProcess::process_fff()
switch (copy_ret_val) {
case SUCCESS: break; // no error
case FAIL_COPY_FILE:
throw std::runtime_error(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?")));
throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?")));
break;
case FAIL_FILES_DIFFERENT:
throw std::runtime_error((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. There might be problem with target device, please try exporting again or using different device. The corrupted output G-code is at %1%.tmp."))) % export_path).str());
throw Slic3r::RuntimeError((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. There might be problem with target device, please try exporting again or using different device. The corrupted output G-code is at %1%.tmp."))) % export_path).str());
break;
case FAIL_RENAMING:
throw std::runtime_error((boost::format(_utf8(L("Renaming of the G-code after copying to the selected destination folder has failed. Current path is %1%.tmp. Please try exporting again."))) % export_path).str());
throw Slic3r::RuntimeError((boost::format(_utf8(L("Renaming of the G-code after copying to the selected destination folder has failed. Current path is %1%.tmp. Please try exporting again."))) % export_path).str());
break;
case FAIL_CHECK_ORIGIN_NOT_OPENED:
throw std::runtime_error((boost::format(_utf8(L("Copying of the temporary G-code has finished but the original code at %1% couldn't be opened during copy check. The output G-code is at %2%.tmp."))) % m_temp_output_path % export_path).str());
throw Slic3r::RuntimeError((boost::format(_utf8(L("Copying of the temporary G-code has finished but the original code at %1% couldn't be opened during copy check. The output G-code is at %2%.tmp."))) % m_temp_output_path % export_path).str());
break;
case FAIL_CHECK_TARGET_NOT_OPENED:
throw std::runtime_error((boost::format(_utf8(L("Copying of the temporary G-code has finished but the exported code couldn't be opened during copy check. The output G-code is at %1%.tmp."))) % export_path).str());
throw Slic3r::RuntimeError((boost::format(_utf8(L("Copying of the temporary G-code has finished but the exported code couldn't be opened during copy check. The output G-code is at %1%.tmp."))) % export_path).str());
break;
default:
BOOST_LOG_TRIVIAL(warning) << "Unexpected fail code(" << (int)copy_ret_val << ") durring copy_file() to " << export_path << ".";
@ -210,7 +240,7 @@ void BackgroundSlicingProcess::thread_proc()
// Process the background slicing task.
m_state = STATE_RUNNING;
lck.unlock();
std::string error;
std::exception_ptr exception;
try {
assert(m_print != nullptr);
switch(m_print->technology()) {
@ -221,15 +251,8 @@ void BackgroundSlicingProcess::thread_proc()
} catch (CanceledException & /* ex */) {
// Canceled, this is all right.
assert(m_print->canceled());
} catch (const std::bad_alloc& ex) {
wxString errmsg = GUI::from_u8((boost::format(_utf8(L("%s has encountered an error. It was likely caused by running out of memory. "
"If you are sure you have enough RAM on your system, this may also be a bug and we would "
"be glad if you reported it."))) % SLIC3R_APP_NAME).str());
error = std::string(errmsg.ToUTF8()) + "\n\n" + std::string(ex.what());
} catch (std::exception &ex) {
error = ex.what();
} catch (...) {
error = "Unknown C++ exception.";
exception = std::current_exception();
}
m_print->finalize();
lck.lock();
@ -237,9 +260,9 @@ void BackgroundSlicingProcess::thread_proc()
if (m_print->cancel_status() != Print::CANCELED_INTERNAL) {
// Only post the canceled event, if canceled by user.
// Don't post the canceled event, if canceled from Print::apply().
wxCommandEvent evt(m_event_finished_id);
evt.SetString(GUI::from_u8(error));
evt.SetInt(m_print->canceled() ? -1 : (error.empty() ? 1 : 0));
SlicingProcessCompletedEvent evt(m_event_finished_id, 0,
(m_state == STATE_CANCELED) ? SlicingProcessCompletedEvent::Cancelled :
exception ? SlicingProcessCompletedEvent::Error : SlicingProcessCompletedEvent::Finished, exception);
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
}
m_print->restart();
@ -299,7 +322,7 @@ bool BackgroundSlicingProcess::start()
// The background processing thread is already running.
return false;
if (! this->idle())
throw std::runtime_error("Cannot start a background task, the worker thread is not idle.");
throw Slic3r::RuntimeError("Cannot start a background task, the worker thread is not idle.");
m_state = STATE_STARTED;
m_print->set_cancel_callback([this](){ this->stop_internal(); });
lck.unlock();
@ -494,7 +517,7 @@ void BackgroundSlicingProcess::prepare_upload()
if (m_print == m_fff_print) {
m_print->set_status(95, _utf8(L("Running post-processing scripts")));
if (copy_file(m_temp_output_path, source_path.string()) != SUCCESS) {
throw std::runtime_error(_utf8(L("Copying of the temporary G-code to the output G-code failed")));
throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed")));
}
run_post_process_scripts(source_path.string(), m_fff_print->config());
m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());

View file

@ -37,6 +37,36 @@ public:
PrintBase::SlicingStatus status;
};
class SlicingProcessCompletedEvent : public wxEvent
{
public:
enum StatusType {
Finished,
Cancelled,
Error
};
SlicingProcessCompletedEvent(wxEventType eventType, int winid, StatusType status, std::exception_ptr exception) :
wxEvent(winid, eventType), m_status(status), m_exception(exception) {}
virtual wxEvent* Clone() const { return new SlicingProcessCompletedEvent(*this); }
StatusType status() const { return m_status; }
bool finished() const { return m_status == Finished; }
bool success() const { return m_status == Finished; }
bool cancelled() const { return m_status == Cancelled; }
bool error() const { return m_status == Error; }
// Unhandled error produced by stdlib or a Win32 structured exception, or unhandled Slic3r's own critical exception.
bool critical_error() const;
// Only valid if error()
void rethrow_exception() const { assert(this->error()); assert(m_exception); std::rethrow_exception(m_exception); }
// Produce a human readable message to be displayed by a notification or a message box.
std::string format_error_message() const;
private:
StatusType m_status;
std::exception_ptr m_exception;
};
wxDEFINE_EVENT(EVT_SLICING_UPDATE, SlicingStatusEvent);
// Print step IDs for keeping track of the print state.

View file

@ -1,15 +1,15 @@
#include <exception>
namespace Slic3r {
class ConfigError : public std::runtime_error {
using std::runtime_error::runtime_error;
class ConfigError : public Slic3r::RuntimeError {
using Slic3r::RuntimeError::RuntimeError;
};
namespace GUI {
class ConfigGUITypeError : public ConfigError {
using ConfigError::ConfigError;
using ConfigError::ConfigError;
};
}
}
} // namespace GUI
} // namespace Slic3r

View file

@ -123,7 +123,7 @@ Bundle& BundleMap::prusa_bundle()
{
auto it = find(PresetBundle::PRUSA_BUNDLE);
if (it == end()) {
throw std::runtime_error("ConfigWizard: Internal error in BundleMap: PRUSA_BUNDLE not loaded");
throw Slic3r::RuntimeError("ConfigWizard: Internal error in BundleMap: PRUSA_BUNDLE not loaded");
}
return it->second;

View file

@ -766,7 +766,7 @@ const char* FirmwareDialog::priv::avr109_dev_name(Avr109Pid usb_pid) {
return "Original Prusa CW1";
break;
default: throw std::runtime_error((boost::format("Invalid avr109 device USB PID: %1%") % usb_pid.boot).str());
default: throw Slic3r::RuntimeError((boost::format("Invalid avr109 device USB PID: %1%") % usb_pid.boot).str());
}
}

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,9 @@ namespace GUI {
class GCodeViewer
{
using Color = std::array<float, 3>;
using IndexBuffer = std::vector<unsigned int>;
using MultiIndexBuffer = std::vector<IndexBuffer>;
static const std::vector<Color> Extrusion_Role_Colors;
static const std::vector<Color> Options_Colors;
static const std::vector<Color> Travel_Colors;
@ -112,10 +115,12 @@ class GCodeViewer
{
struct Endpoint
{
// index into the indices buffer
unsigned int i_id{ 0u };
// sequential id
unsigned int s_id{ 0u };
// index of the index buffer
unsigned int b_id{ 0 };
// index into the index buffer
size_t i_id{ 0 };
// sequential id (index into the vertex buffer)
size_t s_id{ 0 };
Vec3f position{ Vec3f::Zero() };
};
@ -134,16 +139,17 @@ class GCodeViewer
bool matches(const GCodeProcessor::MoveVertex& move) const;
size_t vertices_count() const { return last.s_id - first.s_id + 1; }
bool contains(unsigned int id) const { return first.s_id <= id && id <= last.s_id; }
bool contains(size_t id) const { return first.s_id <= id && id <= last.s_id; }
};
// Used to batch the indices needed to render paths
struct RenderPath
{
Color color;
size_t path_id;
unsigned int path_id;
unsigned int index_buffer_id;
std::vector<unsigned int> sizes;
std::vector<size_t> offsets; // use size_t because we need the pointer's size (used in the call glMultiDrawElements())
std::vector<size_t> offsets; // use size_t because we need an unsigned int whose size matches pointer's size (used in the call glMultiDrawElements())
};
// buffer containing data for rendering a specific toolpath type
@ -158,7 +164,7 @@ class GCodeViewer
ERenderPrimitiveType render_primitive_type;
VBuffer vertices;
IBuffer indices;
std::vector<IBuffer> indices;
std::string shader;
std::vector<Path> paths;
@ -166,7 +172,10 @@ class GCodeViewer
bool visible{ false };
void reset();
void add_path(const GCodeProcessor::MoveVertex& move, unsigned int i_id, unsigned int s_id);
// b_id index of buffer contained in this->indices
// i_id index of first index contained in this->indices[b_id]
// s_id index of first vertex contained in this->vertices
void add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id);
unsigned int indices_per_segment() const {
switch (render_primitive_type)
{
@ -194,6 +203,8 @@ class GCodeViewer
default: { return 0; }
}
}
bool has_data() const { return vertices.id != 0 && !indices.empty() && indices.front().id != 0; }
};
// helper to render shells
@ -264,7 +275,7 @@ class GCodeViewer
#if ENABLE_GCODE_VIEWER_STATISTICS
struct Statistics
{
// times
// time
long long results_time{ 0 };
long long load_time{ 0 };
long long refresh_time{ 0 };
@ -279,15 +290,17 @@ class GCodeViewer
long long indices_gpu_size{ 0 };
long long paths_size{ 0 };
long long render_paths_size{ 0 };
// others
// other
long long travel_segments_count{ 0 };
long long extrude_segments_count{ 0 };
long long max_vertices_in_vertex_buffer{ 0 };
long long max_indices_in_index_buffer{ 0 };
void reset_all() {
reset_times();
reset_opengl();
reset_sizes();
reset_counters();
reset_others();
}
void reset_times() {
@ -311,9 +324,11 @@ class GCodeViewer
render_paths_size = 0;
}
void reset_counters() {
void reset_others() {
travel_segments_count = 0;
extrude_segments_count = 0;
max_vertices_in_vertex_buffer = 0;
max_indices_in_index_buffer = 0;
}
};
#endif // ENABLE_GCODE_VIEWER_STATISTICS
@ -346,8 +361,8 @@ public:
struct Endpoints
{
unsigned int first{ 0 };
unsigned int last{ 0 };
size_t first{ 0 };
size_t last{ 0 };
};
Endpoints endpoints;
@ -371,7 +386,7 @@ public:
private:
unsigned int m_last_result_id{ 0 };
size_t m_vertices_count{ 0 };
size_t m_moves_count{ 0 };
mutable std::vector<TBuffer> m_buffers{ static_cast<size_t>(EMoveType::Extrude) };
// bounding box of toolpaths
BoundingBoxf3 m_paths_bounding_box;
@ -444,7 +459,6 @@ public:
void export_toolpaths_to_obj(const char* filename) const;
private:
void init_shaders();
void load_toolpaths(const GCodeProcessor::Result& gcode_result);
void load_shells(const Print& print, bool initialized);
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
@ -466,6 +480,7 @@ private:
return in_z_range(path.first.position[2]) || in_z_range(path.last.position[2]);
}
bool is_travel_in_z_range(size_t id) const;
void log_memory_used(const std::string& label, long long additional = 0) const;
};
} // namespace GUI

View file

@ -4999,7 +4999,7 @@ bool GLCanvas3D::_init_main_toolbar()
return false;
item.name = "settings";
item.icon_filename = "cog_.svg";
item.icon_filename = "settings.svg";
item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ;
@ -5011,35 +5011,16 @@ bool GLCanvas3D::_init_main_toolbar()
if (!m_main_toolbar.add_item(item))
return false;
/*
if (!m_main_toolbar.add_separator())
return false;
item.name = "layersediting";
item.icon_filename = "layers_white.svg";
item.tooltip = _utf8(L("Variable layer height"));
item.sprite_id = 11;
item.left.toggable = true;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
item.visibility_callback = [this]()->bool
{
bool res = m_process->current_printer_technology() == ptFFF;
// turns off if changing printer technology
if (!res && m_main_toolbar.is_item_visible("layersediting") && m_main_toolbar.is_item_pressed("layersediting"))
force_main_toolbar_left_action(get_main_toolbar_item_id("layersediting"));
return res;
};
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_layers_editing(); };
if (!m_main_toolbar.add_item(item))
return false;
if (!m_main_toolbar.add_separator())
return false;
*/
item.name = "search";
item.icon_filename = "search_.svg";
item.tooltip = _utf8(L("Search")) + " [" + GUI::shortkey_ctrl_prefix() + "F]";
item.sprite_id = 12;
item.sprite_id = 11;
item.left.toggable = true;
item.left.render_callback = [this](float left, float right, float, float) {
if (m_canvas != nullptr)
{
@ -5053,6 +5034,27 @@ bool GLCanvas3D::_init_main_toolbar()
if (!m_main_toolbar.add_item(item))
return false;
if (!m_main_toolbar.add_separator())
return false;
item.name = "layersediting";
item.icon_filename = "layers_white.svg";
item.tooltip = _utf8(L("Variable layer height"));
item.sprite_id = 12;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
item.visibility_callback = [this]()->bool {
bool res = m_process->current_printer_technology() == ptFFF;
// turns off if changing printer technology
if (!res && m_main_toolbar.is_item_visible("layersediting") && m_main_toolbar.is_item_pressed("layersediting"))
force_main_toolbar_left_action(get_main_toolbar_item_id("layersediting"));
return res;
};
item.enabling_callback = []()->bool { return wxGetApp().plater()->can_layers_editing(); };
item.left.render_callback = GLToolbarItem::Default_Render_Callback;
if (!m_main_toolbar.add_item(item))
return false;
return true;
}
@ -5161,10 +5163,10 @@ bool GLCanvas3D::_init_undoredo_toolbar()
if (!m_undoredo_toolbar.add_item(item))
return false;
/*
if (!m_undoredo_toolbar.add_separator())
return false;
*/
return true;
}
@ -5553,6 +5555,10 @@ void GLCanvas3D::_render_selection_center() const
void GLCanvas3D::_check_and_update_toolbar_icon_scale() const
{
// Don't update a toolbar scale, when we are on a Preview
if (wxGetApp().plater()->is_preview_shown())
return;
float scale = wxGetApp().toolbar_icon_scale();
Size cnv_size = get_canvas_size();

View file

@ -211,7 +211,7 @@ public:
copyright_string += //"Slic3r" + _L("is licensed under the") + _L("GNU Affero General Public License, version 3") + "\n\n" +
_L("PrusaSlicer is based on Slic3r by Alessandro Ranellucci and the RepRap community.") + "\n\n" +
_L("Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik and numerous others.") + "\n\n" +
_L("Splash screen could be desabled from the \"Preferences\"");
_L("Splash screen can be disabled from the \"Preferences\"");
word_wrap_string(copyright_string, banner_width, screen_scale);
@ -599,7 +599,7 @@ void GUI_App::init_app_config()
std::string error = app_config->load();
if (!error.empty())
// Error while parsing config file. We'll customize the error message and rethrow to be displayed.
throw std::runtime_error(
throw Slic3r::RuntimeError(
_u8L("Error parsing PrusaSlicer config file, it is probably corrupted. "
"Try to manually delete the file to recover from the error. Your user profiles will not be affected.") +
"\n\n" + AppConfig::config_path() + "\n\n" + error);

View file

@ -927,7 +927,7 @@ void ImGuiWrapper::init_font(bool compress)
if (font == nullptr) {
font = io.Fonts->AddFontDefault();
if (font == nullptr) {
throw std::runtime_error("ImGui: Could not load deafult font");
throw Slic3r::RuntimeError("ImGui: Could not load deafult font");
}
}

View file

@ -7,6 +7,7 @@
#include <wx/numformatter.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "libslic3r/Exception.hpp"
#include "libslic3r/Utils.hpp"
#include "I18N.hpp"
@ -64,7 +65,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
break;
case coNone: break;
default:
throw /*//!ConfigGUITypeError("")*/std::logic_error("This control doesn't exist till now"); break;
throw Slic3r::LogicError("This control doesn't exist till now"); break;
}
}
// Grab a reference to fields for convenience
@ -683,7 +684,7 @@ boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_
// Aggregate the strings the old way.
// Currently used for the post_process config value only.
if (opt_index != -1)
throw std::out_of_range("Can't deserialize option indexed value");
throw Slic3r::OutOfRange("Can't deserialize option indexed value");
// return join(';', m_config->get(opt_key)});
return get_config_value(*m_config, opt_key);
}

View file

@ -107,7 +107,7 @@ namespace GUI {
wxDEFINE_EVENT(EVT_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
wxDEFINE_EVENT(EVT_SLICING_UPDATE, SlicingStatusEvent);
wxDEFINE_EVENT(EVT_SLICING_COMPLETED, wxCommandEvent);
wxDEFINE_EVENT(EVT_PROCESS_COMPLETED, wxCommandEvent);
wxDEFINE_EVENT(EVT_PROCESS_COMPLETED, SlicingProcessCompletedEvent);
wxDEFINE_EVENT(EVT_EXPORT_BEGAN, wxCommandEvent);
// Sidebar widgets
@ -1168,8 +1168,27 @@ void Sidebar::update_sliced_info_sizer()
p->sliced_info->SetTextAndShow(siCost, info_text, new_label);
#if ENABLE_GCODE_VIEWER
// hide the estimate time
p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A");
if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A")
p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A");
else {
info_text = "";
new_label = _L("Estimated printing time") + ":";
if (ps.estimated_normal_print_time != "N/A") {
new_label += format_wxstr("\n - %1%", _L("normal mode"));
info_text += format_wxstr("\n%1%", short_time(ps.estimated_normal_print_time));
// uncomment next line to not disappear slicing finished notif when colapsing sidebar before time estimate
//if (p->plater->is_sidebar_collapsed())
p->plater->get_notification_manager()->set_slicing_complete_large(p->plater->is_sidebar_collapsed());
p->plater->get_notification_manager()->set_slicing_complete_print_time("Estimated printing time: " + ps.estimated_normal_print_time);
}
if (ps.estimated_silent_print_time != "N/A") {
new_label += format_wxstr("\n - %1%", _L("stealth mode"));
info_text += format_wxstr("\n%1%", short_time(ps.estimated_silent_print_time));
}
p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label);
}
#else
if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A")
p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A");
@ -1684,7 +1703,7 @@ struct Plater::priv
void on_select_preset(wxCommandEvent&);
void on_slicing_update(SlicingStatusEvent&);
void on_slicing_completed(wxCommandEvent&);
void on_process_completed(wxCommandEvent&);
void on_process_completed(SlicingProcessCompletedEvent&);
void on_export_began(wxCommandEvent&);
void on_layer_editing_toggled(bool enable);
void on_slicing_began();
@ -3512,7 +3531,7 @@ bool Plater::priv::warnings_dialog()
return res == wxID_OK;
}
void Plater::priv::on_process_completed(wxCommandEvent &evt)
void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
{
// Stop the background task, wait until the thread goes into the "Idle" state.
// At this point of time the thread should be either finished or canceled,
@ -3521,27 +3540,30 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
this->statusbar()->reset_cancel_callback();
this->statusbar()->stop_busy();
const bool canceled = evt.GetInt() < 0;
const bool error = evt.GetInt() == 0;
const bool success = evt.GetInt() > 0;
// Reset the "export G-code path" name, so that the automatic background processing will be enabled again.
this->background_process.reset_export();
if (error) {
wxString message = evt.GetString();
if (message.IsEmpty())
message = _L("Export failed.");
notification_manager->push_slicing_error_notification(boost::nowide::narrow(message), *q->get_current_canvas3D());
this->statusbar()->set_status_text(message);
if (evt.error()) {
std::string message = evt.format_error_message();
if (evt.critical_error()) {
if (q->m_tracking_popup_menu)
// We don't want to pop-up a message box when tracking a pop-up menu.
// We postpone the error message instead.
q->m_tracking_popup_menu_error_message = message;
else
show_error(q, message);
} else
notification_manager->push_slicing_error_notification(message, *q->get_current_canvas3D());
this->statusbar()->set_status_text(from_u8(message));
const wxString invalid_str = _L("Invalid data");
for (auto btn : { ActionButtonType::abReslice, ActionButtonType::abSendGCode, ActionButtonType::abExport })
sidebar->set_btn_label(btn, invalid_str);
process_completed_with_error = true;
}
if (canceled)
if (evt.cancelled())
this->statusbar()->set_status_text(_L("Cancelled"));
this->sidebar->show_sliced_info_sizer(success);
this->sidebar->show_sliced_info_sizer(evt.success());
// This updates the "Slice now", "Export G-code", "Arrange" buttons status.
// Namely, it refreshes the "Out of print bed" property of all the ModelObjects, and it enables
@ -3562,7 +3584,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
default: break;
}
if (canceled) {
if (evt.cancelled()) {
if (wxGetApp().get_mode() == comSimple)
sidebar->set_btn_label(ActionButtonType::abReslice, "Slice now");
show_action_buttons(true);
@ -5378,6 +5400,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
this->set_printer_technology(config.opt_enum<PrinterTechnology>(opt_key));
// print technology is changed, so we should to update a search list
p->sidebar->update_searcher();
p->sidebar->show_sliced_info_sizer(false);
#if ENABLE_GCODE_VIEWER
p->reset_gcode_toolpaths();
#endif // ENABLE_GCODE_VIEWER

View file

@ -741,7 +741,8 @@ void PlaterPresetComboBox::update()
if (m_type == Preset::TYPE_FILAMENT)
{
// Assign an extruder color to the selected item if the extruder color is defined.
filament_rgb = preset.config.opt_string("filament_colour", 0);
filament_rgb = is_selected ? selected_filament_preset->config.opt_string("filament_colour", 0) :
preset.config.opt_string("filament_colour", 0);
extruder_rgb = (is_selected && !extruder_color.empty()) ? extruder_color : filament_rgb;
single_bar = filament_rgb == extruder_rgb;

Some files were not shown because too many files have changed in this diff Show more