Merge remote-tracking branch 'remotes/prusa/master' into dev

optionsgroup is wonky with sizers.
This commit is contained in:
supermerill 2020-11-05 00:21:16 +01:00
commit 488e4d83e4
132 changed files with 20554 additions and 7029 deletions

View File

@ -518,8 +518,10 @@ elseif (SLIC3R_FHS)
set(SLIC3R_FHS_RESOURCES "${CMAKE_INSTALL_FULL_DATAROOTDIR}/SuperSlicer")
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${SLIC3R_FHS_RESOURCES}")
install(FILES src/platform/unix/SuperSlicer.desktop DESTINATION ${SLIC3R_FHS_RESOURCES}/applications)
install(FILES src/platform/unix/PrusaGcodeviewer.desktop DESTINATION ${SLIC3R_FHS_RESOURCES}/applications)
else ()
install(FILES src/platform/unix/SuperSlicer.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/resources/applications)
install(FILES src/platform/unix/PrusaGcodeviewer.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/resources/applications)
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources")
endif ()

11
deps/CGAL/CGAL.cmake vendored
View File

@ -15,6 +15,17 @@ include(GNUInstallDirs)
# If this file is not present, it will not consider the stored absolute path
ExternalProject_Add_Step(dep_CGAL dep_CGAL_relocation_fix
DEPENDEES install
COMMAND ${CMAKE_COMMAND} -E remove CGALConfig-installation-dirs.cmake
WORKING_DIRECTORY "${DESTDIR}/usr/local/${CMAKE_INSTALL_LIBDIR}/cmake/CGAL"
)
# Again, for whatever reason, CGAL thinks that its version is not relevant if
# configured as a header only library. Fixing it by placing a cmake version file
# besides the installed config file.
ExternalProject_Add_Step(dep_CGAL dep_CGAL_version_fix
DEPENDEES install
COMMAND ${CMAKE_COMMAND} -E copy cgal/CGALConfigVersion.cmake "${DESTDIR}/usr/local/${CMAKE_INSTALL_LIBDIR}/cmake/CGAL/CGALConfigVersion.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
)

37
deps/CGAL/cgal/CGALConfigVersion.cmake vendored Normal file
View File

@ -0,0 +1,37 @@
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
# The variable CVF_VERSION must be set before calling configure_file().
set(PACKAGE_VERSION "5.0.0")
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
# if the installed project requested no architecture check, don't perform the check
if("FALSE")
return()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

View File

@ -0,0 +1,12 @@
[Desktop Entry]
Name=PrusaSlicer
GenericName=3D Printing Software
Icon=com.prusa3d.PrusaSlicer
Exec=prusa-slicer %F
Terminal=false
Type=Application
MimeType=model/stl;model/x-wavefront-obj;model/3mf;model/x-geomview-off;application/x-amf;
Categories=Graphics;3DGraphics;Engineering;
Keywords=3D;Printing;Slicer;slice;3D;printer;convert;gcode;stl;obj;amf;SLA
StartupNotify=false
StartupWMClass=prusa-slicer

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>com.prusa3d.PrusaSlicer</id>
<launchable type="desktop-id">com.prusa3d.PrusaSlicer.desktop</launchable>
<provides>
<id>prusa-slicer.desktop</id>
</provides>
<name>PrusaSlicer</name>
<summary>Powerful 3D printing slicer optimized for Prusa printers</summary>
<metadata_license>0BSD</metadata_license>
<project_license>AGPL-3.0-only</project_license>
<description>
<p>
PrusaSlicer takes 3D models (STL, OBJ, AMF) and converts them into G-code
instructions for FFF printers or PNG layers for mSLA 3D printers. It's
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.
</p>
<p>
PrusaSlicer is based on Slic3r by Alessandro Ranelucci and the RepRap community.
</p>
<p>
What are some of PrusaSlicer's main features?
</p>
<ul>
<li>multi-platform (Linux/Mac/Win) and packaged as standalone-app with no dependencies required</li>
<li>complete command-line interface to use it with no GUI</li>
<li>multi-material (multiple extruders) object printing</li>
<li>multiple G-code flavors supported (RepRap, Makerbot, Mach3, Machinekit etc.)</li>
<li>ability to plate multiple objects having distinct print settings</li>
<li>multithread processing</li>
<li>STL auto-repair (tolerance for broken models)</li>
<li>wide automated unit testing</li>
</ul>
</description>
<url type="homepage">https://www.prusa3d.com/prusaslicer/</url>
<url type="help">https://help.prusa3d.com</url>
<url type="bugtracker">https://github.com/prusa3d/PrusaSlicer/issues</url>
<screenshots>
<screenshot type="default">
<image>https://user-images.githubusercontent.com/590307/78981854-24d07580-7b21-11ea-9441-77923534a659.png</image>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/590307/78981860-2863fc80-7b21-11ea-8c2d-8ff79ced2578.png</image>
</screenshot>
<screenshot>
<image>https://user-images.githubusercontent.com/590307/78981862-28fc9300-7b21-11ea-9b0d-d03e16b709d3.png</image>
</screenshot>
</screenshots>
<content_rating type="oars-1.1" />
<releases>
<release version="2.2.0" date="2020-03-21">
<description>
<p>This is final release of PrusaSlicer 2.2.0 introducing SLA hollowing and hole drilling, support for 3rd party printer vendors, 3Dconnexion support,
automatic variable layer height, macOS dark mode support, greatly improved ColorPrint feature and much, much more.
Several bugs found in the previous release candidate are fixed in this final release. See the respective change logs of the previous releases for all the
new features, improvements and bugfixes in the 2.2.0 series.</p>
</description>
</release>
</releases>
</component>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.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="paint_x5F_supports">
<path fill="#ED6B21" d="M88,38.93c-0.83,0-1.5,0.67-1.5,1.5V70.5h-5V45.14c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5V70.5h-5V49.8
c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5v20.7h-5V53.84c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5V70.5h-5V49.8
c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5v20.7h-5V45.14c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5V70.5h-5V40.43
c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5V72v10.99c0,3.59,2.92,6.51,6.51,6.51h2.98c0.67,0.01,6.51,0.24,6.51,6.5v16
c0,3.29,1.99,9.5,9.5,9.5s9.5-6.21,9.5-9.5V96c0-6.26,5.84-6.49,6.5-6.5h3c3.59,0,6.5-2.92,6.5-6.5V72V40.43
C89.5,39.6,88.83,38.93,88,38.93z M86.5,83c0,1.93-1.57,3.5-3.5,3.5h-3c-3.29,0-9.5,1.99-9.5,9.5v15.99
c-0.01,0.67-0.24,6.51-6.5,6.51s-6.49-5.84-6.5-6.5V96c0-7.51-6.21-9.5-9.5-9.5h-2.99c-1.94,0-3.51-1.57-3.51-3.51V73.5h45V83z"/>
<g>
<path fill="#FFFFFF" d="M64,48.03c-0.26,0-0.52-0.07-0.75-0.2l-48-27.69c-0.46-0.27-0.75-0.76-0.75-1.3V8c0-0.83,0.67-1.5,1.5-1.5
s1.5,0.67,1.5,1.5v9.98L64,44.8l46.5-26.83V8c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v10.84c0,0.54-0.29,1.03-0.75,1.3
l-48,27.69C64.52,47.97,64.26,48.03,64,48.03z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 800 800"
style="enable-background:new 0 0 800 800;"
xml:space="preserve"
sodipodi:docname="notification_eject_sd_hover.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"><metadata
id="metadata15"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs13" /><sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2066"
id="namedview11"
showgrid="false"
inkscape:zoom="1.26"
inkscape:cx="400"
inkscape:cy="396.42857"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<style
type="text/css"
id="style2">
.st0{fill:#ED6B21;}
</style>
<path
style="stroke-width:0.85"
class="st0"
d="m 565.50264,534.98775 v 60.775 h -330.565 v -60.775 h 330.565 m 27.88,-48.195 h -386.24 c -11.22,0 -20.315,9.095 -20.315,20.315 v 116.535 c 0,11.22 9.095,20.315 20.315,20.315 h 386.24 c 11.22,0 20.315,-9.095 20.315,-20.315 v -116.45 c 0,-11.22 -9.095,-20.4 -20.315,-20.4 z"
id="path4" />
<path
style="stroke-width:0.85"
class="st0"
d="m 400.09264,235.70275 116.96,155.295 h -233.75 l 116.79,-155.295 m 0,-66.64 c -6.12,0 -12.155,2.72 -16.235,8.16 l -172.635,229.5 c -10.115,13.43 -0.51,32.555 16.235,32.555 h 345.355 c 16.745,0 26.35,-19.125 16.235,-32.555 l -172.805,-229.5 c -3.995,-5.44 -10.03,-8.16 -16.15,-8.16 z"
id="path6" />
<g
id="g4"
transform="matrix(0.9775,0,0,0.9775,53.547,53.54775)">
<path
id="path2"
class="st0"
d="M 597.2,701.3 H 110.6 C 53.2,701.3 6.5,654.6 6.5,597.2 V 110.6 C 6.5,53.2 53.2,6.5 110.6,6.5 h 486.6 c 57.4,0 104.1,46.7 104.1,104.1 v 486.6 c 0,57.4 -46.7,104.1 -104.1,104.1 z M 110.6,52.4 c -32,0 -58.2,26 -58.2,58.2 v 486.6 c 0,32 26,58.2 58.2,58.2 h 486.6 c 32,0 58.2,-26 58.2,-58.2 V 110.6 c 0,-32 -26,-58.2 -58.2,-58.2 z" />
</g>
<path
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.674603"
d="m 150.65676,738.12999 c -12.4717,-1.39663 -26.66772,-5.94192 -37.84321,-12.11671 -17.754551,-9.80992 -33.768844,-26.68981 -42.418124,-44.71089 -5.985061,-12.4701 -8.760227,-23.35456 -9.821918,-38.52249 -0.48061,-6.8663 -0.640464,-87.42616 -0.497289,-250.61508 0.195544,-222.88027 0.294923,-240.94223 1.356742,-246.58759 4.2349,-22.51562 13.68014,-40.62012 29.200931,-55.97194 14.237938,-14.082924 31.958648,-23.427941 52.602238,-27.739791 5.87892,-1.227937 14.00696,-1.268146 256.3492,-1.268146 h 250.27778 l 7.08334,1.561512 c 21.30688,4.697075 36.90336,13.216072 51.96052,28.381502 14.67865,14.784203 23.1932,30.350373 27.76125,50.752683 l 1.56791,7.00271 v 250.95239 c 0,242.72256 -0.0418,251.15149 -1.26428,257.0238 -9.30592,44.69034 -45.18963,77.43352 -89.75566,81.90028 -9.17898,0.92002 -488.33076,0.87927 -496.55943,-0.0425 z M 652.87275,692.49 c 19.93824,-6.17834 34.6922,-21.42493 40.00111,-41.33675 l 1.51306,-5.67494 V 399.58544 153.69259 l -1.52571,-5.73412 c -5.66288,-21.28292 -21.4158,-36.89778 -42.2051,-41.83523 -5.63965,-1.33941 -7.66026,-1.3488 -253.17948,-1.17613 l -247.49447,0.17405 -4.72222,1.5953 c -18.05932,6.10093 -31.7315,19.23923 -37.4918,36.0278 -1.04762,3.05333 -2.22128,7.52472 -2.60813,9.93642 -0.47859,2.9836 -0.705,81.91876 -0.70847,246.99889 -0.005,218.14117 0.10226,243.1829 1.05916,248.25397 4.27172,22.63802 22.24346,40.86392 44.80877,45.4425 3.58848,0.72811 49.16893,0.87009 250.95237,0.78171 l 246.56747,-0.10801 z"
id="path17" /><path
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.674603"
d="m 218.59688,436.65333 c -4.13129,-2.06443 -6.86895,-4.83026 -9.31331,-9.40915 -1.8345,-3.43648 -1.79343,-12.82008 0.0723,-16.52778 1.6224,-3.22405 174.17376,-232.72362 177.28101,-235.79015 3.40221,-3.35765 7.0012,-4.88322 12.34326,-5.23218 4.15899,-0.27168 5.32913,-0.0718 8.86231,1.51379 2.23886,1.00474 4.97342,2.78734 6.07682,3.96132 4.02813,4.28582 175.25817,232.2757 176.9048,235.54571 2.34584,4.65861 2.38759,12.10251 0.0927,16.52929 -2.00877,3.87485 -5.74351,7.80536 -9.18863,9.67026 l -2.69841,1.4607 -178.1462,0.17362 -178.14619,0.17362 z m 298.67589,-45.66907 c -0.0611,-1.0035 -116.48775,-154.99008 -117.18534,-154.99008 -0.71184,0 -116.84805,154.02591 -116.8632,154.99008 -0.004,0.27827 52.6617,0.50595 117.03571,0.50595 64.374,0 117.02978,-0.22768 117.01283,-0.50595 z"
id="path19" /><path
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.674603"
d="m 202.23056,642.87591 c -4.08272,-1.10499 -7.53117,-3.30912 -10.37477,-6.63124 -4.63948,-5.42019 -4.43387,-2.10678 -4.42657,-71.33297 l 0.007,-62.44927 1.60268,-3.44194 c 1.88877,-4.05635 5.3977,-7.75734 9.36436,-9.8769 l 2.84915,-1.52243 h 199.00794 199.00793 l 2.84915,1.52243 c 3.96665,2.11956 7.47559,5.82055 9.36436,9.8769 l 1.60267,3.44194 0.007,62.44927 c 0.008,69.78764 0.26152,65.98231 -4.79028,71.72146 -1.4904,1.69319 -4.37627,3.87229 -6.52672,4.9283 l -3.85513,1.89304 -196.30953,0.12602 c -153.67069,0.0987 -196.97613,-0.0544 -199.37859,-0.70461 z M 565.87502,565.20052 V 534.50608 H 400.25994 234.64486 v 30.69444 30.69446 h 165.61508 165.61508 z"
id="path21" /></svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 800 800"
style="enable-background:new 0 0 800 800;"
xml:space="preserve"
sodipodi:docname="notification_eject_sd.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"><metadata
id="metadata15"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs13" /><sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1918"
inkscape:window-height="2054"
id="namedview11"
showgrid="false"
inkscape:zoom="1.26"
inkscape:cx="400"
inkscape:cy="401.5873"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" />
<style
type="text/css"
id="style2">
.st0{fill:#ED6B21;}
</style>
<path
class="st0"
d="M594.8,558.9v71.5H205.9v-71.5H594.8 M627.6,502.2H173.2c-13.2,0-23.9,10.7-23.9,23.9v137.1 c0,13.2,10.7,23.9,23.9,23.9h454.4c13.2,0,23.9-10.7,23.9-23.9V526.2C651.5,513,640.8,502.2,627.6,502.2L627.6,502.2z"
id="path4" />
<path
class="st0"
d="M400.2,206.8l137.6,182.7h-275L400.2,206.8 M400.2,128.4c-7.2,0-14.3,3.2-19.1,9.6l-203.1,270 c-11.9,15.8-0.6,38.3,19.1,38.3h406.3c19.7,0,31-22.5,19.1-38.3l-203.3-270C414.5,131.6,407.4,128.4,400.2,128.4L400.2,128.4z"
id="path6" />
<g
id="g4"
transform="matrix(1.15,0,0,1.15,-7.50075,-7.5)">
<path
id="path2"
class="st0"
d="M597.2,701.3H110.6c-57.4,0-104.1-46.7-104.1-104.1V110.6C6.5,53.2,53.2,6.5,110.6,6.5h486.6 c57.4,0,104.1,46.7,104.1,104.1v486.6C701.3,654.6,654.6,701.3,597.2,701.3z M110.6,52.4c-32,0-58.2,26-58.2,58.2v486.6 c0,32,26,58.2,58.2,58.2h486.6c32,0,58.2-26,58.2-58.2V110.6c0-32-26-58.2-58.2-58.2L110.6,52.4z" />
</g>
<path
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.793651"
d="M 107.81901,798.00119 C 77.966509,794.83135 49.146122,779.90354 30.060545,757.72544 16.219297,741.64143 7.2605087,723.64471 2.5844311,702.53048 L 0.79365079,694.44444 V 399.60317 104.7619 L 2.5707889,96.74281 C 8.1200484,71.702533 18.222321,53.056007 35.651802,35.682695 53.220959,18.170156 71.802034,8.0954675 96.708127,2.5778576 L 104.7619,0.79365079 h 294.44445 c 281.74132,0 294.75136,0.0623952 301.55851,1.44626191 16.67428,3.3898194 30.80854,9.2277743 44.45639,18.3620833 30.56319,20.455498 49.17772,51.734599 52.83931,88.789134 0.52246,5.28681 0.71992,107.13501 0.57277,295.37077 -0.21452,274.44189 -0.28952,287.63907 -1.67476,294.84127 -9.63677,50.10325 -47.25156,87.71807 -97.3554,97.35548 -7.21079,1.38698 -20.15876,1.45445 -296.82539,1.54754 -159.10715,0.0532 -291.83859,-0.17373 -294.95877,-0.505 z m 582.70983,-52.40653 c 14.11333,-2.49918 25.86756,-8.65506 36.13916,-18.92666 10.4238,-10.4238 16.61917,-22.37735 18.96341,-36.58863 0.59763,-3.62296 0.78014,-91.16224 0.61306,-294.04762 -0.2267,-275.2812 -0.30507,-289.11319 -1.66353,-293.6508 -2.29132,-7.653498 -8.052,-18.790275 -12.80623,-24.757484 -7.93878,-9.964272 -18.57499,-17.346949 -31.48512,-21.854079 l -7.43245,-2.594784 -291.12328,-0.20372 C 142.50327,52.78948 110.02937,52.90047 105.30529,53.98405 79.968659,59.795581 61.031339,78.238321 54.164726,103.78898 l -1.754497,6.52848 -0.240323,282.14286 c -0.151001,177.27655 0.04527,285.53516 0.528069,291.26984 2.318854,27.5434 19.073236,49.76542 44.524247,59.05433 10.087718,3.68173 -4.026285,3.51395 301.243128,3.58099 197.57151,0.0434 288.82563,-0.19746 292.06349,-0.77082 z"
id="path19" /><path
id="path12"
d="M 107.81901,798.00119 C 71.793616,794.17587 39.726024,774.51428 19.725029,743.98814 11.604149,731.59381 6.0410683,718.13847 2.5844311,702.53048 L 0.79365079,694.44444 V 399.20635 103.96825 L 3.035741,94.554887 C 8.7824143,70.427608 18.557382,52.794942 35.676163,35.676161 52.78713,18.565194 70.514246,8.724096 94.444444,3.0513179 l 9.523806,-2.25766869 h 294.84127 c 282.12524,0 295.14809,0.0623746 301.95534,1.44626189 16.66109,3.3871391 30.79289,9.2216269 44.45639,18.3543829 30.53954,20.412782 49.17677,51.732756 52.83931,88.796836 0.52246,5.28681 0.71992,107.13501 0.57277,295.37077 -0.21452,274.44188 -0.28952,287.63907 -1.67476,294.84127 -8.48938,44.13777 -38.62564,78.86883 -80.59962,92.88841 -19.37815,6.47239 11.16453,5.88739 -313.58117,6.0062 -159.10715,0.0579 -291.83859,-0.16532 -294.95877,-0.49659 z m 583.84766,-52.6969 c 13.48971,-2.42242 24.94716,-8.60413 35.32488,-19.05909 10.25229,-10.3286 16.66154,-22.92711 18.61985,-36.60068 0.66689,-4.65647 0.83196,-81.74243 0.62956,-294.0096 C 745.9846,126.77174 745.87745,107.60752 744.6044,102.9114 738.42079,80.100871 721.07257,62.283764 697.9879,55.03493 l -5.92441,-1.860328 H 399.20635 106.34921 L 98.809524,55.78721 C 75.623265,63.821579 59.178748,82.101475 53.902861,105.70593 52.59901,111.53938 52.514615,128.88593 52.47105,400 l -0.04629,288.09524 2.080286,7.60155 c 6.270993,22.91476 22.15377,39.95711 44.384633,47.62505 3.584011,1.23621 7.998091,1.91356 14.999211,2.30168 5.45635,0.30249 136.34921,0.59491 290.87301,0.64982 232.38849,0.0826 281.98128,-0.0849 286.90477,-0.96905 z"
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.793651" /><path
id="path14"
d="m 188.74939,444.33528 c -4.767,-1.68913 -10.12828,-6.7592 -12.71276,-12.02223 -2.90908,-5.92405 -3.07868,-13.78271 -0.41474,-19.21781 1.59087,-3.24578 204.04455,-273.05533 208.24079,-277.52202 0.98764,-1.05129 4.03672,-3.01468 6.77574,-4.3631 4.52929,-2.22976 5.50158,-2.41761 10.74224,-2.07541 6.86047,0.44798 10.76603,2.25377 15.37601,7.10932 3.73681,3.93587 203.30677,268.8636 207.0044,274.79691 2.05716,3.30097 2.4722,4.84315 2.70946,10.06767 0.23771,5.23447 -0.0137,6.8089 -1.6588,10.38763 -2.76417,6.01319 -5.53229,8.93875 -11.0814,11.71167 l -4.85687,2.42701 -208.40498,-0.0627 c -181.84257,-0.0547 -208.82739,-0.21233 -211.71909,-1.23698 z m 348.94902,-54.98925 c 0,-0.9027 -136.36908,-182.10669 -137.30528,-182.44799 -0.54415,-0.19837 -135.36926,178.28524 -137.53574,182.07198 -0.54249,0.9482 19.37332,1.10934 137.10317,1.10934 83.74346,0 137.73785,-0.28747 137.73785,-0.73333 z"
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.793651" /><path
id="path16"
d="m 168.25397,686.16973 c -7.05465,-1.71645 -13.06577,-6.58064 -16.33102,-13.21504 L 150,669.04762 v -74.20635 -74.20635 l 1.8935,-4.19003 c 1.12593,-2.49152 3.46026,-5.59868 5.75857,-7.66505 7.33695,-6.59655 -16.73947,-6.00214 243.08455,-6.00144 l 231.80306,6.3e-4 4.76912,2.2562 c 5.31341,2.5137 9.30333,6.56248 11.81369,11.98794 1.66145,3.59075 1.67116,4.0432 1.67116,77.8181 v 74.20635 l -1.92294,3.90707 c -2.44721,4.97227 -6.5951,9.12016 -11.60261,11.6026 l -3.93477,1.95064 -231.3492,0.12055 c -127.24207,0.0663 -232.42064,-0.14013 -233.73016,-0.45875 z m 426.5873,-91.72529 V 558.33333 H 400 205.15873 v 36.11111 36.11111 H 400 594.84127 Z"
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.793651" /></svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -7,8 +7,8 @@ name = Anycubic
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 0.0.2
# Where to get the updates from?
config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
# changelog_url = http://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
# The printer models will be shown by the Configuration Wizard in this order,
# also the first model installed & the first nozzle installed will be activated after install.
@ -405,8 +405,6 @@ max_layer_height = 0.3
min_layer_height = 0.08
max_print_height = 300
nozzle_diameter = 0.4
octoprint_apikey =
octoprint_host =
printer_notes =
printer_settings_id =
retract_before_travel = 2
@ -420,8 +418,6 @@ retract_lift_below = 0
retract_restart_extra = 0
retract_restart_extra_toolchange = 0
retract_speed = 60
serial_port =
serial_speed = 250000
single_extruder_multi_material = 0
start_gcode =
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+10, max_print_height)} F600{endif} ; Move print head up\nG1 X0 Y100 F3000 ; present print\nM84 ; disable motors
@ -755,8 +751,6 @@ max_layer_height = 0.3
min_layer_height = 0.1
max_print_height = 200
nozzle_diameter = 0.4
octoprint_apikey =
octoprint_host =
printer_notes =
printer_settings_id =
retract_before_travel = 1
@ -770,8 +764,6 @@ retract_lift_below = 0
retract_restart_extra = 0
retract_restart_extra_toolchange = 0
retract_speed = 30
serial_port =
serial_speed = 115200
single_extruder_multi_material = 0
start_gcode = G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nM117 Homing X/Y ...\nG28 X0 Y0 ;move X/Y to min endstops\nM117 Homing Z ...\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F240 ;move the platform down 15mm\nM117 Heating ...\nM104 S[first_layer_temperature]\n ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature]\n ; wait for extruder temp\nM117 Start cleaning ...\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nM117 Intro line ...\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X0.1 Y20 Z[first_layer_height] F5000.0 ; Move to start position\nG1 X0.1 Y200.0 Z[first_layer_height] F1500.0 E15 ; Draw the first line\nG1 X0.4 Y200.0 Z[first_layer_height] F5000.0 ; Move to side a little\nG1 X0.4 Y20 Z0.3[first_layer_height] F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 E-1 F500 ; Retract filiment by 1 mm\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X5 Y20 Z0.3 F240 ; Move over to prevent blob squish\nG92 E0 ; Reset Extruder\nM117 Printing...\n
end_gcode = M117 Cooling down...\nM104 S0 ; turn off extruder\nM140 S0 ; turn off heatbed\nM107 ; Fan off\nM84 ; disable motors\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 ;X-20 Y-20 F240 ;move Z up a bit and retract filament even more\nG28 X0 ;move X to min endstops, so the head is out of the way\nG90 ;Absolute positionning\nG1 Y200 F3000 ;Present print\nM84 ;steppers off\nM300 P300 S4000\nM117 Finished.\n
@ -1197,24 +1189,18 @@ print_settings_id =
# Common print preset
[print:*common predator 0.4 nozzle*]
inherits = *common predator*
printer_variant = 0.4
nozzle_diameter = 0.4
first_layer_height = 0.16
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and printer_notes=~/.*PRINTER_MODEL_PREDATOR.*/ and printer_notes=~/.*PRINTER_HAS_BOWDEN.*/ and nozzle_diameter[0]==0.4
# Common print preset
[print:*common predator 0.6 nozzle*]
inherits = *common predator*
printer_variant = 0.6
nozzle_diameter = 0.6
first_layer_height = 0.24
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and printer_notes=~/.*PRINTER_MODEL_PREDATOR.*/ and printer_notes=~/.*PRINTER_HAS_BOWDEN.*/ and nozzle_diameter[0]==0.6
# Common print preset
[print:*common predator 0.8 nozzle*]
inherits = *common predator*
printer_variant = 0.8
nozzle_diameter = 0.8
first_layer_height = 0.32
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_ANYCUBIC.*/ and printer_notes=~/.*PRINTER_MODEL_PREDATOR.*/ and printer_notes=~/.*PRINTER_HAS_BOWDEN.*/ and nozzle_diameter[0]==0.8
@ -1754,11 +1740,7 @@ machine_max_jerk_y = 5
machine_max_jerk_z = 5
machine_min_extruding_rate = 0
machine_min_travel_rate = 0
octoprint_apikey =
octoprint_host =
printer_settings_id =
serial_port =
serial_speed = 125000
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_ANYCUBIC\nPRINTER_MODEL_PREDATOR\nPRINTER_HAS_BOWDEN\n
default_filament_profile = Generic PLA @PREDATOR

View File

@ -1,3 +1,5 @@
min_slic3r_version = 2.3.0-alpha2
0.0.4 Added initial CR-10 profile, end g-code improvements.
min_slic3r_version = 2.3.0-alpha0
0.0.3 Added Ender-2, Ender-3 BLTouch, updated Ender-3 bed texture.
min_slic3r_version = 2.2.0-alpha3

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="300mm" height="300mm" version="1.1" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<rect x=".25" y=".25" width="299.5" height="299.5" fill="none" stroke="#fff" stroke-width=".5"/>
</svg>

After

Width:  |  Height:  |  Size: 251 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="300mm" height="220mm" version="1.1" viewBox="0 0 300 220" xmlns="http://www.w3.org/2000/svg">
<rect x=".25" y=".25" width="299.5" height="219.5" fill="none" stroke="#fff" stroke-width=".5"/>
</svg>

After

Width:  |  Height:  |  Size: 251 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="400mm" height="400mm" version="1.1" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<rect x=".25" y=".25" width="399.5" height="399.5" fill="none" stroke="#fff" stroke-width=".5"/>
</svg>

After

Width:  |  Height:  |  Size: 251 B

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="500mm" height="500mm" version="1.1" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
<rect x=".25" y=".25" width="499.5" height="499.5" fill="none" stroke="#fff" stroke-width=".5"/>
</svg>

After

Width:  |  Height:  |  Size: 251 B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="225mm" height="225mm" version="1.1" viewBox="0 0 225 225" xmlns="http://www.w3.org/2000/svg">
<rect x=".25" y=".25" width="224.5" height="224.5" fill="none" stroke="#fff" stroke-width=".5"/>
</svg>

After

Width:  |  Height:  |  Size: 251 B

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="350mm" height="350mm" version="1.1" viewBox="0 0 350 350" xmlns="http://www.w3.org/2000/svg">
<rect x=".25" y=".25" width="349.5" height="349.5" fill="none" stroke="#fff" stroke-width=".5"/>
</svg>

After

Width:  |  Height:  |  Size: 251 B

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,12 @@
min_slic3r_version = 2.2.0-alpha3
1.1.10 Updated firmware version.
1.1.9 Updated K values in filament profiles (linear advance). Added new filament profiles and SLA materials.
1.1.8 Updated start/end g-code scripts for MK3 family printer profiles (reduced extruder motor current for some print profiles). Added new filament and SLA material profiles.
1.1.7 Updated end g-code for MMU2 Single printer profiles. Added/updated filament and SLA material profiles.
1.1.6 Updated firmware version for MK2.5/S and MK3/S.
1.1.5 Updated MMU1 specific retraction settings for Prusament PC Blend
1.1.4 Added Prusament PC Blend filament profile.
1.1.3 Added SLA material and filament profile
1.1.6 superslicer: thumbnails & remove top_fan_speed
1.1.5 slic3r++ adaptation: overlapping & top pattern.
1.1.4 changed flow ratio from float to %
@ -15,6 +23,8 @@ min_slic3r_version = 2.1.0
1.1.1-alpha2 Bumped up config version, so our in house customer will get updated profiles.
1.1.0 Filament aliases, Creality profiles and other goodies for PrusaSlicer 2.2.0-alpha0
min_slic3r_version = 2.1.1-beta0
1.0.10 Updated firmware version for MK2.5/S and MK3/S.
1.0.9 Updated firmware version for MK2.5/S and MK3/S.
1.0.8 Various changes in FFF profiles, new filaments/materials added. See changelog.
1.0.7 Updated layer height limits for MINI
1.0.6 Added Prusa MINI profiles
@ -31,6 +41,8 @@ min_slic3r_version = 2.1.0-alpha0
1.0.0-alpha1 Added Prusament ASA profile
1.0.0-alpha0 Filament specific retract for PET and similar copolymers, and for FLEX
min_slic3r_version = 1.42.0-alpha6
0.8.9 Updated firmware version for MK2.5/S and MK3/S.
0.8.8 Updated firmware version for MK2.5/S and MK3/S.
0.8.7 Updated firmware version
0.8.6 Updated firmware version for MK2.5/S and MK3/S
0.8.5 Updated SL1 printer and material settings
@ -57,6 +69,8 @@ min_slic3r_version = 1.42.0-alpha
0.4.0-alpha3 Update of SLA profiles
0.4.0-alpha2 First SLA profiles
min_slic3r_version = 1.41.3-alpha
0.4.12 Updated firmware version for MK2.5/S and MK3/S.
0.4.11 Updated firmware version for MK2.5/S and MK3/S.
0.4.10 Updated firmware version
0.4.9 Updated firmware version for MK2.5/S and MK3/S
0.4.8 MK2.5/3/S FW update
@ -69,6 +83,7 @@ min_slic3r_version = 1.41.3-alpha
0.4.1 New MK2.5S and MK3S FW versions
0.4.0 Changelog: https://github.com/prusa3d/Slic3r-settings/blob/master/live/PrusaResearch/changelog.txt
min_slic3r_version = 1.41.1
0.3.11 Updated firmware version for MK2.5/S and MK3/S.
0.3.10 Updated firmware version
0.3.9 Updated firmware version for MK2.5/S and MK3/S
0.3.8 MK2.5/3/S FW update
@ -127,4 +142,4 @@ min_slic3r_version = 1.40.0-alpha
0.1.3 Fixed an incorrect position of the max_print_height parameter
0.1.2 Wipe tower changes
0.1.1 Minor print speed adjustments
0.1.0 Initial
0.1.0 Initial

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,3 @@
min_slic3r_version = 2.3.0-alpha0
0.0.1 Initial TriLAB bundle
min_slic3r_version = 2.3.0-alpha0
0.0.2 Added 0.15mm print profile
0.0.1 Initial TriLAB bundle

View File

@ -4,13 +4,13 @@
[vendor]
# Vendor name will be shown by the Config Wizard.
name = TRILAB
name = TriLAB
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 0.0.1
config_version = 0.0.2
# Where to get the updates from?
config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/TriLAB/
# changelog_url = http://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/TriLAB/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
# The printer models will be shown by the Configuration Wizard in this order,
# also the first model installed & the first nozzle installed will be activated after install.
@ -43,10 +43,15 @@ default_materials = DeltiQ PLA; DeltiQ ASA; DeltiQ PET; DeltiQ ABS; DeltiQ CPE
# All presets starting with asterisk, for example *common*, are intermediate and they will
# not make it into the user interface.
[print:DeltiQ 0.15mm]
inherits = DeltiQ 0.2mm
layer_height = 0.15
bottom_solid_layers = 5
top_solid_layers = 6
[print:DeltiQ 0.2mm]
avoid_crossing_perimeters = 0
bottom_solid_layers = 3
bottom_solid_layers = 4
bridge_acceleration = 1000
bridge_angle = 0
bridge_flow_ratio = 0.95
@ -143,7 +148,7 @@ thin_walls = 0
threads = 4
top_infill_extrusion_width = 0.4
top_solid_infill_speed = 30
top_solid_layers = 4
top_solid_layers = 5
travel_speed = 150
wipe_tower = 0
wipe_tower_bridging = 10
@ -254,7 +259,6 @@ extra_loading_move = -2
extruder_colour = ""
extruder_offset = 0x0
gcode_flavor = repetier
host_type = octoprint
layer_gcode = ;AFTER_LAYER_CHANGE\nM117 layer [layer_num] at [layer_z]mm\n;[layer_z]\n
machine_max_acceleration_e = 10000,5000
machine_max_acceleration_extruding = 1500,1250
@ -277,14 +281,11 @@ max_print_height = 320
min_layer_height = 0.15
nozzle_diameter = 0.4
parking_pos_retraction = 92
print_host =
printer_model =
printer_notes = TRILAB
printer_settings_id =
printer_variant =
printer_vendor =
printhost_apikey =
printhost_cafile =
remaining_times = 0
retract_before_travel = 2
retract_before_wipe = 100%
@ -297,8 +298,6 @@ retract_lift_below = 0
retract_restart_extra = 0
retract_restart_extra_toolchange = 0
retract_speed = 33
serial_port =
serial_speed = 250000
silent_mode = 1
single_extruder_multi_material = 0
start_gcode = ;START\nM220 S100 ; Set feedmultiply back to 100percent\nG90 ; Absolute positioning\nM83 ; Relative extruder\nM107 ; Layer fan OFF\nM190 S[first_layer_bed_temperature] ; Set bed temperature and wait\nM104 S[first_layer_temperature] ; Set extruder temperature\nG28 ; Home all axes\nG33 ; auto leveling rutine\nG1 X-62 Y-108 Z0.3 F6000 ; Go to purge position start\nG92 E0 ; Zero extruder\nM109 S[first_layer_temperature] ; Set and wait - hotend temperature\nG3 X62 Y-108 I62 J108 E10 F200 ; Go ARC to purge end\nG92 E0 ; Zero extruder

View File

@ -7,4 +7,5 @@ THIS DIRECTORY CONTAINS THE imgui-1.75 58b3e02 SOURCE DISTRIBUTION.
Customized with the following commits:
042880ba2df913916b2cc77f7bb677e07bfd2c58
67c55c74901f1d337ef08f2090a87cfb4263bb0f
a94c952b40d36b1505fb77b87c0dd739e1034659
a94c952b40d36b1505fb77b87c0dd739e1034659
3ca3a544a87cc569b69351a77996c287763388a5

View File

@ -121,6 +121,8 @@ namespace ImGui
const char MinimalizeHoverMarker = 0xF;
const char WarningMarker = 0x10;
const char ErrorMarker = 0x11;
const char EjectMarker = 0x12;
const char EjectHoverMarker = 0x13;
// void MyFunction(const char* name, const MyMatrix44& v);
}

View File

@ -107,6 +107,9 @@ void AppConfig::set_defaults()
if (get("use_free_camera").empty())
set("use_free_camera", "0");
if (get("reverse_mouse_wheel_zoom").empty())
set("reverse_mouse_wheel_zoom", "0");
#endif // !ENABLE_GCODE_VIEWER
#if ENABLE_ENVIRONMENT_MAP
@ -130,6 +133,9 @@ void AppConfig::set_defaults()
if (get("use_free_camera").empty())
set("use_free_camera", "0");
if (get("reverse_mouse_wheel_zoom").empty())
set("reverse_mouse_wheel_zoom", "0");
#endif // ENABLE_GCODE_VIEWER
if (get("show_splash_screen").empty())
@ -211,6 +217,20 @@ std::string AppConfig::load()
m_legacy_datadir = ini_ver < Semver(1, 40, 0);
}
// Legacy conversion
if (m_mode == EAppMode::Editor) {
// Convert [extras] "physical_printer" to [presets] "physical_printer",
// remove the [extras] section if it becomes empty.
if (auto it_section = m_storage.find("extras"); it_section != m_storage.end()) {
if (auto it_physical_printer = it_section->second.find("physical_printer"); it_physical_printer != it_section->second.end()) {
m_storage["presets"]["physical_printer"] = it_physical_printer->second;
it_section->second.erase(it_physical_printer);
}
if (it_section->second.empty())
m_storage.erase(it_section);
}
}
// Override missing or keys with their defaults.
this->set_defaults();
m_dirty = false;
@ -433,6 +453,7 @@ void AppConfig::reset_selections()
it->second.erase("sla_print");
it->second.erase("sla_material");
it->second.erase("printer");
it->second.erase("physical_printer");
m_dirty = true;
}
}

View File

@ -142,20 +142,20 @@ public:
#endif // ENABLE_GCODE_VIEWER
// Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
bool legacy_datadir() const { return m_legacy_datadir; }
void set_legacy_datadir(bool value) { m_legacy_datadir = value; }
bool legacy_datadir() const { return m_legacy_datadir; }
void set_legacy_datadir(bool value) { m_legacy_datadir = value; }
// Get the Slic3r version check url.
// This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file.
std::string version_check_url() const;
std::string version_check_url() const;
// Returns the original Slic3r version found in the ini file before it was overwritten
// by the current version
Semver orig_version() const { return m_orig_version; }
Semver orig_version() const { return m_orig_version; }
// Does the config file exist?
#if ENABLE_GCODE_VIEWER
bool exists();
bool exists();
#else
static bool exists();
#endif // ENABLE_GCODE_VIEWER

View File

@ -62,8 +62,6 @@ add_library(libslic3r STATIC
Fill/FillRectilinear.hpp
Fill/FillRectilinear2.cpp
Fill/FillRectilinear2.hpp
Fill/FillRectilinear3.cpp
Fill/FillRectilinear3.hpp
Fill/FillSmooth.cpp
Fill/FillSmooth.hpp
Flow.cpp
@ -83,8 +81,6 @@ add_library(libslic3r STATIC
Format/STL.hpp
Format/SL1.hpp
Format/SL1.cpp
GCode/Analyzer.cpp
GCode/Analyzer.hpp
GCode/ThumbnailData.cpp
GCode/ThumbnailData.hpp
GCode/CoolingBuffer.cpp
@ -115,8 +111,6 @@ add_library(libslic3r STATIC
GCodeReader.hpp
# GCodeSender.cpp
# GCodeSender.hpp
GCodeTimeEstimator.cpp
GCodeTimeEstimator.hpp
GCodeWriter.cpp
GCodeWriter.hpp
Geometry.cpp

View File

@ -19,6 +19,8 @@ SLIC3R_DERIVE_EXCEPTION(InvalidArgument, LogicError);
SLIC3R_DERIVE_EXCEPTION(OutOfRange, LogicError);
SLIC3R_DERIVE_EXCEPTION(IOError, CriticalException);
SLIC3R_DERIVE_EXCEPTION(FileIOError, IOError);
SLIC3R_DERIVE_EXCEPTION(HostNetworkError, IOError);
SLIC3R_DERIVE_EXCEPTION(ExportError, CriticalException);
// 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

View File

@ -295,7 +295,7 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
}
ExtrusionRole ExtrusionEntity::string_to_role(const std::string& role)
ExtrusionRole ExtrusionEntity::string_to_role(const std::string_view role)
{
if (role == L("Perimeter"))
return erPerimeter;

View File

@ -6,6 +6,7 @@
#include "Polyline.hpp"
#include <assert.h>
#include <string_view>
namespace Slic3r {
@ -169,7 +170,7 @@ public:
virtual void visit(ExtrusionVisitorConst &visitor) const = 0;
static std::string role_to_string(ExtrusionRole role);
static ExtrusionRole string_to_role(const std::string& role);
static ExtrusionRole string_to_role(const std::string_view role);
};
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;

View File

@ -16,7 +16,6 @@
#include "FillPlanePath.hpp"
#include "FillRectilinear.hpp"
#include "FillRectilinear2.hpp"
#include "FillRectilinear3.hpp"
#include "FillAdaptive.hpp"
#include "FillSmooth.hpp"
#include "../MedialAxis.hpp"

View File

@ -162,7 +162,9 @@ struct SegmentIntersection
// Vertical link, up.
Up,
// Vertical link, down.
Down
Down,
// Phony intersection point has no link.
Phony,
};
enum class LinkQuality : uint8_t {
@ -362,6 +364,25 @@ struct SegmentedIntersectionLine
std::vector<SegmentIntersection> intersections;
};
static SegmentIntersection phony_outer_intersection(SegmentIntersection::SegmentIntersectionType type, coord_t pos)
{
assert(type == SegmentIntersection::OUTER_LOW || type == SegmentIntersection::OUTER_HIGH);
SegmentIntersection out;
// Invalid contour & segment.
out.iContour = std::numeric_limits<size_t>::max();
out.iSegment = std::numeric_limits<size_t>::max();
out.pos_p = pos;
out.type = type;
// Invalid prev / next.
out.prev_on_contour = -1;
out.next_on_contour = -1;
out.prev_on_contour_type = SegmentIntersection::LinkType::Phony;
out.next_on_contour_type = SegmentIntersection::LinkType::Phony;
out.prev_on_contour_quality = SegmentIntersection::LinkQuality::Invalid;
out.next_on_contour_quality = SegmentIntersection::LinkQuality::Invalid;
return out;
}
// A container maintaining an expolygon with its inner offsetted polygon.
// The purpose of the inner offsetted polygon is to provide segments to connect the infill lines.
struct ExPolygonWithOffset
@ -939,6 +960,60 @@ static void slice_region_by_vertical_lines(std::vector<SegmentedIntersectionLine
}
#ifndef NDEBUG
bool validate_segment_intersection_connectivity(const std::vector<SegmentedIntersectionLine> &segs)
{
// Validate the connectivity.
for (size_t i_vline = 0; i_vline + 1 < segs.size(); ++ i_vline) {
const SegmentedIntersectionLine &il_left = segs[i_vline];
const SegmentedIntersectionLine &il_right = segs[i_vline + 1];
for (const SegmentIntersection &it : il_left.intersections) {
if (it.has_right_horizontal()) {
const SegmentIntersection &it_right = il_right.intersections[it.right_horizontal()];
// For a right link there is a symmetric left link.
assert(it.iContour == it_right.iContour);
assert(it.type == it_right.type);
assert(it_right.has_left_horizontal());
assert(it_right.left_horizontal() == int(&it - il_left.intersections.data()));
}
}
for (const SegmentIntersection &it : il_right.intersections) {
if (it.has_left_horizontal()) {
const SegmentIntersection &it_left = il_left.intersections[it.left_horizontal()];
// For a right link there is a symmetric left link.
assert(it.iContour == it_left.iContour);
assert(it.type == it_left.type);
assert(it_left.has_right_horizontal());
assert(it_left.right_horizontal() == int(&it - il_right.intersections.data()));
}
}
}
for (size_t i_vline = 0; i_vline < segs.size(); ++ i_vline) {
const SegmentedIntersectionLine &il = segs[i_vline];
for (const SegmentIntersection &it : il.intersections) {
auto i_it = int(&it - il.intersections.data());
if (it.has_left_vertical_up()) {
assert(il.intersections[it.left_vertical_up()].left_vertical_down() == i_it);
assert(il.intersections[it.left_vertical_up()].prev_on_contour_quality == it.prev_on_contour_quality);
}
if (it.has_left_vertical_down()) {
assert(il.intersections[it.left_vertical_down()].left_vertical_up() == i_it);
assert(il.intersections[it.left_vertical_down()].prev_on_contour_quality == it.prev_on_contour_quality);
}
if (it.has_right_vertical_up()) {
assert(il.intersections[it.right_vertical_up()].right_vertical_down() == i_it);
assert(il.intersections[it.right_vertical_up()].next_on_contour_quality == it.next_on_contour_quality);
}
if (it.has_right_vertical_down()) {
assert(il.intersections[it.right_vertical_down()].right_vertical_up() == i_it);
assert(il.intersections[it.right_vertical_down()].next_on_contour_quality == it.next_on_contour_quality);
}
}
}
return true;
}
#endif /* NDEBUG */
// Connect each contour / vertical line intersection point with another two contour / vertical line intersection points.
// (fill in SegmentIntersection::{prev_on_contour, prev_on_contour_vertical, next_on_contour, next_on_contour_vertical}.
// These contour points are either on the same vertical line, or on the vertical line left / right to the current one.
@ -1107,55 +1182,104 @@ static void connect_segment_intersections_by_contours(
}
}
#ifndef NDEBUG
// Validate the connectivity.
for (size_t i_vline = 0; i_vline + 1 < segs.size(); ++i_vline) {
const SegmentedIntersectionLine& il_left = segs[i_vline];
const SegmentedIntersectionLine& il_right = segs[i_vline + 1];
for (const SegmentIntersection& it : il_left.intersections) {
if (it.has_right_horizontal()) {
const SegmentIntersection& it_right = il_right.intersections[it.right_horizontal()];
// For a right link there is a symmetric left link.
assert(it.iContour == it_right.iContour);
assert(it.type == it_right.type);
assert(it_right.has_left_horizontal());
assert(it_right.left_horizontal() == int(&it - il_left.intersections.data()));
assert(validate_segment_intersection_connectivity(segs));
}
static void pinch_contours_insert_phony_outer_intersections(std::vector<SegmentedIntersectionLine> &segs)
{
// Keep the vector outside the loops, so they will not be reallocated.
// Where to insert new outer points.
std::vector<size_t> insert_after;
// Mapping of indices of current intersection line after inserting new outer points.
std::vector<int32_t> map;
std::vector<SegmentIntersection> temp_intersections;
for (size_t i_vline = 1; i_vline < segs.size(); ++ i_vline) {
SegmentedIntersectionLine &il = segs[i_vline];
assert(il.intersections.empty() || il.intersections.size() >= 2);
if (! il.intersections.empty()) {
assert(il.intersections.front().type == SegmentIntersection::OUTER_LOW);
assert(il.intersections.back().type == SegmentIntersection::OUTER_HIGH);
auto end = il.intersections.end() - 1;
insert_after.clear();
for (auto it = il.intersections.begin() + 1; it != end;) {
if (it->type == SegmentIntersection::OUTER_HIGH) {
++ it;
assert(it->type == SegmentIntersection::OUTER_LOW);
++ it;
} else {
auto lo = it;
assert(lo->type == SegmentIntersection::INNER_LOW);
auto hi = ++ it;
assert(hi->type == SegmentIntersection::INNER_HIGH);
auto lo2 = ++ it;
if (lo2->type == SegmentIntersection::INNER_LOW) {
// INNER_HIGH followed by INNER_LOW. The outer contour may have squeezed the inner contour into two separate loops.
// In that case one shall insert a phony OUTER_HIGH / OUTER_LOW pair.
int up = hi->vertical_up();
int dn = lo2->vertical_down();
#ifndef _NDEBUG
assert(up == -1 || up > 0);
assert(dn == -1 || dn >= 0);
assert((up == -1 && dn == -1) || (dn + 1 == up));
#endif // _NDEBUG
bool pinched = dn + 1 != up;
if (pinched) {
// hi is not connected with its inner contour to lo2.
// Insert a phony OUTER_HIGH / OUTER_LOW pair.
#if 0
static int pinch_idx = 0;
printf("Pinched %d\n", pinch_idx++);
#endif
insert_after.emplace_back(hi - il.intersections.begin());
}
for (const SegmentIntersection& it : il_right.intersections) {
if (it.has_left_horizontal()) {
const SegmentIntersection& it_left = il_left.intersections[it.left_horizontal()];
// For a right link there is a symmetric left link.
assert(it.iContour == it_left.iContour);
assert(it.type == it_left.type);
assert(it_left.has_right_horizontal());
assert(it_left.right_horizontal() == int(&it - il_right.intersections.data()));
}
}
}
for (size_t i_vline = 0; i_vline < segs.size(); ++i_vline) {
const SegmentedIntersectionLine& il = segs[i_vline];
for (const SegmentIntersection& it : il.intersections) {
auto i_it = int(&it - il.intersections.data());
if (it.has_left_vertical_up()) {
assert(il.intersections[it.left_vertical_up()].left_vertical_down() == i_it);
assert(il.intersections[it.left_vertical_up()].prev_on_contour_quality == it.prev_on_contour_quality);
if (! insert_after.empty()) {
// Insert phony OUTER_HIGH / OUTER_LOW pairs, adjust indices pointing to intersection points on this contour.
map.clear();
{
size_t i = 0;
temp_intersections.clear();
for (size_t idx_inset_after : insert_after) {
for (; i <= idx_inset_after; ++ i) {
map.emplace_back(temp_intersections.size());
temp_intersections.emplace_back(il.intersections[i]);
}
if (it.has_left_vertical_down()) {
assert(il.intersections[it.left_vertical_down()].left_vertical_up() == i_it);
assert(il.intersections[it.left_vertical_down()].prev_on_contour_quality == it.prev_on_contour_quality);
coord_t pos = (temp_intersections.back().pos() + il.intersections[i].pos()) / 2;
temp_intersections.emplace_back(phony_outer_intersection(SegmentIntersection::OUTER_HIGH, pos));
temp_intersections.emplace_back(phony_outer_intersection(SegmentIntersection::OUTER_LOW, pos));
}
if (it.has_right_vertical_up()) {
assert(il.intersections[it.right_vertical_up()].right_vertical_down() == i_it);
assert(il.intersections[it.right_vertical_up()].next_on_contour_quality == it.next_on_contour_quality);
for (; i < il.intersections.size(); ++ i) {
map.emplace_back(temp_intersections.size());
temp_intersections.emplace_back(il.intersections[i]);
}
if (it.has_right_vertical_down()) {
assert(il.intersections[it.right_vertical_down()].right_vertical_up() == i_it);
assert(il.intersections[it.right_vertical_down()].next_on_contour_quality == it.next_on_contour_quality);
temp_intersections.swap(il.intersections);
}
// Reindex references on current intersection line.
for (SegmentIntersection &ip : il.intersections) {
if (ip.has_left_vertical())
ip.prev_on_contour = map[ip.prev_on_contour];
if (ip.has_right_vertical())
ip.next_on_contour = map[ip.next_on_contour];
}
// Reindex references on previous intersection line.
for (SegmentIntersection &ip : segs[i_vline - 1].intersections)
if (ip.has_right_horizontal())
ip.next_on_contour = map[ip.next_on_contour];
if (i_vline < segs.size()) {
// Reindex references on next intersection line.
for (SegmentIntersection &ip : segs[i_vline + 1].intersections)
if (ip.has_left_horizontal())
ip.prev_on_contour = map[ip.prev_on_contour];
}
}
}
}
#endif /* NDEBUG */
assert(validate_segment_intersection_connectivity(segs));
}
// Find the last INNER_HIGH intersection starting with INNER_LOW, that is followed by OUTER_HIGH intersection.
@ -2119,7 +2243,7 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
// After how many rounds without an improvement to exit?
constexpr int num_rounds_no_change_exit = 8;
// With how many ants each of the run will be performed?
const int num_ants = std::min<int>(regions.size(), 10);
const int num_ants = std::min(int(regions.size()), 10);
// Base (initial) pheromone level. This value will be adjusted based on the length of the first greedy path found.
float pheromone_initial_deposit = 0.5f;
// Evaporation rate of pheromones.
@ -2197,7 +2321,7 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
}
// Set an initial pheromone value to 10% of the greedy path's value.
pheromone_initial_deposit = 0.1 / total_length;
pheromone_initial_deposit = 0.1f / total_length;
path_matrix.update_inital_pheromone(pheromone_initial_deposit);
}
@ -2395,9 +2519,21 @@ static void polylines_from_paths(const std::vector<MonotonousRegionLink>& path,
// Handle nearly zero length edges.
if (polyline->points.size() <= 1 ||
(polyline->points.size() == 2 &&
std::abs(polyline->points.front()(0) - polyline->points.back()(0)) < SCALED_EPSILON &&
std::abs(polyline->points.front()(1) - polyline->points.back()(1)) < SCALED_EPSILON))
std::abs(polyline->points.front().x() - polyline->points.back().x()) < SCALED_EPSILON &&
std::abs(polyline->points.front().y() - polyline->points.back().y()) < SCALED_EPSILON))
polylines_out.pop_back();
else if (polylines_out.size() >= 2) {
assert(polyline->points.size() >= 2);
// Merge the two last polylines. An extrusion may have been split by an introduction of phony outer points on intersection lines
// to cope with pinching of inner offset contours.
Polyline &pl_prev = polylines_out[polylines_out.size() - 2];
if (std::abs(polyline->points.front().x() - pl_prev.points.back().x()) < SCALED_EPSILON &&
std::abs(polyline->points.front().y() - pl_prev.points.back().y()) < SCALED_EPSILON) {
pl_prev.points.back() = (pl_prev.points.back() + polyline->points.front()) / 2;
pl_prev.points.insert(pl_prev.points.end(), polyline->points.begin() + 1, polyline->points.end());
polylines_out.pop_back();
}
}
polyline = nullptr;
};
@ -2550,7 +2686,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
surface->expolygon,
- rotate_vector.first,
float(scale_(0 /*this->overlap*/ - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->get_spacing())),
float(scale_(0 /*this->overlap*/ - 0.5 * this->get_spacing())));
float(scale_(0 /*this->overlap*/ - 0.5f * this->get_spacing())));
if (poly_with_offset.n_contours_inner == 0) {
// Not a single infill line fits.
//Prusa: maybe one shall trigger the gap fill here?
@ -2623,6 +2759,10 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
//FIXME this is a hack to get the monotonous infill rolling. We likely want a smarter switch, likely based on user decison.
bool monotonous_infill = params.monotonous; // || params.density > 0.99;
if (monotonous_infill) {
// Sometimes the outer contour pinches the inner contour from both sides along a single vertical line.
// This situation is not handled correctly by generate_montonous_regions().
// Insert phony OUTER_HIGH / OUTER_LOW pairs at the position where the contour is pinched.
pinch_contours_insert_phony_outer_intersections(segs);
std::vector<MonotonousRegion> regions = generate_montonous_regions(segs);
connect_monotonous_regions(regions, poly_with_offset, segs);
if (!regions.empty()) {

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
#ifndef slic3r_FillRectilinear3_hpp_
#define slic3r_FillRectilinear3_hpp_
#include "../libslic3r.h"
#include "FillBase.hpp"
namespace Slic3r {
class Surface;
class FillRectilinear3 : public Fill
{
public:
virtual Fill* clone() const override { return new FillRectilinear3(*this); };
virtual ~FillRectilinear3() {}
virtual Polylines fill_surface(const Surface *surface, const FillParams &params) const override;
struct FillDirParams
{
FillDirParams(coordf_t spacing, double angle, coordf_t pattern_shift = 0.f) :
spacing(spacing), angle(angle), pattern_shift(pattern_shift) {}
coordf_t spacing;
double angle;
coordf_t pattern_shift;
};
protected:
bool fill_surface_by_lines(const Surface *surface, const FillParams &params, std::vector<FillDirParams> &fill_dir_params, Polylines &polylines_out) const;
};
class FillGrid3 : public FillRectilinear3
{
public:
virtual Fill* clone() const override { return new FillGrid3(*this); };
virtual ~FillGrid3() {}
virtual Polylines fill_surface(const Surface *surface, const FillParams &params) const override;
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
virtual float _layer_angle(size_t /* idx */) const override { return 0.f; }
};
class FillTriangles3 : public FillRectilinear3
{
public:
virtual Fill* clone() const override { return new FillTriangles3(*this); };
virtual ~FillTriangles3() {}
virtual Polylines fill_surface(const Surface *surface, const FillParams &params) const override;
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
virtual float _layer_angle(size_t /* idx */) const override { return 0.f; }
};
class FillStars3 : public FillRectilinear3
{
public:
virtual Fill* clone() const override { return new FillStars3(*this); };
virtual ~FillStars3() {}
virtual Polylines fill_surface(const Surface *surface, const FillParams &params) const override;
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
virtual float _layer_angle(size_t /* idx */) const override { return 0.f; }
};
class FillCubic3 : public FillRectilinear3
{
public:
virtual Fill* clone() const override { return new FillCubic3(*this); };
virtual ~FillCubic3() {}
virtual Polylines fill_surface(const Surface *surface, const FillParams &params)const override;
protected:
// The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill.
virtual float _layer_angle(size_t /* idx */) const override { return 0.f; }
};
}; // namespace Slic3r
#endif // slic3r_FillRectilinear3_hpp_

View File

@ -383,6 +383,7 @@ void fill_slicerconf(ConfMap &m, const SLAPrint &print)
static constexpr auto banned_keys = {
"compatible_printers"sv,
"compatible_prints"sv,
//FIXME The print host keys should not be exported to full_print_config anymore. The following keys may likely be removed.
"print_host"sv,
"printhost_apikey"sv,
"printhost_cafile"sv

View File

@ -5,7 +5,6 @@
#include "ExtrusionEntity.hpp"
#include "EdgeGrid.hpp"
#include "Geometry.hpp"
#include "GCode/Analyzer.hpp"
#include "GCode/FanMover.hpp"
#include "GCode/PrintExtents.hpp"
#include "GCode/WipeTower.hpp"
@ -1135,14 +1134,14 @@ namespace DoExport {
++ dst.second;
};
print_statistics.filament_stats.insert(std::pair<size_t, float>{extruder.id(), (float)used_filament});
append(out_filament_used_mm, "%.1lf", used_filament);
append(out_filament_used_cm3, "%.1lf", extruded_volume * 0.001);
append(out_filament_used_mm, "%.2lf", used_filament);
append(out_filament_used_cm3, "%.2lf", extruded_volume * 0.001);
if (filament_weight > 0.) {
print_statistics.total_weight = print_statistics.total_weight + filament_weight;
append(out_filament_used_g, "%.1lf", filament_weight);
append(out_filament_used_g, "%.2lf", filament_weight);
if (filament_cost > 0.) {
print_statistics.total_cost = print_statistics.total_cost + filament_cost;
append(out_filament_cost, "%.1lf", filament_cost);
append(out_filament_cost, "%.2lf", filament_cost);
}
}
print_statistics.total_used_filament += used_filament;
@ -1829,8 +1828,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
// Modifies
print.m_print_statistics));
_write(file, "\n");
_write_format(file, "; total filament used [g] = %.1lf\n", print.m_print_statistics.total_weight);
_write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost);
_write_format(file, "; total filament used [g] = %.2lf\n", print.m_print_statistics.total_weight);
_write_format(file, "; total filament cost = %.2lf\n", print.m_print_statistics.total_cost);
if (print.m_print_statistics.total_toolchanges > 0)
_write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
#if ENABLE_GCODE_VIEWER
@ -1844,7 +1843,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
// Append full config.
_write(file, "\n", true);
{
std::string full_config = "";
std::string full_config;
append_full_config(print, full_config);
if (!full_config.empty())
_write(file, full_config, true);
@ -2174,7 +2173,7 @@ std::string GCode::emit_custom_gcode_per_print_z(
// Color Change or Tool Change as Color Change.
#if ENABLE_GCODE_VIEWER
// add tag for processor
gcode += "; " + GCodeProcessor::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n";
gcode += ";" + GCodeProcessor::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n";
#else
// add tag for analyzer
gcode += "; " + GCodeAnalyzer::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n";
@ -2198,7 +2197,7 @@ std::string GCode::emit_custom_gcode_per_print_z(
{
#if ENABLE_GCODE_VIEWER
// add tag for processor
gcode += "; " + GCodeProcessor::Pause_Print_Tag + "\n";
gcode += ";" + GCodeProcessor::Pause_Print_Tag + "\n";
#else
// add tag for analyzer
gcode += "; " + GCodeAnalyzer::Pause_Print_Tag + "\n";
@ -2214,13 +2213,13 @@ std::string GCode::emit_custom_gcode_per_print_z(
} else {
#if ENABLE_GCODE_VIEWER
// add tag for processor
gcode += "; " + GCodeProcessor::Custom_Code_Tag + "\n";
gcode += ";" + GCodeProcessor::Custom_Code_Tag + "\n";
#else
// add tag for analyzer
gcode += "; " + GCodeAnalyzer::Custom_Code_Tag + "\n";
#endif // ENABLE_GCODE_VIEWER
// add tag for time estimator
//gcode += "; " + GCodeTimeEstimator::Custom_Code_Tag + "\n";
//gcode += "; " + GCodeTimeEstimator::Custom_Code_Tag + "\n";
#endif // ENABLE_GCODE_VIEWER
if (gcode_type == CustomGCode::Template) // Template Cistom Gcode
gcode += print.config().template_custom_gcode;
else // custom Gcode
@ -2870,10 +2869,11 @@ void GCode::append_full_config(const Print &print, std::string &str)
const std::vector<std::string> banned_keys {
"compatible_printers",
"compatible_prints",
//FIXME The print host keys should not be exported to full_print_config anymore. The following keys may likely be removed.
"print_host",
"printhost_apikey",
"printhost_cafile",
"printhost_slug"
"printhost_cafile",
"printhost_slug"
};
assert(std::is_sorted(banned_keys.begin(), banned_keys.end()));
auto is_banned = [banned_keys](const std::string &key) {

File diff suppressed because it is too large Load Diff

View File

@ -1,364 +0,0 @@
#ifndef slic3r_GCode_Analyzer_hpp_
#define slic3r_GCode_Analyzer_hpp_
#if !ENABLE_GCODE_VIEWER
#include "../libslic3r.h"
#include "../PrintConfig.hpp"
#include "../ExtrusionEntity.hpp"
#include "../Point.hpp"
#include "../GCodeReader.hpp"
#include <regex>
namespace Slic3r {
class GCodePreviewData;
class GCodeTimeEstimator;
class GCodeAnalyzer
{
public:
static const std::string Extrusion_Role_Tag;
static const std::string Mm3_Per_Mm_Tag;
static const std::string Width_Tag;
static const std::string Height_Tag;
static const std::string Color_Change_Tag;
static const std::string Pause_Print_Tag;
static const std::string Custom_Code_Tag;
static const std::string End_Pause_Print_Or_Custom_Code_Tag;
static const float Default_mm3_per_mm;
static const float Default_Width;
static const float Default_Height;
enum EUnits : unsigned char
{
Millimeters,
Inches
};
enum EAxis : unsigned char
{
X,
Y,
Z,
E,
Num_Axis
};
enum EPositioningType : unsigned char
{
Absolute,
Relative
};
struct Metadata
{
ExtrusionRole extrusion_role;
unsigned int extruder_id;
float mm3_per_mm;
float width; // mm
float height; // mm
float feedrate; // mm/s
float fan_speed; // percentage
float extruder_temp; //oC
float layer_duration; //s
float layer_elapsed_time; //s
unsigned int cp_color_id;
Metadata();
Metadata(ExtrusionRole extrusion_role, unsigned int extruder_id, float mm3_per_mm,
float width, float height, float feedrate, float fan_speed, float extruder_temp,
float layer_duration, float layer_elapsed_time, unsigned int cp_color_id);
bool operator != (const Metadata& other) const;
};
struct GCodeMove
{
enum EType : unsigned char
{
Noop,
Retract,
Unretract,
Tool_change,
Move,
Extrude,
Num_Types
};
EType type;
Metadata data;
Vec3f start_position;
Vec3f end_position;
float delta_extruder;
GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, float mm3_per_mm,
float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder,
float fan_speed, float extruder_temp, float layer_duration, float layer_elapsed_time, unsigned int cp_color_id);
GCodeMove(EType type, const Metadata& data, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder);
};
typedef std::vector<GCodeMove> GCodeMovesList;
typedef std::map<GCodeMove::EType, GCodeMovesList> TypeToMovesMap;
typedef std::map<unsigned int, Vec2d> ExtruderOffsetsMap;
typedef std::map<unsigned int, unsigned int> ExtruderToColorMap;
private:
struct State
{
EUnits units;
EPositioningType global_positioning_type;
EPositioningType e_local_positioning_type;
Metadata data;
Vec3f start_position = Vec3f::Zero();
float cached_position[5];
float start_extrusion;
float position[Num_Axis];
float origin[Num_Axis];
unsigned int cp_color_counter = 0;
};
private:
State m_state;
GCodeReader m_parser;
TypeToMovesMap m_moves_map;
ExtruderOffsetsMap m_extruder_offsets;
unsigned int m_extruders_count;
GCodeFlavor m_gcode_flavor;
ExtruderToColorMap m_extruder_color;
// The output of process_layer()
std::string m_process_output;
public:
GCodeAnalyzer() { reset(); }
void set_extruder_offsets(const ExtruderOffsetsMap& extruder_offsets) { m_extruder_offsets = extruder_offsets; }
void set_extruders_count(unsigned int count);
void set_extrusion_axis(char axis) { m_parser.set_extrusion_axis(axis); }
void set_gcode_flavor(const GCodeFlavor& flavor) { m_gcode_flavor = flavor; }
// Reinitialize the analyzer
void reset();
// Adds the gcode contained in the given string to the analysis and returns it after removing the workcodes
const std::string& process_gcode(const std::string& gcode);
// Calculates all data needed for gcode visualization
// throws CanceledException through print->throw_if_canceled() (sent by the caller as callback).
void calc_gcode_preview_data(GCodePreviewData& preview_data, GCodeTimeEstimator& time_estimator, std::function<void()> cancel_callback = std::function<void()>());
// Return an estimate of the memory consumed by the time estimator.
size_t memory_used() const;
static bool is_valid_extrusion_role(ExtrusionRole role);
private:
// Processes the given gcode line
void _process_gcode_line(GCodeReader& reader, const GCodeReader::GCodeLine& line);
// Move
void _processG1(const GCodeReader::GCodeLine& line);
// Retract
void _processG10(const GCodeReader::GCodeLine& line);
// Unretract
void _processG11(const GCodeReader::GCodeLine& line);
// Firmware controlled Retract
void _processG22(const GCodeReader::GCodeLine& line);
// Firmware controlled Unretract
void _processG23(const GCodeReader::GCodeLine& line);
// Set to Absolute Positioning
void _processG90(const GCodeReader::GCodeLine& line);
// Set to Relative Positioning
void _processG91(const GCodeReader::GCodeLine& line);
// Set Position
void _processG92(const GCodeReader::GCodeLine& line);
// Set extruder to absolute mode
void _processM82(const GCodeReader::GCodeLine& line);
// Set extruder to relative mode
void _processM83(const GCodeReader::GCodeLine& line);
// Extruder temperature change
void _processM104orM109(const GCodeReader::GCodeLine& line);
// Set fan speed
void _processM106(const GCodeReader::GCodeLine& line);
// Disable fan
void _processM107(const GCodeReader::GCodeLine& line);
// Set tool (MakerWare and Sailfish flavor)
void _processM108orM135(const GCodeReader::GCodeLine& line);
// Recall stored home offsets
void _processM132(const GCodeReader::GCodeLine& line);
// Repetier: Store x, y and z position
void _processM401(const GCodeReader::GCodeLine& line);
// Repetier: Go to stored position
void _processM402(const GCodeReader::GCodeLine& line);
// Processes T line (Select Tool)
void _processT(const std::string& command);
void _processT(const GCodeReader::GCodeLine& line);
// Processes the tags
// Returns true if any tag has been processed
bool _process_tags(const GCodeReader::GCodeLine& line);
// Processes extrusion role tag
void _process_extrusion_role_tag(const std::string& comment, size_t pos);
// Processes mm3_per_mm tag
void _process_mm3_per_mm_tag(const std::string& comment, size_t pos);
// Processes width tag
void _process_width_tag(const std::string& comment, size_t pos);
// Processes height tag
void _process_height_tag(const std::string& comment, size_t pos);
// Processes color change tag
void _process_color_change_tag(unsigned extruder);
// Processes pause print and custom gcode tag
void _process_pause_print_or_custom_code_tag();
// Processes new layer tag
void _process_end_pause_print_or_custom_code_tag();
void _set_units(EUnits units);
EUnits _get_units() const;
void _set_global_positioning_type(EPositioningType type);
EPositioningType _get_global_positioning_type() const;
void _set_e_local_positioning_type(EPositioningType type);
EPositioningType _get_e_local_positioning_type() const;
void _set_extrusion_role(ExtrusionRole extrusion_role);
ExtrusionRole _get_extrusion_role() const;
void _set_extruder_id(unsigned int id);
unsigned int _get_extruder_id() const;
void _set_cp_color_id(unsigned int id);
unsigned int _get_cp_color_id() const;
void _set_mm3_per_mm(float value);
float _get_mm3_per_mm() const;
void _set_width(float width);
float _get_width() const;
void _set_height(float height);
float _get_height() const;
void _set_feedrate(float feedrate_mm_sec);
float _get_feedrate() const;
void _set_extruder_temp(float new_temperature);
float _get_extruder_temp() const;
void _set_fan_speed(float fan_speed_percentage);
float _get_fan_speed() const;
void _set_layer_duration(float layer_duration_sec);
float _get_layer_duration() const;
void _set_axis_position(EAxis axis, float position);
float _get_axis_position(EAxis axis) const;
void _set_axis_origin(EAxis axis, float position);
float _get_axis_origin(EAxis axis) const;
// Sets axes position to zero
void _reset_axes_position();
// Sets origin position to zero
void _reset_axes_origin();
void _set_start_position(const Vec3f& position);
const Vec3f& _get_start_position() const;
void _set_cached_position(unsigned char axis, float position);
float _get_cached_position(unsigned char axis) const;
void _reset_cached_position();
void _set_start_extrusion(float extrusion);
float _get_start_extrusion() const;
float _get_delta_extrusion() const;
// Returns current xyz position (from m_state.position[])
Vec3f _get_end_position() const;
// Adds a new move with the given data
void _store_move(GCodeMove::EType type);
// Checks if the given int is a valid extrusion role (contained into enum ExtrusionRole)
bool _is_valid_extrusion_role(int value) const;
// All the following methods throw CanceledException through print->throw_if_canceled() (sent by the caller as callback).
void _calc_gcode_preview_extrusion_layers(GCodePreviewData& preview_data, GCodeTimeEstimator& time_estimator, std::function<void()> cancel_callback);
void _calc_gcode_preview_travel(GCodePreviewData& preview_data, std::function<void()> cancel_callback);
void _calc_gcode_preview_retractions(GCodePreviewData& preview_data, std::function<void()> cancel_callback);
void _calc_gcode_preview_unretractions(GCodePreviewData& preview_data, std::function<void()> cancel_callback);
};
class BufferData {
public:
std::string raw;
float time;
float speed;
BufferData(std::string line, float time = 0, float speed = 0) : raw(line), time(time), speed(speed) {}
};
class FanMover
{
private:
const std::regex regex_fan_speed;
const float nb_seconds_delay;
const bool with_D_option;
// in unit/second
double current_speed;
float buffer_time_size;
GCodeReader m_parser;
int expected_fan_speed;
int current_fan_speed;
// The output of process_layer()
std::list<BufferData> buffer;
std::string m_process_output;
public:
FanMover(const float nb_seconds_delay, const bool with_D_option) : regex_fan_speed("S[0-9]+"), nb_seconds_delay(nb_seconds_delay), with_D_option(with_D_option){}
// Adds the gcode contained in the given string to the analysis and returns it after removing the workcodes
const std::string& process_gcode(const std::string& gcode);
private:
// Processes the given gcode line
void _process_gcode_line(GCodeReader& reader, const GCodeReader::GCodeLine& line);
};
} // namespace Slic3r
#endif // !ENABLE_GCODE_VIEWER
#endif /* slic3r_GCode_Analyzer_hpp_ */

View File

@ -215,7 +215,7 @@ void FanMover::_remove_slow_fan(int16_t min_speed, float past_sec) {
void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCodeLine& line)
{
// processes 'normal' gcode lines
std::string cmd = line.cmd();
std::string cmd(line.cmd());
double time = 0;
int16_t fan_speed = -1;
if (cmd.length() > 1) {
@ -272,7 +272,7 @@ void FanMover::_process_gcode_line(GCodeReader& reader, const GCodeReader::GCode
while (it != m_buffer.end() && time_count > 0) {
if (time_count - it->time < 0) {
//found something that is lower than us
_put_in_middle_G1(it, time_count, BufferData{ line.cmd(), 0, fan_speed });
_put_in_middle_G1(it, time_count, BufferData( std::string(line.cmd()), 0, fan_speed ));
//found, stop
break;
}

View File

@ -10,6 +10,11 @@
#include <float.h>
#include <assert.h>
#if __has_include(<charconv>)
#include <charconv>
#include <utility>
#endif
#if ENABLE_GCODE_VIEWER
#include <chrono>
@ -171,7 +176,7 @@ void GCodeProcessor::TimeMachine::reset()
prev.reset();
gcode_time.reset();
blocks = std::vector<TimeBlock>();
g1_times_cache = std::vector<float>();
g1_times_cache = std::vector<G1LinesCacheItem>();
std::fill(moves_time.begin(), moves_time.end(), 0.0f);
std::fill(roles_time.begin(), roles_time.end(), 0.0f);
layers_time = std::vector<float>();
@ -293,7 +298,7 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks)
}
layers_time[block.layer_id - 1] += block_time;
}
g1_times_cache.push_back(time);
g1_times_cache.push_back({ block.g1_line_id, time });
}
if (keep_last_n_blocks)
@ -359,7 +364,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
std::string ret;
if (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag) {
if (export_remaining_time_enabled && (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag)) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
@ -372,10 +377,11 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
else if (line == Estimated_Printing_Time_Placeholder_Tag) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
PrintEstimatedTimeStatistics::ETimeMode mode = static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i);
if (mode == PrintEstimatedTimeStatistics::ETimeMode::Normal || machine.enabled) {
char buf[128];
sprintf(buf, "; estimated printing time (%s mode) = %s\n",
(static_cast<PrintEstimatedTimeStatistics::ETimeMode>(i) == PrintEstimatedTimeStatistics::ETimeMode::Normal) ? "normal" : "silent",
(mode == PrintEstimatedTimeStatistics::ETimeMode::Normal) ? "normal" : "silent",
get_time_dhms(machine.time).c_str());
ret += buf;
}
@ -395,12 +401,22 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
return false;
};
// Iterators for the normal and silent cached time estimate entry recently processed, used by process_line_G1.
auto g1_times_cache_it = Slic3r::reserve_vector<std::vector<TimeMachine::G1LinesCacheItem>::const_iterator>(machines.size());
for (const auto& machine : machines)
g1_times_cache_it.emplace_back(machine.g1_times_cache.begin());
// add lines M73 to exported gcode
auto process_line_G1 = [&]() {
if (export_remaining_time_enabled) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedTimeStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled && g1_lines_counter < machine.g1_times_cache.size()) {
float elapsed_time = machine.g1_times_cache[g1_lines_counter];
if (machine.enabled) {
// Skip all machine.g1_times_cache below g1_lines_counter.
auto& it = g1_times_cache_it[i];
while (it != machine.g1_times_cache.end() && it->id < g1_lines_counter)
++it;
if (it != machine.g1_times_cache.end() && it->id == g1_lines_counter) {
float elapsed_time = it->elapsed_time;
std::pair<int, int> to_export = { int(100.0f * elapsed_time / machine.time),
time_in_minutes(machine.time - elapsed_time) };
if (last_exported[i] != to_export) {
@ -410,6 +426,8 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
}
}
}
}
}
};
// helper function to write to disk
@ -470,7 +488,8 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
const std::vector<std::pair<GCodeProcessor::EProducer, std::string>> GCodeProcessor::Producers = {
{ EProducer::PrusaSlicer, "PrusaSlicer" },
{ EProducer::SuperSlicer, "SuperSlicer" },
{ EProducer::SuperSlicer, "SuperSlicer" }, { EProducer::Slic3rPE, "Slic3r Prusa Edition" },
{ EProducer::Slic3r, "Slic3r" },
{ EProducer::Cura, "Cura_SteamEngine" },
{ EProducer::Simplify3D, "Simplify3D" },
{ EProducer::CraftWare, "CraftWare" },
@ -750,6 +769,7 @@ void GCodeProcessor::reset()
m_filament_diameters = std::vector<float>(Min_Extruder_Count, 1.75f);
m_extruded_last_z = 0.0f;
m_g1_line_id = 0;
m_layer_id = 0;
m_cp_color.reset();
@ -780,9 +800,9 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
// parse the gcode file to detect its producer
if (m_producers_enabled) {
m_parser.parse_file(filename, [this](GCodeReader& reader, const GCodeReader::GCodeLine& line) {
std::string cmd = line.cmd();
const std::string_view cmd = line.cmd();
if (cmd.length() == 0) {
std::string comment = line.comment();
const std::string_view comment = line.comment();
if (comment.length() > 1 && detect_producer(comment))
m_parser.quit_parsing_file();
}
@ -790,7 +810,7 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
// if the gcode was produced by SuperSlicer,
// extract the config from it
if (m_producer == EProducer::SuperSlicer) {
if (m_producer == EProducer::PrusaSlicer || m_producer == EProducer::SuperSlicer || m_producer == EProducer::Slic3rPE || m_producer == EProducer::Slic3r) {
DynamicPrintConfig config;
config.apply(FullPrintConfig::defaults());
config.load_from_gcode_file(filename);
@ -827,7 +847,6 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
// post-process to add M73 lines into the gcode
if (m_time_processor.export_remaining_time_enabled)
m_time_processor.post_process(filename);
//update times for resuts
@ -916,7 +935,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line)
// update start position
m_start_position = m_end_position;
std::string cmd = line.cmd();
const std::string_view cmd = line.cmd();
if (cmd.length() > 1) {
// process command lines
switch (::toupper(cmd[0]))
@ -989,64 +1008,105 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line)
}
}
else {
std::string comment = line.comment();
if (comment.length() > 1)
// process tags embedded into comments
process_tags(comment);
const std::string &comment = line.raw();
if (comment.length() > 2 && comment.front() == ';')
// Process tags embedded into comments. Tag comments always start at the start of a line
// with a comment and continue with a tag without any whitespace separator.
process_tags(comment.substr(1));
}
}
void GCodeProcessor::process_tags(const std::string& comment)
static inline bool starts_with(const std::string_view comment, const std::string_view tag)
{
// producers tags
if (m_producers_enabled) {
if (m_producer != EProducer::Unknown) {
if (process_producers_tags(comment))
return;
size_t tag_len = tag.size();
return comment.size() >= tag_len && comment.substr(0, tag_len) == tag;
}
#if __has_include(<charconv>)
template <typename T, typename = void>
struct is_from_chars_convertible : std::false_type {};
template <typename T>
struct is_from_chars_convertible<T, std::void_t<decltype(std::from_chars(std::declval<const char*>(), std::declval<const char*>(), std::declval<T&>()))>> : std::true_type {};
#endif
// Returns true if the number was parsed correctly into out and the number spanned the whole input string.
template<typename T>
[[nodiscard]] static inline bool parse_number(const std::string_view sv, T &out)
{
// https://www.bfilipek.com/2019/07/detect-overload-from-chars.html#example-stdfromchars
#if __has_include(<charconv>)
// Visual Studio 19 supports from_chars all right.
// OSX compiler that we use only implements std::from_chars just for ints.
// GCC that we compile on does not provide <charconv> at all.
if constexpr (is_from_chars_convertible<T>::value) {
auto str_end = sv.data() + sv.size();
auto [end_ptr, error_code] = std::from_chars(sv.data(), str_end, out);
return error_code == std::errc() && end_ptr == str_end;
}
else
#endif
{
// Legacy conversion, which is costly due to having to make a copy of the string before conversion.
try {
assert(sv.size() < 1024);
assert(sv.data() != nullptr);
std::string str { sv };
size_t read = 0;
if constexpr (std::is_same_v<T, int>)
out = std::stoi(str, &read);
else if constexpr (std::is_same_v<T, long>)
out = std::stol(str, &read);
else if constexpr (std::is_same_v<T, float>)
out = std::stof(str, &read);
else if constexpr (std::is_same_v<T, double>)
out = std::stod(str, &read);
return str.size() == read;
} catch (...) {
return false;
}
}
}
void GCodeProcessor::process_tags(const std::string_view comment)
{
// producers tags
if (m_producers_enabled && process_producers_tags(comment))
return;
// extrusion role tag
size_t pos = comment.find(Extrusion_Role_Tag);
if (pos != comment.npos) {
m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(pos + Extrusion_Role_Tag.length()));
if (starts_with(comment, Extrusion_Role_Tag)) {
m_extrusion_role = ExtrusionEntity::string_to_role(comment.substr(Extrusion_Role_Tag.length()));
return;
}
if (!m_producers_enabled || m_producer == EProducer::PrusaSlicer || m_producer == EProducer::SuperSlicer) {
if ( (!m_producers_enabled || m_producer == EProducer::PrusaSlicer || m_producer == EProducer::SuperSlicer) &&
starts_with(comment, Height_Tag)) {
// height tag
pos = comment.find(Height_Tag);
if (pos != comment.npos) {
try {
m_height = std::stof(comment.substr(pos + Height_Tag.length()));
}
catch (...) {
if (! parse_number(comment.substr(Height_Tag.size()), m_height))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ").";
}
return;
}
}
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
// width tag
pos = comment.find(Width_Tag);
if (pos != comment.npos) {
try {
m_width_compare.last_tag_value = std::stof(comment.substr(pos + Width_Tag.length()));
}
catch (...) {
if (starts_with(comment, Width_Tag)) {
if (! parse_number(comment.substr(Width_Tag.size()), m_width_compare.last_tag_value))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ").";
}
return;
}
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
// color change tag
pos = comment.find(Color_Change_Tag);
if (pos != comment.npos) {
pos = comment.find_last_of(",T");
try {
unsigned char extruder_id = (pos == comment.npos) ? 0 : static_cast<unsigned char>(std::stoi(comment.substr(pos + 1)));
if (starts_with(comment, Color_Change_Tag)) {
unsigned char extruder_id = 0;
if (starts_with(comment.substr(Color_Change_Tag.size()), ",T")) {
int eid;
if (! parse_number(comment.substr(Color_Change_Tag.size() + 2), eid) || eid < 0 || eid > 255) {
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ").";
return;
}
extruder_id = static_cast<unsigned char>(eid);
}
m_extruder_colors[extruder_id] = static_cast<unsigned char>(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview
++m_cp_color.counter;
@ -1059,52 +1119,40 @@ void GCodeProcessor::process_tags(const std::string& comment)
}
process_custom_gcode_time(CustomGCode::ColorChange);
}
catch (...) {
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ").";
}
return;
}
// pause print tag
pos = comment.find(Pause_Print_Tag);
if (pos != comment.npos) {
if (comment == Pause_Print_Tag) {
store_move_vertex(EMoveType::Pause_Print);
process_custom_gcode_time(CustomGCode::PausePrint);
return;
}
// custom code tag
pos = comment.find(Custom_Code_Tag);
if (pos != comment.npos) {
if (comment == Custom_Code_Tag) {
store_move_vertex(EMoveType::Custom_GCode);
return;
}
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
// mm3_per_mm print tag
pos = comment.find(Mm3_Per_Mm_Tag);
if (pos != comment.npos) {
try {
m_mm3_per_mm_compare.last_tag_value = std::stof(comment.substr(pos + Mm3_Per_Mm_Tag.length()));
}
catch (...) {
if (starts_with(comment, Mm3_Per_Mm_Tag)) {
if (! parse_number(comment.substr(Mm3_Per_Mm_Tag.size()), m_mm3_per_mm_compare.last_tag_value))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Mm3_Per_Mm (" << comment << ").";
}
return;
}
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
// layer change tag
pos = comment.find(Layer_Change_Tag);
if (pos != comment.npos) {
if (comment == Layer_Change_Tag) {
++m_layer_id;
return;
}
}
bool GCodeProcessor::process_producers_tags(const std::string& comment)
bool GCodeProcessor::process_producers_tags(const std::string_view comment)
{
switch (m_producer)
{
@ -1118,18 +1166,18 @@ bool GCodeProcessor::process_producers_tags(const std::string& comment)
}
}
bool GCodeProcessor::process_prusaslicer_tags(const std::string& comment)
bool GCodeProcessor::process_prusaslicer_tags(const std::string_view comment)
{
return false;
}
bool GCodeProcessor::process_cura_tags(const std::string& comment)
bool GCodeProcessor::process_cura_tags(const std::string_view comment)
{
// TYPE -> extrusion role
std::string tag = "TYPE:";
size_t pos = comment.find(tag);
if (pos != comment.npos) {
std::string type = comment.substr(pos + tag.length());
const std::string_view type = comment.substr(pos + tag.length());
if (type == "SKIRT")
m_extrusion_role = erSkirt;
else if (type == "WALL-OUTER")
@ -1158,7 +1206,7 @@ bool GCodeProcessor::process_cura_tags(const std::string& comment)
tag = "FLAVOR:";
pos = comment.find(tag);
if (pos != comment.npos) {
std::string flavor = comment.substr(pos + tag.length());
const std::string_view flavor = comment.substr(pos + tag.length());
if (flavor == "BFB")
m_flavor = gcfMarlin; // << ???????????????????????
else if (flavor == "Mach3")
@ -1188,7 +1236,7 @@ bool GCodeProcessor::process_cura_tags(const std::string& comment)
return false;
}
bool GCodeProcessor::process_simplify3d_tags(const std::string& comment)
bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment)
{
// extrusion roles
@ -1276,7 +1324,7 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment)
std::string tag = " tool";
pos = comment.find(tag);
if (pos == 0) {
std::string data = comment.substr(pos + tag.length());
const std::string_view data = comment.substr(pos + tag.length());
std::string h_tag = "H";
size_t h_start = data.find(h_tag);
size_t h_end = data.find_first_of(' ', h_start);
@ -1284,21 +1332,13 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment)
size_t w_start = data.find(w_tag);
size_t w_end = data.find_first_of(' ', w_start);
if (h_start != data.npos) {
try {
m_height_compare.last_tag_value = std::stof(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end));
}
catch (...) {
if (! parse_number(data.substr(h_start + 1, (h_end != data.npos) ? h_end - h_start - 1 : h_end), m_height_compare.last_tag_value))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ").";
}
}
if (w_start != data.npos) {
try {
m_width_compare.last_tag_value = std::stof(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end));
}
catch (...) {
if (! parse_number(data.substr(w_start + 1, (w_end != data.npos) ? w_end - w_start - 1 : w_end), m_width_compare.last_tag_value))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ").";
}
}
return true;
}
@ -1307,13 +1347,13 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string& comment)
return false;
}
bool GCodeProcessor::process_craftware_tags(const std::string& comment)
bool GCodeProcessor::process_craftware_tags(const std::string_view comment)
{
// segType -> extrusion role
std::string tag = "segType:";
size_t pos = comment.find(tag);
if (pos != comment.npos) {
std::string type = comment.substr(pos + tag.length());
const std::string_view type = comment.substr(pos + tag.length());
if (type == "Skirt")
m_extrusion_role = erSkirt;
else if (type == "Perimeter")
@ -1347,13 +1387,13 @@ bool GCodeProcessor::process_craftware_tags(const std::string& comment)
return false;
}
bool GCodeProcessor::process_ideamaker_tags(const std::string& comment)
bool GCodeProcessor::process_ideamaker_tags(const std::string_view comment)
{
// TYPE -> extrusion role
std::string tag = "TYPE:";
size_t pos = comment.find(tag);
if (pos != comment.npos) {
std::string type = comment.substr(pos + tag.length());
const std::string_view type = comment.substr(pos + tag.length());
if (type == "RAFT")
m_extrusion_role = erSkirt;
else if (type == "WALL-OUTER")
@ -1382,12 +1422,8 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment)
tag = "WIDTH:";
pos = comment.find(tag);
if (pos != comment.npos) {
try {
m_width_compare.last_tag_value = std::stof(comment.substr(pos + tag.length()));
}
catch (...) {
if (! parse_number(comment.substr(pos + tag.length()), m_width_compare.last_tag_value))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ").";
}
return true;
}
@ -1395,12 +1431,8 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment)
tag = "HEIGHT:";
pos = comment.find(tag);
if (pos != comment.npos) {
try {
m_height_compare.last_tag_value = std::stof(comment.substr(pos + tag.length()));
}
catch (...) {
if (! parse_number(comment.substr(pos + tag.length()), m_height_compare.last_tag_value))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ").";
}
return true;
}
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
@ -1408,7 +1440,7 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string& comment)
return false;
}
bool GCodeProcessor::detect_producer(const std::string& comment)
bool GCodeProcessor::detect_producer(const std::string_view comment)
{
for (const auto& [id, search_string] : Producers) {
size_t pos = comment.find(search_string);
@ -1460,6 +1492,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
return type;
};
++m_g1_line_id;
// enable processing of lines M201/M203/M204/M205
m_time_processor.machine_envelope_processing_enabled = true;
@ -1565,6 +1599,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
block.move_type = type;
block.role = m_extrusion_role;
block.distance = distance;
block.g1_line_id = m_g1_line_id;
block.layer_id = m_layer_id;
// calculates block cruise feedrate
@ -2074,11 +2109,14 @@ void GCodeProcessor::process_T(const GCodeReader::GCodeLine& line)
process_T(line.cmd());
}
void GCodeProcessor::process_T(const std::string& command)
void GCodeProcessor::process_T(const std::string_view command)
{
if (command.length() > 1) {
try {
unsigned char id = static_cast<unsigned char>(std::stoi(command.substr(1)));
int eid;
if (! parse_number(command.substr(1), eid) || eid < 0 || eid > 255) {
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << command << ").";
} else {
unsigned char id = static_cast<unsigned char>(eid);
if (m_extruder_id != id) {
unsigned char extruders_count = static_cast<unsigned char>(m_extruder_offsets.size());
if (id >= extruders_count)
@ -2100,11 +2138,8 @@ void GCodeProcessor::process_T(const std::string& command)
store_move_vertex(EMoveType::Tool_change);
}
}
catch (...) {
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid toolchange (" << command << ").";
}
}
}
void GCodeProcessor::store_move_vertex(EMoveType type)
{

View File

@ -11,6 +11,7 @@
#include <array>
#include <vector>
#include <string>
#include <string_view>
namespace Slic3r {
@ -145,6 +146,7 @@ namespace Slic3r {
EMoveType move_type{ EMoveType::Noop };
ExtrusionRole role{ erNone };
unsigned int g1_line_id{ 0 };
unsigned int layer_id{ 0 };
float distance{ 0.0f }; // mm
float acceleration{ 0.0f }; // mm/s^2
@ -182,6 +184,12 @@ namespace Slic3r {
void reset();
};
struct G1LinesCacheItem
{
unsigned int id;
float elapsed_time;
};
bool enabled;
float acceleration; // mm/s^2
// hard limit for the acceleration, to which the firmware will clamp.
@ -194,7 +202,7 @@ namespace Slic3r {
State prev;
CustomGCodeTime gcode_time;
std::vector<TimeBlock> blocks;
std::vector<float> g1_times_cache;
std::vector<G1LinesCacheItem> g1_times_cache;
std::array<float, static_cast<size_t>(EMoveType::Count)> moves_time;
std::array<float, static_cast<size_t>(ExtrusionRole::erCount)> roles_time;
std::vector<float> layers_time;
@ -380,6 +388,7 @@ namespace Slic3r {
ExtruderColors m_extruder_colors;
std::vector<float> m_filament_diameters;
float m_extruded_last_z;
unsigned int m_g1_line_id;
unsigned int m_layer_id;
CpColor m_cp_color;
float m_temperature;
@ -388,7 +397,8 @@ namespace Slic3r {
{
Unknown,
PrusaSlicer,
SuperSlicer,
SuperSlicer, Slic3rPE,
Slic3r,
Cura,
Simplify3D,
CraftWare,
@ -442,15 +452,15 @@ namespace Slic3r {
void process_gcode_line(const GCodeReader::GCodeLine& line);
// Process tags embedded into comments
void process_tags(const std::string& comment);
bool process_producers_tags(const std::string& comment);
bool process_prusaslicer_tags(const std::string& comment);
bool process_cura_tags(const std::string& comment);
bool process_simplify3d_tags(const std::string& comment);
bool process_craftware_tags(const std::string& comment);
bool process_ideamaker_tags(const std::string& comment);
void process_tags(const std::string_view comment);
bool process_producers_tags(const std::string_view comment);
bool process_prusaslicer_tags(const std::string_view comment);
bool process_cura_tags(const std::string_view comment);
bool process_simplify3d_tags(const std::string_view comment);
bool process_craftware_tags(const std::string_view comment);
bool process_ideamaker_tags(const std::string_view comment);
bool detect_producer(const std::string& comment);
bool detect_producer(const std::string_view comment);
// Move
void process_G0(const GCodeReader::GCodeLine& line);
@ -539,7 +549,7 @@ namespace Slic3r {
// Processes T line (Select Tool)
void process_T(const GCodeReader::GCodeLine& line);
void process_T(const std::string& command);
void process_T(const std::string_view command);
void store_move_vertex(EMoveType type);

View File

@ -165,9 +165,10 @@ static inline float parse_float(const char *&line)
return result;
};
#define EXTRUSION_ROLE_TAG ";_EXTRUSION_ROLE:"
bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLine &buf)
{
static constexpr const char *EXTRUSION_ROLE_TAG = ";_EXTRUSION_ROLE:";
if (strncmp(line, EXTRUSION_ROLE_TAG, strlen(EXTRUSION_ROLE_TAG)) == 0) {
line += strlen(EXTRUSION_ROLE_TAG);
int role = atoi(line);

View File

@ -1,4 +1,3 @@
#include "Analyzer.hpp"
#include "PreviewData.hpp"
#include <I18N.hpp>
#include "Utils.hpp"

View File

@ -6,6 +6,7 @@
#include <cstdlib>
#include <functional>
#include <string>
#include <string_view>
#include "PrintConfig.hpp"
namespace Slic3r {
@ -17,13 +18,13 @@ public:
GCodeLine() { reset(); }
void reset() { m_mask = 0; memset(m_axis, 0, sizeof(m_axis)); m_raw.clear(); }
const std::string& raw() const { return m_raw; }
const std::string cmd() const {
const std::string& raw() const { return m_raw; }
const std::string_view cmd() const {
const char *cmd = GCodeReader::skip_whitespaces(m_raw.c_str());
return std::string(cmd, GCodeReader::skip_word(cmd));
return std::string_view(cmd, GCodeReader::skip_word(cmd) - cmd);
}
const std::string comment() const
{ size_t pos = m_raw.find(';'); return (pos == std::string::npos) ? "" : m_raw.substr(pos + 1); }
const std::string_view comment() const
{ size_t pos = m_raw.find(';'); return (pos == std::string::npos) ? std::string_view() : std::string_view(m_raw).substr(pos + 1); }
bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; }
float value(Axis axis) const { return m_axis[axis]; }

File diff suppressed because it is too large Load Diff

View File

@ -1,524 +0,0 @@
#ifndef slic3r_GCodeTimeEstimator_hpp_
#define slic3r_GCodeTimeEstimator_hpp_
#include "libslic3r.h"
#include "PrintConfig.hpp"
#include "GCodeReader.hpp"
#include "CustomGCode.hpp"
#if !ENABLE_GCODE_VIEWER
#define ENABLE_MOVE_STATS 0
namespace Slic3r {
//
// Some of the algorithms used by class GCodeTimeEstimator were inpired by
// Cura Engine's class TimeEstimateCalculator
// https://github.com/Ultimaker/CuraEngine/blob/master/src/timeEstimate.h
//
class GCodeTimeEstimator
{
public:
static const std::string Normal_First_M73_Output_Placeholder_Tag;
static const std::string Silent_First_M73_Output_Placeholder_Tag;
static const std::string Normal_Last_M73_Output_Placeholder_Tag;
static const std::string Silent_Last_M73_Output_Placeholder_Tag;
static const std::string Color_Change_Tag;
static const std::string Pause_Print_Tag;
enum EMode : unsigned char
{
Normal,
Silent
};
enum EUnits : unsigned char
{
Millimeters,
Inches
};
enum EAxis : unsigned char
{
X,
Y,
Z,
E,
Num_Axis
};
enum EPositioningType : unsigned char
{
Absolute,
Relative
};
private:
struct Axis
{
float position; // mm
float origin; // mm
float max_feedrate; // mm/s
float max_acceleration; // mm/s^2
float max_jerk; // mm/s
};
struct Feedrates
{
float feedrate; // mm/s
float axis_feedrate[Num_Axis]; // mm/s
float abs_axis_feedrate[Num_Axis]; // mm/s
float safe_feedrate; // mm/s
void reset();
};
struct State
{
GCodeFlavor dialect;
EUnits units;
EPositioningType global_positioning_type;
EPositioningType e_local_positioning_type;
Axis axis[Num_Axis];
float feedrate; // mm/s
float acceleration; // mm/s^2
// hard limit for the acceleration, to which the firmware will clamp.
float max_acceleration; // mm/s^2
float travel_acceleration; // mm/s^2
// hard limit for the travel_acceleration, to which the firmware will clamp.
float max_travel_acceleration; // mm/s^2
float retract_acceleration; // mm/s^2
float minimum_feedrate; // mm/s
float minimum_travel_feedrate; // mm/s
float extrude_factor_override_percentage;
// Additional load / unload times for a filament exchange sequence.
std::vector<float> filament_load_times;
std::vector<float> filament_unload_times;
unsigned int g1_line_id;
// extruder_id is currently used to correctly calculate filament load / unload times
// into the total print time. This is currently only really used by the MK3 MMU2:
// Extruder id (-1) means no filament is loaded yet, all the filaments are parked in the MK3 MMU2 unit.
static const unsigned int extruder_id_unloaded = (unsigned int)-1;
unsigned int extruder_id;
};
public:
struct Block
{
#if ENABLE_MOVE_STATS
enum EMoveType : unsigned char
{
Noop,
Retract,
Unretract,
Tool_change,
Move,
Extrude,
Num_Types
};
#endif // ENABLE_MOVE_STATS
struct FeedrateProfile
{
float entry; // mm/s
float cruise; // mm/s
float exit; // mm/s
};
struct Trapezoid
{
float accelerate_until; // mm
float decelerate_after; // mm
float cruise_feedrate; // mm/sec
float acceleration_time(float entry_feedrate, float acceleration) const;
float cruise_time() const;
float deceleration_time(float distance, float acceleration) const;
float cruise_distance() const;
// This function gives the time needed to accelerate from an initial speed to reach a final distance.
static float acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration);
// This function gives the final speed while accelerating at the given constant acceleration from the given initial speed along the given distance.
static float speed_from_distance(float initial_feedrate, float distance, float acceleration);
};
struct Flags
{
bool recalculate;
bool nominal_length;
};
#if ENABLE_MOVE_STATS
EMoveType move_type;
#endif // ENABLE_MOVE_STATS
Flags flags;
float distance; // mm
float z;
float acceleration; // mm/s^2
float max_entry_speed; // mm/s
float safe_feedrate; // mm/s
FeedrateProfile feedrate;
Trapezoid trapezoid;
float duration;
// Ordnary index of this G1 line in the file.
int g1_line_id { -1 };
// Returns the time spent accelerating toward cruise speed, in seconds
float acceleration_time() const;
// Returns the time spent at cruise speed, in seconds
float cruise_time() const;
// Returns the time spent decelerating from cruise speed, in seconds
float deceleration_time() const;
// Returns the distance covered at cruise speed, in mm
float cruise_distance() const;
// Calculates this block's trapezoid
void calculate_trapezoid();
// Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the
// acceleration within the allotted distance.
static float max_allowable_speed(float acceleration, float target_velocity, float distance);
// Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the given acceleration:
static float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration);
// This function gives you the point at which you must start braking (at the rate of -acceleration) if
// you started at speed initial_rate and accelerated until this point and want to end at the final_rate after
// a total travel of distance. This can be used to compute the intersection point between acceleration and
// deceleration in the cases where the trapezoid has no plateau (i.e. never reaches maximum speed)
static float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance);
};
typedef std::vector<Block> BlocksList;
struct Layer
{
float z;
float duration;
float min_time;
Layer(float z, float duration, float min_time)
: z(z), duration(duration), min_time(min_time)
{}
};
typedef std::vector<Layer> LayersList;
#if ENABLE_MOVE_STATS
struct MoveStats
{
unsigned int count;
float time;
MoveStats();
};
typedef std::map<Block::EMoveType, MoveStats> MovesStatsMap;
#endif // ENABLE_MOVE_STATS
public:
typedef std::pair<int, float> G1LineIdTime;
typedef std::vector<G1LineIdTime> G1LineIdsTimes;
struct PostProcessData
{
const G1LineIdsTimes& g1_times;
float time;
};
private:
EMode m_mode;
GCodeReader m_parser;
State m_state;
Feedrates m_curr;
Feedrates m_prev;
BlocksList m_blocks;
LayersList m_layers;
// Size of the firmware planner queue. The old 8-bit Marlins usually just managed 16 trapezoidal blocks.
// Let's be conservative and plan for newer boards with more memory.
static constexpr size_t planner_queue_size = 64;
// The firmware recalculates last planner_queue_size trapezoidal blocks each time a new block is added.
// We are not simulating the firmware exactly, we calculate a sequence of blocks once a reasonable number of blocks accumulate.
static constexpr size_t planner_refresh_if_larger = planner_queue_size * 4;
// Map from g1 line id to its elapsed time from the start of the print.
G1LineIdsTimes m_g1_times;
float m_time; // s
// data to calculate custom code times
bool m_needs_custom_gcode_times;
std::vector<std::pair<CustomGCode::Type, float>> m_custom_gcode_times;
float m_custom_gcode_time_cache;
#if ENABLE_MOVE_STATS
MovesStatsMap _moves_stats;
#endif // ENABLE_MOVE_STATS
public:
explicit GCodeTimeEstimator(EMode mode);
// Adds the given gcode line
void add_gcode_line(const std::string& gcode_line);
void add_gcode_block(const char *ptr);
void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); }
// Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block()
// start_from_beginning:
// if set to true all blocks will be used to calculate the time estimate,
// if set to false only the blocks not yet processed will be used and the calculated time will be added to the current calculated time
void calculate_time(bool start_from_beginning);
// Calculates the time estimate from the given gcode in string format
//void calculate_time_from_text(const std::string& gcode);
// Calculates the time estimate from the gcode contained in the file with the given filename
//void calculate_time_from_file(const std::string& file);
// Calculates the time estimate from the gcode contained in given list of gcode lines
//void calculate_time_from_lines(const std::vector<std::string>& gcode_lines);
// Process the gcode contained in the file with the given filename,
// replacing placeholders with correspondent new lines M73
// placing new lines M73 (containing the remaining time) where needed (in dependence of the given interval in seconds)
// and removing working tags (as those used for color changes)
// if normal_mode == nullptr no M73 line will be added for normal mode
// if silent_mode == nullptr no M73 line will be added for silent mode
static bool post_process(const std::string& filename, float interval_sec, const PostProcessData* const normal_mode, const PostProcessData* const silent_mode);
// Set current position on the given axis with the given value
void set_axis_position(EAxis axis, float position);
// Set current origin on the given axis with the given value
void set_axis_origin(EAxis axis, float position);
void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec);
void set_axis_max_acceleration(EAxis axis, float acceleration);
void set_axis_max_jerk(EAxis axis, float jerk);
// Returns current position on the given axis
float get_axis_position(EAxis axis) const;
// Returns current origin on the given axis
float get_axis_origin(EAxis axis) const;
float get_axis_max_feedrate(EAxis axis) const;
float get_axis_max_acceleration(EAxis axis) const;
float get_axis_max_jerk(EAxis axis) const;
void set_feedrate(float feedrate_mm_sec);
float get_feedrate() const;
void set_acceleration(float acceleration_mm_sec2);
float get_acceleration() const;
// Maximum acceleration for the machine. The firmware simulator will clamp the M204 Sxxx to this maximum.
void set_max_acceleration(float acceleration_mm_sec2);
float get_max_acceleration() const;
void set_travel_acceleration(float acceleration_mm_sec2);
float get_travel_acceleration() const;
// Maximum acceleration for the machine. The firmware simulator will clamp the M204 Txxx to this maximum.
void set_max_travel_acceleration(float acceleration_mm_sec2);
float get_max_travel_acceleration() const;
void set_retract_acceleration(float acceleration_mm_sec2);
float get_retract_acceleration() const;
void set_minimum_feedrate(float feedrate_mm_sec);
float get_minimum_feedrate() const;
void set_minimum_travel_feedrate(float feedrate_mm_sec);
float get_minimum_travel_feedrate() const;
void set_filament_load_times(const std::vector<double> &filament_load_times);
void set_filament_unload_times(const std::vector<double> &filament_unload_times);
float get_filament_load_time(unsigned int id_extruder);
float get_filament_unload_time(unsigned int id_extruder);
void set_extrude_factor_override_percentage(float percentage);
float get_extrude_factor_override_percentage() const;
void set_dialect(GCodeFlavor dialect);
GCodeFlavor get_dialect() const;
void set_units(EUnits units);
EUnits get_units() const;
void set_global_positioning_type(EPositioningType type);
EPositioningType get_global_positioning_type() const;
void set_e_local_positioning_type(EPositioningType type);
EPositioningType get_e_local_positioning_type() const;
int get_g1_line_id() const;
void increment_g1_line_id();
void reset_g1_line_id();
void set_extrusion_axis(char axis) { m_parser.set_extrusion_axis(axis); }
void set_extruder_id(unsigned int id);
unsigned int get_extruder_id() const;
void reset_extruder_id();
//function for layer duration
void calculate_layer_duration();
float get_layer_duration(float z);
float get_layer_time(float z);
void reset_layers();
void set_default();
// Call this method before to start adding lines using add_gcode_line() when reusing an instance of GCodeTimeEstimator
void reset();
// multiply the stored time by a factor.
void scale_time(float scaling);
// Returns the estimated time, in seconds
float get_time() const;
// Returns the estimated time, in format DDd HHh MMm SSs
std::string get_time_dhms() const;
// Returns the estimated time, in format DDd HHh MMm
std::string get_time_dhm() const;
// Returns the estimated time, in minutes (integer)
std::string get_time_minutes() const;
// Returns the estimated time, in seconds, for each custom gcode
std::vector<std::pair<CustomGCode::Type, float>> get_custom_gcode_times() const;
// Returns the estimated time, in format DDd HHh MMm SSs, for each color
// If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)"
std::vector<std::string> get_color_times_dhms(bool include_remaining) const;
// Returns the estimated time, in minutes (integer), for each color
// If include_remaining==true the strings will be formatted as: "time for color (remaining time at color start)"
std::vector<std::string> get_color_times_minutes(bool include_remaining) const;
//TODO: check if I can remove that
// Returns the estimated time, in format DDd HHh MMm, for each custom_gcode
// If include_remaining==true the strings will be formatted as: "time for custom_gcode (remaining time at color start)"
std::vector<std::pair<CustomGCode::Type, std::string>> get_custom_gcode_times_dhm(bool include_remaining) const;
// Return an estimate of the memory consumed by the time estimator.
size_t memory_used() const;
PostProcessData get_post_process_data() const { return PostProcessData{ m_g1_times, m_time }; }
private:
void _reset();
void _reset_time();
void _reset_blocks();
// Calculates the time estimate
void _calculate_time(size_t keep_last_n_blocks);
// Processes the given gcode line
void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line);
// Move
void _processG1(const GCodeReader::GCodeLine& line);
// Dwell
void _processG4(const GCodeReader::GCodeLine& line);
// Set Units to Inches
void _processG20(const GCodeReader::GCodeLine& line);
// Set Units to Millimeters
void _processG21(const GCodeReader::GCodeLine& line);
// Move to Origin (Home)
void _processG28(const GCodeReader::GCodeLine& line);
// Set to Absolute Positioning
void _processG90(const GCodeReader::GCodeLine& line);
// Set to Relative Positioning
void _processG91(const GCodeReader::GCodeLine& line);
// Set Position
void _processG92(const GCodeReader::GCodeLine& line);
// Sleep or Conditional stop
void _processM1(const GCodeReader::GCodeLine& line);
// Set extruder to absolute mode
void _processM82(const GCodeReader::GCodeLine& line);
// Set extruder to relative mode
void _processM83(const GCodeReader::GCodeLine& line);
// Set Extruder Temperature and Wait
void _processM109(const GCodeReader::GCodeLine& line);
// Set max printing acceleration
void _processM201(const GCodeReader::GCodeLine& line);
// Set maximum feedrate
void _processM203(const GCodeReader::GCodeLine& line);
// Set default acceleration
void _processM204(const GCodeReader::GCodeLine& line);
// Advanced settings
void _processM205(const GCodeReader::GCodeLine& line);
// Set extrude factor override percentage
void _processM221(const GCodeReader::GCodeLine& line);
// Set allowable instantaneous speed change
void _processM566(const GCodeReader::GCodeLine& line);
// Unload the current filament into the MK3 MMU2 unit at the end of print.
void _processM702(const GCodeReader::GCodeLine& line);
// Processes T line (Select Tool)
void _processT(const GCodeReader::GCodeLine& line);
// Processes the tags
// Returns true if any tag has been processed
bool _process_tags(const GCodeReader::GCodeLine& line);
// Processes ColorChangeTag and PausePrintTag
void _process_custom_gcode_tag(CustomGCode::Type code);
// Simulates firmware st_synchronize() call
void _simulate_st_synchronize(float additional_time);
void _forward_pass();
void _reverse_pass();
void _planner_forward_pass_kernel(Block& prev, Block& curr);
void _planner_reverse_pass_kernel(Block& curr, Block& next);
void _recalculate_trapezoids();
// Returns the given time is seconds in format DDd HHh MMm SSs
static std::string _get_time_dhms(float time_in_secs);
// Returns the given time is minutes in format DDd HHh MMm
static std::string _get_time_dhm(float time_in_secs);
// Returns the given, in minutes (integer)
static std::string _get_time_minutes(float time_in_secs);
#if ENABLE_MOVE_STATS
void _log_moves_stats() const;
#endif // ENABLE_MOVE_STATS
};
} /* namespace Slic3r */
#endif // !ENABLE_GCODE_VIEWER
#endif /* slic3r_GCodeTimeEstimator_hpp_ */

View File

@ -645,10 +645,11 @@ const std::vector<std::string>& Preset::printer_options()
"fan_kickstart",
"fan_speedup_overhangs",
"fan_speedup_time",
"gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
"gcode_flavor", "use_relative_e_distances",
"use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
"min_length",
"host_type", "print_host", "printhost_apikey", "printhost_cafile", "printhost_slug",
//FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
"host_type", "print_host", "printhost_apikey", "printhost_cafile", "printhost_port",
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
"color_change_gcode", "pause_print_gcode", "template_custom_gcode", "feature_gcode",
@ -783,7 +784,8 @@ const std::vector<std::string>& Preset::sla_printer_options()
"gamma_correction",
"min_exposure_time", "max_exposure_time",
"min_initial_exposure_time", "max_initial_exposure_time",
"print_host", "printhost_apikey", "printhost_cafile", "printhost_slug",
//FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
"print_host", "printhost_apikey", "printhost_cafile", "printhost_port",
"printer_notes",
"inherits",
"thumbnails",
@ -904,42 +906,6 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string
return this->load_preset(path, name, std::move(cfg), select);
}
enum class ProfileHostParams
{
Same,
Different,
Anonymized,
};
static ProfileHostParams profile_host_params_same_or_anonymized(const DynamicPrintConfig &cfg_old, const DynamicPrintConfig &cfg_new)
{
auto opt_print_host_old = cfg_old.option<ConfigOptionString>("print_host");
auto opt_printhost_apikey_old = cfg_old.option<ConfigOptionString>("printhost_apikey");
auto opt_printhost_cafile_old = cfg_old.option<ConfigOptionString>("printhost_cafile");
auto opt_printhost_slug_old = cfg_old.option<ConfigOptionString>("printhost_slug");
auto opt_print_host_new = cfg_new.option<ConfigOptionString>("print_host");
auto opt_printhost_apikey_new = cfg_new.option<ConfigOptionString>("printhost_apikey");
auto opt_printhost_cafile_new = cfg_new.option<ConfigOptionString>("printhost_cafile");
auto opt_printhost_slug_new = cfg_new.option<ConfigOptionString>("printhost_slug");
// If the new print host data is undefined, use the old data.
bool new_print_host_undefined = (opt_print_host_new == nullptr || opt_print_host_new ->empty()) &&
(opt_printhost_apikey_new == nullptr || opt_printhost_apikey_new ->empty()) &&
(opt_printhost_cafile_new == nullptr || opt_printhost_cafile_new ->empty()) &&
(opt_printhost_slug_new == nullptr || opt_printhost_slug_new ->empty());
if (new_print_host_undefined)
return ProfileHostParams::Anonymized;
auto opt_same = [](const ConfigOptionString *l, const ConfigOptionString *r) {
return ((l == nullptr || l->empty()) && (r == nullptr || r->empty())) ||
(l != nullptr && r != nullptr && l->value == r->value);
};
return (opt_same(opt_print_host_old, opt_print_host_new) && opt_same(opt_printhost_apikey_old, opt_printhost_apikey_new) &&
opt_same(opt_printhost_cafile_old, opt_printhost_cafile_new) && opt_same(opt_printhost_slug_old, opt_printhost_slug_new))
? ProfileHostParams::Same : ProfileHostParams::Different;
}
static bool profile_print_params_same(const DynamicPrintConfig &cfg_old, const DynamicPrintConfig &cfg_new)
{
t_config_option_keys diff = cfg_old.diff(cfg_new);
@ -949,10 +915,11 @@ static bool profile_print_params_same(const DynamicPrintConfig &cfg_old, const D
"compatible_printers", "compatible_printers_condition", "inherits",
"print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id",
"printer_model", "printer_variant", "default_print_profile", "default_filament_profile", "default_sla_print_profile", "default_sla_material_profile",
"print_host", "printhost_apikey", "printhost_slug", "printhost_cafile" })
//FIXME remove the print host keys?
"print_host", "printhost_apikey", "printhost_cafile", "printhost_port" })
diff.erase(std::remove(diff.begin(), diff.end(), key), diff.end());
// Preset with the same name as stored inside the config exists.
return diff.empty() && profile_host_params_same_or_anonymized(cfg_old, cfg_new) != ProfileHostParams::Different;
return diff.empty();
}
// Load a preset from an already parsed config file, insert it into the sorted sequence of presets
@ -981,27 +948,12 @@ Preset& PresetCollection::load_external_preset(
it = this->find_preset_renamed(original_name);
found = it != m_presets.end();
}
if (found) {
if (profile_print_params_same(it->config, cfg)) {
if (found && profile_print_params_same(it->config, cfg)) {
// The preset exists and it matches the values stored inside config.
if (select)
this->select_preset(it - m_presets.begin());
return *it;
}
if (profile_host_params_same_or_anonymized(it->config, cfg) == ProfileHostParams::Anonymized) {
// The project being loaded is anonymized. Replace the empty host keys of the loaded profile with the data from the original profile.
// See "Octoprint Settings when Opening a .3MF file" GH issue #3244
auto opt_update = [it, &cfg](const std::string &opt_key) {
auto opt = it->config.option<ConfigOptionString>(opt_key);
if (opt != nullptr)
cfg.set_key_value(opt_key, opt->clone());
};
opt_update("print_host");
opt_update("printhost_apikey");
opt_update("printhost_cafile");
opt_update("printhost_slug");
}
}
// Update the "inherits" field.
std::string &inherits = Preset::inherits(cfg);
if (found && inherits.empty()) {
@ -1579,7 +1531,7 @@ const std::vector<std::string>& PhysicalPrinter::printer_options()
"print_host",
"printhost_apikey",
"printhost_cafile",
"printhost_slug",
"printhost_port",
"printhost_authorization_type",
// HTTP digest authentization (RFC 2617)
"printhost_user",
@ -1589,19 +1541,12 @@ const std::vector<std::string>& PhysicalPrinter::printer_options()
return s_opts;
}
const std::vector<std::string>& PhysicalPrinter::print_host_options()
{
static std::vector<std::string> s_opts;
if (s_opts.empty()) {
s_opts = {
static constexpr auto legacy_print_host_options = {
"print_host",
"printhost_apikey",
"printhost_cafile",
"printhost_slug"
"printhost_port"
};
}
return s_opts;
}
std::vector<std::string> PhysicalPrinter::presets_with_print_host_information(const PrinterPresetCollection& printer_presets)
{
@ -1615,7 +1560,7 @@ std::vector<std::string> PhysicalPrinter::presets_with_print_host_information(co
bool PhysicalPrinter::has_print_host_information(const DynamicPrintConfig& config)
{
for (const std::string& opt : print_host_options())
for (const char *opt : legacy_print_host_options)
if (!config.opt_string(opt).empty())
return true;
@ -1632,6 +1577,7 @@ bool PhysicalPrinter::has_empty_config() const
return config.opt_string("print_host" ).empty() &&
config.opt_string("printhost_apikey" ).empty() &&
config.opt_string("printhost_cafile" ).empty() &&
config.opt_string("printhost_port" ).empty() &&
config.opt_string("printhost_user" ).empty() &&
config.opt_string("printhost_password").empty() &&
config.opt_string("printhost_slug" ).empty();
@ -1818,9 +1764,7 @@ void PhysicalPrinterCollection::load_printers_from_presets(PrinterPresetCollecti
int cnt=0;
for (Preset& preset: printer_presets) {
DynamicPrintConfig& config = preset.config;
const std::vector<std::string>& options = PhysicalPrinter::print_host_options();
for(const std::string& option : options) {
for(const char* option : legacy_print_host_options) {
if (!config.opt_string(option).empty()) {
// check if printer with those "Print Host upload" options already exist
PhysicalPrinter* existed_printer = find_printer_with_same_config(config);
@ -1839,7 +1783,7 @@ void PhysicalPrinterCollection::load_printers_from_presets(PrinterPresetCollecti
}
// erase "Print Host upload" information from the preset
for (const std::string& opt : options)
for (const char *opt : legacy_print_host_options)
config.opt_string(opt).clear();
// save changes for preset
preset.save();
@ -1847,7 +1791,7 @@ void PhysicalPrinterCollection::load_printers_from_presets(PrinterPresetCollecti
// update those changes for edited preset if it's equal to the preset
Preset& edited = printer_presets.get_edited_preset();
if (preset.name == edited.name) {
for (const std::string& opt : options)
for (const char *opt : legacy_print_host_options)
edited.config.opt_string(opt).clear();
}
@ -1896,7 +1840,7 @@ PhysicalPrinter* PhysicalPrinterCollection::find_printer_with_same_config(const
{
for (const PhysicalPrinter& printer :*this) {
bool is_equal = true;
for (const std::string& opt : PhysicalPrinter::print_host_options())
for (const char *opt : legacy_print_host_options)
if (is_equal && printer.config.opt_string(opt) != config.opt_string(opt))
is_equal = false;

View File

@ -37,11 +37,11 @@ static std::vector<std::string> s_project_options {
const char *PresetBundle::PRUSA_BUNDLE = "PrusaResearch";
PresetBundle::PresetBundle() :
prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
sla_materials(Preset::TYPE_SLA_MATERIAL, Preset::sla_material_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults())),
sla_prints(Preset::TYPE_SLA_PRINT, Preset::sla_print_options(), static_cast<const SLAPrintObjectConfig&>(SLAFullPrintConfig::defaults())),
printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults()), "- default FFF -"),
printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults()), "- default FFF -"),
physical_printers(PhysicalPrinter::printer_options())
{
// The following keys are handled by the UI, they do not have a counterpart in any StaticPrintConfig derived classes,
@ -77,11 +77,12 @@ PresetBundle::PresetBundle() :
for (size_t i = 0; i < 2; ++ i) {
// The following ugly switch is to avoid printers.preset(0) to return the edited instance, as the 0th default is the current one.
Preset &preset = this->printers.default_preset(i);
preset.config.optptr("printer_settings_id", true);
preset.config.optptr("printer_vendor", true);
preset.config.optptr("printer_model", true);
preset.config.optptr("printer_variant", true);
preset.config.optptr("thumbnails", true);
for (const char *key : {
"printer_settings_id", "printer_vendor", "printer_model", "printer_variant", "thumbnails",
//FIXME the following keys are only created here for compatibility to be able to parse legacy Printer profiles.
// These keys are converted to Physical Printer profile. After the conversion, they shall be removed.
"host_type", "print_host", "printhost_apikey", "printhost_cafile"})
preset.config.optptr(key, true);
if (i == 0) {
preset.config.optptr("default_print_profile", true);
preset.config.option<ConfigOptionStrings>("default_filament_profile", true)->values = { "" };
@ -458,7 +459,7 @@ void PresetBundle::load_selections(AppConfig &config, const std::string &preferr
this->update_multi_material_filament_presets();
// Parse the initial physical printer name.
std::string initial_physical_printer_name = remove_ini_suffix(config.get("extras", "physical_printer"));
std::string initial_physical_printer_name = remove_ini_suffix(config.get("presets", "physical_printer"));
// Activate physical printer from the config
if (!initial_physical_printer_name.empty())
@ -482,8 +483,7 @@ void PresetBundle::export_selections(AppConfig &config)
config.set("presets", "sla_print", sla_prints.get_selected_preset_name());
config.set("presets", "sla_material", sla_materials.get_selected_preset_name());
config.set("presets", "printer", printers.get_selected_preset_name());
config.set("extras", "physical_printer", physical_printers.get_selected_full_printer_name());
config.set("presets", "physical_printer", physical_printers.get_selected_full_printer_name());
}
DynamicPrintConfig PresetBundle::full_config() const
@ -496,6 +496,7 @@ DynamicPrintConfig PresetBundle::full_config() const
DynamicPrintConfig PresetBundle::full_config_secure() const
{
DynamicPrintConfig config = this->full_config();
//FIXME legacy, the keys should not be there after conversion to a Physical Printer profile.
config.erase("print_host");
config.erase("printhost_apikey");
config.erase("printhost_cafile");

View File

@ -151,11 +151,11 @@ void PrintConfigDef::init_common_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString(""));
def = this->add("printhost_slug", coString);
def = this->add("printhost_port", coString);
def->label = L("Printer");
def->tooltip = L("Name of the printer");
def->mode = comAdvanced;
def->gui_type = "select_open";
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionString(""));
def = this->add("printhost_cafile", coString);
@ -2883,27 +2883,6 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloat(30));
#endif
def = this->add("serial_port", coString);
def->gui_type = "select_open";
def->label = "";
def->full_label = L("Serial port");
def->category = OptionCategory::general;
def->tooltip = L("USB/serial port for printer connection.");
def->width = 20;
def->set_default_value(new ConfigOptionString(""));
def = this->add("serial_speed", coInt);
def->gui_type = "i_enum_open";
def->label = OptionCategory::general;
def->full_label = L("Serial port speed");
def->tooltip = L("Speed (baud) of USB/serial port for printer connection.");
def->min = 1;
def->max = 300000;
def->enum_values.push_back("115200");
def->enum_values.push_back("250000");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(250000));
def = this->add("skirt_distance", coFloat);
def->label = L("Distance from object");
def->category = OptionCategory::skirtBrim;
@ -4869,7 +4848,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
#ifndef HAS_PRESSURE_EQUALIZER
"max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
"cooling"
"cooling", "serial_port", "serial_speed"
};
// In PrusaSlicer 2.3.0-alpha0 the "monotonous" infill was introduced, which was later renamed to "monotonic".
@ -5295,7 +5274,6 @@ StaticPrintConfig::StaticCache<class Slic3r::PrintRegionConfig> PrintRegionConfi
StaticPrintConfig::StaticCache<class Slic3r::MachineEnvelopeConfig> MachineEnvelopeConfig::s_cache_MachineEnvelopeConfig;
StaticPrintConfig::StaticCache<class Slic3r::GCodeConfig> GCodeConfig::s_cache_GCodeConfig;
StaticPrintConfig::StaticCache<class Slic3r::PrintConfig> PrintConfig::s_cache_PrintConfig;
StaticPrintConfig::StaticCache<class Slic3r::HostConfig> HostConfig::s_cache_HostConfig;
StaticPrintConfig::StaticCache<class Slic3r::FullPrintConfig> FullPrintConfig::s_cache_FullPrintConfig;
StaticPrintConfig::StaticCache<class Slic3r::SLAMaterialConfig> SLAMaterialConfig::s_cache_SLAMaterialConfig;

View File

@ -11,11 +11,10 @@
// class StaticPrintConfig : public StaticConfig
// class PrintObjectConfig : public StaticPrintConfig
// class PrintRegionConfig : public StaticPrintConfig
// class HostConfig : public StaticPrintConfig
// class MachineEnvelopeConfig : public StaticPrintConfig
// class GCodeConfig : public StaticPrintConfig
// class PrintConfig : public MachineEnvelopeConfig, public GCodeConfig
// class FullPrintConfig : PrintObjectConfig,PrintRegionConfig,PrintConfig,HostConfig
// class FullPrintConfig : PrintObjectConfig,PrintRegionConfig,PrintConfig
// class SLAPrintObjectConfig : public StaticPrintConfig
// class SLAMaterialConfig : public StaticPrintConfig
// class SLAPrinterConfig : public StaticPrintConfig
@ -1350,40 +1349,14 @@ protected:
}
};
class HostConfig : public StaticPrintConfig
{
STATIC_PRINT_CONFIG_CACHE(HostConfig)
public:
ConfigOptionEnum<PrintHostType> host_type;
ConfigOptionString print_host;
ConfigOptionString printhost_apikey;
ConfigOptionString printhost_cafile;
ConfigOptionString printhost_slug;
ConfigOptionString serial_port;
ConfigOptionInt serial_speed;
protected:
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
OPT_PTR(host_type);
OPT_PTR(print_host);
OPT_PTR(printhost_apikey);
OPT_PTR(printhost_cafile);
OPT_PTR(printhost_slug);
OPT_PTR(serial_port);
OPT_PTR(serial_speed);
}
};
// This object is mapped to Perl as Slic3r::Config::Full.
class FullPrintConfig :
public PrintObjectConfig,
public PrintRegionConfig,
public PrintConfig,
public HostConfig
public PrintConfig
{
STATIC_PRINT_CONFIG_CACHE_DERIVED(FullPrintConfig)
FullPrintConfig() : PrintObjectConfig(0), PrintRegionConfig(0), PrintConfig(0), HostConfig(0) { initialize_cache(); *this = s_cache_FullPrintConfig.defaults(); }
FullPrintConfig() : PrintObjectConfig(0), PrintRegionConfig(0), PrintConfig(0) { initialize_cache(); *this = s_cache_FullPrintConfig.defaults(); }
public:
// Validate the FullPrintConfig. Returns an empty string on success, otherwise an error message is returned.
@ -1391,13 +1364,12 @@ public:
protected:
// Protected constructor to be called to initialize ConfigCache::m_default.
FullPrintConfig(int) : PrintObjectConfig(0), PrintRegionConfig(0), PrintConfig(0), HostConfig(0) {}
FullPrintConfig(int) : PrintObjectConfig(0), PrintRegionConfig(0), PrintConfig(0) {}
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
this->PrintObjectConfig::initialize(cache, base_ptr);
this->PrintRegionConfig::initialize(cache, base_ptr);
this->PrintConfig ::initialize(cache, base_ptr);
this->HostConfig ::initialize(cache, base_ptr);
}
};

View File

@ -58,4 +58,11 @@
#define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER)
//===================
// 2.3.0.alpha3 techs
//===================
#define ENABLE_2_3_0_ALPHA3 1
#define ENABLE_CTRL_M_ON_WINDOWS (0 && ENABLE_2_3_0_ALPHA3)
#endif // _prusaslicer_technologies_h_

View File

@ -25,12 +25,12 @@ public:
std::string formatted_errorstr() const
{
return L("Error with zip archive") + " " + m_zipname + ": " +
get_errorstr() + "!";
get_errorstr();
}
SLIC3R_NORETURN void blow_up() const
{
throw Slic3r::RuntimeError(formatted_errorstr());
throw Slic3r::ExportError(formatted_errorstr());
}
bool is_alive()

View File

@ -429,24 +429,20 @@ CopyFileResult copy_file_inner(const std::string& from, const std::string& to, s
// the copy_file() function will fail appropriately and we don't want the permission()
// calls to cause needless failures on permissionless filesystems (ie. FATs on SD cards etc.)
// or when the target file doesn't exist.
//This error code is ignored
boost::system::error_code ec;
boost::filesystem::permissions(target, perms, ec);
//if (ec)
// BOOST_LOG_TRIVIAL(error) << "Copy file permisions before copy error message: " << ec.message();
// This error code is passed up
if (ec)
BOOST_LOG_TRIVIAL(error) << "boost::filesystem::permisions before copy error message (this could be irrelevant message based on file system): " << ec.message();
ec.clear();
boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, ec);
if (ec) {
error_message = ec.message();
return FAIL_COPY_FILE;
}
//ec.clear();
ec.clear();
boost::filesystem::permissions(target, perms, ec);
//if (ec)
// BOOST_LOG_TRIVIAL(error) << "Copy file permisions after copy error message: " << ec.message();
if (ec)
BOOST_LOG_TRIVIAL(error) << "boost::filesystem::permisions after copy error message (this could be irrelevant message based on file system): " << ec.message();
return SUCCESS;
}

View File

@ -0,0 +1,9 @@
[Desktop Entry]
Name=Prusa GCode viewer
Exec=prusa-slicer --gcodeviewer %F
Icon=PrusaSlicer # TODO: change when the new icon is ready
Terminal=false
Type=Application
MimeType=text/x.gcode;
Categories=Graphics;3DGraphics;
Keywords=3D;Printing;Slicer;

View File

@ -1,9 +1,12 @@
[Desktop Entry]
Name=PrusaSlicer
Exec=prusa-slicer %F
GenericName=3D Printing Software
Icon=PrusaSlicer
Exec=prusa-slicer %F
Terminal=false
Type=Application
MimeType=model/stl;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;application/x-amf;
Categories=Graphics;3DGraphics;
Keywords=3D;Printing;Slicer;
Categories=Graphics;3DGraphics;Engineering;
Keywords=3D;Printing;Slicer;slice;3D;printer;convert;gcode;stl;obj;amf;SLA
StartupNotify=false
StartupWMClass=prusa-slicer

View File

@ -129,6 +129,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Field.hpp
GUI/OptionsGroup.cpp
GUI/OptionsGroup.hpp
GUI/OG_CustomCtrl.cpp
GUI/OG_CustomCtrl.hpp
GUI/BedShapeDialog.cpp
GUI/BedShapeDialog.hpp
GUI/2DBed.cpp

View File

@ -31,8 +31,11 @@ void Snapshot::clear()
this->comment.clear();
this->reason = SNAPSHOT_UNKNOWN;
this->print.clear();
this->sla_print.clear();
this->filaments.clear();
this->sla_material.clear();
this->printer.clear();
this->physical_printer.clear();
}
void Snapshot::load_ini(const std::string &path)
@ -94,6 +97,8 @@ void Snapshot::load_ini(const std::string &path)
for (auto &kvp : section.second) {
if (kvp.first == "print") {
this->print = kvp.second.data();
} else if (kvp.first == "sla_print") {
this->sla_print = kvp.second.data();
} else if (boost::starts_with(kvp.first, "filament")) {
int idx = 0;
if (kvp.first == "filament" || sscanf(kvp.first.c_str(), "filament_%d", &idx) == 1) {
@ -101,8 +106,12 @@ void Snapshot::load_ini(const std::string &path)
this->filaments.resize(idx + 1, std::string());
this->filaments[idx] = kvp.second.data();
}
} else if (kvp.first == "sla_material") {
this->sla_material = kvp.second.data();
} else if (kvp.first == "printer") {
this->printer = kvp.second.data();
} else if (kvp.first == "physical_printer") {
this->physical_printer = kvp.second.data();
}
}
} else if (boost::starts_with(section.first, group_name_vendor) && section.first.size() > group_name_vendor.size()) {
@ -172,10 +181,13 @@ void Snapshot::save_ini(const std::string &path)
// Export the active presets at the time of the snapshot.
c << std::endl << "[presets]" << std::endl;
c << "print = " << this->print << std::endl;
c << "sla_print = " << this->sla_print << std::endl;
c << "filament = " << this->filaments.front() << std::endl;
for (size_t i = 1; i < this->filaments.size(); ++ i)
c << "filament_" << std::to_string(i) << " = " << this->filaments[i] << std::endl;
c << "sla_material = " << this->sla_material << std::endl;
c << "printer = " << this->printer << std::endl;
c << "physical_printer = " << this->physical_printer << std::endl;
// Export the vendor configs.
for (const VendorConfig &vc : this->vendor_configs) {
@ -199,14 +211,17 @@ void Snapshot::export_selections(AppConfig &config) const
{
assert(filaments.size() >= 1);
config.clear_section("presets");
config.set("presets", "print", print);
config.set("presets", "filament", filaments.front());
config.set("presets", "print", print);
config.set("presets", "sla_print", sla_print);
config.set("presets", "filament", filaments.front());
for (unsigned i = 1; i < filaments.size(); ++i) {
char name[64];
sprintf(name, "filament_%u", i);
config.set("presets", name, filaments[i]);
}
config.set("presets", "printer", printer);
config.set("presets", "sla_material", sla_material);
config.set("presets", "printer", printer);
config.set("presets", "physical_printer", physical_printer);
}
void Snapshot::export_vendor_configs(AppConfig &config) const
@ -217,8 +232,10 @@ void Snapshot::export_vendor_configs(AppConfig &config) const
config.set_vendors(std::move(vendors));
}
// Perform a deep compare of the active print / filament / printer / vendor directories.
// Return true if the content of the current print / filament / printer / vendor directories
static constexpr auto snapshot_subdirs = { "print", "sla_print", "filament", "sla_material", "printer", "physical_printer", "vendor" };
// Perform a deep compare of the active print / sla_print / filament / sla_material / printer / physical_printer / vendor directories.
// Return true if the content of the current print / sla_print / filament / sla_material / printer / physical_printer / vendor directories
// matches the state stored in this snapshot.
bool Snapshot::equal_to_active(const AppConfig &app_config) const
{
@ -243,7 +260,7 @@ bool Snapshot::equal_to_active(const AppConfig &app_config) const
// 2) Check, whether this snapshot references the same set of ini files as the current state.
boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
boost::filesystem::path snapshot_dir = boost::filesystem::path(Slic3r::data_dir()) / SLIC3R_SNAPSHOTS_DIR / this->id;
for (const char *subdir : { "print", "filament", "printer", "vendor" }) {
for (const char *subdir : snapshot_subdirs) {
boost::filesystem::path path1 = data_dir / subdir;
boost::filesystem::path path2 = snapshot_dir / subdir;
std::vector<std::string> files1, files2;
@ -369,9 +386,12 @@ const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot:
snapshot.comment = comment;
snapshot.reason = reason;
// Active presets at the time of the snapshot.
snapshot.print = app_config.get("presets", "print");
snapshot.print = app_config.get("presets", "print");
snapshot.sla_print = app_config.get("presets", "sla_print");
snapshot.filaments.emplace_back(app_config.get("presets", "filament"));
snapshot.printer = app_config.get("presets", "printer");
snapshot.sla_material = app_config.get("presets", "sla_material");
snapshot.printer = app_config.get("presets", "printer");
snapshot.physical_printer = app_config.get("presets", "physical_printer");
for (unsigned i = 1; i < 1000; ++ i) {
char name[64];
sprintf(name, "filament_%u", i);
@ -414,7 +434,7 @@ const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot:
boost::filesystem::create_directory(snapshot_dir);
// Backup the presets.
for (const char *subdir : { "print", "filament", "printer", "vendor" })
for (const char *subdir : snapshot_subdirs)
copy_config_dir_single_level(data_dir / subdir, snapshot_dir / subdir);
snapshot.save_ini((snapshot_dir / "snapshot.ini").string());
assert(m_snapshots.empty() || m_snapshots.back().time_captured <= snapshot.time_captured);
@ -438,11 +458,11 @@ void SnapshotDB::restore_snapshot(const Snapshot &snapshot, AppConfig &app_confi
boost::filesystem::path snapshot_db_dir = SnapshotDB::create_db_dir();
boost::filesystem::path snapshot_dir = snapshot_db_dir / snapshot.id;
// Remove existing ini files and restore the ini files from the snapshot.
for (const char *subdir : { "print", "filament", "printer", "vendor" }) {
for (const char *subdir : snapshot_subdirs) {
delete_existing_ini_files(data_dir / subdir);
copy_config_dir_single_level(snapshot_dir / subdir, data_dir / subdir);
}
// Update AppConfig with the selections of the print / filament / printer profiles
// Update AppConfig with the selections of the print / sla_print / filament / sla_material / printer profiles
// and about the installed printer types and variants.
snapshot.export_selections(app_config);
snapshot.export_vendor_configs(app_config);

View File

@ -23,8 +23,11 @@ namespace Config {
// Slic3r.ini
// vendor/
// print/
// sla_print/
// filament/
// sla_material
// printer/
// physical_printer/
class Snapshot
{
public:
@ -42,12 +45,12 @@ public:
void load_ini(const std::string &path);
void save_ini(const std::string &path);
// Export the print / filament / printer selections to be activated into the AppConfig.
// Export the print / sla_print / filament / sla_material / printer selections to be activated into the AppConfig.
void export_selections(AppConfig &config) const;
void export_vendor_configs(AppConfig &config) const;
// Perform a deep compare of the active print / filament / printer / vendor directories.
// Return true if the content of the current print / filament / printer / vendor directories
// Perform a deep compare of the active print / sla_print / filament / sla_material / printer / physical_printer / vendor directories.
// Return true if the content of the current print / sla_print / filament / sla_material / printer / physical_printer / vendor directories
// matches the state stored in this snapshot.
bool equal_to_active(const AppConfig &app_config) const;
@ -65,8 +68,11 @@ public:
// Active presets at the time of the snapshot.
std::string print;
std::string sla_print;
std::vector<std::string> filaments;
std::string sla_material;
std::string printer;
std::string physical_printer;
// Annotation of the vendor configuration stored in the snapshot.
// This information is displayed to the user and used to decide compatibility
@ -97,7 +103,7 @@ public:
size_t load_db();
void update_slic3r_versions(std::vector<Index> &index_db);
// Create a snapshot directory, copy the vendor config bundles, user print/filament/printer profiles,
// Create a snapshot directory, copy the vendor config bundles, user print / sla_print / filament / sla_material / printer / physical_printer profiles,
// create an index.
const Snapshot& take_snapshot(const AppConfig &app_config, Snapshot::Reason reason, const std::string &comment = "");
const Snapshot& restore_snapshot(const std::string &id, AppConfig &app_config);

View File

@ -53,6 +53,24 @@ bool SlicingProcessCompletedEvent::critical_error() const
return true;
}
bool SlicingProcessCompletedEvent::invalidate_plater() const
{
if (critical_error())
{
try {
this->rethrow_exception();
}
catch (const Slic3r::ExportError&) {
// Exception thrown by copying file does not ivalidate plater
return false;
}
catch (...) {
}
return true;
}
return false;
}
std::string SlicingProcessCompletedEvent::format_error_message() const
{
std::string error;
@ -143,19 +161,19 @@ void BackgroundSlicingProcess::process_fff()
switch (copy_ret_val) {
case SUCCESS: break; // no error
case FAIL_COPY_FILE:
throw Slic3r::RuntimeError((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?\nError message: %1%"))) % error_message).str());
throw Slic3r::ExportError((boost::format(_utf8(L("Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?\nError message: %1%"))) % error_message).str());
break;
case FAIL_FILES_DIFFERENT:
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());
throw Slic3r::ExportError((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 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());
throw Slic3r::ExportError((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 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());
throw Slic3r::ExportError((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 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());
throw Slic3r::ExportError((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:
throw Slic3r::RuntimeError(_utf8(L("Unknown error occured during exporting G-code.")));

View File

@ -57,6 +57,8 @@ public:
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;
// Critical errors does invalidate plater except CopyFileError.
bool invalidate_plater() 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.

View File

@ -32,15 +32,6 @@ double Camera::MaxFovDeg = 60.0;
Camera::Camera()
: requires_zoom_to_bed(false)
, m_type(Perspective)
, m_target(Vec3d::Zero())
, m_zenit(45.0f)
, m_zoom(1.0)
, m_distance(DefaultDistance)
, m_gui_scale(1.0)
, m_view_matrix(Transform3d::Identity())
, m_view_rotation(1., 0., 0., 0.)
, m_projection_matrix(Transform3d::Identity())
{
set_default_orientation();
}
@ -58,11 +49,12 @@ std::string Camera::get_type_as_string() const
void Camera::set_type(EType type)
{
if (m_type != type)
{
if (m_type != type) {
m_type = type;
wxGetApp().app_config->set("use_perspective_camera", (m_type == Perspective) ? "1" : "0");
wxGetApp().app_config->save();
if (m_update_config_on_type_change_enabled) {
wxGetApp().app_config->set("use_perspective_camera", (m_type == Perspective) ? "1" : "0");
wxGetApp().app_config->save();
}
}
}

View File

@ -29,19 +29,20 @@ struct Camera
bool requires_zoom_to_bed;
private:
EType m_type;
Vec3d m_target;
float m_zenit;
double m_zoom;
EType m_type{ Perspective };
bool m_update_config_on_type_change_enabled{ false };
Vec3d m_target{ Vec3d::Zero() };
float m_zenit{ 45.0f };
double m_zoom{ 1.0 };
// Distance between camera position and camera target measured along the camera Z axis
mutable double m_distance;
mutable double m_gui_scale;
mutable double m_distance{ DefaultDistance };
mutable double m_gui_scale{ 1.0 };
mutable std::array<int, 4> m_viewport;
mutable Transform3d m_view_matrix;
mutable Transform3d m_view_matrix{ Transform3d::Identity() };
// We are calculating the rotation part of the m_view_matrix from m_view_rotation.
mutable Eigen::Quaterniond m_view_rotation;
mutable Transform3d m_projection_matrix;
mutable Eigen::Quaterniond m_view_rotation{ 1.0, 0.0, 0.0, 0.0 };
mutable Transform3d m_projection_matrix{ Transform3d::Identity() };
mutable std::pair<double, double> m_frustrum_zs;
BoundingBoxf3 m_scene_box;
@ -56,6 +57,8 @@ public:
void set_type(const std::string& type);
void select_next_type();
void enable_update_config_on_type_change(bool enable) { m_update_config_on_type_change_enabled = enable; }
const Vec3d& get_target() const { return m_target; }
void set_target(const Vec3d& target);

View File

@ -48,9 +48,17 @@ static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_eve
text += "</b></font><br>";
// End of row header.
text += _(L("SuperSlicer version")) + ": " + snapshot.slic3r_version_captured.to_string() + "<br>";
bool has_fff = ! snapshot.print.empty() || ! snapshot.filaments.empty();
bool has_sla = ! snapshot.sla_print.empty() || ! snapshot.sla_material.empty();
if (has_fff || ! has_sla) {
text += _(L("print")) + ": " + snapshot.print + "<br>";
text += _(L("filaments")) + ": " + snapshot.filaments.front() + "<br>";
text += _(L("printer")) + ": " + snapshot.printer + "<br>";
}
if (has_sla) {
text += _(L("SLA print")) + ": " + snapshot.sla_print + "<br>";
text += _(L("SLA material")) + ": " + snapshot.sla_material + "<br>";
}
text += _(L("printer")) + ": " + (snapshot.physical_printer.empty() ? snapshot.printer : snapshot.physical_printer) + "<br>";
bool compatible = true;
for (const Config::Snapshot::VendorConfig &vc : snapshot.vendor_configs) {

View File

@ -12,9 +12,7 @@
#include "I18N.hpp"
#include "ExtruderSequenceDialog.hpp"
#include "libslic3r/Print.hpp"
#if ENABLE_GCODE_VIEWER
#include "libslic3r/AppConfig.hpp"
#endif // ENABLE_GCODE_VIEWER
#include <wx/button.h>
#include <wx/dialog.h>
@ -55,11 +53,6 @@ static std::string gcode(Type type)
}
}
static bool is_lower_thumb_editable()
{
return Slic3r::GUI::get_app_config()->get("seq_top_layer_only") == "0";
}
Control::Control( wxWindow *parent,
wxWindowID id,
int lowerValue,
@ -305,6 +298,8 @@ wxSize Control::get_size() const
void Control::get_size(int* w, int* h) const
{
GetSize(w, h);
if (m_draw_mode == dmSequentialGCodeView)
return; // we have no more icons for drawing
is_horizontal() ? *w -= m_lock_icon_dim : *h -= m_lock_icon_dim;
}
@ -481,8 +476,10 @@ void Control::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_
{
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
#if ENABLE_GCODE_VIEWER
if (!m_enable_action_icon)
return;
#endif // ENABLE_GCODE_VIEWER
// suppress add tick on first layer
if (tick == 0)
@ -918,6 +915,10 @@ void Control::draw_revert_icon(wxDC& dc)
void Control::draw_cog_icon(wxDC& dc)
{
#if ENABLE_GCODE_VIEWER
if (m_draw_mode == dmSequentialGCodeView)
return;
#endif // ENABLE_GCODE_VIEWER
int width, height;
get_size(&width, &height);
@ -964,6 +965,13 @@ int Control::get_value_from_position(const wxCoord x, const wxCoord y)
return int(m_min_value + double(height - SLIDER_MARGIN - y) / step + 0.5);
}
bool Control::is_lower_thumb_editable()
{
if (m_draw_mode == dmSequentialGCodeView)
return Slic3r::GUI::get_app_config()->get("seq_top_layer_only") == "0";
return true;
}
bool Control::detect_selected_slider(const wxPoint& pt)
{
if (is_point_in_rect(pt, m_rect_lower_thumb))

View File

@ -293,6 +293,7 @@ protected:
void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const;
void update_thumb_rect(const wxCoord begin_x, const wxCoord begin_y, const SelectedSlider& selection);
bool is_lower_thumb_editable();
bool detect_selected_slider(const wxPoint& pt);
void correct_lower_value();
void correct_higher_value();

View File

@ -13,6 +13,7 @@
#include <wx/tooltip.h>
#include <wx/notebook.h>
#include <boost/algorithm/string/predicate.hpp>
#include "OG_CustomCtrl.hpp"
#ifdef __WXOSX__
#define wxOSX true
@ -63,18 +64,16 @@ Field::~Field()
m_back_to_initial_value = nullptr;
if (m_back_to_sys_value)
m_back_to_sys_value = nullptr;
if (getWindow()) {
wxWindow* win = getWindow();
win->Destroy();
win = nullptr;
}
}
void Field::PostInitialize()
{
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
m_Undo_btn = new RevertButton(m_parent, "bullet_white.png");
m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png");
m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); }));
m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); }));
m_blinking_bmp = new BlinkingBitmap(m_parent);
switch (m_opt.type)
{
@ -95,6 +94,7 @@ void Field::PostInitialize()
// initialize m_unit_value
m_em_unit = em_unit(m_parent);
parent_is_custom_ctrl = dynamic_cast<OG_CustomCtrl*>(m_parent) != nullptr;
BUILD();
@ -217,10 +217,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
break;
}
wxString label = m_Label->GetLabel();
if (label.Last() == '\n') label.RemoveLast();
while (label.Last() == ' ') label.RemoveLast();
if (label.Last() == ':') label.RemoveLast();
wxString label = m_opt.full_label.empty() ? _(m_opt.label) : _(m_opt.full_label);
show_error(m_parent, from_u8((boost::format(_utf8(L("%s doesn't support percentage"))) % label).str()));
set_value(double_to_string(m_opt.min), true);
m_value = m_opt.min;
@ -317,28 +314,14 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
}
}
void Field::msw_rescale(bool rescale_sidetext)
void Field::msw_rescale()
{
m_Undo_to_sys_btn->msw_rescale();
m_Undo_btn->msw_rescale();
m_blinking_bmp->msw_rescale();
// update em_unit value
m_em_unit = em_unit(m_parent);
// update sidetext if it is needed
if (m_side_text && rescale_sidetext)
{
auto size = wxSize(def_width_thinner() * m_em_unit, -1);
m_side_text->SetSize(size);
m_side_text->SetMinSize(size);
}
}
void Field::sys_color_changed()
{
m_Undo_to_sys_btn->msw_rescale();
m_Undo_btn->msw_rescale();
}
template<class T>
@ -399,6 +382,8 @@ void TextCtrl::BUILD() {
const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/;
auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style);
if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)temp->GetSize().GetHeight()/m_em_unit;
temp->SetFont(m_opt.is_code ?
Slic3r::GUI::wxGetApp().code_font():
Slic3r::GUI::wxGetApp().normal_font());
@ -562,16 +547,23 @@ boost::any& TextCtrl::get_value()
return m_value;
}
void TextCtrl::msw_rescale(bool rescale_sidetext/* = false*/)
void TextCtrl::msw_rescale()
{
Field::msw_rescale(rescale_sidetext);
Field::msw_rescale();
auto size = wxSize(def_width() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.height >= 0)
size.SetHeight(m_opt.height*m_em_unit);
else if (parent_is_custom_ctrl && opt_height > 0)
size.SetHeight(lround(opt_height*m_em_unit));
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
if (size != wxDefaultSize)
{
wxTextCtrl* field = dynamic_cast<wxTextCtrl*>(window);
if (parent_is_custom_ctrl)
field->SetSize(size);
else
field->SetMinSize(size);
}
@ -663,7 +655,7 @@ boost::any& CheckBox::get_value()
return m_value;
}
void CheckBox::msw_rescale(bool rescale_sidetext/* = false*/)
void CheckBox::msw_rescale()
{
Field::msw_rescale();
@ -717,6 +709,9 @@ void SpinCtrl::BUILD() {
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
if (m_opt.height < 0 && parent_is_custom_ctrl)
opt_height = (double)temp->GetSize().GetHeight() / m_em_unit;
// XXX: On OS X the wxSpinCtrl widget is made up of two subwidgets, unfortunatelly
// the kill focus event is not propagated to the encompassing widget,
// so we need to bind it on the inner text widget instead. (Ugh.)
@ -798,26 +793,35 @@ void SpinCtrl::propagate_value()
suppress_propagation = false;
}
void SpinCtrl::msw_rescale(bool rescale_sidetext/* = false*/)
void SpinCtrl::msw_rescale()
{
Field::msw_rescale(rescale_sidetext);
Field::msw_rescale();
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height * m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width * m_em_unit);
wxSpinCtrl* field = dynamic_cast<wxSpinCtrl*>(window);
if (parent_is_custom_ctrl)
field->SetSize(wxSize(def_width() * m_em_unit, lround(opt_height * m_em_unit)));
else
field->SetMinSize(wxSize(def_width() * m_em_unit, int(1.9f*field->GetFont().GetPixelSize().y)));
}
#ifdef __WXOSX__
using choice_ctrl = wxBitmapComboBox;
#else
using choice_ctrl = wxComboBox;
#endif // __WXOSX__
void Choice::BUILD() {
wxSize size(def_width_wider() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
wxBitmapComboBox* temp;
choice_ctrl* temp;
if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) {
m_is_editable = true;
temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
}
else {
#ifdef __WXOSX__
@ -825,11 +829,11 @@ void Choice::BUILD() {
* so ToolTip doesn't shown.
* Next workaround helps to solve this problem
*/
temp = new wxBitmapComboBox();
temp = new choice_ctrl();
temp->SetTextCtrlStyle(wxTE_READONLY);
temp->Create(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr);
#else
temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY);
temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY);
#endif //__WXOSX__
}
@ -852,7 +856,8 @@ void Choice::BUILD() {
set_selection();
}
#ifndef __WXGTK__
#ifdef __WXOSX__
//#ifndef __WXGTK__
/* Workaround for a correct rendering of the control without Bitmap (under MSW and OSX):
*
* 1. We should create small Bitmap to fill Bitmaps RefData,
@ -882,7 +887,7 @@ void Choice::BUILD() {
}
double old_val = !m_value.empty() ? boost::any_cast<double>(m_value) : -99999;
if (is_defined_input_value<wxBitmapComboBox>(window, m_opt.type)) {
if (is_defined_input_value<choice_ctrl>(window, m_opt.type)) {
if (fabs(old_val - boost::any_cast<double>(get_value())) <= 0.0001)
return;
else
@ -905,7 +910,7 @@ void Choice::set_selection()
wxString text_value = wxString("");
wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
switch (m_opt.type) {
case coFloat:
case coPercent: {
@ -975,7 +980,7 @@ void Choice::set_value(const std::string& value, bool change_event) //! Redunda
++idx;
}
wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
idx == m_opt.enum_values.size() ?
field->SetValue(value) :
field->SetSelection(idx);
@ -1013,7 +1018,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
{
m_disable_change_event = !change_event;
wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
switch (m_opt.type) {
case coInt:
@ -1093,11 +1098,11 @@ void Choice::set_values(const std::vector<std::string>& values)
// # it looks that Clear() also clears the text field in recent wxWidgets versions,
// # but we want to preserve it
auto ww = dynamic_cast<wxBitmapComboBox*>(window);
auto ww = dynamic_cast<choice_ctrl*>(window);
auto value = ww->GetValue();
ww->Clear();
ww->Append("");
for (auto el : values)
for (const auto &el : values)
ww->Append(wxString(el));
ww->SetValue(value);
@ -1117,9 +1122,29 @@ void Choice::convert_to_enum_value(int ret_enum) {
m_value = static_cast<T>(m_opt.default_value.get()->getInt());
}
//TODO: check if used (from prusa)
void Choice::set_values(const wxArrayString &values)
{
if (values.empty())
return;
m_disable_change_event = true;
// # it looks that Clear() also clears the text field in recent wxWidgets versions,
// # but we want to preserve it
auto ww = dynamic_cast<wxBitmapComboBox*>(window);
auto value = ww->GetValue();
ww->Clear();
ww->Append("");
for (const auto &el : values)
ww->Append(el);
ww->SetValue(value);
m_disable_change_event = false;
}
boost::any& Choice::get_value()
{
wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
wxString ret_str = field->GetValue();
@ -1182,16 +1207,20 @@ boost::any& Choice::get_value()
return m_value;
}
void Choice::msw_rescale(bool rescale_sidetext/* = false*/)
void Choice::enable() { dynamic_cast<choice_ctrl*>(window)->Enable(); };
void Choice::disable() { dynamic_cast<choice_ctrl*>(window)->Disable(); };
void Choice::msw_rescale()
{
Field::msw_rescale();
wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window);
choice_ctrl* field = dynamic_cast<choice_ctrl*>(window);
#ifdef __WXOSX__
const wxString selection = field->GetValue();// field->GetString(index);
/* To correct scaling (set new controll size) of a wxBitmapCombobox
* we need to refill control with new bitmaps. So, in our case :
* 1. clear conrol
* 1. clear control
* 2. add content
* 3. add scaled "empty" bitmap to the at least one item
*/
@ -1224,6 +1253,16 @@ void Choice::msw_rescale(bool rescale_sidetext/* = false*/)
idx == m_opt.enum_values.size() ?
field->SetValue(selection) :
field->SetSelection(idx);
#else
auto size = wxSize(def_width_wider() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0) size.SetHeight(m_opt.height * m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width * m_em_unit);
if (parent_is_custom_ctrl)
field->SetSize(size);
else
field->SetMinSize(size);
#endif
}
void ColourPicker::BUILD()
@ -1247,6 +1286,8 @@ void ColourPicker::BUILD()
}
auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size);
if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)temp->GetSize().GetHeight() / m_em_unit;
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
@ -1303,14 +1344,20 @@ boost::any& ColourPicker::get_value()
return m_value;
}
void ColourPicker::msw_rescale(bool rescale_sidetext/* = false*/)
void ColourPicker::msw_rescale()
{
Field::msw_rescale();
wxColourPickerCtrl* field = dynamic_cast<wxColourPickerCtrl*>(window);
auto size = wxSize(def_width() * m_em_unit, wxDefaultCoord);
if (m_opt.height >= 0) size.SetHeight(m_opt.height * m_em_unit);
if (m_opt.height >= 0)
size.SetHeight(m_opt.height * m_em_unit);
else if (parent_is_custom_ctrl && opt_height > 0)
size.SetHeight(lround(opt_height * m_em_unit));
if (m_opt.width >= 0) size.SetWidth(m_opt.width * m_em_unit);
if (parent_is_custom_ctrl)
field->SetSize(size);
else
field->SetMinSize(size);
if (field->GetColour() == wxTransparentColour)
@ -1331,6 +1378,9 @@ void PointCtrl::BUILD()
x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER);
y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER);
if (parent_is_custom_ctrl && m_opt.height < 0)
opt_height = (double)x_textctrl->GetSize().GetHeight() / m_em_unit;
x_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font());
x_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT);
y_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@ -1348,9 +1398,6 @@ void PointCtrl::BUILD()
temp->Add(static_text_y, 0, wxALIGN_CENTER_VERTICAL, 0);
temp->Add(y_textctrl);
// x_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), x_textctrl->GetId());
// y_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), y_textctrl->GetId());
x_textctrl->Bind(wxEVT_TEXT_ENTER, ([this](wxCommandEvent e) { propagate_value(x_textctrl); }), x_textctrl->GetId());
y_textctrl->Bind(wxEVT_TEXT_ENTER, ([this](wxCommandEvent e) { propagate_value(y_textctrl); }), y_textctrl->GetId());
@ -1364,15 +1411,22 @@ void PointCtrl::BUILD()
y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y));
}
void PointCtrl::msw_rescale(bool rescale_sidetext/* = false*/)
void PointCtrl::msw_rescale()
{
Field::msw_rescale();
const wxSize field_size(4 * m_em_unit, -1);
wxSize field_size(4 * m_em_unit, -1);
if (parent_is_custom_ctrl) {
field_size.SetHeight(lround(opt_height * m_em_unit));
x_textctrl->SetSize(field_size);
y_textctrl->SetSize(field_size);
}
else {
x_textctrl->SetMinSize(field_size);
y_textctrl->SetMinSize(field_size);
}
}
bool PointCtrl::value_was_changed(wxTextCtrl* win)
{
@ -1463,7 +1517,7 @@ void StaticText::BUILD()
temp->SetToolTip(get_tooltip_text(legend));
}
void StaticText::msw_rescale(bool rescale_sidetext/* = false*/)
void StaticText::msw_rescale()
{
Field::msw_rescale();

View File

@ -87,6 +87,8 @@ protected:
void on_set_focus(wxEvent& event);
/// Call the attached on_change method.
void on_change_field();
public:
/// Call the attached m_back_to_initial_value method.
void on_back_to_initial_value();
/// Call the attached m_back_to_sys_value method.
@ -119,6 +121,9 @@ public:
const t_config_option_key m_opt_id;//! {""};
int m_opt_idx = 0;
double opt_height{ 0.0 };
bool parent_is_custom_ctrl{ false };
/// Sets a value for this control.
/// subclasses should overload with a specific version
/// Postcondition: Method does not fire the on_change event.
@ -140,9 +145,6 @@ public:
void field_changed() { on_change_field(); }
// set icon to "UndoToSystemValue" button according to an inheritance of preset
// void set_nonsys_btn_icon(const wxBitmap& icon);
Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {};
Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {};
virtual ~Field();
@ -151,8 +153,6 @@ public:
virtual wxSizer* getSizer() { return nullptr; }
virtual wxWindow* getWindow() { return nullptr; }
wxStaticText* getLabel() { return m_Label; }
bool is_matched(const std::string& string, const std::string& pattern);
void get_value_by_opt_type(wxString& str, const bool check_value = true);
@ -168,7 +168,6 @@ public:
bool set_undo_bitmap(const ScalableBitmap *bmp) {
if (m_undo_bitmap != bmp) {
m_undo_bitmap = bmp;
m_Undo_btn->SetBitmap_(*bmp);
return true;
}
return false;
@ -177,33 +176,21 @@ public:
bool set_undo_to_sys_bitmap(const ScalableBitmap *bmp) {
if (m_undo_to_sys_bitmap != bmp) {
m_undo_to_sys_bitmap = bmp;
m_Undo_to_sys_btn->SetBitmap_(*bmp);
return true;
}
return false;
}
bool set_label_colour(const wxColour *clr) {
if (m_Label == nullptr) return false;
if (m_label_color != clr) {
m_label_color = clr;
m_Label->SetForegroundColour(*clr);
m_Label->Refresh(true);
}
return false;
}
bool set_label_colour_force(const wxColour *clr) {
if (m_Label == nullptr) return false;
m_Label->SetForegroundColour(*clr);
m_Label->Refresh(true);
return false;
}
bool set_undo_tooltip(const wxString *tip) {
if (m_undo_tooltip != tip) {
m_undo_tooltip = tip;
m_Undo_btn->SetToolTip(*tip);
return true;
}
return false;
@ -212,17 +199,16 @@ public:
bool set_undo_to_sys_tooltip(const wxString *tip) {
if (m_undo_to_sys_tooltip != tip) {
m_undo_to_sys_tooltip = tip;
m_Undo_to_sys_btn->SetToolTip(*tip);
return true;
}
return false;
}
void set_side_text_ptr(wxStaticText* side_text) {
m_side_text = side_text;
bool* get_blink_ptr() {
return &m_blink;
}
virtual void msw_rescale(bool rescale_sidetext = false);
virtual void msw_rescale();
void sys_color_changed();
bool get_enter_pressed() const { return bEnterPressed; }
@ -233,26 +219,26 @@ public:
static int def_width_wider() ;
static int def_width_thinner() ;
BlinkingBitmap* blinking_bitmap() const { return m_blinking_bmp;}
const ScalableBitmap* undo_bitmap() { return m_undo_bitmap; }
const wxString* undo_tooltip() { return m_undo_tooltip; }
const ScalableBitmap* undo_to_sys_bitmap() { return m_undo_to_sys_bitmap; }
const wxString* undo_to_sys_tooltip() { return m_undo_to_sys_tooltip; }
const wxColour* label_color() { return m_label_color; }
const bool blink() { return m_blink; }
protected:
RevertButton* m_Undo_btn = nullptr;
// Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
const ScalableBitmap* m_undo_bitmap = nullptr;
const wxString* m_undo_tooltip = nullptr;
RevertButton* m_Undo_to_sys_btn = nullptr;
// Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
const ScalableBitmap* m_undo_to_sys_bitmap = nullptr;
const wxString* m_undo_to_sys_tooltip = nullptr;
BlinkingBitmap* m_blinking_bmp{ nullptr };
bool m_blink{ false };
wxStaticText* m_Label = nullptr;
// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
const wxColour* m_label_color = nullptr;
wxStaticText* m_side_text = nullptr;
// current value
boost::any m_value;
// last maeningful value
@ -308,7 +294,7 @@ public:
boost::any& get_value() override;
void msw_rescale(bool rescale_sidetext = false) override;
void msw_rescale() override;
void enable() override;
void disable() override;
@ -336,7 +322,7 @@ public:
void set_na_value() override;
boost::any& get_value() override;
void msw_rescale(bool rescale_sidetext = false) override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxCheckBox*>(window)->Enable(); }
void disable() override { dynamic_cast<wxCheckBox*>(window)->Disable(); }
@ -379,7 +365,7 @@ public:
return m_value = value;
}
void msw_rescale(bool rescale_sidetext = false) override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); }
void disable() override { dynamic_cast<wxSpinCtrl*>(window)->Disable(); }
@ -410,12 +396,13 @@ public:
void set_value(const std::string& value, bool change_event = false);
void set_value(const boost::any& value, bool change_event = false);
void set_values(const std::vector<std::string> &values);
void set_values(const wxArrayString &values);
boost::any& get_value() override;
void msw_rescale(bool rescale_sidetext = false) override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxBitmapComboBox*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); };
void enable() override ;//{ dynamic_cast<wxBitmapComboBox*>(window)->Enable(); };
void disable() override;//{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); };
wxWindow* getWindow() override { return window; }
};
@ -438,7 +425,7 @@ public:
}
void set_value(const boost::any& value, bool change_event = false) override;
boost::any& get_value() override;
void msw_rescale(bool rescale_sidetext = false) override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxColourPickerCtrl*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxColourPickerCtrl*>(window)->Disable(); };
@ -464,7 +451,7 @@ public:
void set_value(const boost::any& value, bool change_event = false);
boost::any& get_value() override;
void msw_rescale(bool rescale_sidetext = false) override;
void msw_rescale() override;
void enable() override {
x_textctrl->Enable();
@ -500,7 +487,7 @@ public:
boost::any& get_value()override { return m_value; }
void msw_rescale(bool rescale_sidetext = false) override;
void msw_rescale() override;
void enable() override { dynamic_cast<wxStaticText*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxStaticText*>(window)->Disable(); };

View File

@ -303,6 +303,9 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
reset();
load_toolpaths(gcode_result);
if (m_layers_zs.empty())
return;
if (wxGetApp().is_editor())
load_shells(print, initialized);
else {
@ -450,8 +453,39 @@ void GCodeViewer::render() const
auto init_gl_data = [this]() {
static bool first_run = true;
if (first_run) {
// initializes opengl data of TBuffers
for (size_t i = 0; i < m_buffers.size(); ++i) {
TBuffer& buffer = m_buffers[i];
switch (buffer_type(i))
{
default: { break; }
case EMoveType::Tool_change:
case EMoveType::Color_change:
case EMoveType::Pause_Print:
case EMoveType::Custom_GCode:
case EMoveType::Retract:
case EMoveType::Unretract:
{
buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110";
break;
}
case EMoveType::Extrude:
{
buffer.shader = "gouraud_light";
break;
}
case EMoveType::Travel:
{
buffer.shader = "toolpaths_lines";
break;
}
}
}
// initializes tool marker
m_sequential_view.marker.init();
// initializes point sizes
std::array<int, 2> point_sizes;
::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data());
m_detected_point_sizes = { static_cast<float>(point_sizes[0]), static_cast<float>(point_sizes[1]) };
@ -472,8 +506,10 @@ void GCodeViewer::render() const
glsafe(::glEnable(GL_DEPTH_TEST));
render_toolpaths();
if (m_sequential_view.current.last != m_sequential_view.endpoints.last) {
m_sequential_view.marker.set_world_position(m_sequential_view.current_position);
m_sequential_view.marker.render();
}
render_shells();
render_legend();
#if ENABLE_GCODE_VIEWER_STATISTICS
@ -939,6 +975,7 @@ void GCodeViewer::init()
}
}
// initializes non opengl data of TBuffers
for (size_t i = 0; i < m_buffers.size(); ++i) {
TBuffer& buffer = m_buffers[i];
switch (buffer_type(i))
@ -953,21 +990,18 @@ void GCodeViewer::init()
{
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point;
buffer.vertices.format = VBuffer::EFormat::Position;
buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110";
break;
}
case EMoveType::Extrude:
{
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle;
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
buffer.shader = "gouraud_light";
break;
}
case EMoveType::Travel:
{
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line;
buffer.vertices.format = VBuffer::EFormat::PositionNormal1;
buffer.shader = "toolpaths_lines";
break;
}
}
@ -1513,6 +1547,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
}
}
if (progress_dialog != nullptr) {
progress_dialog->Update(100, "");
progress_dialog->Fit();
}
log_memory_usage("Loaded G-code generated indices buffers, ", vertices, indices);
// toolpaths data -> send indices data to gpu
@ -1586,6 +1625,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
}
// set layers z range
if (!m_layers_zs.empty())
m_layers_z_range = { m_layers_zs.front(), m_layers_zs.back() };
// roles -> remove duplicates

View File

@ -357,7 +357,7 @@ public:
Transform3f m_world_transform;
float m_z_offset{ 0.5f };
std::array<float, 4> m_color{ 1.0f, 1.0f, 1.0f, 0.5f };
bool m_visible{ false };
bool m_visible{ true };
public:
void init();

View File

@ -1465,6 +1465,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
#endif // ENABLE_GCODE_VIEWER
wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_JUMP_TO, wxKeyEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_COLLAPSE_SIDEBAR, SimpleEvent);
@ -2907,6 +2908,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
// see include/wx/defs.h enum wxKeyCode
int keyCode = evt.GetKeyCode();
int ctrlMask = wxMOD_CONTROL;
int shiftMask = wxMOD_SHIFT;
auto imgui = wxGetApp().imgui();
if (imgui->update_key_data(evt)) {
@ -2942,6 +2944,15 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
post_event(SimpleEvent(EVT_GLTOOLBAR_COPY));
break;
#if ENABLE_CTRL_M_ON_WINDOWS
case WXK_CONTROL_M:
{
Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller();
controller.show_settings_dialog(!controller.is_settings_dialog_shown());
m_dirty = true;
break;
}
#else
#if defined(__linux__) || defined(__APPLE__)
case WXK_CONTROL_M:
{
@ -2951,6 +2962,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
break;
}
#endif /* __linux__ */
#endif // ENABLE_CTRL_M_ON_WINDOWS
#ifdef __APPLE__
case 'v':
@ -2994,6 +3006,18 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); break;
default: evt.Skip();
}
}
else if ((evt.GetModifiers() & shiftMask) != 0) {
switch (keyCode) {
case 'g':
case 'G': {
if (dynamic_cast<Preview*>(m_canvas->GetParent()) != nullptr)
post_event(wxKeyEvent(EVT_GLCANVAS_JUMP_TO, evt));
break;
}
default:
evt.Skip();
}
} else if (evt.HasModifiers()) {
evt.Skip();
} else {
@ -3217,7 +3241,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
// m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux
post_event(SimpleEvent(EVT_GLCANVAS_TAB));
}
else if (keyCode == WXK_TAB && evt.ShiftDown()) {
else if (keyCode == WXK_TAB && evt.ShiftDown() && ! wxGetApp().is_gcode_viewer()) {
// Collapse side-panel with Shift+Tab
post_event(SimpleEvent(EVT_GLCANVAS_COLLAPSE_SIDEBAR));
}
@ -3356,17 +3380,17 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
if (evt.MiddleIsDown())
return;
if (wxGetApp().imgui()->update_mouse_data(evt)) {
m_dirty = true;
return;
}
#if ENABLE_RETINA_GL
const float scale = m_retina_helper->get_scale_factor();
evt.SetX(evt.GetX() * scale);
evt.SetY(evt.GetY() * scale);
#endif
if (wxGetApp().imgui()->update_mouse_data(evt)) {
m_dirty = true;
return;
}
#ifdef __WXMSW__
// For some reason the Idle event is not being generated after the mouse scroll event in case of scrolling with the two fingers on the touch pad,
// if the event is not allowed to be passed further.
@ -3407,7 +3431,8 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
return;
// Calculate the zoom delta and apply it to the current zoom factor
_update_camera_zoom((double)evt.GetWheelRotation() / (double)evt.GetWheelDelta());
double direction_factor = (wxGetApp().app_config->get("reverse_mouse_wheel_zoom") == "1") ? -1.0 : 1.0;
_update_camera_zoom(direction_factor * (double)evt.GetWheelRotation() / (double)evt.GetWheelDelta());
}
void GLCanvas3D::on_timer(wxTimerEvent& evt)

View File

@ -113,6 +113,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
#endif // ENABLE_GCODE_VIEWER
wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_JUMP_TO, wxKeyEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_COLLAPSE_SIDEBAR, SimpleEvent);

View File

@ -724,6 +724,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.
#if ENABLE_GCODE_VIEWER
if (is_editor()) {
throw Slic3r::RuntimeError(
_u8L("Error parsing PrusaSlicer config file, it is probably corrupted. "
@ -731,11 +732,14 @@ void GUI_App::init_app_config()
"\n\n" + app_config->config_path() + "\n\n" + error);
}
else {
#endif // ENABLE_GCODE_VIEWER
throw Slic3r::RuntimeError(
_u8L("Error parsing PrusaGCodeViewer config file, it is probably corrupted. "
"Try to manually delete the file to recover from the error.") +
"\n\n" + app_config->config_path() + "\n\n" + error);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
}
}
}

View File

@ -359,7 +359,7 @@ bool Preview::init(wxWindow* parent, Model* model)
get_option_type_string(OptionType::PausePrints) + "|0|" +
get_option_type_string(OptionType::CustomGCodes) + "|0|" +
get_option_type_string(OptionType::Shells) + "|0|" +
get_option_type_string(OptionType::ToolMarker) + "|0|" +
get_option_type_string(OptionType::ToolMarker) + "|1|" +
get_option_type_string(OptionType::Legend) + "|1"
);
Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items);
@ -614,6 +614,16 @@ void Preview::msw_rescale()
refresh_print();
}
void Preview::jump_layers_slider(wxKeyEvent& evt)
{
#if ENABLE_GCODE_VIEWER
if (m_layers_slider) m_layers_slider->OnChar(evt);
#else
if (m_slider)
m_slider->OnKeyDown(evt);
#endif // ENABLE_GCODE_VIEWER
}
#if ENABLE_GCODE_VIEWER
void Preview::move_layers_slider(wxKeyEvent& evt)
{
@ -1326,7 +1336,7 @@ void Preview::load_print_as_fff(bool keep_z_range)
// It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature.
// Color by feature if it is a single extruder print.
unsigned int number_extruders = (unsigned int)print->extruders().size();
int tool_idx = m_choice_view_type->FindString(_(L("Tool")));
int tool_idx = m_choice_view_type->FindString(_L("Tool"));
int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type
m_choice_view_type->SetSelection(type);
#if ENABLE_GCODE_VIEWER

View File

@ -190,6 +190,7 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config,
void refresh_print();
void msw_rescale();
void jump_layers_slider(wxKeyEvent& evt);
#if ENABLE_GCODE_VIEWER
void move_layers_slider(wxKeyEvent& evt);
void edit_layers_slider(wxKeyEvent& evt);

View File

@ -232,9 +232,12 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
else {
m_imgui->begin(_L("Autoset custom supports"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
ImGui::AlignTextToFramePadding();
m_imgui->text(_L("Threshold:") + " " + _L("deg"));
m_imgui->text(_L("Threshold:"));
std::string format_str = std::string("%.f") + I18N::translate_utf8("°",
"Degree sign to use in the respective slider in FDM supports gizmo,"
"placed after the number with no whitespace in between.");
ImGui::SameLine();
if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f"))
if (m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, format_str.data()))
m_parent.set_slope_normal_angle(90.f - m_angle_threshold_deg);
if (m_imgui->button(_L("Enforce")))
select_facets_by_angle(m_angle_threshold_deg, false);

View File

@ -104,7 +104,7 @@ bool GLGizmosManager::init()
m_gizmos.emplace_back(new GLGizmoCut(m_parent, "cut.svg", 4));
m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", 5));
m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", 6));
m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "sla_supports.svg", 7));
m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "fdm_supports.svg", 7));
m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "seam.svg", 8));
m_common_gizmos_data.reset(new CommonGizmosDataPool(&m_parent));

View File

@ -49,7 +49,9 @@ static const std::map<const char, std::string> font_icons = {
{ImGui::MinimalizeMarker , "notification_minimalize" },
{ImGui::MinimalizeHoverMarker , "notification_minimalize_hover" },
{ImGui::WarningMarker , "notification_warning" },
{ImGui::ErrorMarker , "notification_error" }
{ImGui::ErrorMarker , "notification_error" },
{ImGui::EjectMarker , "notification_eject_sd" },
{ImGui::EjectHoverMarker , "notification_eject_sd_hover" },
};
const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.333f, 0.333f, 0.333f, 1.0f };

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