mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-14 17:12:07 +00:00
* FIX: linux: fix the building issue on Linux Mint 21.3 Virginia
github: https://github.com/bambulab/BambuStudio/issues/3874
author: https://github.com/lucianoloder
Change-Id: Ia3db6923d5dd68dba532d7bdba6f93f73cc51d59
* FIX: auto-arranging incorrect with rotation enabled
auto-arranging incorrect with rotation enabled and the objects already have been rotated.
jira: STUDIO-6022
Change-Id: I349d663efb1fc71367c8a77aa8ed5047a0bf2017
(cherry picked from commit 75fe40257a274ed83886e1ee20ce8dedd0de48f6)
* ENH: update X1C & X1E start gcode
1.Fix fan problem
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I68ee5be78e142e8a2a210a1a70f5663893390610
* ENH: update A series gcode
1. Update A1 series start gcode and change filament gcode
2. Add G2814 command
3. Add multi-filament extrusion compensation and vibration suppression
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I57d2bc8e98d3e547881dc1369c1fb31413c6205d
* FIX: fix some cali problem of P series
jira: none
Change-Id: Id57ea8d65da22ab653cca49509cb923ff065e43f
* FIX: fix can't enter ',' in multiplicator
github: #3805
Change-Id: I6dd70822d1c2e79d66c70514d6dd580ab029c7ea
* calib wizard
* NEW: FlipLines infill
jira:6701
New infill pattern that combine block lines infill and switching layers for smooth transition.
Change-Id: I2608a2d39b14efcdfe9d39a9437280da350b94c0
(cherry picked from commit 8d0a09c8b763dfc924cbba9913c241e6afadbc7f)
* ENH: add nozzle blob detection and air printing detection
jira: new
Change-Id: Ie4a19a7ad7d0b10a021c516cbc3a84b4ae734302
* FIX: Top surface bridging fail on 3DHC & FL infill
Add 45 degree angle offset when processing the bridge.
Need to raise infill_direction to invalidate posPrepareInfill
jira: 6774
Change-Id: I5e6bef3aa814b01c5f30398ac745937a67e3ef4c
(cherry picked from commit 7b12cab10b88f432a11414f8caa1c6427777a1ba)
* FIX: the error display when reset virtual slot
jira: none
Change-Id: I5ae5899baf1bfc2aaadb832083b277855a669fd5
* FIX: Error "Voronoi cell doesn't contain a sourcepoint"
github: 3859
Change-Id: Idca84992bcba5380bfe05e63ac9a5e40419dcfdf
* fix build error
* FIX: CLI: fix the crash issue caused by get_min_flush_volumes
JIRA: no jira
Change-Id: I0d5bfd605e51ebddac8fddc4d83dab5055b0fbf2
* FIX: can't use support filament in gcode.3mf
1. Add total_filament_volumes, directly access it to get used filaments
github:#3865
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I4fae4f1947b4ebd16e394e0f3cf5fb0e9f979717
* ENH: p series support long retraction
1. P series support long retraction in filament
2. Add long retraction params in common.json
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Ib94184fa1f0b5ab151360f1f053d8c8ff92e7e18
* ENH::modify some logs level
jira:[for log]
Change-Id: I6a46b8fcd3a030b4b630e800fe9a9ac5c387f117
* NEW: support multi device
JIRA: STUDIO-6072
Change-Id: Ic514c4097767b0a728368c9ea48ee103c031fbb0
Signed-off-by: Stone Li <stone.li@bambulab.com>
* ENH: update A1 series gcode
1.Update filament change gcode and machine start gcode for
A1 and A1 mini
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I2f3be3fd89fef21e717a32f2b89985fc046f7f6e
* FIX: always have 0th filament in ams mapping
1. Only set the filament id in map when flush length is not 0
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I6e0aeaf010f6e6dcbdc3bca5c0034aa60750bb67
* ENH: add filament id in slice info
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Ic5fe4632bca8acacc9ffd072ee2ed207c1da37aa
* ENH: refine ui for multi machine
JIRA: STUDIO-6819 STUDIO-6824
1. Shrink the Send Print dialog box
2. add input box for flipping panel
Change-Id: I4174c79ecd239c374ee11478951e12be399c57ce
* FIX: fix Issues with sending multiple devices
JIRA: STUDIO-6876
Signed-off-by: Kunlong Ma <kunlong.ma@bambulab.com>
Change-Id: I33c6a932863fc715c3f0eb5dfd4b299f980a4918
* NEW: support hms error code
Change-Id: Ic256a83cf501fb05bb9d3203f3d24cb1d1290fa4
* FIX:fixed some multi job issue
Change-Id: I338078ad8fcf809888db9d8daeb470a9bf4eab46
* NEW:support pin code binding
Change-Id: Ida5d47881fbd83f3ffedc80369cfe377114d7f13
* ENH:add printable check for devices
Change-Id: I672988fa9cfa986d924bfc64331752f4aef68067
(cherry picked from commit 69de9e5b8334ec94eec7fcee31038b8ff42d1d3b)
* FIX: add more fonts
jira: none
Change-Id: I6bafed3563083858f29e92a3d84906a2e53dcb5c
(cherry picked from commit afbea693e807dcc1c406a59aa5376b9ea2a5d606)
* ENH: load more fonts
this feature is according to Prusa by Filip Sykala<filip.sykala@prusa3d.cz>, thanks to Filip Sykala
jira: none
Change-Id: I55e92f184f750c0b93b679d4382aaa5b164ec5c3
(cherry picked from commit d05522c4cc5d7ee4cac42de398b88d347a55f74b)
* ENH: add ProfileDescription for translate
1.Add ProfileDescription.hpp simply for translating
jira:NEW
Signed-off-by: XunZhangBambu <xun.zhang@bambulab.com>
Change-Id: Iaa3ced1edccf67eaeebde35c1e8b36442d2e9a6f
* ENH: Improve CrossHatch transation layers
jira: 6701
Change name from Flippingline to CrossHatch.
Reduce noise, improve speed by 6.5%. Improve transation layers by
gradually increasing rotation angle and overshoot the transation
layer while direction changed.
Change-Id: I17fcc45b409074d121bf5bb5702e15553d925b51
* UP
* ENH: modify the default config for multi-device
JIRA: STUDIO-6072
Change-Id: If6e7582a8274eb5e685b8b8545f6eab5d17de3f5
Signed-off-by: Stone Li <stone.li@bambulab.com>
* ENH: add long retraction for P series
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I6890695b67e674fc5cdc2a208e89bd9e41404213
* FIX: all plates stats data missing issue
jira: new
Change-Id: I137a2b6d69ad08791f5a9a9788653621960dc63f
* ENH:update pre print options
jira:[for multi]
Change-Id: I2e9bb8a09436a71749af98a0bad94e9922f95c81
* FIX:fixed can't popup pinbind win on macos
jira:[STUDIO-6895]
Change-Id: I664bba78cf27420d736b586df19e3c09c6f8ed21
* FIX:fixed the task of padding cannot be cancelled
Change-Id: I401a22118c14ca7601be7a925cfd8e4796dfc1e9
* ENH:Play video after redirecting to device page
jira:[STUDIO-6884]
Change-Id: Ia5e2ac84e3d71baacfcf941b782dab2325f35d54
* FIX: fix ui bug in send multi machine page for mac
JIRA: STUDIO-6882
Incorrect background color when renaming during multi machine printing
Change-Id: I6c551f5023ffe747e7a7e2f5703b0707c9505922
* FIX: Fix some bugs in maintaining the selected status of local tasks
JIRA: STUDIO-6824
Change-Id: I12c4da3fc56ac5077b3ccd7e89a4b57c3675eaf5
* ENH: local task sort by send time by default
JIRA: STUDIO-6885
Change-Id: I03b5881a39ab2e90c5b9cf46052ba465ee707ccc
* FIX: Clicking to continue printing does not take effect in error code
JIRA: STUDIO-6830
Detected an incomplete printing task error pop-up when power outage occurred. Clicking to continue printing did not take effect
Change-Id: Ie85a1602093dabac861cd1f41ea21e1c312c83e9
* ENH: use designTitle when designId > 0
JIRA: STUDIO-6072
Change-Id: I8342df053edeab16f930522e099e2eef91e5c5a4
Signed-off-by: Stone Li <stone.li@bambulab.com>
* NEW:import vertex and mtl color from obj file
Jira: STUDIO-6805
Change-Id: Iaacb13ee2451effdb83e5aba4b7fe1637b7fc95f
* FIX:change the strategy of merge_ka_kd
Upgrade ui, users can directly ok to proceed to the next step
jira: STUDIO-6805
Change-Id: Ia81019c2eacb503666680c0b8583d026baa0134c
(cherry picked from commit 38a2434753c8e3b422267283b16c75f6ad195b14)
* FIX:use default_strategy after modifed cluster number
jira: STUDIO-6915
Change-Id: I4e0c3d62f5a766f73d48d1e06c4364fc6babe1ac
* FIX: the bug of incorrect button without restarting
JIRA: STUDIO-6824
The bug can cause the user to not restart when opening the multi-device option, but the button of send multi-devices appears
Change-Id: I0837fa79ecc1d8ab5ce98273ad134fa2f830421e
* FIX: wrong default value for long retraction
jira:NEW
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Ifc2ec57a320fdb14e7ca746e5795501ed146ff32
* FIX: error code pop-up window without retry button in some code
JIRA: STUDIO-6922
Change-Id: I67464bebaba4558618301592c455db8824bbfe30
* FIX: air printing and nozzle blob detection issue
jira: STUDIO-6897
Change-Id: I008ddb24b74119d7e4124ae26310b4b86c42a799
* FIX:fix bugs of algo and read quad in obj file
Jira: STUDIO-6805
Change-Id: I6c33e8197225f27dccdfa0681e64d76d1df14f61
* dd
* ENH:Set the default nozzle diameter to 0.4
jira:[for nozzle]
Change-Id: I74a5c9b0460046496b897eae3d9f917ac1b99052
* FIX:fixed backspace error on macos
Change-Id: I76066391783c04857c1a60a6f8438111501b6d7c
* ENH:Subscription list deduplication
jira:[for mulit]
Change-Id: I10e9d849986c9661b587c7b1a509180c2451816e
* ENH:update wiki url for Pin Code
jira:[pin code]
Change-Id: I95faaa396a839b5b159119ef235b650c76706a84
* NEW:add OpenCV.cmake in deps
jira: none
Change-Id: I1ae4a2bd5618e9e620b08a937904d6af5d00bc41
* FIX:cancel obj import restrictions
jira: none
Change-Id: Iaf3e799ca982ad6aeb3ec76e9a416c4c8e4d100c
* NEW:add multiple printer restrictions
jira:[for multiple]
Change-Id: I0bb5a0c1062a543c42f8d67a9347efa358b0864a
* ENH:Added two entrances for adding devices
jira:[multi device]
Change-Id: Ieb6197e067d422979606f93b22b337a2399aec74
* slic3r: Fix wxFont being undefined
[427/494] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
FAILED: src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
/usr/bin/c++ -DBOOST_ATOMIC_NO_LIB -DBOOST_CHRONO_NO_LIB -DBOOST_DATE_TIME_NO_LIB -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_NO_LIB -DBOOST_LOCALE_NO_LIB -DBOOST_LOG_NO_LIB -DBOOST_REGEX_NO_LIB -DBOOST_SYSTEM_NO_LIB -DBOOST_THREAD_NO_LIB -DCURL_STATICLIB -DGLEW_STATIC -DLIBNEST2D_GEOMETRIES_libslic3r -DLIBNEST2D_OPTIMIZER_nlopt -DLIBNEST2D_STATIC -DLIBNEST2D_THREADING_tbb -DOPENSSL_CERT_OVERRIDE -DOPENVDB_OPENEXR_STATICLIB -DOPENVDB_STATICLIB -DSLIC3R_CURRENTLY_COMPILING_GUI_MODULE -DSLIC3R_GUI -DTBB_USE_CAPTURED_EXCEPTION=0 -DUNICODE -DUSE_TBB -DWXINTL_NO_GETTEXT_MACRO -D_UNICODE -D__WXGTK3__ -D__WXGTK__ -DwxDEBUG_LEVEL=0 -DwxNO_UNSAFE_WXSTRING_CONV -DwxUSE_UNICODE -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/run/build/BambuStudio/src -I/run/build/BambuStudio/build/src/platform -I/run/build/BambuStudio/src/hidapi/include -I/run/build/BambuStudio/src/slic3r/Utils -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/include/fribidi -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gio-unix-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gstreamer-1.0 -I/run/build/BambuStudio/build/src/libslic3r -I/run/build/BambuStudio/deps/build/destdir/usr/local/include/opencascade -I/run/build/BambuStudio/src/libnest2d/include -I/run/build/BambuStudio/src/miniz -I/run/build/BambuStudio/src/glu-libtess/include -I/run/build/BambuStudio/src/clipper2/Clipper2Lib/include -I/run/build/BambuStudio/src/minilzo -isystem /run/build/BambuStudio/src/eigen -isystem /run/build/BambuStudio/src/libigl -isystem /app/lib/wx/include/gtk3-unicode-static-3.1 -isystem /app/include/wx-3.1 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/opencv4 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/OpenEXR -std=gnu++20 -fext-numeric-literals -Wall -Wno-reorder -pthread -O3 -DNDEBUG -std=gnu++17 -fPIC -fsigned-char -Werror=return-type -Wno-ignored-attributes -Wno-unknown-pragmas -DOPENVDB_ABI_VERSION_NUMBER=8 -MD -MT src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -MF src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o.d -o src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -c /run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp
In file included from /run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp:1:
/run/build/BambuStudio/src/slic3r/Utils/FontUtils.hpp:51:21: error: ‘wxFont’ does not name a type
51 | bool can_load(const wxFont &font);
| ^~~~~~
* slic3r: Fix missing BOOST_LOG_TRIVIAL declaration
[427/494] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
FAILED: src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o
/usr/bin/c++ -DBOOST_ATOMIC_NO_LIB -DBOOST_CHRONO_NO_LIB -DBOOST_DATE_TIME_NO_LIB -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_NO_LIB -DBOOST_LOCALE_NO_LIB -DBOOST_LOG_NO_LIB -DBOOST_REGEX_NO_LIB -DBOOST_SYSTEM_NO_LIB -DBOOST_THREAD_NO_LIB -DCURL_STATICLIB -DGLEW_STATIC -DLIBNEST2D_GEOMETRIES_libslic3r -DLIBNEST2D_OPTIMIZER_nlopt -DLIBNEST2D_STATIC -DLIBNEST2D_THREADING_tbb -DOPENSSL_CERT_OVERRIDE -DOPENVDB_OPENEXR_STATICLIB -DOPENVDB_STATICLIB -DSLIC3R_CURRENTLY_COMPILING_GUI_MODULE -DSLIC3R_GUI -DTBB_USE_CAPTURED_EXCEPTION=0 -DUNICODE -DUSE_TBB -DWXINTL_NO_GETTEXT_MACRO -D_UNICODE -D__WXGTK3__ -D__WXGTK__ -DwxDEBUG_LEVEL=0 -DwxNO_UNSAFE_WXSTRING_CONV -DwxUSE_UNICODE -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/run/build/BambuStudio/src -I/run/build/BambuStudio/build/src/platform -I/run/build/BambuStudio/src/hidapi/include -I/run/build/BambuStudio/src/slic3r/Utils -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/include/fribidi -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gio-unix-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gstreamer-1.0 -I/run/build/BambuStudio/build/src/libslic3r -I/run/build/BambuStudio/deps/build/destdir/usr/local/include/opencascade -I/run/build/BambuStudio/src/libnest2d/include -I/run/build/BambuStudio/src/miniz -I/run/build/BambuStudio/src/glu-libtess/include -I/run/build/BambuStudio/src/clipper2/Clipper2Lib/include -I/run/build/BambuStudio/src/minilzo -isystem /run/build/BambuStudio/src/eigen -isystem /run/build/BambuStudio/src/libigl -isystem /app/lib/wx/include/gtk3-unicode-static-3.1 -isystem /app/include/wx-3.1 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/opencv4 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/OpenEXR -std=gnu++20 -fext-numeric-literals -Wall -Wno-reorder -pthread -O3 -DNDEBUG -std=gnu++17 -fPIC -fsigned-char -Werror=return-type -Wno-ignored-attributes -Wno-unknown-pragmas -DOPENVDB_ABI_VERSION_NUMBER=8 -MD -MT src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -MF src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o.d -o src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/FontUtils.cpp.o -c /run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp
/run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp: In function ‘std::unique_ptr<Slic3r::FontFile> Slic3r::create_font_file(const char*)’:
/run/build/BambuStudio/src/slic3r/Utils/FontUtils.cpp:127:27: error: ‘error’ was not declared in this scope; did you mean ‘perror’?
127 | BOOST_LOG_TRIVIAL(error) << "Couldn't open " << file_path << " for reading.";
| ^~~~~
| perror
[447/494] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o
FAILED: src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o
/usr/bin/c++ -DBOOST_ATOMIC_NO_LIB -DBOOST_CHRONO_NO_LIB -DBOOST_DATE_TIME_NO_LIB -DBOOST_FILESYSTEM_NO_LIB -DBOOST_IOSTREAMS_NO_LIB -DBOOST_LOCALE_NO_LIB -DBOOST_LOG_NO_LIB -DBOOST_REGEX_NO_LIB -DBOOST_SYSTEM_NO_LIB -DBOOST_THREAD_NO_LIB -DCURL_STATICLIB -DGLEW_STATIC -DLIBNEST2D_GEOMETRIES_libslic3r -DLIBNEST2D_OPTIMIZER_nlopt -DLIBNEST2D_STATIC -DLIBNEST2D_THREADING_tbb -DOPENSSL_CERT_OVERRIDE -DOPENVDB_OPENEXR_STATICLIB -DOPENVDB_STATICLIB -DSLIC3R_CURRENTLY_COMPILING_GUI_MODULE -DSLIC3R_GUI -DTBB_USE_CAPTURED_EXCEPTION=0 -DUNICODE -DUSE_TBB -DWXINTL_NO_GETTEXT_MACRO -D_UNICODE -D__WXGTK3__ -D__WXGTK__ -DwxDEBUG_LEVEL=0 -DwxNO_UNSAFE_WXSTRING_CONV -DwxUSE_UNICODE -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/run/build/BambuStudio/src -I/run/build/BambuStudio/build/src/platform -I/run/build/BambuStudio/src/hidapi/include -I/run/build/BambuStudio/src/slic3r/Utils -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/webp -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/atk-1.0 -I/usr/include/fribidi -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gio-unix-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gstreamer-1.0 -I/run/build/BambuStudio/build/src/libslic3r -I/run/build/BambuStudio/deps/build/destdir/usr/local/include/opencascade -I/run/build/BambuStudio/src/libnest2d/include -I/run/build/BambuStudio/src/miniz -I/run/build/BambuStudio/src/glu-libtess/include -I/run/build/BambuStudio/src/clipper2/Clipper2Lib/include -I/run/build/BambuStudio/src/minilzo -isystem /run/build/BambuStudio/src/eigen -isystem /run/build/BambuStudio/src/libigl -isystem /app/lib/wx/include/gtk3-unicode-static-3.1 -isystem /app/include/wx-3.1 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/opencv4 -isystem /run/build/BambuStudio/deps/build/destdir/usr/local/include/OpenEXR -std=gnu++20 -fext-numeric-literals -Wall -Wno-reorder -pthread -O3 -DNDEBUG -std=gnu++17 -fPIC -fsigned-char -Werror=return-type -Wno-ignored-attributes -Wno-unknown-pragmas -DOPENVDB_ABI_VERSION_NUMBER=8 -MD -MT src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o -MF src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o.d -o src/slic3r/CMakeFiles/libslic3r_gui.dir/GUI/TaskManager.cpp.o -c /run/build/BambuStudio/src/slic3r/GUI/TaskManager.cpp
In file included from /run/build/BambuStudio/src/slic3r/GUI/TaskManager.cpp:1:
/run/build/BambuStudio/src/slic3r/GUI/TaskManager.hpp: In member function ‘void Slic3r::TaskStateInfo::set_state(Slic3r::TaskState)’:
/run/build/BambuStudio/src/slic3r/GUI/TaskManager.hpp:40:9: error: ‘BOOST_LOG_TRIVIAL’ was not declared in this scope
40 | BOOST_LOG_TRIVIAL(trace) << "TaskStateInfo set state = " << get_task_state_enum_str(ts);
| ^~~~~~~~~~~~~~~~~
* fix OpenCV
* wip - build break
* fix build error wip
* ENH: support preset description(tooltip)
Change-Id: Iff005baac4974c538d1109fb0ba1df20b04a8f69
Jira: STUDIO-5754
* fix more build errors
* Revert "ENH: load more fonts"
This reverts commit 32b6fd199a.
* change colors
* misc fixes
* restore export gcode btn
---------
Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Signed-off-by: Stone Li <stone.li@bambulab.com>
Signed-off-by: Kunlong Ma <kunlong.ma@bambulab.com>
Signed-off-by: XunZhangBambu <xun.zhang@bambulab.com>
Co-authored-by: lane.wei <lane.wei@bambulab.com>
Co-authored-by: Arthur <arthur.tang@bambulab.com>
Co-authored-by: xun.zhang <xun.zhang@bambulab.com>
Co-authored-by: zhimin.zeng <zhimin.zeng@bambulab.com>
Co-authored-by: Kunlong Ma <kunlong.ma@bambulab.com>
Co-authored-by: jianjia.ma <jianjia.ma@bambulab.com>
Co-authored-by: liz.li <liz.li@bambulab.com>
Co-authored-by: tao wang <tao.wang@bambulab.com>
Co-authored-by: Stone Li <stone.li@bambulab.com>
Co-authored-by: zhou.xu <zhou.xu@bambulab.com>
Co-authored-by: Bastien Nocera <hadess@hadess.net>
Co-authored-by: chunmao.guo <chunmao.guo@bambulab.com>
1688 lines
66 KiB
C++
1688 lines
66 KiB
C++
#include "WebGuideDialog.hpp"
|
|
#include "ConfigWizard.hpp"
|
|
|
|
#include <string.h>
|
|
#include "I18N.hpp"
|
|
#include "libslic3r/AppConfig.hpp"
|
|
#include "slic3r/GUI/wxExtensions.hpp"
|
|
#include "slic3r/GUI/GUI_App.hpp"
|
|
#include "libslic3r_version.h"
|
|
|
|
#include <wx/sizer.h>
|
|
#include <wx/toolbar.h>
|
|
#include <wx/textdlg.h>
|
|
|
|
#include <wx/wx.h>
|
|
#include <wx/display.h>
|
|
#include <wx/fileconf.h>
|
|
#include <wx/file.h>
|
|
#include <wx/wfstream.h>
|
|
|
|
#include <boost/cast.hpp>
|
|
#include <boost/lexical_cast.hpp>
|
|
#include <boost/filesystem.hpp>
|
|
|
|
#include "MainFrame.hpp"
|
|
#include <boost/dll.hpp>
|
|
#include <slic3r/GUI/Widgets/WebView.hpp>
|
|
#include <slic3r/Utils/Http.hpp>
|
|
#include <libslic3r/miniz_extension.hpp>
|
|
#include <libslic3r/Utils.hpp>
|
|
#include "CreatePresetsDialog.hpp"
|
|
|
|
using namespace nlohmann;
|
|
|
|
namespace Slic3r { namespace GUI {
|
|
|
|
json m_ProfileJson;
|
|
|
|
static wxString update_custom_filaments()
|
|
{
|
|
json m_Res = json::object();
|
|
m_Res["command"] = "update_custom_filaments";
|
|
m_Res["sequence_id"] = "2000";
|
|
json m_CustomFilaments = json::array();
|
|
PresetBundle * preset_bundle = wxGetApp().preset_bundle;
|
|
std::map<std::string, std::vector<Preset const *>> temp_filament_id_to_presets = preset_bundle->filaments.get_filament_presets();
|
|
|
|
std::vector<std::pair<std::string, std::string>> need_sort;
|
|
bool need_delete_some_filament = false;
|
|
for (std::pair<std::string, std::vector<Preset const *>> filament_id_to_presets : temp_filament_id_to_presets) {
|
|
std::string filament_id = filament_id_to_presets.first;
|
|
if (filament_id.empty()) continue;
|
|
if (filament_id == "null") {
|
|
need_delete_some_filament = true;
|
|
}
|
|
bool filament_with_base_id = false;
|
|
bool not_need_show = false;
|
|
std::string filament_name;
|
|
for (const Preset *preset : filament_id_to_presets.second) {
|
|
if (preset->is_system) {
|
|
not_need_show = true;
|
|
break;
|
|
}
|
|
if (preset->inherits() != "") continue;
|
|
if (!preset->base_id.empty()) filament_with_base_id = true;
|
|
|
|
if (!not_need_show) {
|
|
auto filament_vendor = dynamic_cast<ConfigOptionStrings *>(const_cast<Preset *>(preset)->config.option("filament_vendor", false));
|
|
if (filament_vendor && filament_vendor->values.size() && filament_vendor->values[0] == "Generic") not_need_show = true;
|
|
}
|
|
|
|
if (filament_name.empty()) {
|
|
std::string preset_name = preset->name;
|
|
size_t index_at = preset_name.find(" @");
|
|
if (std::string::npos != index_at) { preset_name = preset_name.substr(0, index_at); }
|
|
filament_name = preset_name;
|
|
}
|
|
}
|
|
if (not_need_show) continue;
|
|
if (!filament_name.empty()) {
|
|
if (filament_with_base_id) {
|
|
need_sort.push_back(std::make_pair("[Action Required] " + filament_name, filament_id));
|
|
} else {
|
|
|
|
need_sort.push_back(std::make_pair(filament_name, filament_id));
|
|
}
|
|
}
|
|
}
|
|
std::sort(need_sort.begin(), need_sort.end(), [](const std::pair<std::string, std::string> &a, const std::pair<std::string, std::string> &b) { return a.first < b.first; });
|
|
if (need_delete_some_filament) {
|
|
need_sort.push_back(std::make_pair("[Action Required]", "null"));
|
|
}
|
|
json temp_j;
|
|
for (std::pair<std::string, std::string> &filament_name_to_id : need_sort) {
|
|
temp_j["name"] = filament_name_to_id.first;
|
|
temp_j["id"] = filament_name_to_id.second;
|
|
m_CustomFilaments.push_back(temp_j);
|
|
}
|
|
m_Res["data"] = m_CustomFilaments;
|
|
wxString strJS = wxString::Format("HandleStudio(%s)", wxString::FromUTF8(m_Res.dump(-1, ' ', false, json::error_handler_t::ignore)));
|
|
return strJS;
|
|
}
|
|
|
|
GuideFrame::GuideFrame(GUI_App *pGUI, long style)
|
|
: DPIDialog((wxWindow *) (pGUI->mainframe), wxID_ANY, "OrcaSlicer", wxDefaultPosition, wxDefaultSize, style),
|
|
m_appconfig_new()
|
|
{
|
|
SetBackgroundColour(*wxWHITE);
|
|
// INI
|
|
m_SectionName = "firstguide";
|
|
PrivacyUse = false;
|
|
InstallNetplugin = false;
|
|
|
|
m_MainPtr = pGUI;
|
|
|
|
// set the frame icon
|
|
wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
|
|
|
|
wxString TargetUrl = SetStartPage(BBL_WELCOME, false);
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", set start page to welcome ");
|
|
|
|
// Create the webview
|
|
m_browser = WebView::CreateWebView(this, TargetUrl);
|
|
if (m_browser == nullptr) {
|
|
wxLogError("Could not init m_browser");
|
|
return;
|
|
}
|
|
m_browser->Hide();
|
|
m_browser->SetSize(0, 0);
|
|
|
|
SetSizer(topsizer);
|
|
|
|
topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
|
|
|
|
// Log backend information
|
|
// wxLogMessage(wxWebView::GetBackendVersionInfo().ToString());
|
|
// wxLogMessage("Backend: %s Version: %s",
|
|
// m_browser->GetClassInfo()->GetClassName(),wxWebView::GetBackendVersionInfo().ToString());
|
|
// wxLogMessage("User Agent: %s", m_browser->GetUserAgent());
|
|
|
|
// Set a more sensible size for web browsing
|
|
wxSize pSize = FromDIP(wxSize(820, 660));
|
|
SetSize(pSize);
|
|
|
|
int screenheight = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y, NULL);
|
|
int screenwidth = wxSystemSettings::GetMetric(wxSYS_SCREEN_X, NULL);
|
|
int MaxY = (screenheight - pSize.y) > 0 ? (screenheight - pSize.y) / 2 : 0;
|
|
wxPoint tmpPT((screenwidth - pSize.x) / 2, MaxY);
|
|
Move(tmpPT);
|
|
#ifdef __WXMSW__
|
|
this->Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent& e) {
|
|
if ((m_page == BBL_FILAMENT_ONLY || m_page == BBL_MODELS_ONLY) && e.GetKeyCode() == WXK_ESCAPE) {
|
|
if (this->IsModal())
|
|
this->EndModal(wxID_CANCEL);
|
|
else
|
|
this->Close();
|
|
}
|
|
else
|
|
e.Skip();
|
|
});
|
|
#endif
|
|
// Connect the webview events
|
|
Bind(wxEVT_WEBVIEW_NAVIGATING, &GuideFrame::OnNavigationRequest, this, m_browser->GetId());
|
|
Bind(wxEVT_WEBVIEW_NAVIGATED, &GuideFrame::OnNavigationComplete, this, m_browser->GetId());
|
|
Bind(wxEVT_WEBVIEW_LOADED, &GuideFrame::OnDocumentLoaded, this, m_browser->GetId());
|
|
Bind(wxEVT_WEBVIEW_ERROR, &GuideFrame::OnError, this, m_browser->GetId());
|
|
Bind(wxEVT_WEBVIEW_NEWWINDOW, &GuideFrame::OnNewWindow, this, m_browser->GetId());
|
|
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &GuideFrame::OnTitleChanged, this, m_browser->GetId());
|
|
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, &GuideFrame::OnFullScreenChanged, this, m_browser->GetId());
|
|
Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &GuideFrame::OnScriptMessage, this, m_browser->GetId());
|
|
|
|
// Connect the idle events
|
|
// Bind(wxEVT_IDLE, &GuideFrame::OnIdle, this);
|
|
// Bind(wxEVT_CLOSE_WINDOW, &GuideFrame::OnClose, this);
|
|
|
|
LoadProfile();
|
|
|
|
// UI
|
|
SetStartPage(BBL_REGION);
|
|
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", finished");
|
|
wxGetApp().UpdateDlgDarkUI(this);
|
|
}
|
|
|
|
GuideFrame::~GuideFrame()
|
|
{
|
|
if (m_browser) {
|
|
delete m_browser;
|
|
m_browser = nullptr;
|
|
}
|
|
}
|
|
|
|
void GuideFrame::load_url(wxString &url)
|
|
{
|
|
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__<< " enter, url=" << url.ToStdString();
|
|
WebView::LoadUrl(m_browser, url);
|
|
m_browser->SetFocus();
|
|
UpdateState();
|
|
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< " exit";
|
|
}
|
|
|
|
wxString GuideFrame::SetStartPage(GuidePage startpage, bool load)
|
|
{
|
|
m_page = startpage;
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" enter, load=%1%, start_page=%2%")%load%int(startpage);
|
|
//wxLogMessage("GUIDE: webpage_1 %s", (boost::filesystem::path(resources_dir()) / "web\\guide\\1\\index.html").make_preferred().string().c_str() );
|
|
wxString TargetUrl = from_u8( (boost::filesystem::path(resources_dir()) / "web/guide/1/index.html").make_preferred().string() );
|
|
//wxLogMessage("GUIDE: webpage_2 %s", TargetUrl.mb_str());
|
|
|
|
if (startpage == BBL_WELCOME){
|
|
SetTitle(_L("Setup Wizard"));
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/1/index.html").make_preferred().string());
|
|
} else if (startpage == BBL_REGION) {
|
|
SetTitle(_L("Setup Wizard"));
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/11/index.html").make_preferred().string());
|
|
} else if (startpage == BBL_MODELS) {
|
|
SetTitle(_L("Setup Wizard"));
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/21/index.html").make_preferred().string());
|
|
} else if (startpage == BBL_FILAMENTS) {
|
|
SetTitle(_L("Setup Wizard"));
|
|
|
|
int nSize = m_ProfileJson["model"].size();
|
|
|
|
if (nSize>0)
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/22/index.html").make_preferred().string());
|
|
else
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/21/index.html").make_preferred().string());
|
|
} else if (startpage == BBL_FILAMENT_ONLY) {
|
|
SetTitle("");
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/23/index.html").make_preferred().string());
|
|
} else if (startpage == BBL_MODELS_ONLY) {
|
|
SetTitle("");
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/24/index.html").make_preferred().string());
|
|
}
|
|
else {
|
|
SetTitle(_L("Setup Wizard"));
|
|
TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/21/index.html").make_preferred().string());
|
|
}
|
|
|
|
wxString strlang = wxGetApp().current_language_code_safe();
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(", strlang=%1%") % into_u8(strlang);
|
|
if (strlang != "")
|
|
TargetUrl = wxString::Format("%s?lang=%s", w2s(TargetUrl), strlang);
|
|
|
|
TargetUrl = "file://" + TargetUrl;
|
|
if (load)
|
|
load_url(TargetUrl);
|
|
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< " exit";
|
|
return TargetUrl;
|
|
}
|
|
|
|
/**
|
|
* Method that retrieves the current state from the web control and updates
|
|
* the GUI the reflect this current state.
|
|
*/
|
|
void GuideFrame::UpdateState()
|
|
{
|
|
// SetTitle(m_browser->GetCurrentTitle());
|
|
}
|
|
|
|
void GuideFrame::OnIdle(wxIdleEvent &WXUNUSED(evt))
|
|
{
|
|
if (m_browser->IsBusy()) {
|
|
wxSetCursor(wxCURSOR_ARROWWAIT);
|
|
} else {
|
|
wxSetCursor(wxNullCursor);
|
|
}
|
|
}
|
|
|
|
// void GuideFrame::OnClose(wxCloseEvent& evt)
|
|
//{
|
|
// this->Hide();
|
|
//}
|
|
|
|
/**
|
|
* Callback invoked when there is a request to load a new page (for instance
|
|
* when the user clicks a link)
|
|
*/
|
|
void GuideFrame::OnNavigationRequest(wxWebViewEvent &evt)
|
|
{
|
|
// wxLogMessage("%s", "Navigation request to '" + evt.GetURL() + "'
|
|
// (target='" + evt.GetTarget() + "')");
|
|
|
|
UpdateState();
|
|
}
|
|
|
|
/**
|
|
* Callback invoked when a navigation request was accepted
|
|
*/
|
|
void GuideFrame::OnNavigationComplete(wxWebViewEvent &evt)
|
|
{
|
|
//wxLogMessage("%s", "Navigation complete; url='" + evt.GetURL() + "'");
|
|
m_browser->Show();
|
|
Layout();
|
|
|
|
wxString NewUrl = evt.GetURL();
|
|
|
|
UpdateState();
|
|
}
|
|
|
|
/**
|
|
* Callback invoked when a page is finished loading
|
|
*/
|
|
void GuideFrame::OnDocumentLoaded(wxWebViewEvent &evt)
|
|
{
|
|
// Only notify if the document is the main frame, not a subframe
|
|
wxString tmpUrl = evt.GetURL();
|
|
wxString NowUrl = m_browser->GetCurrentURL();
|
|
|
|
if (evt.GetURL() == m_browser->GetCurrentURL()) {
|
|
// wxLogMessage("%s", "Document loaded; url='" + evt.GetURL() + "'");
|
|
}
|
|
UpdateState();
|
|
|
|
// wxCommandEvent *event = new
|
|
// wxCommandEvent(EVT_WEB_RESPONSE_MESSAGE,this->GetId()); wxQueueEvent(this,
|
|
// event);
|
|
}
|
|
|
|
/**
|
|
* On new window, we veto to stop extra windows appearing
|
|
*/
|
|
void GuideFrame::OnNewWindow(wxWebViewEvent &evt)
|
|
{
|
|
wxString flag = " (other)";
|
|
|
|
wxString NewUrl= evt.GetURL();
|
|
wxLaunchDefaultBrowser(NewUrl);
|
|
//if (evt.GetNavigationAction() == wxWEBVIEW_NAV_ACTION_USER) { flag = " (user)"; }
|
|
// wxLogMessage("%s", "New window; url='" + evt.GetURL() + "'" + flag);
|
|
|
|
// If we handle new window events then just load them in this window as we
|
|
// are a single window browser
|
|
// if (m_tools_handle_new_window->IsChecked())
|
|
// m_browser->LoadURL(evt.GetURL());
|
|
|
|
UpdateState();
|
|
}
|
|
|
|
void GuideFrame::OnTitleChanged(wxWebViewEvent &evt)
|
|
{
|
|
// SetTitle(evt.GetString());
|
|
// wxLogMessage("%s", "Title changed; title='" + evt.GetString() + "'");
|
|
}
|
|
|
|
void GuideFrame::OnFullScreenChanged(wxWebViewEvent &evt)
|
|
{
|
|
// wxLogMessage("Full screen changed; status = %d", evt.GetInt());
|
|
ShowFullScreen(evt.GetInt() != 0);
|
|
}
|
|
|
|
void GuideFrame::OnScriptMessage(wxWebViewEvent &evt)
|
|
{
|
|
try {
|
|
wxString strInput = evt.GetString();
|
|
BOOST_LOG_TRIVIAL(trace) << "GuideFrame::OnScriptMessage;OnRecv:" << strInput.c_str();
|
|
json j = json::parse(strInput);
|
|
|
|
wxString strCmd = j["command"];
|
|
BOOST_LOG_TRIVIAL(trace) << "GuideFrame::OnScriptMessage;Command:" << strCmd;
|
|
|
|
if (strCmd == "close_page") {
|
|
this->EndModal(wxID_CANCEL);
|
|
}
|
|
if (strCmd == "user_clause") {
|
|
wxString strAction = j["data"]["action"];
|
|
|
|
if (strAction == "refuse") {
|
|
// CloseTheApp
|
|
this->EndModal(wxID_OK);
|
|
|
|
m_MainPtr->mainframe->Close(); // Refuse Clause, App quit immediately
|
|
}
|
|
} else if (strCmd == "user_private_choice") {
|
|
wxString strAction = j["data"]["action"];
|
|
|
|
if (strAction == "agree") {
|
|
PrivacyUse = true;
|
|
} else {
|
|
PrivacyUse = false;
|
|
}
|
|
}
|
|
else if (strCmd == "request_userguide_profile") {
|
|
json m_Res = json::object();
|
|
m_Res["command"] = "response_userguide_profile";
|
|
m_Res["sequence_id"] = "10001";
|
|
m_Res["response"] = m_ProfileJson;
|
|
|
|
//wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', false, json::error_handler_t::ignore));
|
|
wxString strJS = wxString::Format("HandleStudio(%s)", m_Res.dump(-1, ' ', true));
|
|
|
|
BOOST_LOG_TRIVIAL(trace) << "GuideFrame::OnScriptMessage;request_userguide_profile:" << strJS.c_str();
|
|
wxGetApp().CallAfter([this,strJS] { RunScript(strJS); });
|
|
}
|
|
else if (strCmd == "request_custom_filaments") {
|
|
wxString strJS = update_custom_filaments();
|
|
wxGetApp().CallAfter([this, strJS] { RunScript(strJS); });
|
|
}
|
|
else if (strCmd == "create_custom_filament") {
|
|
this->EndModal(wxID_OK);
|
|
wxQueueEvent(wxGetApp().plater(), new SimpleEvent(EVT_CREATE_FILAMENT));
|
|
} else if (strCmd == "modify_custom_filament") {
|
|
m_editing_filament_id = j["id"];
|
|
this->EndModal(wxID_EDIT);
|
|
}
|
|
else if (strCmd == "save_userguide_models")
|
|
{
|
|
json MSelected = j["data"];
|
|
|
|
int nModel = m_ProfileJson["model"].size();
|
|
for (int m = 0; m < nModel; m++) {
|
|
json TmpModel = m_ProfileJson["model"][m];
|
|
m_ProfileJson["model"][m]["nozzle_selected"] = "";
|
|
|
|
for (auto it = MSelected.begin(); it != MSelected.end(); ++it) {
|
|
json OneSelect = it.value();
|
|
|
|
wxString s1 = TmpModel["model"];
|
|
wxString s2 = OneSelect["model"];
|
|
if (s1.compare(s2) == 0) {
|
|
m_ProfileJson["model"][m]["nozzle_selected"] = OneSelect["nozzle_diameter"];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (strCmd == "save_userguide_filaments") {
|
|
//reset
|
|
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it)
|
|
{
|
|
m_ProfileJson["filament"][it.key()]["selected"] = 0;
|
|
}
|
|
|
|
json fSelected = j["data"]["filament"];
|
|
int nF = fSelected.size();
|
|
for (int m = 0; m < nF; m++)
|
|
{
|
|
std::string fName = fSelected[m];
|
|
|
|
m_ProfileJson["filament"][fName]["selected"] = 1;
|
|
}
|
|
}
|
|
else if (strCmd == "user_guide_finish") {
|
|
SaveProfile();
|
|
|
|
std::string oldregion = m_ProfileJson["region"];
|
|
bool bLogin = false;
|
|
if (m_Region != oldregion) {
|
|
AppConfig* config = GUI::wxGetApp().app_config;
|
|
std::string country_code = config->get_country_code();
|
|
NetworkAgent* agent = wxGetApp().getAgent();
|
|
if (agent) {
|
|
agent->set_country_code(country_code);
|
|
if (wxGetApp().is_user_login()) {
|
|
bLogin = true;
|
|
agent->user_logout();
|
|
}
|
|
}
|
|
}
|
|
|
|
this->EndModal(wxID_OK);
|
|
|
|
if (InstallNetplugin)
|
|
GUI::wxGetApp().CallAfter([this] { GUI::wxGetApp().ShowDownNetPluginDlg(); });
|
|
|
|
if (bLogin)
|
|
GUI::wxGetApp().CallAfter([this] { login(); });
|
|
}
|
|
else if (strCmd == "user_guide_cancel") {
|
|
this->EndModal(wxID_CANCEL);
|
|
this->Close();
|
|
} else if (strCmd == "save_region") {
|
|
m_Region = j["region"];
|
|
}
|
|
else if (strCmd == "network_plugin_install") {
|
|
std::string sAction = j["data"]["action"];
|
|
|
|
if (sAction == "yes") {
|
|
if (!network_plugin_ready)
|
|
InstallNetplugin = true;
|
|
else //already ready
|
|
InstallNetplugin = false;
|
|
}
|
|
else
|
|
InstallNetplugin = false;
|
|
}
|
|
} catch (std::exception &e) {
|
|
// wxMessageBox(e.what(), "json Exception", MB_OK);
|
|
BOOST_LOG_TRIVIAL(trace) << "GuideFrame::OnScriptMessage;Error:" << e.what();
|
|
}
|
|
|
|
wxString strAll = m_ProfileJson.dump(-1,' ',false, json::error_handler_t::ignore);
|
|
}
|
|
|
|
void GuideFrame::RunScript(const wxString &javascript)
|
|
{
|
|
// Remember the script we run in any case, so the next time the user opens
|
|
// the "Run Script" dialog box, it is shown there for convenient updating.
|
|
//m_javascript = javascript;
|
|
|
|
// wxLogMessage("Running JavaScript:\n%s\n", javascript);
|
|
|
|
if (!m_browser) return;
|
|
|
|
WebView::RunScript(m_browser, javascript);
|
|
}
|
|
|
|
#if wxUSE_WEBVIEW_IE
|
|
void GuideFrame::OnRunScriptObjectWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
|
|
{
|
|
wxWebViewIE::MSWSetModernEmulationLevel();
|
|
RunScript("function f(){var person = new Object();person.name = 'Foo'; \
|
|
person.lastName = 'Bar';return person;}f();");
|
|
wxWebViewIE::MSWSetModernEmulationLevel(false);
|
|
}
|
|
|
|
void GuideFrame::OnRunScriptDateWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
|
|
{
|
|
wxWebViewIE::MSWSetModernEmulationLevel();
|
|
RunScript("function f(){var d = new Date('10/08/2017 21:30:40'); \
|
|
var tzoffset = d.getTimezoneOffset() * 60000; return \
|
|
new Date(d.getTime() - tzoffset);}f();");
|
|
wxWebViewIE::MSWSetModernEmulationLevel(false);
|
|
}
|
|
|
|
void GuideFrame::OnRunScriptArrayWithEmulationLevel(wxCommandEvent &WXUNUSED(evt))
|
|
{
|
|
wxWebViewIE::MSWSetModernEmulationLevel();
|
|
RunScript("function f(){ return [\"foo\", \"bar\"]; }f();");
|
|
wxWebViewIE::MSWSetModernEmulationLevel(false);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Callback invoked when a loading error occurs
|
|
*/
|
|
void GuideFrame::OnError(wxWebViewEvent &evt)
|
|
{
|
|
#define WX_ERROR_CASE(type) \
|
|
case type: category = #type; break;
|
|
|
|
wxString category;
|
|
switch (evt.GetInt()) {
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CONNECTION);
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CERTIFICATE);
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_AUTH);
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_SECURITY);
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_NOT_FOUND);
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_REQUEST);
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_USER_CANCELLED);
|
|
WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
|
|
}
|
|
|
|
// wxLogMessage("%s", "Error; url='" + evt.GetURL() + "', error='" +
|
|
// category + " (" + evt.GetString() + ")'");
|
|
|
|
// Show the info bar with an error
|
|
// m_info->ShowMessage(_L("An error occurred loading ") + evt.GetURL() +
|
|
// "\n" + "'" + category + "'", wxICON_ERROR);
|
|
BOOST_LOG_TRIVIAL(trace) << "GuideFrame::OnError: An error occurred loading " << evt.GetURL() << category;
|
|
|
|
UpdateState();
|
|
}
|
|
|
|
void GuideFrame::OnScriptResponseMessage(wxCommandEvent &WXUNUSED(evt))
|
|
{
|
|
// if (!m_response_js.empty())
|
|
//{
|
|
// RunScript(m_response_js);
|
|
//}
|
|
|
|
// RunScript("This is a message to Web!");
|
|
// RunScript("postMessage(\"AABBCCDD\");");
|
|
}
|
|
|
|
bool GuideFrame::IsFirstUse()
|
|
{
|
|
wxString strUse;
|
|
std::string strVal = wxGetApp().app_config->get(std::string(m_SectionName.mb_str()), "finish");
|
|
if (strVal == "1")
|
|
return false;
|
|
|
|
if (bbl_bundle_rsrc == true)
|
|
return true;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*int GuideFrame::CopyDir(const boost::filesystem::path &from_dir, const boost::filesystem::path &to_dir)
|
|
{
|
|
if (!boost::filesystem::is_directory(from_dir)) return -1;
|
|
// i assume to_dir.parent surely exists
|
|
if (!boost::filesystem::is_directory(to_dir)) boost::filesystem::create_directory(to_dir);
|
|
for (auto &dir_entry : boost::filesystem::directory_iterator(from_dir)) {
|
|
if (!boost::filesystem::is_directory(dir_entry.path())) {
|
|
std::string em;
|
|
CopyFileResult cfr = copy_file(dir_entry.path().string(), (to_dir / dir_entry.path().filename()).string(), em, false);
|
|
if (cfr != SUCCESS) { BOOST_LOG_TRIVIAL(error) << "Error when copying files from " << from_dir << " to " << to_dir << ": " << em; }
|
|
} else {
|
|
CopyDir(dir_entry.path(), to_dir / dir_entry.path().filename());
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}*/
|
|
|
|
int GuideFrame::SaveProfile()
|
|
{
|
|
// SoftFever: don't collect info
|
|
//privacy
|
|
// if (PrivacyUse == true) {
|
|
// m_MainPtr->app_config->set(std::string(m_SectionName.mb_str()), "privacyuse", "1");
|
|
// } else
|
|
// m_MainPtr->app_config->set(std::string(m_SectionName.mb_str()), "privacyuse", "0");
|
|
|
|
m_MainPtr->app_config->set("region", m_Region);
|
|
|
|
//finish
|
|
m_MainPtr->app_config->set(std::string(m_SectionName.mb_str()), "finish", "1");
|
|
|
|
m_MainPtr->app_config->save();
|
|
|
|
//Load BBS Conf
|
|
/*wxString strConfPath = wxGetApp().app_config->config_path();
|
|
json jCfg;
|
|
std::ifstream(w2s(strConfPath)) >> jCfg;
|
|
|
|
//model
|
|
jCfg["models"] = json::array();
|
|
int nM = m_ProfileJson["model"].size();
|
|
int nModelChoose = 0;
|
|
for (int m = 0; m < nM; m++)
|
|
{
|
|
json amodel = m_ProfileJson["model"][m];
|
|
|
|
amodel["nozzle_diameter"] = amodel["nozzle_selected"];
|
|
amodel.erase("nozzle_selected");
|
|
amodel.erase("preview");
|
|
amodel.erase("sub_path");
|
|
amodel.erase("cover");
|
|
amodel.erase("materials");
|
|
|
|
std::string ss = amodel["nozzle_diameter"];
|
|
if (ss.compare("") != 0) {
|
|
nModelChoose++;
|
|
jCfg["models"].push_back(amodel);
|
|
}
|
|
}
|
|
if (nModelChoose == 0)
|
|
jCfg.erase("models");
|
|
|
|
if (nModelChoose > 0) {
|
|
// filament
|
|
jCfg["filaments"] = json::array();
|
|
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) {
|
|
if (it.value()["selected"] == 1) { jCfg["filaments"].push_back(it.key()); }
|
|
}
|
|
|
|
// Preset
|
|
jCfg["presets"]["filaments"] = json::array();
|
|
jCfg["presets"]["filaments"].push_back(jCfg["filaments"][0]);
|
|
|
|
std::string PresetMachine = m_ProfileJson["machine"][0]["name"];
|
|
jCfg["presets"]["machine"] = PresetMachine;
|
|
|
|
int nTotal = m_ProfileJson["process"].size();
|
|
int nSet = nTotal / 2;
|
|
if (nSet > 0) nSet--;
|
|
|
|
std::string sMode = m_ProfileJson["process"][nSet]["name"];
|
|
jCfg["presets"]["process"] = sMode;
|
|
|
|
} else {
|
|
jCfg["presets"]["filaments"] = json::array();
|
|
jCfg["presets"]["filaments"].push_back("Default Filament");
|
|
|
|
jCfg["presets"]["machine"] = "Default Printer";
|
|
|
|
jCfg["presets"]["process"] = "Default Setting";
|
|
}
|
|
|
|
std::string sOut = jCfg.dump(4, ' ', false);
|
|
|
|
std::ofstream output_file(w2s(strConfPath));
|
|
output_file << sOut;
|
|
output_file.close();
|
|
|
|
//Copy Profiles
|
|
if (bbl_bundle_rsrc)
|
|
{
|
|
CopyDir(rsrc_vendor_dir,vendor_dir);
|
|
}*/
|
|
|
|
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
|
|
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "before save to app_config: "<< std::endl<<strAll;
|
|
|
|
//set filaments to app_config
|
|
const std::string §ion_name = AppConfig::SECTION_FILAMENTS;
|
|
std::map<std::string, std::string> section_new;
|
|
m_appconfig_new.clear_section(section_name);
|
|
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) {
|
|
if (it.value()["selected"] == 1){
|
|
section_new[it.key()] = "true";
|
|
}
|
|
}
|
|
m_appconfig_new.set_section(section_name, section_new);
|
|
|
|
//set vendors to app_config
|
|
Slic3r::AppConfig::VendorMap empty_vendor_map;
|
|
m_appconfig_new.set_vendors(empty_vendor_map);
|
|
for (auto it = m_ProfileJson["model"].begin(); it != m_ProfileJson["model"].end(); ++it)
|
|
{
|
|
if (it.value().is_object()) {
|
|
json temp_model = it.value();
|
|
std::string model_name = temp_model["model"];
|
|
std::string vendor_name = temp_model["vendor"];
|
|
std::string selected = temp_model["nozzle_selected"];
|
|
boost::trim(selected);
|
|
std::string nozzle;
|
|
while (selected.size() > 0) {
|
|
auto pos = selected.find(';');
|
|
if (pos != std::string::npos) {
|
|
nozzle = selected.substr(0, pos);
|
|
m_appconfig_new.set_variant(vendor_name, model_name, nozzle, "true");
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("vendor_name %1%, model_name %2%, nozzle %3% selected")%vendor_name %model_name %nozzle;
|
|
selected = selected.substr(pos + 1);
|
|
boost::trim(selected);
|
|
}
|
|
else {
|
|
m_appconfig_new.set_variant(vendor_name, model_name, selected, "true");
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("vendor_name %1%, model_name %2%, nozzle %3% selected")%vendor_name %model_name %selected;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//m_appconfig_new
|
|
|
|
return 0;
|
|
}
|
|
|
|
static std::set<std::string> get_new_added_presets(const std::map<std::string, std::string>& old_data, const std::map<std::string, std::string>& new_data)
|
|
{
|
|
auto get_aliases = [](const std::map<std::string, std::string>& data) {
|
|
std::set<std::string> old_aliases;
|
|
for (auto item : data) {
|
|
const std::string& name = item.first;
|
|
size_t pos = name.find("@");
|
|
old_aliases.emplace(pos == std::string::npos ? name : name.substr(0, pos-1));
|
|
}
|
|
return old_aliases;
|
|
};
|
|
|
|
std::set<std::string> old_aliases = get_aliases(old_data);
|
|
std::set<std::string> new_aliases = get_aliases(new_data);
|
|
std::set<std::string> diff;
|
|
std::set_difference(new_aliases.begin(), new_aliases.end(), old_aliases.begin(), old_aliases.end(), std::inserter(diff, diff.begin()));
|
|
|
|
return diff;
|
|
}
|
|
|
|
static std::string get_first_added_preset(const std::map<std::string, std::string>& old_data, const std::map<std::string, std::string>& new_data)
|
|
{
|
|
std::set<std::string> diff = get_new_added_presets(old_data, new_data);
|
|
if (diff.empty())
|
|
return std::string();
|
|
return *diff.begin();
|
|
}
|
|
|
|
bool GuideFrame::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater, bool& apply_keeped_changes)
|
|
{
|
|
const auto enabled_vendors = m_appconfig_new.vendors();
|
|
const auto old_enabled_vendors = app_config->vendors();
|
|
|
|
const auto enabled_filaments = m_appconfig_new.has_section(AppConfig::SECTION_FILAMENTS) ? m_appconfig_new.get_section(AppConfig::SECTION_FILAMENTS) : std::map<std::string, std::string>();
|
|
const auto old_enabled_filaments = app_config->has_section(AppConfig::SECTION_FILAMENTS) ? app_config->get_section(AppConfig::SECTION_FILAMENTS) : std::map<std::string, std::string>();
|
|
|
|
bool check_unsaved_preset_changes = false;
|
|
std::vector<std::string> install_bundles;
|
|
std::vector<std::string> remove_bundles;
|
|
const auto vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR).make_preferred();
|
|
for (const auto &it : enabled_vendors) {
|
|
if (it.second.size() > 0) {
|
|
auto vendor_file = vendor_dir/(it.first + ".json");
|
|
if (!fs::exists(vendor_file)) {
|
|
install_bundles.emplace_back(it.first);
|
|
}
|
|
}
|
|
}
|
|
|
|
//add the removed vendor bundles
|
|
for (const auto &it : old_enabled_vendors) {
|
|
if (it.second.size() > 0) {
|
|
if (enabled_vendors.find(it.first) != enabled_vendors.end())
|
|
continue;
|
|
auto vendor_file = vendor_dir/(it.first + ".json");
|
|
if (fs::exists(vendor_file)) {
|
|
remove_bundles.emplace_back(it.first);
|
|
}
|
|
}
|
|
}
|
|
|
|
check_unsaved_preset_changes = (enabled_vendors != old_enabled_vendors) || (enabled_filaments != old_enabled_filaments);
|
|
wxString header = _L("The configuration package is changed in previous Config Guide");
|
|
wxString caption = _L("Configuration package changed");
|
|
int act_btns = ActionButtons::KEEP|ActionButtons::SAVE;
|
|
|
|
if (check_unsaved_preset_changes &&
|
|
!wxGetApp().check_and_keep_current_preset_changes(caption, header, act_btns, &apply_keeped_changes))
|
|
return false;
|
|
|
|
if (install_bundles.size() > 0) {
|
|
// Install bundles from resources.
|
|
// Don't create snapshot - we've already done that above if applicable.
|
|
if (! updater->install_bundles_rsrc(std::move(install_bundles), false))
|
|
return false;
|
|
} else {
|
|
BOOST_LOG_TRIVIAL(info) << "No bundles need to be installed from resource directory";
|
|
}
|
|
|
|
// Not remove, because these bundles may be updated
|
|
//if (remove_bundles.size() > 0) {
|
|
// //remove unused bundles
|
|
// for (const auto &it : remove_bundles) {
|
|
// auto vendor_file = vendor_dir/(it + ".json");
|
|
// auto sub_dir = vendor_dir/(it);
|
|
// if (fs::exists(vendor_file))
|
|
// fs::remove(vendor_file);
|
|
// if (fs::exists(sub_dir))
|
|
// fs::remove_all(sub_dir);
|
|
// }
|
|
//} else {
|
|
// BOOST_LOG_TRIVIAL(info) << "No bundles need to be removed";
|
|
//}
|
|
|
|
std::string preferred_model;
|
|
std::string preferred_variant;
|
|
PrinterTechnology preferred_pt = ptFFF;
|
|
auto get_preferred_printer_model = [preset_bundle, enabled_vendors, old_enabled_vendors, preferred_pt](const std::string& bundle_name, std::string& variant) {
|
|
const auto config = enabled_vendors.find(bundle_name);
|
|
if (config == enabled_vendors.end())
|
|
return std::string();
|
|
|
|
const std::map<std::string, std::set<std::string>>& model_maps = config->second;
|
|
//for (const auto& vendor_profile : preset_bundle->vendors) {
|
|
for (const auto model_it: model_maps) {
|
|
if (model_it.second.size() > 0) {
|
|
variant = *model_it.second.begin();
|
|
const auto config_old = old_enabled_vendors.find(bundle_name);
|
|
if (config_old == old_enabled_vendors.end())
|
|
return model_it.first;
|
|
const auto model_it_old = config_old->second.find(model_it.first);
|
|
if (model_it_old == config_old->second.end())
|
|
return model_it.first;
|
|
else if (model_it_old->second != model_it.second) {
|
|
for (const auto& var : model_it.second)
|
|
if (model_it_old->second.find(var) == model_it_old->second.end()) {
|
|
variant = var;
|
|
return model_it.first;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//}
|
|
if (!variant.empty())
|
|
variant.clear();
|
|
return std::string();
|
|
};
|
|
// Prusa printers are considered first, then 3rd party.
|
|
if (preferred_model = get_preferred_printer_model(PresetBundle::BBL_BUNDLE, preferred_variant);
|
|
preferred_model.empty()) {
|
|
for (const auto& bundle : enabled_vendors) {
|
|
if (bundle.first == PresetBundle::BBL_BUNDLE) { continue; }
|
|
if (preferred_model = get_preferred_printer_model(bundle.first, preferred_variant);
|
|
!preferred_model.empty())
|
|
break;
|
|
}
|
|
}
|
|
|
|
std::string first_added_filament;
|
|
auto get_first_added_material_preset = [this, app_config](const std::string& section_name, std::string& first_added_preset) {
|
|
if (m_appconfig_new.has_section(section_name)) {
|
|
// get first of new added preset names
|
|
const std::map<std::string, std::string>& old_presets = app_config->has_section(section_name) ? app_config->get_section(section_name) : std::map<std::string, std::string>();
|
|
first_added_preset = get_first_added_preset(old_presets, m_appconfig_new.get_section(section_name));
|
|
}
|
|
};
|
|
// Not switch filament
|
|
//get_first_added_material_preset(AppConfig::SECTION_FILAMENTS, first_added_filament);
|
|
|
|
//update the app_config
|
|
app_config->set_section(AppConfig::SECTION_FILAMENTS, enabled_filaments);
|
|
app_config->set_vendors(m_appconfig_new);
|
|
|
|
if (check_unsaved_preset_changes)
|
|
preset_bundle->load_presets(*app_config, ForwardCompatibilitySubstitutionRule::EnableSilentDisableSystem,
|
|
{preferred_model, preferred_variant, first_added_filament, std::string()});
|
|
|
|
// Update the selections from the compatibilty.
|
|
preset_bundle->export_selections(*app_config);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool GuideFrame::run()
|
|
{
|
|
//BOOST_LOG_TRIVIAL(info) << boost::format("Running ConfigWizard, reason: %1%, start_page: %2%") % reason % start_page;
|
|
|
|
GUI_App &app = wxGetApp();
|
|
|
|
//p->set_run_reason(reason);
|
|
//p->set_start_page(start_page);
|
|
app.preset_bundle->export_selections(*app.app_config);
|
|
|
|
BOOST_LOG_TRIVIAL(info) << "GuideFrame before ShowModal";
|
|
// display position
|
|
int main_frame_display_index = wxDisplay::GetFromWindow(wxGetApp().mainframe);
|
|
int guide_display_index = wxDisplay::GetFromWindow(this);
|
|
if (main_frame_display_index != guide_display_index) {
|
|
wxDisplay display = wxDisplay(main_frame_display_index);
|
|
wxRect screenRect = display.GetGeometry();
|
|
int guide_x = screenRect.x + (screenRect.width - this->GetSize().GetWidth()) / 2;
|
|
int guide_y = screenRect.y + (screenRect.height - this->GetSize().GetHeight()) / 2;
|
|
this->SetPosition(wxPoint(guide_x, guide_y));
|
|
}
|
|
|
|
int result = this->ShowModal();
|
|
if (result == wxID_OK) {
|
|
bool apply_keeped_changes = false;
|
|
BOOST_LOG_TRIVIAL(info) << "GuideFrame returned ok";
|
|
if (! this->apply_config(app.app_config, app.preset_bundle, app.preset_updater, apply_keeped_changes))
|
|
return false;
|
|
|
|
if (apply_keeped_changes)
|
|
app.apply_keeped_preset_modifications();
|
|
|
|
app.app_config->set_legacy_datadir(false);
|
|
app.update_mode();
|
|
// BBS
|
|
//app.obj_manipul()->update_ui_from_settings();
|
|
BOOST_LOG_TRIVIAL(info) << "GuideFrame applied";
|
|
this->Close();
|
|
return true;
|
|
} else if (result == wxID_CANCEL) {
|
|
BOOST_LOG_TRIVIAL(info) << "GuideFrame cancelled";
|
|
if (app.preset_bundle->printers.only_default_printers()) {
|
|
//we install the default here
|
|
bool apply_keeped_changes = false;
|
|
//clear filament section and use default materials
|
|
app.app_config->set_variant(PresetBundle::BBL_BUNDLE,
|
|
PresetBundle::BBL_DEFAULT_PRINTER_MODEL, PresetBundle::BBL_DEFAULT_PRINTER_VARIANT, "true");
|
|
app.app_config->clear_section(AppConfig::SECTION_FILAMENTS);
|
|
app.preset_bundle->load_selections(*app.app_config, {PresetBundle::BBL_DEFAULT_PRINTER_MODEL, PresetBundle::BBL_DEFAULT_PRINTER_VARIANT, PresetBundle::BBL_DEFAULT_FILAMENT, std::string()});
|
|
|
|
app.app_config->set_legacy_datadir(false);
|
|
app.update_mode();
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
} else if (result == wxID_EDIT) {
|
|
this->Close();
|
|
FilamentInfomation *filament_info = new FilamentInfomation();
|
|
filament_info->filament_id = m_editing_filament_id;
|
|
wxQueueEvent(wxGetApp().plater(), new SimpleEvent(EVT_MODIFY_FILAMENT, filament_info));
|
|
return false;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
int GuideFrame::GetFilamentInfo( std::string VendorDirectory, json & pFilaList, std::string filepath, std::string &sVendor, std::string &sType)
|
|
{
|
|
//GetStardardFilePath(filepath);
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " GetFilamentInfo:VendorDirectory - " << VendorDirectory << ", Filepath - "<<filepath;
|
|
|
|
try {
|
|
std::string contents;
|
|
LoadFile(filepath, contents);
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Json Contents: " << contents;
|
|
json jLocal = json::parse(contents);
|
|
|
|
if (sVendor == "") {
|
|
if (jLocal.contains("filament_vendor"))
|
|
sVendor = jLocal["filament_vendor"][0];
|
|
else {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << filepath << " - Not Contains filament_vendor";
|
|
}
|
|
}
|
|
|
|
if (sType == "") {
|
|
if (jLocal.contains("filament_type"))
|
|
sType = jLocal["filament_type"][0];
|
|
else {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << filepath << " - Not Contains filament_type";
|
|
}
|
|
}
|
|
|
|
if (sVendor == "" || sType == "")
|
|
{
|
|
if (jLocal.contains("inherits")) {
|
|
std::string FName = jLocal["inherits"];
|
|
|
|
if (!pFilaList.contains(FName)) {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "pFilaList - Not Contains inherits filaments: " << FName;
|
|
return -1;
|
|
}
|
|
|
|
std::string FPath = pFilaList[FName]["sub_path"];
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Before Format Inherits Path: VendorDirectory - " << VendorDirectory << ", sub_path - " << FPath;
|
|
wxString strNewFile = wxString::Format("%s%c%s", wxString(VendorDirectory.c_str(), wxConvUTF8), boost::filesystem::path::preferred_separator, FPath);
|
|
boost::filesystem::path inherits_path(w2s(strNewFile));
|
|
|
|
//boost::filesystem::path nf(strNewFile.c_str());
|
|
if (boost::filesystem::exists(inherits_path))
|
|
return GetFilamentInfo(VendorDirectory,pFilaList, inherits_path.string(), sVendor, sType);
|
|
else {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " inherits File Not Exist: " << inherits_path;
|
|
return -1;
|
|
}
|
|
} else {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << filepath << " - Not Contains inherits";
|
|
if (sType == "") {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "sType is Empty";
|
|
return -1;
|
|
}
|
|
else
|
|
sVendor = "Generic";
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
catch(nlohmann::detail::parse_error &err) {
|
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<<filepath <<" got a nlohmann::detail::parse_error, reason = " << err.what();
|
|
return -1;
|
|
}
|
|
catch (std::exception &e)
|
|
{
|
|
// wxLogMessage("GUIDE: load_profile_error %s ", e.what());
|
|
// wxMessageBox(e.what(), "", MB_OK);
|
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse " << filepath <<" got exception: "<<e.what();
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int GuideFrame::LoadProfile()
|
|
{
|
|
try {
|
|
//wxString ExePath = boost::dll::program_location().parent_path().string();
|
|
//wxString TargetFolder = ExePath + "\\resources\\profiles\\";
|
|
//wxString TargetFolderSearch = ExePath + "\\resources\\profiles\\*.json";
|
|
|
|
//intptr_t handle;
|
|
//_finddata_t findData;
|
|
|
|
//handle = _findfirst(TargetFolderSearch.mb_str(), &findData); // ???????????
|
|
//if (handle == -1) { return -1; }
|
|
|
|
//do {
|
|
// if (findData.attrib & _A_SUBDIR && strcmp(findData.name, ".") == 0 && strcmp(findData.name, "..") == 0) // ??????????"."?".."
|
|
// {
|
|
// // cout << findData.name << "\t<dir>\n";
|
|
// } else {
|
|
// wxString strVendor = wxString(findData.name).BeforeLast('.');
|
|
// LoadProfileFamily(strVendor, TargetFolder + findData.name);
|
|
// }
|
|
|
|
//} while (_findnext(handle, &findData) == 0); // ???????????
|
|
|
|
// BBS: change directories by design
|
|
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", will load config from %1%.") % bbl_bundle_path;
|
|
m_ProfileJson = json::parse("{}");
|
|
//m_ProfileJson["configpath"] = Slic3r::data_dir();
|
|
m_ProfileJson["model"] = json::array();
|
|
m_ProfileJson["machine"] = json::object();
|
|
m_ProfileJson["filament"] = json::object();
|
|
m_ProfileJson["process"] = json::array();
|
|
|
|
vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR ).make_preferred();
|
|
rsrc_vendor_dir = (boost::filesystem::path(resources_dir()) / "profiles").make_preferred();
|
|
|
|
// BBS: add BBL as default
|
|
// BBS: add json logic for vendor bundle
|
|
auto bbl_bundle_path = vendor_dir;
|
|
bbl_bundle_rsrc = false;
|
|
if (!boost::filesystem::exists((vendor_dir / PresetBundle::BBL_BUNDLE).replace_extension(".json"))) {
|
|
bbl_bundle_path = rsrc_vendor_dir;
|
|
bbl_bundle_rsrc = true;
|
|
}
|
|
|
|
// intptr_t handle;
|
|
//_finddata_t findData;
|
|
|
|
//handle = _findfirst((bbl_bundle_path / "*.json").make_preferred().string().c_str(), &findData); // ???????????
|
|
// if (handle == -1) { return -1; }
|
|
|
|
// do {
|
|
// if (findData.attrib & _A_SUBDIR && strcmp(findData.name, ".") == 0 && strcmp(findData.name, "..") == 0) // ??????????"."?".."
|
|
// {
|
|
// // cout << findData.name << "\t<dir>\n";
|
|
// } else {
|
|
// wxString strVendor = wxString(findData.name).BeforeLast('.');
|
|
// LoadProfileFamily(w2s(strVendor), vendor_dir.make_preferred().string() + "\\"+ findData.name);
|
|
// }
|
|
|
|
//} while (_findnext(handle, &findData) == 0); // ???????????
|
|
|
|
|
|
//load BBL bundle from user data path
|
|
string targetPath = bbl_bundle_path.make_preferred().string();
|
|
boost::filesystem::path myPath(targetPath);
|
|
boost::filesystem::directory_iterator endIter;
|
|
for (boost::filesystem::directory_iterator iter(myPath); iter != endIter; iter++) {
|
|
if (boost::filesystem::is_directory(*iter)) {
|
|
//cout << "is dir" << endl;
|
|
//cout << iter->path().string() << endl;
|
|
} else {
|
|
//cout << "is a file" << endl;
|
|
//cout << iter->path().string() << endl;
|
|
|
|
wxString strVendor = from_u8(iter->path().string()).BeforeLast('.');
|
|
strVendor = strVendor.AfterLast( '\\');
|
|
strVendor = strVendor.AfterLast('\/');
|
|
wxString strExtension = from_u8(iter->path().string()).AfterLast('.').Lower();
|
|
|
|
if (w2s(strVendor) == PresetBundle::BBL_BUNDLE && strExtension.CmpNoCase("json") == 0)
|
|
LoadProfileFamily(w2s(strVendor), iter->path().string());
|
|
}
|
|
}
|
|
|
|
//string others_targetPath = rsrc_vendor_dir.string();
|
|
boost::filesystem::directory_iterator others_endIter;
|
|
for (boost::filesystem::directory_iterator iter(rsrc_vendor_dir); iter != others_endIter; iter++) {
|
|
if (boost::filesystem::is_directory(*iter)) {
|
|
//cout << "is dir" << endl;
|
|
//cout << iter->path().string() << endl;
|
|
} else {
|
|
//cout << "is a file" << endl;
|
|
//cout << iter->path().string() << endl;
|
|
wxString strVendor = from_u8(iter->path().string()).BeforeLast('.');
|
|
strVendor = strVendor.AfterLast( '\\');
|
|
strVendor = strVendor.AfterLast('\/');
|
|
wxString strExtension = from_u8(iter->path().string()).AfterLast('.').Lower();
|
|
|
|
if (w2s(strVendor) != PresetBundle::BBL_BUNDLE && strExtension.CmpNoCase("json")==0)
|
|
LoadProfileFamily(w2s(strVendor), iter->path().string());
|
|
}
|
|
}
|
|
|
|
|
|
//LoadProfileFamily(PresetBundle::BBL_BUNDLE, bbl_bundle_path.string());
|
|
|
|
const auto enabled_filaments = wxGetApp().app_config->has_section(AppConfig::SECTION_FILAMENTS) ? wxGetApp().app_config->get_section(AppConfig::SECTION_FILAMENTS) : std::map<std::string, std::string>();
|
|
m_appconfig_new.set_vendors(*wxGetApp().app_config);
|
|
m_appconfig_new.set_section(AppConfig::SECTION_FILAMENTS, enabled_filaments);
|
|
|
|
for (auto it = m_ProfileJson["model"].begin(); it != m_ProfileJson["model"].end(); ++it)
|
|
{
|
|
if (it.value().is_object()) {
|
|
json& temp_model = it.value();
|
|
std::string model_name = temp_model["model"];
|
|
std::string vendor_name = temp_model["vendor"];
|
|
std::string nozzle_diameter = temp_model["nozzle_diameter"];
|
|
std::string selected;
|
|
boost::trim(nozzle_diameter);
|
|
std::string nozzle;
|
|
bool enabled = false, first=true;
|
|
while (nozzle_diameter.size() > 0) {
|
|
auto pos = nozzle_diameter.find(';');
|
|
if (pos != std::string::npos) {
|
|
nozzle = nozzle_diameter.substr(0, pos);
|
|
enabled = m_appconfig_new.get_variant(vendor_name, model_name, nozzle);
|
|
if (enabled) {
|
|
if (!first)
|
|
selected += ";";
|
|
selected += nozzle;
|
|
first = false;
|
|
}
|
|
nozzle_diameter = nozzle_diameter.substr(pos + 1);
|
|
boost::trim(nozzle_diameter);
|
|
}
|
|
else {
|
|
enabled = m_appconfig_new.get_variant(vendor_name, model_name, nozzle_diameter);
|
|
if (enabled) {
|
|
if (!first)
|
|
selected += ";";
|
|
selected += nozzle_diameter;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
temp_model["nozzle_selected"] = selected;
|
|
//m_ProfileJson["model"][a]["nozzle_selected"]
|
|
}
|
|
}
|
|
|
|
if (m_ProfileJson["model"].size() == 1) {
|
|
std::string strNozzle = m_ProfileJson["model"][0]["nozzle_diameter"];
|
|
m_ProfileJson["model"][0]["nozzle_selected"]=strNozzle;
|
|
}
|
|
|
|
|
|
for (auto it = m_ProfileJson["filament"].begin(); it != m_ProfileJson["filament"].end(); ++it) {
|
|
//json temp_filament = it.value();
|
|
std::string filament_name = it.key();
|
|
if (enabled_filaments.find(filament_name) != enabled_filaments.end())
|
|
m_ProfileJson["filament"][filament_name]["selected"] = 1;
|
|
}
|
|
|
|
//----region
|
|
m_Region = wxGetApp().app_config->get("region");
|
|
m_ProfileJson["region"] = m_Region;
|
|
|
|
m_ProfileJson["network_plugin_install"] = wxGetApp().app_config->get("app","installed_networking");
|
|
m_ProfileJson["network_plugin_compability"] = wxGetApp().is_compatibility_version() ? "1" : "0";
|
|
network_plugin_ready = wxGetApp().is_compatibility_version();
|
|
}
|
|
catch (std::exception &e) {
|
|
//wxLogMessage("GUIDE: load_profile_error %s ", e.what());
|
|
// wxMessageBox(e.what(), "", MB_OK);
|
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", error: "<< e.what() <<std::endl;
|
|
}
|
|
|
|
std::string strAll = m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore);
|
|
//wxLogMessage("GUIDE: profile_json_s2 %s ", m_ProfileJson.dump(-1, ' ', false, json::error_handler_t::ignore));
|
|
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished, json contents: "<< std::endl<<strAll;
|
|
return 0;
|
|
}
|
|
|
|
void StringReplace(string &strBase, string strSrc, string strDes)
|
|
{
|
|
string::size_type pos = 0;
|
|
string::size_type srcLen = strSrc.size();
|
|
string::size_type desLen = strDes.size();
|
|
pos = strBase.find(strSrc, pos);
|
|
while ((pos != string::npos)) {
|
|
strBase.replace(pos, srcLen, strDes);
|
|
pos = strBase.find(strSrc, (pos + desLen));
|
|
}
|
|
}
|
|
|
|
|
|
//int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath)
|
|
//{
|
|
// //wxString strFolder = strFilePath.BeforeLast(boost::filesystem::path::preferred_separator);
|
|
// boost::filesystem::path file_path(strFilePath);
|
|
// boost::filesystem::path vendor_dir = boost::filesystem::absolute(file_path.parent_path()/ strVendor).make_preferred();
|
|
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", vendor path %1%.")% vendor_dir.string();
|
|
// try {
|
|
//
|
|
// //wxLogMessage("GUIDE: json_path1 %s", w2s(strFilePath));
|
|
//
|
|
// std::string contents;
|
|
// LoadFile(strFilePath, contents);
|
|
// //wxLogMessage("GUIDE: json_path1 content: %s", contents);
|
|
// json jLocal=json::parse(contents);
|
|
// //wxLogMessage("GUIDE: json_path1 Loaded");
|
|
//
|
|
// // BBS:models
|
|
// json pmodels = jLocal["machine_model_list"];
|
|
// int nsize = pmodels.size();
|
|
//
|
|
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% machine models")%nsize;
|
|
//
|
|
// for (int n = 0; n < nsize; n++) {
|
|
// json OneModel = pmodels.at(n);
|
|
//
|
|
// OneModel["model"] = OneModel["name"];
|
|
// OneModel.erase("name");
|
|
//
|
|
// std::string s1 = OneModel["model"];
|
|
// std::string s2 = OneModel["sub_path"];
|
|
//
|
|
// boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
// std::string sub_file = sub_path.string();
|
|
//
|
|
// //wxLogMessage("GUIDE: json_path2 %s", w2s(ModelFilePath));
|
|
// LoadFile(sub_file, contents);
|
|
// //wxLogMessage("GUIDE: json_path2 content: %s", contents);
|
|
// json pm=json::parse(contents);
|
|
// //wxLogMessage("GUIDE: json_path2 loaded");
|
|
//
|
|
// OneModel["vendor"] = strVendor;
|
|
// std::string NozzleOpt = pm["nozzle_diameter"];
|
|
// StringReplace(NozzleOpt, " ", "");
|
|
// OneModel["nozzle_diameter"] = NozzleOpt;
|
|
// OneModel["materials"] = pm["default_materials"];
|
|
//
|
|
// //wxString strCoverPath = wxString::Format("%s\\%s\\%s_cover.png", strFolder, strVendor, std::string(s1.mb_str()));
|
|
// std::string cover_file = s1+"_cover.png";
|
|
// boost::filesystem::path cover_path = boost::filesystem::absolute(vendor_dir / cover_file).make_preferred();
|
|
// OneModel["cover"] = cover_path.string();
|
|
//
|
|
// OneModel["nozzle_selected"] = "";
|
|
//
|
|
// m_ProfileJson["model"].push_back(OneModel);
|
|
// }
|
|
//
|
|
// // BBS:Machine
|
|
// json pmachine = jLocal["machine_list"];
|
|
// nsize = pmachine.size();
|
|
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% machines")%nsize;
|
|
// for (int n = 0; n < nsize; n++) {
|
|
// json OneMachine = pmachine.at(n);
|
|
//
|
|
// std::string s1 = OneMachine["name"];
|
|
// std::string s2 = OneMachine["sub_path"];
|
|
//
|
|
// //wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
|
// boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
// std::string sub_file = sub_path.string();
|
|
// LoadFile(sub_file, contents);
|
|
// json pm = json::parse(contents);
|
|
//
|
|
// std::string strInstant = pm["instantiation"];
|
|
// if (strInstant.compare("true") == 0) {
|
|
// OneMachine["model"] = pm["printer_model"];
|
|
//
|
|
// m_ProfileJson["machine"].push_back(OneMachine);
|
|
// }
|
|
// }
|
|
//
|
|
// // BBS:Filament
|
|
// json pFilament = jLocal["filament_list"];
|
|
// nsize = pFilament.size();
|
|
//
|
|
// int nFalse = 0;
|
|
// int nModel = 0;
|
|
// int nFinish = 0;
|
|
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% filaments")%nsize;
|
|
// for (int n = 0; n < nsize; n++) {
|
|
// json OneFF = pFilament.at(n);
|
|
//
|
|
// std::string s1 = OneFF["name"];
|
|
// std::string s2 = OneFF["sub_path"];
|
|
//
|
|
// if (!m_ProfileJson["filament"].contains(s1))
|
|
// {
|
|
// //wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
|
// boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
// std::string sub_file = sub_path.string();
|
|
// LoadFile(sub_file, contents);
|
|
// json pm = json::parse(contents);
|
|
//
|
|
// std::string strInstant = pm["instantiation"];
|
|
// if (strInstant == "true") {
|
|
// std::string sV;
|
|
// std::string sT;
|
|
//
|
|
// int nRet = GetFilamentInfo(sub_file, sV, sT);
|
|
// if (nRet != 0) continue;
|
|
//
|
|
// OneFF["vendor"] = sV;
|
|
// OneFF["type"] = sT;
|
|
//
|
|
// OneFF["models"] = "";
|
|
// OneFF["selected"] = 0;
|
|
// }
|
|
// else
|
|
// continue;
|
|
//
|
|
// } else {
|
|
// OneFF = m_ProfileJson["filament"][s1];
|
|
// }
|
|
//
|
|
// std::string vModel = "";
|
|
// int nm = m_ProfileJson["model"].size();
|
|
// int bFind = 0;
|
|
// for (int m = 0; m < nm; m++) {
|
|
// std::string strFF = m_ProfileJson["model"][m]["materials"];
|
|
// strFF = (boost::format(";%1%;")%strFF).str();
|
|
// std::string strTT = (boost::format(";%1%;")%s1).str();
|
|
// if (strFF.find(strTT) != std::string::npos) {
|
|
// std::string sModel = m_ProfileJson["model"][m]["model"];
|
|
//
|
|
// vModel = (boost::format("%1%[%2%]")%vModel %sModel).str();
|
|
// bFind = 1;
|
|
// }
|
|
// }
|
|
//
|
|
// OneFF["models"] = vModel;
|
|
//
|
|
// m_ProfileJson["filament"][s1] = OneFF;
|
|
// }
|
|
//
|
|
// //process
|
|
// json pProcess = jLocal["process_list"];
|
|
// nsize = pProcess.size();
|
|
// BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% processes")%nsize;
|
|
// for (int n = 0; n < nsize; n++) {
|
|
// json OneProcess = pProcess.at(n);
|
|
//
|
|
// std::string s2 = OneProcess["sub_path"];
|
|
// //wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
|
// boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
// std::string sub_file = sub_path.string();
|
|
// LoadFile(sub_file, contents);
|
|
// json pm = json::parse(contents);
|
|
//
|
|
// std::string bInstall = pm["instantiation"];
|
|
// if (bInstall == "true")
|
|
// {
|
|
// m_ProfileJson["process"].push_back(OneProcess);
|
|
// }
|
|
// }
|
|
//
|
|
// }
|
|
// catch(nlohmann::detail::parse_error &err) {
|
|
// BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<<strFilePath <<" got a nlohmann::detail::parse_error, reason = " << err.what();
|
|
// return -1;
|
|
// }
|
|
// catch (std::exception &e) {
|
|
// // wxMessageBox(e.what(), "", MB_OK);
|
|
// //wxLogMessage("GUIDE: LoadFamily Error: %s", e.what());
|
|
// BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << strFilePath << " got exception: " << e.what();
|
|
// return -1;
|
|
// }
|
|
//
|
|
// return 0;
|
|
//}
|
|
|
|
int GuideFrame::LoadProfileFamily(std::string strVendor, std::string strFilePath)
|
|
{
|
|
// wxString strFolder = strFilePath.BeforeLast(boost::filesystem::path::preferred_separator);
|
|
boost::filesystem::path file_path(strFilePath);
|
|
boost::filesystem::path vendor_dir = boost::filesystem::absolute(file_path.parent_path() / strVendor).make_preferred();
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", vendor path %1%.") % vendor_dir.string();
|
|
try {
|
|
// wxLogMessage("GUIDE: json_path1 %s", w2s(strFilePath));
|
|
|
|
std::string contents;
|
|
LoadFile(strFilePath, contents);
|
|
// wxLogMessage("GUIDE: json_path1 content: %s", contents);
|
|
json jLocal = json::parse(contents);
|
|
// wxLogMessage("GUIDE: json_path1 Loaded");
|
|
|
|
// BBS:models
|
|
json pmodels = jLocal["machine_model_list"];
|
|
int nsize = pmodels.size();
|
|
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% machine models") % nsize;
|
|
|
|
for (int n = 0; n < nsize; n++) {
|
|
json OneModel = pmodels.at(n);
|
|
|
|
OneModel["model"] = OneModel["name"];
|
|
OneModel.erase("name");
|
|
|
|
std::string s1 = OneModel["model"];
|
|
std::string s2 = OneModel["sub_path"];
|
|
|
|
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
std::string sub_file = sub_path.string();
|
|
|
|
// wxLogMessage("GUIDE: json_path2 %s", w2s(ModelFilePath));
|
|
LoadFile(sub_file, contents);
|
|
// wxLogMessage("GUIDE: json_path2 content: %s", contents);
|
|
json pm = json::parse(contents);
|
|
// wxLogMessage("GUIDE: json_path2 loaded");
|
|
|
|
OneModel["vendor"] = strVendor;
|
|
std::string NozzleOpt = pm["nozzle_diameter"];
|
|
StringReplace(NozzleOpt, " ", "");
|
|
OneModel["nozzle_diameter"] = NozzleOpt;
|
|
OneModel["materials"] = pm["default_materials"];
|
|
|
|
// wxString strCoverPath = wxString::Format("%s\\%s\\%s_cover.png", strFolder, strVendor, std::string(s1.mb_str()));
|
|
std::string cover_file = s1 + "_cover.png";
|
|
boost::filesystem::path cover_path = boost::filesystem::absolute(vendor_dir / cover_file).make_preferred();
|
|
OneModel["cover"] = cover_path.string();
|
|
|
|
OneModel["nozzle_selected"] = "";
|
|
|
|
m_ProfileJson["model"].push_back(OneModel);
|
|
}
|
|
|
|
// BBS:Machine
|
|
json pmachine = jLocal["machine_list"];
|
|
nsize = pmachine.size();
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% machines") % nsize;
|
|
for (int n = 0; n < nsize; n++) {
|
|
json OneMachine = pmachine.at(n);
|
|
|
|
std::string s1 = OneMachine["name"];
|
|
std::string s2 = OneMachine["sub_path"];
|
|
|
|
// wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
|
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
std::string sub_file = sub_path.string();
|
|
LoadFile(sub_file, contents);
|
|
json pm = json::parse(contents);
|
|
|
|
std::string strInstant = pm["instantiation"];
|
|
if (strInstant.compare("true") == 0) {
|
|
OneMachine["model"] = pm["printer_model"];
|
|
OneMachine["nozzle"] = pm["nozzle_diameter"][0];
|
|
|
|
m_ProfileJson["machine"][s1]=OneMachine;
|
|
}
|
|
}
|
|
|
|
// BBS:Filament
|
|
json pFilament = jLocal["filament_list"];
|
|
json tFilaList = json::object();
|
|
nsize = pFilament.size();
|
|
|
|
for (int n = 0; n < nsize; n++) {
|
|
json OneFF = pFilament.at(n);
|
|
|
|
std::string s1 = OneFF["name"];
|
|
std::string s2 = OneFF["sub_path"];
|
|
|
|
tFilaList[s1] = OneFF;
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Vendor: " << strVendor <<", tFilaList Add: " << s1;
|
|
}
|
|
|
|
int nFalse = 0;
|
|
int nModel = 0;
|
|
int nFinish = 0;
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% filaments") % nsize;
|
|
for (int n = 0; n < nsize; n++) {
|
|
json OneFF = pFilament.at(n);
|
|
|
|
std::string s1 = OneFF["name"];
|
|
std::string s2 = OneFF["sub_path"];
|
|
|
|
if (!m_ProfileJson["filament"].contains(s1)) {
|
|
// wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
|
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
std::string sub_file = sub_path.string();
|
|
LoadFile(sub_file, contents);
|
|
json pm = json::parse(contents);
|
|
|
|
std::string strInstant = pm["instantiation"];
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Load Filament:" << s1 << ",Path:" << sub_file << ",instantiation?" << strInstant;
|
|
|
|
if (strInstant == "true") {
|
|
std::string sV;
|
|
std::string sT;
|
|
|
|
int nRet = GetFilamentInfo(vendor_dir.string(),tFilaList, sub_file, sV, sT);
|
|
if (nRet != 0) {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Load Filament:" << s1 << ",GetFilamentInfo Failed, Vendor:" << sV << ",Type:"<< sT;
|
|
continue;
|
|
}
|
|
|
|
OneFF["vendor"] = sV;
|
|
OneFF["type"] = sT;
|
|
|
|
OneFF["models"] = "";
|
|
|
|
json pPrinters = pm["compatible_printers"];
|
|
int nPrinter = pPrinters.size();
|
|
std::string ModelList = "";
|
|
for (int i = 0; i < nPrinter; i++)
|
|
{
|
|
std::string sP = pPrinters.at(i);
|
|
if (m_ProfileJson["machine"].contains(sP))
|
|
{
|
|
std::string mModel = m_ProfileJson["machine"][sP]["model"];
|
|
std::string mNozzle = m_ProfileJson["machine"][sP]["nozzle"];
|
|
std::string NewModel = mModel + "++" + mNozzle;
|
|
|
|
ModelList = (boost::format("%1%[%2%]") % ModelList % NewModel).str();
|
|
}
|
|
}
|
|
|
|
OneFF["models"] = ModelList;
|
|
OneFF["selected"] = 0;
|
|
|
|
m_ProfileJson["filament"][s1] = OneFF;
|
|
} else
|
|
continue;
|
|
|
|
}
|
|
}
|
|
|
|
// process
|
|
json pProcess = jLocal["process_list"];
|
|
nsize = pProcess.size();
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", got %1% processes") % nsize;
|
|
for (int n = 0; n < nsize; n++) {
|
|
json OneProcess = pProcess.at(n);
|
|
|
|
std::string s2 = OneProcess["sub_path"];
|
|
// wxString ModelFilePath = wxString::Format("%s\\%s\\%s", strFolder, strVendor, s2);
|
|
boost::filesystem::path sub_path = boost::filesystem::absolute(vendor_dir / s2).make_preferred();
|
|
std::string sub_file = sub_path.string();
|
|
LoadFile(sub_file, contents);
|
|
json pm = json::parse(contents);
|
|
|
|
std::string bInstall = pm["instantiation"];
|
|
if (bInstall == "true") { m_ProfileJson["process"].push_back(OneProcess); }
|
|
}
|
|
|
|
} catch (nlohmann::detail::parse_error &err) {
|
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << strFilePath << " got a nlohmann::detail::parse_error, reason = " << err.what();
|
|
return -1;
|
|
} catch (std::exception &e) {
|
|
// wxMessageBox(e.what(), "", MB_OK);
|
|
// wxLogMessage("GUIDE: LoadFamily Error: %s", e.what());
|
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": parse " << strFilePath << " got exception: " << e.what();
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void GuideFrame::StrReplace(std::string &strBase, std::string strSrc, std::string strDes)
|
|
{
|
|
int pos = 0;
|
|
int srcLen = strSrc.size();
|
|
int desLen = strDes.size();
|
|
pos = strBase.find(strSrc, pos);
|
|
while ((pos != std::string::npos)) {
|
|
strBase.replace(pos, srcLen, strDes);
|
|
pos = strBase.find(strSrc, (pos + desLen));
|
|
}
|
|
}
|
|
|
|
std::string GuideFrame::w2s(wxString sSrc)
|
|
{
|
|
return std::string(sSrc.mb_str());
|
|
}
|
|
|
|
void GuideFrame::GetStardardFilePath(std::string &FilePath) {
|
|
StrReplace(FilePath, "\\", w2s(wxString::Format("%c", boost::filesystem::path::preferred_separator)));
|
|
StrReplace(FilePath, "\/", w2s(wxString::Format("%c", boost::filesystem::path::preferred_separator)));
|
|
}
|
|
|
|
bool GuideFrame::LoadFile(std::string jPath, std::string &sContent)
|
|
{
|
|
try {
|
|
boost::nowide::ifstream t(jPath);
|
|
std::stringstream buffer;
|
|
buffer << t.rdbuf();
|
|
sContent=buffer.str();
|
|
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << boost::format(", load %1% into buffer")% jPath;
|
|
}
|
|
catch (std::exception &e)
|
|
{
|
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", got exception: "<<e.what();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int GuideFrame::DownloadPlugin()
|
|
{
|
|
return wxGetApp().download_plugin(
|
|
"plugins", "network_plugin.zip",
|
|
[this](int status, int percent, bool& cancel) {
|
|
return ShowPluginStatus(status, percent, cancel);
|
|
}
|
|
, nullptr);
|
|
}
|
|
|
|
int GuideFrame::InstallPlugin()
|
|
{
|
|
return wxGetApp().install_plugin("plugins", "network_plugin.zip",
|
|
[this](int status, int percent, bool &cancel) {
|
|
return ShowPluginStatus(status, percent, cancel);
|
|
}
|
|
);
|
|
}
|
|
|
|
int GuideFrame::ShowPluginStatus(int status, int percent, bool& cancel)
|
|
{
|
|
//TODO
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
}} // namespace Slic3r::GUI
|