merge upstream changes

Signed-off-by: SoftFever <103989404+SoftFever@users.noreply.github.com>
This commit is contained in:
SoftFever 2023-01-21 00:37:10 +08:00
parent 1bdedb1c47
commit 2492e5d39c
156 changed files with 33597 additions and 65667 deletions

View file

@ -78,7 +78,9 @@ using namespace nlohmann;
#include "slic3r/GUI/Camera.hpp"
#include <GLFW/glfw3.h>
#ifdef __WXGTK__
#include <X11/Xlib.h>
#endif
#ifdef SLIC3R_GUI
#include "slic3r/GUI/GUI_Init.hpp"
@ -332,6 +334,10 @@ int CLI::run(int argc, char **argv)
// startup if gtk3 is used. This env var has to be set explicitly to
// instruct the window manager to fall back to X server mode.
::setenv("GDK_BACKEND", "x11", /* replace */ true);
// Also on Linux, we need to tell Xlib that we will be using threads,
// lest we crash when we fire up GStreamer.
XInitThreads();
#endif
// Switch boost::filesystem to utf8.

View file

@ -240,7 +240,7 @@ else ()
set(MACOSX_BUNDLE_ICON_FILE Icon.icns)
set(MACOSX_BUNDLE_BUNDLE_NAME "Bambu Studio")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${SLIC3R_VERSION})
set(MACOSX_BUNDLE_COPYRIGHT "Copyright(C) 2022-2032 Bambu Lab")
set(MACOSX_BUNDLE_COPYRIGHT "Copyright(C) 2021-2023 Lunkuo All Rights Reserved")
endif()
add_custom_command(TARGET BambuStudio POST_BUILD
COMMAND ln -sfn "${SLIC3R_RESOURCES_DIR}" "${BIN_RESOURCES_DIR}"

View file

@ -1,73 +0,0 @@
The OpenGL Extension Wrangler Library
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
Copyright (C) 2002, Lev Povalahev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
Mesa 3-D graphics library
Version: 7.0
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyright (c) 2007 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

View file

@ -1,260 +0,0 @@
THIS IS NOT THE COMPLETE GLEW DISTRIBUTION. ONLY FILES NEEDED FOR COMPILING GLEW INTO SLIC3R WERE PUT INTO THE SLIC3R SOURCE DISTRIBUTION.
# GLEW - The OpenGL Extension Wrangler Library
The OpenGL Extension Wrangler Library (GLEW) is a cross-platform open-source C/C++ extension loading library. GLEW provides efficient run-time mechanisms for determining which OpenGL extensions are supported on the target platform. OpenGL core and extension functionality is exposed in a single header file. GLEW has been tested on a variety of operating systems, including Windows, Linux, Mac OS X, FreeBSD, Irix, and Solaris.
![](http://glew.sourceforge.net/glew.png)
http://glew.sourceforge.net/
https://github.com/nigels-com/glew
[![Build Status](https://travis-ci.org/nigels-com/glew.svg?branch=master)](https://travis-ci.org/nigels-com/glew)
[![Gitter](https://badges.gitter.im/nigels-com/glew.svg)](https://gitter.im/nigels-com/glew?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Download](https://img.shields.io/sourceforge/dm/glew.svg)](https://sourceforge.net/projects/glew/files/latest/download)
## Table of Contents
* [Downloads](#downloads)
* [Recent snapshots](#recent-snapshots)
* [Build](#build)
* [Linux and Mac](#linux-and-mac)
* [Using GNU Make](#using-gnu-make)
* [Install build tools](#install-build-tools)
* [Build](#build-1)
* [Linux EGL](#linux-egl)
* [Linux OSMesa](#linux-osmesa)
* [Linux mingw-w64](#linux-mingw-w64)
* [Using cmake](#using-cmake)
* [Install build tools](#install-build-tools-1)
* [Build](#build-2)
* [Windows](#windows)
* [Visual Studio](#visual-studio)
* [MSYS/Mingw](#msysmingw)
* [MSYS2/Mingw-w64](#msys2mingw-w64)
* [glewinfo](#glewinfo)
* [Code Generation](#code-generation)
* [Authors](#authors)
* [Contributions](#contributions)
* [Copyright and Licensing](#copyright-and-licensing)
## Downloads
Current release is [2.1.0](https://sourceforge.net/projects/glew/files/glew/2.1.0/).
[(Change Log)](http://glew.sourceforge.net/log.html)
Sources available as
[ZIP](https://sourceforge.net/projects/glew/files/glew/2.1.0/glew-2.1.0.zip/download) or
[TGZ](https://sourceforge.net/projects/glew/files/glew/2.1.0/glew-2.1.0.tgz/download).
Windows binaries for [32-bit and 64-bit](https://sourceforge.net/projects/glew/files/glew/2.1.0/glew-2.1.0-win32.zip/download).
### Recent snapshots
Snapshots may contain new features, bug-fixes or new OpenGL extensions ahead of tested, official releases.
[glew-20200115.tgz](https://sourceforge.net/projects/glew/files/glew/snapshots/glew-20200115.tgz/download) *GLEW 2.2.0 RC3: fixes*
[glew-20190928.tgz](https://sourceforge.net/projects/glew/files/glew/snapshots/glew-20190928.tgz/download) *GLEW 2.2.0 RC2: New extensions, bug fixes*
## Build
It is highly recommended to build from a tgz or zip release snapshot.
The code generation workflow is a complex brew of gnu make, perl and python, that works best on Linux or Mac.
The code generation is known to work on Windows using [MSYS2](https://www.msys2.org/).
For most end-users of GLEW the official releases are the best choice, with first class support.
### Linux and Mac
#### Using GNU Make
GNU make is the primary build system for GLEW, historically.
It includes targets for building the sources and headers, for maintenance purposes.
##### Install build tools
Debian/Ubuntu/Mint: `$ sudo apt-get install build-essential libxmu-dev libxi-dev libgl-dev`
RedHat/CentOS/Fedora: `$ sudo yum install libXmu-devel libXi-devel libGL-devel`
FreeBSD: `# pkg install xorg lang/gcc git cmake gmake bash python perl5`
##### Build
$ make
$ sudo make install
$ make clean
Targets: `all, glew.lib (sub-targets: glew.lib.shared, glew.lib.static), glew.bin, clean, install, uninstall`
Variables: `SYSTEM=linux-clang, GLEW_DEST=/usr/local, STRIP=`
_Note: you may need to call `make` in the **auto** folder first_
##### Linux EGL
$ sudo apt install libegl1-mesa-dev
$ make SYSTEM=linux-egl
##### Linux OSMesa
$ sudo apt install libosmesa-dev
$ make SYSTEM=linux-osmesa
##### Linux mingw-w64
$ sudo apt install mingw-w64
$ make SYSTEM=linux-mingw32
$ make SYSTEM=linux-mingw64
#### Using cmake
The cmake build is mostly contributer maintained.
Due to the multitude of use cases this is maintained on a _best effort_ basis.
Pull requests are welcome.
*CMake 2.8.12 or higher is required.*
##### Install build tools
Debian/Ubuntu/Mint: `$ sudo apt-get install build-essential libxmu-dev libxi-dev libgl-dev cmake git`
RedHat/CentOS/Fedora: `$ sudo yum install libXmu-devel libXi-devel libGL-devel cmake git`
##### Build
$ cd build
$ cmake ./cmake
$ make -j4
| Target | Description |
| ---------- | ----------- |
| glew | Build the glew shared library. |
| glew_s | Build the glew static library. |
| glewinfo | Build the `glewinfo` executable (requires `BUILD_UTILS` to be `ON`). |
| visualinfo | Build the `visualinfo` executable (requires `BUILD_UTILS` to be `ON`). |
| install | Install all enabled targets into `CMAKE_INSTALL_PREFIX`. |
| clean | Clean up build artifacts. |
| all | Build all enabled targets (default target). |
| Variables | Description |
| --------------- | ----------- |
| BUILD_UTILS | Build the `glewinfo` and `visualinfo` executables. |
| GLEW_REGAL | Build in Regal mode. |
| GLEW_OSMESA | Build in off-screen Mesa mode. |
| BUILD_FRAMEWORK | Build as MacOSX Framework. Setting `CMAKE_INSTALL_PREFIX` to `/Library/Frameworks` is recommended. |
### Windows
#### Visual Studio
Use the provided Visual Studio project file in build/vc15/
Projects for vc6, vc10, vc12 and vc14 are also provided
#### MSYS/Mingw
Available from [Mingw](http://www.mingw.org/)
Requirements: bash, make, gcc
$ mingw32-make
$ mingw32-make install
$ mingw32-make install.all
Alternative toolchain: `SYSTEM=mingw-win32`
#### MSYS2/Mingw-w64
Available from [Msys2](http://msys2.github.io/) and/or [Mingw-w64](http://mingw-w64.org/)
Requirements: bash, make, gcc
$ pacman -S gcc make mingw-w64-i686-gcc mingw-w64-x86_64-gcc
$ make
$ make install
$ make install.all
Alternative toolchain: `SYSTEM=msys, SYSTEM=msys-win32, SYSTEM=msys-win64`
## glewinfo
`glewinfo` is a command-line tool useful for inspecting the capabilities of an
OpenGL implementation and GLEW support for that. Please include `glewinfo.txt`
with bug reports, as appropriate.
---------------------------
GLEW Extension Info
---------------------------
GLEW version 2.0.0
Reporting capabilities of pixelformat 3
Running on a Intel(R) HD Graphics 3000 from Intel
OpenGL version 3.1.0 - Build 9.17.10.4229 is supported
GL_VERSION_1_1: OK
---------------
GL_VERSION_1_2: OK
---------------
glCopyTexSubImage3D: OK
glDrawRangeElements: OK
glTexImage3D: OK
glTexSubImage3D: OK
...
## Code Generation
A Unix or Mac environment is needed for building GLEW from scratch to
include new extensions, or customize the code generation. The extension
data is regenerated from the top level source directory with:
make extensions
An alternative to generating the GLEW sources from scratch is to
download a pre-generated (unsupported) snapshot:
https://sourceforge.net/projects/glew/files/glew/snapshots/
## Authors
GLEW is currently maintained by [Nigel Stewart](https://github.com/nigels-com)
with bug fixes, new OpenGL extension support and new releases.
GLEW was developed by [Milan Ikits](http://www.cs.utah.edu/~ikits/)
and [Marcelo Magallon](http://wwwvis.informatik.uni-stuttgart.de/~magallon/).
Aaron Lefohn, Joe Kniss, and Chris Wyman were the first users and also
assisted with the design and debugging process.
The acronym GLEW originates from Aaron Lefohn.
Pasi K&auml;rkk&auml;inen identified and fixed several problems with
GLX and SDL. Nate Robins created the `wglinfo` utility, to
which modifications were made by Michael Wimmer.
## Contributions
GLEW welcomes community contributions. Typically these are co-ordinated
via [Issues](https://github.com/nigels-com/glew/issues) or
[Pull Requests](https://github.com/nigels-com/glew/pulls) in the
GitHub web interface.
Be sure to mention platform and compiler toolchain details when filing
a bug report. The output of `glewinfo` can be quite useful for discussion
also.
Generally GLEW is usually released once a year, around the time of the Siggraph
computer graphics conference. If you're not using the current release
version of GLEW, be sure to check if the issue or bug is fixed there.
## Copyright and Licensing
GLEW is originally derived from the EXTGL project by Lev Povalahev.
The source code is licensed under the
[Modified BSD License](http://glew.sourceforge.net/glew.txt), the
[Mesa 3-D License](http://glew.sourceforge.net/mesa.txt) (MIT) and the
[Khronos License](http://glew.sourceforge.net/khronos.txt) (MIT).
The automatic code generation scripts are released under the
[GNU GPL](http://glew.sourceforge.net/gpl.txt).

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -181,7 +181,7 @@ bool GCode::gcode_label_objects = true;
length *= (1. - gcodegen.writer().extruder()->retract_before_wipe());
//SoftFever: allow 100% retract before wipe
// if (length > 0)
if (length >= 0)
{
/* Calculate how long we need to travel in order to consume the required
amount of retraction. In other words, how far do we move in XY at wipe_speed
@ -1320,24 +1320,26 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (print.config().print_sequence == PrintSequence::ByObject) {
// Add each of the object's layers separately.
for (auto object : print.objects()) {
std::vector<coordf_t> zs;
//BBS: fix the issue that total layer is not right
std::vector<coord_t> zs;
zs.reserve(object->layers().size() + object->support_layers().size());
for (auto layer : object->layers())
zs.push_back(layer->print_z);
zs.push_back((coord_t)(layer->print_z / EPSILON));
for (auto layer : object->support_layers())
zs.push_back(layer->print_z);
zs.push_back((coord_t)(layer->print_z / EPSILON));
std::sort(zs.begin(), zs.end());
m_layer_count += (unsigned int)(object->instances().size() * (std::unique(zs.begin(), zs.end()) - zs.begin()));
}
} else {
// Print all objects with the same print_z together.
std::vector<coordf_t> zs;
//BBS: fix the issue that total layer is not right
std::vector<coord_t> zs;
for (auto object : print.objects()) {
zs.reserve(zs.size() + object->layers().size() + object->support_layers().size());
for (auto layer : object->layers())
zs.push_back(layer->print_z);
zs.push_back((coord_t)(layer->print_z / EPSILON));
for (auto layer : object->support_layers())
zs.push_back(layer->print_z);
zs.push_back((coord_t)(layer->print_z / EPSILON));
}
std::sort(zs.begin(), zs.end());
m_layer_count = (unsigned int)(std::unique(zs.begin(), zs.end()) - zs.begin());
@ -1366,6 +1368,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write_format("; %s\n", Slic3r::header_slic3r_generated().c_str());
//BBS: total estimated printing time
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
//BBS: total layer number
file.write_format("; total layer number: %d\n", m_layer_count);
file.write_format("; HEADER_BLOCK_END\n\n");
@ -3841,8 +3845,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
//BBS: Overhang_threshold_none means Overhang_threshold_1_4 and forcing cooling for all external perimeter
int overhang_threshold = EXTRUDER_CONFIG(overhang_fan_threshold) == Overhang_threshold_none ?
Overhang_threshold_none : EXTRUDER_CONFIG(overhang_fan_threshold) - 1;
if ((EXTRUDER_CONFIG(overhang_fan_threshold) == Overhang_threshold_none && path.role() == erExternalPerimeter) ||
path.get_overhang_degree() > overhang_threshold ||
if ((EXTRUDER_CONFIG(overhang_fan_threshold) == Overhang_threshold_none && path.role() == erExternalPerimeter)) {
gcode += ";_OVERHANG_FAN_START\n";
comment = ";_EXTRUDE_SET_SPEED";
} else if (path.get_overhang_degree() > overhang_threshold ||
is_bridge(path.role()))
gcode += ";_OVERHANG_FAN_START\n";
else
@ -3920,8 +3926,11 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
//BBS: Overhang_threshold_none means Overhang_threshold_1_4 and forcing cooling for all external perimeter
int overhang_threshold = EXTRUDER_CONFIG(overhang_fan_threshold) == Overhang_threshold_none ?
Overhang_threshold_none : EXTRUDER_CONFIG(overhang_fan_threshold) - 1;
if ((EXTRUDER_CONFIG(overhang_fan_threshold) == Overhang_threshold_none && path.role() == erExternalPerimeter) ||
path.get_overhang_degree() > overhang_threshold ||
if ((EXTRUDER_CONFIG(overhang_fan_threshold) == Overhang_threshold_none && path.role() == erExternalPerimeter)) {
gcode += ";_EXTRUDE_END\n";
gcode += ";_OVERHANG_FAN_END\n";
} else if (path.get_overhang_degree() > overhang_threshold ||
is_bridge(path.role()))
gcode += ";_OVERHANG_FAN_END\n";
else

View file

@ -270,7 +270,8 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
// get non 100% overhang paths by intersecting this loop with the grown lower slices
Polylines remain_polines;
if (perimeter_generator.config->enable_overhang_speed) {
//BBS: don't calculate overhang degree when enable fuzzy skin. It's unmeaning
if (perimeter_generator.config->enable_overhang_speed && perimeter_generator.config->fuzzy_skin == FuzzySkinType::None) {
for (auto it = lower_polygons_series->begin();
it != lower_polygons_series->end(); it++)
{

View file

@ -765,14 +765,14 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
convex_hulls_temp.push_back(convex_hull);
if (!intersection(convex_hulls_other, convex_hulls_temp).empty()) {
if (warning) {
warning->string = inst->model_instance->get_object()->name + L(" is too close to others, there may be collisions when printing.\n");
warning->string = inst->model_instance->get_object()->name + L(" is too close to others, there may be collisions when printing.") + "\n";
warning->object = inst->model_instance->get_object();
}
}
if (!intersection(exclude_polys, convex_hull).empty()) {
return {inst->model_instance->get_object()->name + L(" is too close to exclusion area, there may be collisions when printing.\n"), inst->model_instance->get_object()};
return {inst->model_instance->get_object()->name + L(" is too close to exclusion area, there may be collisions when printing.") + "\n", inst->model_instance->get_object()};
/*if (warning) {
warning->string = inst->model_instance->get_object()->name + L(" is too close to exclusion area, there may be collisions when printing.\n");
warning->string = inst->model_instance->get_object()->name + L(" is too close to exclusion area, there may be collisions when printing.") + "\n";
warning->object = inst->model_instance->get_object();
}*/
}
@ -1139,7 +1139,8 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
}
StringObjectException except;
except.string = format(L("Plate %d: %s does not support filament %s\n"), this->get_plate_index() + 1, L(bed_type_name), extruder_id + 1);
except.string = format(L("Plate %d: %s does not support filament %s"), this->get_plate_index() + 1, L(bed_type_name), extruder_id + 1);
except.string += "\n";
except.type = STRING_EXCEPT_FILAMENT_NOT_MATCH_BED_TYPE;
except.params.push_back(std::to_string(this->get_plate_index() + 1));
except.params.push_back(L(bed_type_name));

View file

@ -1486,7 +1486,7 @@ void TreeSupport::generate_toolpaths()
filler_interface->spacing = support_extrusion_width;
FillParams fill_params;
fill_params.density = interface_density;
fill_params.density = object_config.raft_first_layer_density * 0.01;
fill_params.dont_adjust = true;
fill_expolygons_generate_paths(ts_layer->support_fills.entities, std::move(offset_ex(raft_areas, scale_(expand_offset))),
@ -1596,14 +1596,13 @@ void TreeSupport::generate_toolpaths()
// base_areas
filler_support->spacing = support_flow.spacing();
Flow flow = (layer_id == 0 && m_raft_layers == 0) ? m_object->print()->brim_flow() : support_flow;
if (area_group.dist_to_top < 10 && !with_infill && m_object_config->support_style!=smsTreeHybrid) {
if (layer_id>0 && area_group.dist_to_top < 10 && !with_infill && m_object_config->support_style!=smsTreeHybrid) {
if (area_group.dist_to_top < 5) // 1 wall at the top <5mm
make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, 1, flow, erSupportMaterial);
else // at least 2 walls for range [5,10)
make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, std::max(wall_count, size_t(2)), flow, erSupportMaterial);
} else {
if (with_infill && layer_id > 0 && m_support_params.base_fill_pattern != ipLightning) {
} else if (layer_id > 0 && with_infill && m_support_params.base_fill_pattern != ipLightning) {
filler_support->angle = Geometry::deg2rad(object_config.support_angle.value);
// allow infill-only mode if support is thick enough
@ -1614,11 +1613,12 @@ void TreeSupport::generate_toolpaths()
make_perimeter_and_infill(ts_layer->support_fills.entities, *m_object->print(), poly, std::max(size_t(1), wall_count), flow,
erSupportMaterial, filler_support.get(), support_density);
}
} else {
make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly,
layer_id > 0 ? wall_count : std::numeric_limits<size_t>::max(), flow, erSupportMaterial);
}
}
else {
make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly,
layer_id > 0 ? wall_count : std::numeric_limits<size_t>::max(), flow, erSupportMaterial);
}
}
}
if (m_support_params.base_fill_pattern == ipLightning)

View file

@ -12,7 +12,7 @@ PRODUCTVERSION @SLIC3R_VERSION@
VALUE "ProductName", "@SLIC3R_APP_NAME@ G-code Viewer"
VALUE "ProductVersion", "@SLIC3R_BUILD_ID@"
VALUE "InternalName", "@SLIC3R_APP_NAME@ G-code Viewer"
VALUE "LegalCopyright", "Copyright \251 2016-2021 Bambu Research, \251 2011-2018 Alessandro Ranellucci"
VALUE "LegalCopyright", "Copyright(C) 2021-2023 Lunkuo All Rights Reserved"
VALUE "OriginalFilename", "bambu-gcodeviewer.exe"
}
}

View file

@ -12,7 +12,7 @@ PRODUCTVERSION @SLIC3R_VERSION@
VALUE "ProductName", "@SLIC3R_APP_NAME@"
VALUE "ProductVersion", "@SLIC3R_BUILD_ID@"
VALUE "InternalName", "@SLIC3R_APP_NAME@"
VALUE "LegalCopyright", "Copyright \251 2016-2021 Bambu Research, \251 2011-2018 Alessandro Ranellucci"
VALUE "LegalCopyright", "Copyright(C) 2021-2023 Lunkuo All Rights Reserved"
VALUE "OriginalFilename", "bambu-studio.exe"
}
}

View file

@ -5,7 +5,7 @@
<key>CFBundleExecutable</key>
<string>@SLIC3R_APP_KEY@</string>
<key>CFBundleGetInfoString</key>
<string>@SLIC3R_APP_NAME@ Copyright (C) 2011-2019 Alessandro Ranellucci, (C) 2016-2021 Bambu Reseach</string>
<string>@SLIC3R_APP_NAME@ Copyright(C) 2021-2023 Lunkuo All Rights Reserved</string>
<key>CFBundleIconFile</key>
<string>BambuStudio.icns</string>
<key>CFBundleName</key>

View file

@ -153,6 +153,8 @@ set(SLIC3R_GUI_SOURCES
GUI/AMSSetting.hpp
GUI/AMSMaterialsSetting.cpp
GUI/AMSMaterialsSetting.hpp
GUI/ExtrusionCalibration.cpp
GUI/ExtrusionCalibration.hpp
GUI/PresetHints.cpp
GUI/PresetHints.hpp
GUI/GUI.cpp
@ -463,6 +465,12 @@ else ()
)
endif ()
if (UNIX AND NOT APPLE)
list(APPEND SLIC3R_GUI_SOURCES
GUI/Printer/gstbambusrc.c
)
endif ()
add_library(libslic3r_gui STATIC ${SLIC3R_GUI_SOURCES})
target_include_directories(libslic3r_gui PRIVATE Utils)
@ -513,4 +521,10 @@ if (UNIX AND NOT APPLE)
find_package(GTK${SLIC3R_GTK} REQUIRED)
target_include_directories(libslic3r_gui PRIVATE ${GTK${SLIC3R_GTK}_INCLUDE_DIRS})
target_link_libraries(libslic3r_gui ${GTK${SLIC3R_GTK}_LIBRARIES})
# We add GStreamer for bambu:/// support.
pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
pkg_check_modules(GST_BASE REQUIRED gstreamer-base-1.0)
target_link_libraries(libslic3r_gui ${GSTREAMER_LIBRARIES} ${GST_BASE_LIBRARIES})
target_include_directories(libslic3r_gui PRIVATE ${GSTREAMER_INCLUDE_DIRS} ${GST_BASE_INCLUDE_DIRS})
endif ()

View file

@ -1,4 +1,6 @@
#include "AMSMaterialsSetting.hpp"
#include "ExtrusionCalibration.hpp"
#include "MsgDialog.hpp"
#include "GUI_App.hpp"
#include "libslic3r/Preset.hpp"
#include "I18N.hpp"
@ -6,11 +8,6 @@
namespace Slic3r { namespace GUI {
static bool show_flag;
#ifdef __APPLE__
#define COMBOBOX_FILAMENT (m_comboBox_filament_mac)
#else
#define COMBOBOX_FILAMENT (m_comboBox_filament)
#endif
AMSMaterialsSetting::AMSMaterialsSetting(wxWindow *parent, wxWindowID id)
: DPIDialog(parent, id, _L("AMS Materials Setting"), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
{
@ -23,171 +20,10 @@ void AMSMaterialsSetting::create()
SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_sizer_filament = new wxBoxSizer(wxHORIZONTAL);
m_title_filament = new wxStaticText(this, wxID_ANY, _L("Filament"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_filament->SetFont(::Label::Body_13);
m_title_filament->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_filament->Wrap(-1);
m_sizer_filament->Add(m_title_filament, 0, wxALIGN_CENTER, 0);
m_sizer_filament->Add(0, 0, 0, wxEXPAND, 0);
#ifdef __APPLE__
m_comboBox_filament_mac = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
#else
m_comboBox_filament = new ::ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
#endif
m_sizer_filament->Add(COMBOBOX_FILAMENT, 1, wxALIGN_CENTER, 0);
m_readonly_filament = new TextInput(this, wxEmptyString, "", "", wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, wxTE_READONLY);
m_readonly_filament->SetBorderColor(StateColor(std::make_pair(0xDBDBDB, (int)StateColor::Focused), std::make_pair(0x009688, (int)StateColor::Hovered),
std::make_pair(0xDBDBDB, (int)StateColor::Normal)));
m_readonly_filament->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto& e) {
;
});
m_sizer_filament->Add(m_readonly_filament, 1, wxALIGN_CENTER, 0);
m_readonly_filament->Hide();
wxBoxSizer *m_sizer_colour = new wxBoxSizer(wxHORIZONTAL);
m_title_colour = new wxStaticText(this, wxID_ANY, _L("Colour"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_colour->SetFont(::Label::Body_13);
m_title_colour->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_colour->Wrap(-1);
m_sizer_colour->Add(m_title_colour, 0, wxALIGN_CENTER, 0);
m_sizer_colour->Add(0, 0, 0, wxEXPAND, 0);
m_clrData = new wxColourData();
m_clrData->SetChooseFull(true);
m_clrData->SetChooseAlpha(false);
m_clr_picker = new Button(this, wxEmptyString, wxEmptyString, wxBU_AUTODRAW);
m_clr_picker->SetCanFocus(false);
m_clr_picker->SetSize(FromDIP(50), FromDIP(25));
m_clr_picker->SetMinSize(wxSize(FromDIP(50), FromDIP(25)));
m_clr_picker->SetCornerRadius(FromDIP(6));
m_clr_picker->SetBorderColor(wxColour(172, 172, 172));
m_clr_picker->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_clr_picker, this);
m_sizer_colour->Add(m_clr_picker, 0, 0, 0);
wxBoxSizer *m_sizer_temperature = new wxBoxSizer(wxHORIZONTAL);
m_title_temperature = new wxStaticText(this, wxID_ANY, _L("Nozzle\nTemperature"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_temperature->SetFont(::Label::Body_13);
m_title_temperature->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_temperature->Wrap(-1);
m_sizer_temperature->Add(m_title_temperature, 0, wxALIGN_CENTER, 0);
m_sizer_temperature->Add(0, 0, 0, wxEXPAND, 0);
wxBoxSizer *sizer_other = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizer_tempinput = new wxBoxSizer(wxHORIZONTAL);
m_input_nozzle_max = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_min = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_max->Enable(false);
m_input_nozzle_min->Enable(false);
m_input_nozzle_max->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_input_nozzle_max->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
m_input_nozzle_min->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_input_nozzle_min->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
auto bitmap_max_degree = new wxStaticBitmap(this, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
auto bitmap_min_degree = new wxStaticBitmap(this, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
sizer_tempinput->Add(m_input_nozzle_max, 1, wxALIGN_CENTER, 0);
sizer_tempinput->Add(bitmap_min_degree, 0, wxALIGN_CENTER, 0);
sizer_tempinput->Add(FromDIP(10), 0, 0, 0);
sizer_tempinput->Add(m_input_nozzle_min, 1, wxALIGN_CENTER, 0);
sizer_tempinput->Add(bitmap_max_degree, 0, wxALIGN_CENTER, 0);
wxBoxSizer *sizer_temp_txt = new wxBoxSizer(wxHORIZONTAL);
auto m_title_max = new wxStaticText(this, wxID_ANY, _L("max"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
m_title_max->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_max->SetFont(::Label::Body_13);
auto m_title_min = new wxStaticText(this, wxID_ANY, _L("min"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
m_title_min->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_min->SetFont(::Label::Body_13);
sizer_temp_txt->Add(m_title_max, 1, wxALIGN_CENTER, 0);
sizer_temp_txt->Add(FromDIP(10), 0, 0, 0);
sizer_temp_txt->Add(m_title_min, 1, wxALIGN_CENTER | wxRIGHT, FromDIP(16));
sizer_other->Add(sizer_temp_txt, 0, wxALIGN_CENTER, 0);
sizer_other->Add(sizer_tempinput, 0, wxALIGN_CENTER, 0);
m_sizer_temperature->Add(sizer_other, 0, wxALL | wxALIGN_CENTER, 0);
m_sizer_temperature->AddStretchSpacer();
wxString warning_string = wxString::FromUTF8(
(boost::format(_u8L("The input value should be greater than %1% and less than %2%")) % FILAMENT_MIN_TEMP % FILAMENT_MAX_TEMP).str());
warning_text = new wxStaticText(this, wxID_ANY, warning_string, wxDefaultPosition, wxDefaultSize, 0);
warning_text->SetFont(::Label::Body_13);
warning_text->SetForegroundColour(wxColour(255, 111, 0));
warning_text->Wrap(AMS_MATERIALS_SETTING_BODY_WIDTH);
warning_text->SetMinSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
warning_text->Hide();
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &e) {
warning_text->Hide();
Layout();
Fit();
e.Skip();
});
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent &e) {
input_min_finish();
e.Skip();
});
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) {
input_min_finish();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent &e) {
warning_text->Hide();
Layout();
Fit();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent &e) {
input_max_finish();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &e) {
input_max_finish();
e.Skip();
});
m_panel_SN = new wxPanel(this, wxID_ANY);
wxBoxSizer *m_sizer_SN = new wxBoxSizer(wxVERTICAL);
m_sizer_SN->AddSpacer(FromDIP(16));
wxBoxSizer *m_sizer_SN_inside = new wxBoxSizer(wxHORIZONTAL);
auto m_title_SN = new wxStaticText(m_panel_SN, wxID_ANY, _L("SN"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_SN->SetFont(::Label::Body_13);
m_title_SN->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_SN->Wrap(-1);
m_sizer_SN_inside->Add(m_title_SN, 0, wxALIGN_CENTER, 0);
m_sizer_SN_inside->Add(0, 0, 0, wxEXPAND, 0);
m_sn_number = new wxStaticText(m_panel_SN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
m_sizer_SN_inside->Add(m_sn_number, 0, wxALIGN_CENTER, 0);
m_sizer_SN->Add(m_sizer_SN_inside);
m_panel_SN->SetSizer(m_sizer_SN);
m_panel_SN->Layout();
m_panel_SN->Fit();
wxBoxSizer* m_tip_sizer = new wxBoxSizer(wxHORIZONTAL);
m_tip_readonly = new wxStaticText(this, wxID_ANY, _L("Setting AMS slot information while printing is not supported"), wxDefaultPosition, wxSize(-1, AMS_MATERIALS_SETTING_INPUT_SIZE.y));
m_tip_readonly->Hide();
m_tip_sizer->Add(m_tip_readonly, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20));
m_panel_normal = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
create_panel_normal(m_panel_normal);
m_panel_kn = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
create_panel_kn(m_panel_kn);
wxBoxSizer *m_sizer_button = new wxBoxSizer(wxHORIZONTAL);
@ -217,17 +53,11 @@ void AMSMaterialsSetting::create()
m_sizer_button->Add(m_button_confirm, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20));
m_sizer_button->Add(m_button_close, 0, wxALIGN_CENTER, 0);
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main->Add(m_sizer_filament, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main->Add(m_sizer_colour, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main->Add(m_sizer_temperature, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
m_sizer_main->Add(warning_text, 0, wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(m_panel_SN, 0, wxLEFT, FromDIP(20));
m_sizer_main->Add(m_panel_normal, 0, wxALL, FromDIP(2));
m_sizer_main->Add(m_panel_kn, 0, wxALL, FromDIP(2));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(24));
m_sizer_main->Add(m_tip_sizer, 0, wxLEFT, FromDIP(20));
m_sizer_main->Add(m_sizer_button, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(16));
@ -235,8 +65,240 @@ void AMSMaterialsSetting::create()
Layout();
Fit();
Bind(wxEVT_PAINT, &AMSMaterialsSetting::paintEvent, this);
COMBOBOX_FILAMENT->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent& e) {
warning_text->Hide();
Layout();
Fit();
e.Skip();
});
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) {
input_min_finish();
e.Skip();
});
m_input_nozzle_min->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) {
input_min_finish();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [this](wxFocusEvent& e) {
warning_text->Hide();
Layout();
Fit();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) {
input_max_finish();
e.Skip();
});
m_input_nozzle_max->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) {
input_max_finish();
e.Skip();
});
Bind(wxEVT_PAINT, &AMSMaterialsSetting::paintEvent, this);
m_comboBox_filament->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
}
void AMSMaterialsSetting::create_panel_normal(wxWindow* parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* m_sizer_filament = new wxBoxSizer(wxHORIZONTAL);
m_title_filament = new wxStaticText(parent, wxID_ANY, _L("Filament"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_filament->SetFont(::Label::Body_13);
m_title_filament->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_filament->Wrap(-1);
m_sizer_filament->Add(m_title_filament, 0, wxALIGN_CENTER, 0);
m_sizer_filament->Add(0, 0, 0, wxEXPAND, 0);
#ifdef __APPLE__
m_comboBox_filament = new wxComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
#else
m_comboBox_filament = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, 0, nullptr, wxCB_READONLY);
#endif
m_sizer_filament->Add(m_comboBox_filament, 1, wxALIGN_CENTER, 0);
m_readonly_filament = new TextInput(parent, wxEmptyString, "", "", wxDefaultPosition, AMS_MATERIALS_SETTING_COMBOX_WIDTH, wxTE_READONLY);
m_readonly_filament->SetBorderColor(StateColor(std::make_pair(0xDBDBDB, (int)StateColor::Focused), std::make_pair(0x00AE42, (int)StateColor::Hovered),
std::make_pair(0xDBDBDB, (int)StateColor::Normal)));
m_readonly_filament->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto& e) {
;
});
m_sizer_filament->Add(m_readonly_filament, 1, wxALIGN_CENTER, 0);
m_readonly_filament->Hide();
wxBoxSizer* m_sizer_colour = new wxBoxSizer(wxHORIZONTAL);
m_title_colour = new wxStaticText(parent, wxID_ANY, _L("Colour"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_colour->SetFont(::Label::Body_13);
m_title_colour->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_colour->Wrap(-1);
m_sizer_colour->Add(m_title_colour, 0, wxALIGN_CENTER, 0);
m_sizer_colour->Add(0, 0, 0, wxEXPAND, 0);
m_clrData = new wxColourData();
m_clrData->SetChooseFull(true);
m_clrData->SetChooseAlpha(false);
m_clr_picker = new Button(parent, wxEmptyString, wxEmptyString, wxBU_AUTODRAW);
m_clr_picker->SetCanFocus(false);
m_clr_picker->SetSize(FromDIP(50), FromDIP(25));
m_clr_picker->SetMinSize(wxSize(FromDIP(50), FromDIP(25)));
m_clr_picker->SetCornerRadius(FromDIP(6));
m_clr_picker->SetBorderColor(wxColour(172, 172, 172));
m_clr_picker->Bind(wxEVT_BUTTON, &AMSMaterialsSetting::on_clr_picker, this);
m_sizer_colour->Add(m_clr_picker, 0, 0, 0);
wxBoxSizer* m_sizer_temperature = new wxBoxSizer(wxHORIZONTAL);
m_title_temperature = new wxStaticText(parent, wxID_ANY, _L("Nozzle\nTemperature"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_temperature->SetFont(::Label::Body_13);
m_title_temperature->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_temperature->Wrap(-1);
m_sizer_temperature->Add(m_title_temperature, 0, wxALIGN_CENTER, 0);
m_sizer_temperature->Add(0, 0, 0, wxEXPAND, 0);
wxBoxSizer* sizer_other = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizer_tempinput = new wxBoxSizer(wxHORIZONTAL);
m_input_nozzle_max = new ::TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_min = new ::TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_nozzle_max->Enable(false);
m_input_nozzle_min->Enable(false);
m_input_nozzle_max->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_input_nozzle_max->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
m_input_nozzle_min->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_input_nozzle_min->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
auto bitmap_max_degree = new wxStaticBitmap(parent, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
auto bitmap_min_degree = new wxStaticBitmap(parent, -1, create_scaled_bitmap("degree", nullptr, 16), wxDefaultPosition, wxDefaultSize);
sizer_tempinput->Add(m_input_nozzle_max, 1, wxALIGN_CENTER, 0);
sizer_tempinput->Add(bitmap_min_degree, 0, wxALIGN_CENTER, 0);
sizer_tempinput->Add(FromDIP(10), 0, 0, 0);
sizer_tempinput->Add(m_input_nozzle_min, 1, wxALIGN_CENTER, 0);
sizer_tempinput->Add(bitmap_max_degree, 0, wxALIGN_CENTER, 0);
wxBoxSizer* sizer_temp_txt = new wxBoxSizer(wxHORIZONTAL);
auto m_title_max = new wxStaticText(parent, wxID_ANY, _L("max"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
m_title_max->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_max->SetFont(::Label::Body_13);
auto m_title_min = new wxStaticText(parent, wxID_ANY, _L("min"), wxDefaultPosition, AMS_MATERIALS_SETTING_INPUT_SIZE);
m_title_min->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_min->SetFont(::Label::Body_13);
sizer_temp_txt->Add(m_title_max, 1, wxALIGN_CENTER, 0);
sizer_temp_txt->Add(FromDIP(10), 0, 0, 0);
sizer_temp_txt->Add(m_title_min, 1, wxALIGN_CENTER | wxRIGHT, FromDIP(16));
sizer_other->Add(sizer_temp_txt, 0, wxALIGN_CENTER, 0);
sizer_other->Add(sizer_tempinput, 0, wxALIGN_CENTER, 0);
m_sizer_temperature->Add(sizer_other, 0, wxALL | wxALIGN_CENTER, 0);
m_sizer_temperature->AddStretchSpacer();
wxString warning_string = wxString::FromUTF8(
(boost::format(_u8L("The input value should be greater than %1% and less than %2%")) % FILAMENT_MIN_TEMP % FILAMENT_MAX_TEMP).str());
warning_text = new wxStaticText(parent, wxID_ANY, warning_string, wxDefaultPosition, wxDefaultSize, 0);
warning_text->SetFont(::Label::Body_13);
warning_text->SetForegroundColour(wxColour(255, 111, 0));
warning_text->Wrap(AMS_MATERIALS_SETTING_BODY_WIDTH);
warning_text->SetMinSize(wxSize(AMS_MATERIALS_SETTING_BODY_WIDTH, -1));
warning_text->Hide();
m_panel_SN = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
wxBoxSizer* m_sizer_SN = new wxBoxSizer(wxVERTICAL);
m_sizer_SN->AddSpacer(FromDIP(16));
wxBoxSizer* m_sizer_SN_inside = new wxBoxSizer(wxHORIZONTAL);
auto m_title_SN = new wxStaticText(m_panel_SN, wxID_ANY, _L("SN"), wxDefaultPosition, wxSize(AMS_MATERIALS_SETTING_LABEL_WIDTH, -1), 0);
m_title_SN->SetFont(::Label::Body_13);
m_title_SN->SetForegroundColour(AMS_MATERIALS_SETTING_GREY800);
m_title_SN->Wrap(-1);
m_sizer_SN_inside->Add(m_title_SN, 0, wxALIGN_CENTER, 0);
m_sizer_SN_inside->Add(0, 0, 0, wxEXPAND, 0);
m_sn_number = new wxStaticText(m_panel_SN, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
m_sn_number->SetForegroundColour(*wxBLACK);
m_sizer_SN_inside->Add(m_sn_number, 0, wxALIGN_CENTER, 0);
m_sizer_SN->Add(m_sizer_SN_inside);
m_panel_SN->SetSizer(m_sizer_SN);
m_panel_SN->Layout();
m_panel_SN->Fit();
wxBoxSizer* m_tip_sizer = new wxBoxSizer(wxHORIZONTAL);
m_tip_readonly = new wxStaticText(parent, wxID_ANY, _L("Setting AMS slot information while printing is not supported"), wxDefaultPosition, wxSize(-1, AMS_MATERIALS_SETTING_INPUT_SIZE.y));
m_tip_readonly->SetForegroundColour(*wxBLACK);
m_tip_readonly->Hide();
m_tip_sizer->Add(m_tip_readonly, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(20));
sizer->Add(0, 0, 0, wxTOP, FromDIP(16));
sizer->Add(m_sizer_filament, 0, wxLEFT | wxRIGHT, FromDIP(20));
sizer->Add(0, 0, 0, wxTOP, FromDIP(16));
sizer->Add(m_sizer_colour, 0, wxLEFT | wxRIGHT, FromDIP(20));
sizer->Add(0, 0, 0, wxTOP, FromDIP(16));
sizer->Add(m_sizer_temperature, 0, wxLEFT | wxRIGHT, FromDIP(20));
sizer->Add(0, 0, 0, wxTOP, FromDIP(5));
sizer->Add(warning_text, 0, wxLEFT | wxRIGHT, FromDIP(20));
sizer->Add(m_panel_SN, 0, wxLEFT, FromDIP(20));
sizer->Add(0, 0, 0, wxTOP, FromDIP(24));
sizer->Add(m_tip_sizer, 0, wxLEFT, FromDIP(20));
parent->SetSizer(sizer);
}
void AMSMaterialsSetting::create_panel_kn(wxWindow* parent)
{
auto sizer = new wxBoxSizer(wxVERTICAL);
// title
auto ratio_text = new wxStaticText(parent, wxID_ANY, _L("Factors of dynamic flow cali"));
ratio_text->SetFont(Label::Head_14);
auto kn_val_sizer = new wxFlexGridSizer(0, 2, 0, 0);
kn_val_sizer->SetFlexibleDirection(wxBOTH);
kn_val_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
kn_val_sizer->AddGrowableCol(1);
// k params input
m_k_param = new wxStaticText(parent, wxID_ANY, _L("Factor K"), wxDefaultPosition, wxDefaultSize, 0);
m_k_param->SetFont(::Label::Body_13);
m_k_param->SetForegroundColour(wxColour(50, 58, 61));
m_k_param->Wrap(-1);
kn_val_sizer->Add(m_k_param, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
m_input_k_val = new TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_k_val->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
kn_val_sizer->Add(m_input_k_val, 0, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL, FromDIP(5));
// n params input
wxBoxSizer* n_sizer = new wxBoxSizer(wxHORIZONTAL);
m_n_param = new wxStaticText(parent, wxID_ANY, _L("Factor N"), wxDefaultPosition, wxDefaultSize, 0);
m_n_param->SetFont(::Label::Body_13);
m_n_param->SetForegroundColour(wxColour(50, 58, 61));
m_n_param->Wrap(-1);
kn_val_sizer->Add(m_n_param, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5));
m_input_n_val = new TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE | wxTE_PROCESS_ENTER);
m_input_n_val->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
kn_val_sizer->Add(m_input_n_val, 0, wxALL | wxEXPAND | wxALIGN_CENTER_VERTICAL, FromDIP(5));
// hide n
m_n_param->Hide();
m_input_n_val->Hide();
sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
sizer->Add(ratio_text, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
sizer->Add(kn_val_sizer, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(20));
sizer->Add(0, 0, 0, wxTOP, FromDIP(10));
parent->SetSizer(sizer);
}
void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt)
@ -250,7 +312,7 @@ void AMSMaterialsSetting::paintEvent(wxPaintEvent &evt)
AMSMaterialsSetting::~AMSMaterialsSetting()
{
COMBOBOX_FILAMENT->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
m_comboBox_filament->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(AMSMaterialsSetting::on_select_filament), NULL, this);
}
void AMSMaterialsSetting::input_min_finish()
@ -287,6 +349,7 @@ void AMSMaterialsSetting::input_max_finish()
void AMSMaterialsSetting::update()
{
if (obj) {
update_widgets();
if (obj->is_in_printing() || obj->can_resume()) {
enable_confirm_button(false);
} else {
@ -297,12 +360,12 @@ void AMSMaterialsSetting::update()
void AMSMaterialsSetting::enable_confirm_button(bool en)
{
if (!m_is_third) {
m_button_confirm->Show(en);
if (!m_is_third) {
m_tip_readonly->Hide();
}
else {
m_button_confirm->Show(en);
COMBOBOX_FILAMENT->Show(en);
m_comboBox_filament->Show(en);
m_readonly_filament->Show(!en);
m_tip_readonly->Show(!en);
}
@ -310,37 +373,138 @@ void AMSMaterialsSetting::enable_confirm_button(bool en)
void AMSMaterialsSetting::on_select_ok(wxCommandEvent &event)
{
if (!m_is_third) {
wxString k_text = m_input_k_val->GetTextCtrl()->GetValue();
wxString n_text = m_input_n_val->GetTextCtrl()->GetValue();
if (is_virtual_tray()) {
if (!ExtrusionCalibration::check_k_validation(k_text)) {
wxString k_tips = _L("Please input a valid value (K in 0~0.5)");
wxString kn_tips = _L("Please input a valid value (K in 0~0.5, N in 0.6~2.0)");
MessageDialog msg_dlg(nullptr, k_tips, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
double n = 0.0;
try {
n_text.ToDouble(&n);
}
catch (...) {
;
}
obj->command_extrusion_cali_set(VIRTUAL_TRAY_ID, "", "", k, n);
Close();
return;
}
wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue();
auto filament = COMBOBOX_FILAMENT->GetValue();
} else {
if (!m_is_third) {
// check and set k n
if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
if (!ExtrusionCalibration::check_k_validation(k_text)) {
wxString k_tips = _L("Please input a valid value (K in 0~0.5)");
wxString kn_tips = _L("Please input a valid value (K in 0~0.5, N in 0.6~2.0)");
MessageDialog msg_dlg(nullptr, k_tips, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
}
wxString nozzle_temp_max = m_input_nozzle_max->GetTextCtrl()->GetValue();
long nozzle_temp_min_int, nozzle_temp_max_int;
nozzle_temp_min.ToLong(&nozzle_temp_min_int);
nozzle_temp_max.ToLong(&nozzle_temp_max_int);
wxColour color = m_clrData->GetColour();
char col_buf[10];
sprintf(col_buf, "%02X%02X%02XFF", (int) color.Red(), (int) color.Green(), (int) color.Blue());
ams_filament_id = "";
// set k / n value
if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
// set extrusion cali ratio
int cali_tray_id = ams_id * 4 + tray_id;
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
if (it->alias.compare(COMBOBOX_FILAMENT->GetValue().ToStdString()) == 0) {
ams_filament_id = it->filament_id;
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
double n = 0.0;
try {
n_text.ToDouble(&n);
}
catch (...) {
;
}
obj->command_extrusion_cali_set(cali_tray_id, "", "", k, n);
}
Close();
return;
}
wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue();
auto filament = m_comboBox_filament->GetValue();
wxString nozzle_temp_max = m_input_nozzle_max->GetTextCtrl()->GetValue();
long nozzle_temp_min_int, nozzle_temp_max_int;
nozzle_temp_min.ToLong(&nozzle_temp_min_int);
nozzle_temp_max.ToLong(&nozzle_temp_max_int);
wxColour color = m_clrData->GetColour();
char col_buf[10];
sprintf(col_buf, "%02X%02X%02XFF", (int) color.Red(), (int) color.Green(), (int) color.Blue());
ams_filament_id = "";
ams_setting_id = "";
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) {
ams_filament_id = it->filament_id;
ams_setting_id = it->setting_id;
}
}
}
}
if (ams_filament_id.empty() || nozzle_temp_min.empty() || nozzle_temp_max.empty() || m_filament_type.empty()) {
BOOST_LOG_TRIVIAL(trace) << "Invalid Setting id";
} else {
if (obj) {
obj->command_ams_filament_settings(ams_id, tray_id, ams_filament_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int);
if (ams_filament_id.empty() || nozzle_temp_min.empty() || nozzle_temp_max.empty() || m_filament_type.empty()) {
BOOST_LOG_TRIVIAL(trace) << "Invalid Setting id";
} else {
if (obj) {
if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
if (!ExtrusionCalibration::check_k_validation(k_text)) {
wxString k_tips = _L("Please input a valid value (K in 0~0.5)");
wxString kn_tips = _L("Please input a valid value (K in 0~0.5, N in 0.6~2.0)");
MessageDialog msg_dlg(nullptr, k_tips, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
}
// set filament
if (!is_virtual_tray()) {
obj->command_ams_filament_settings(ams_id, tray_id, ams_filament_id, ams_setting_id, std::string(col_buf), m_filament_type, nozzle_temp_min_int, nozzle_temp_max_int);
}
// set k / n value
if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
// set extrusion cali ratio
int cali_tray_id = ams_id * 4 + tray_id;
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
double n = 0.0;
try {
n_text.ToDouble(&n);
}
catch (...) {
;
}
obj->command_extrusion_cali_set(cali_tray_id, "", "", k, n);
}
}
}
}
Close();
@ -373,6 +537,29 @@ void AMSMaterialsSetting::on_clr_picker(wxCommandEvent & event)
}
}
bool AMSMaterialsSetting::is_virtual_tray()
{
if (tray_id == VIRTUAL_TRAY_ID)
return true;
return false;
}
void AMSMaterialsSetting::update_widgets()
{
// virtual tray
if (is_virtual_tray()) {
m_panel_normal->Hide();
m_panel_kn->Show();
} else if (obj && obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
m_panel_normal->Show();
m_panel_kn->Show();
} else {
m_panel_normal->Show();
m_panel_kn->Hide();
}
Layout();
}
bool AMSMaterialsSetting::Show(bool show)
{
if (show) {
@ -384,102 +571,126 @@ bool AMSMaterialsSetting::Show(bool show)
return DPIDialog::Show(show);
}
void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_min, wxString temp_max)
void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_min, wxString temp_max, wxString k, wxString n)
{
m_clr_picker->SetBackgroundColor(wxColour(
m_clrData->GetColour().Red(),
m_clrData->GetColour().Green(),
m_clrData->GetColour().Blue(),
254
));
update_widgets();
// set default value
if (k.IsEmpty())
k = "0.000";
if (n.IsEmpty())
n = "0.000";
if (!m_is_third) {
m_button_confirm->Hide();
m_sn_number->SetLabel(sn);
m_panel_SN->Show();
COMBOBOX_FILAMENT->Hide();
m_readonly_filament->Show();
m_readonly_filament->GetTextCtrl()->SetLabel("Bambu " + filament);
m_input_nozzle_min->GetTextCtrl()->SetValue(temp_min);
m_input_nozzle_max->GetTextCtrl()->SetValue(temp_max);
m_input_k_val->GetTextCtrl()->SetValue(k);
m_input_n_val->GetTextCtrl()->SetValue(n);
if (is_virtual_tray()) {
m_button_confirm->Show();
update();
Layout();
Fit();
ShowModal();
return;
}
} else {
m_clr_picker->SetBackgroundColor(wxColour(
m_clrData->GetColour().Red(),
m_clrData->GetColour().Green(),
m_clrData->GetColour().Blue(),
254
));
m_button_confirm->Show();
m_panel_SN->Hide();
COMBOBOX_FILAMENT->Show();
m_readonly_filament->Hide();
if (!m_is_third) {
if (obj && obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
m_button_confirm->Show();
} else {
m_button_confirm->Hide();
}
m_sn_number->SetLabel(sn);
m_panel_SN->Show();
m_comboBox_filament->Hide();
m_readonly_filament->Show();
m_readonly_filament->GetTextCtrl()->SetLabel("Bambu " + filament);
m_input_nozzle_min->GetTextCtrl()->SetValue(temp_min);
m_input_nozzle_max->GetTextCtrl()->SetValue(temp_max);
update();
Layout();
Fit();
ShowModal();
return;
}
m_button_confirm->Show();
m_panel_SN->Hide();
m_comboBox_filament->Show();
m_readonly_filament->Hide();
int selection_idx = -1, idx = 0;
wxArrayString filament_items;
std::set<std::string> filament_id_set;
int selection_idx = -1, idx = 0;
wxArrayString filament_items;
std::set<std::string> filament_id_set;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
BOOST_LOG_TRIVIAL(trace) << "system_preset_bundle filament number=" << preset_bundle->filaments.size();
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
// filter by system preset
if (!filament_it->is_system) continue;
for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) {
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
BOOST_LOG_TRIVIAL(trace) << "system_preset_bundle filament number=" << preset_bundle->filaments.size();
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
// filter by system preset
if (!printer_it->is_system) continue;
// get printer_model
ConfigOption* printer_model_opt = printer_it->config.option("printer_model");
ConfigOptionString* printer_model_str = dynamic_cast<ConfigOptionString*>(printer_model_opt);
if (!printer_model_str || !obj)
continue;
if (!filament_it->is_system) continue;
// use printer_model as printer type
if (printer_model_str->value != MachineObject::get_preset_printer_model_name(obj->printer_type))
continue;
ConfigOption* printer_opt = filament_it->config.option("compatible_printers");
ConfigOptionStrings* printer_strs = dynamic_cast<ConfigOptionStrings*>(printer_opt);
for (auto printer_str : printer_strs->values) {
if (printer_it->name == printer_str) {
if (filament_id_set.find(filament_it->filament_id) != filament_id_set.end()) {
continue;
}
else {
filament_id_set.insert(filament_it->filament_id);
// name matched
filament_items.push_back(filament_it->alias);
if (filament_it->filament_id == ams_filament_id) {
selection_idx = idx;
for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) {
// filter by system preset
if (!printer_it->is_system) continue;
// get printer_model
ConfigOption* printer_model_opt = printer_it->config.option("printer_model");
ConfigOptionString* printer_model_str = dynamic_cast<ConfigOptionString*>(printer_model_opt);
if (!printer_model_str || !obj)
continue;
// update if nozzle_temperature_range is found
ConfigOption* opt_min = filament_it->config.option("nozzle_temperature_range_low");
if (opt_min) {
ConfigOptionInts* opt_min_ints = dynamic_cast<ConfigOptionInts*>(opt_min);
if (opt_min_ints) {
wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0));
m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min);
}
}
ConfigOption* opt_max = filament_it->config.option("nozzle_temperature_range_high");
if (opt_max) {
ConfigOptionInts* opt_max_ints = dynamic_cast<ConfigOptionInts*>(opt_max);
if (opt_max_ints) {
wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0));
m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max);
}
}
// use printer_model as printer type
if (printer_model_str->value != MachineObject::get_preset_printer_model_name(obj->printer_type))
continue;
ConfigOption* printer_opt = filament_it->config.option("compatible_printers");
ConfigOptionStrings* printer_strs = dynamic_cast<ConfigOptionStrings*>(printer_opt);
for (auto printer_str : printer_strs->values) {
if (printer_it->name == printer_str) {
if (filament_id_set.find(filament_it->filament_id) != filament_id_set.end()) {
continue;
}
else {
filament_id_set.insert(filament_it->filament_id);
// name matched
filament_items.push_back(filament_it->alias);
if (filament_it->filament_id == ams_filament_id) {
selection_idx = idx;
// update if nozzle_temperature_range is found
ConfigOption* opt_min = filament_it->config.option("nozzle_temperature_range_low");
if (opt_min) {
ConfigOptionInts* opt_min_ints = dynamic_cast<ConfigOptionInts*>(opt_min);
if (opt_min_ints) {
wxString text_nozzle_temp_min = wxString::Format("%d", opt_min_ints->get_at(0));
m_input_nozzle_min->GetTextCtrl()->SetValue(text_nozzle_temp_min);
}
}
ConfigOption* opt_max = filament_it->config.option("nozzle_temperature_range_high");
if (opt_max) {
ConfigOptionInts* opt_max_ints = dynamic_cast<ConfigOptionInts*>(opt_max);
if (opt_max_ints) {
wxString text_nozzle_temp_max = wxString::Format("%d", opt_max_ints->get_at(0));
m_input_nozzle_max->GetTextCtrl()->SetValue(text_nozzle_temp_max);
}
}
}
idx++;
}
idx++;
}
}
}
}
m_comboBox_filament->Set(filament_items);
m_comboBox_filament->SetSelection(selection_idx);
post_select_event();
}
COMBOBOX_FILAMENT->Set(filament_items);
COMBOBOX_FILAMENT->SetSelection(selection_idx);
post_select_event();
}
update();
@ -490,8 +701,8 @@ void AMSMaterialsSetting::Popup(wxString filament, wxString sn, wxString temp_mi
void AMSMaterialsSetting::post_select_event() {
wxCommandEvent event(wxEVT_COMBOBOX);
event.SetEventObject(COMBOBOX_FILAMENT);
wxPostEvent(COMBOBOX_FILAMENT, event);
event.SetEventObject(m_comboBox_filament);
wxPostEvent(m_comboBox_filament, event);
}
void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
@ -500,8 +711,7 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
auto a = it->alias;
if (it->alias.compare(COMBOBOX_FILAMENT->GetValue().ToStdString()) == 0) {
if (it->alias.compare(m_comboBox_filament->GetValue().ToStdString()) == 0) {
// ) if nozzle_temperature_range is found
ConfigOption* opt_min = it->config.option("nozzle_temperature_range_low");
if (opt_min) {

View file

@ -41,9 +41,11 @@ public:
void update();
void enable_confirm_button(bool en);
bool Show(bool show) override;
void Popup(wxString filament = wxEmptyString, wxString sn = wxEmptyString, wxString temp_min = wxEmptyString, wxString temp_max = wxEmptyString);
void Popup(wxString filament = wxEmptyString, wxString sn = wxEmptyString,
wxString temp_min = wxEmptyString, wxString temp_max = wxEmptyString,
wxString k = wxEmptyString, wxString n = wxEmptyString);
void post_select_event();
void post_select_event();
void set_color(wxColour color);
@ -52,6 +54,7 @@ public:
int tray_id { 0 }; /* 0 ~ 3 */
std::string ams_filament_id;
std::string ams_setting_id;
bool m_is_third;
wxString m_brand_filament;
@ -61,15 +64,20 @@ public:
std::string m_filament_type;
protected:
void create_panel_normal(wxWindow* parent);
void create_panel_kn(wxWindow* parent);
void on_dpi_changed(const wxRect &suggested_rect) override;
void on_select_filament(wxCommandEvent& evt);
void on_select_ok(wxCommandEvent &event);
void on_select_close(wxCommandEvent &event);
void on_clr_picker(wxCommandEvent &event);
bool is_virtual_tray();
void update_widgets();
protected:
StateColor m_btn_bg_green;
StateColor m_btn_bg_gray;
wxPanel * m_panel_normal;
wxPanel * m_panel_SN;
wxStaticText * m_sn_number;
wxStaticText * warning_text;
@ -77,7 +85,6 @@ protected:
wxStaticText * m_title_filament;
wxStaticText * m_title_colour;
wxStaticText * m_title_temperature;
wxStaticText * m_label_other;
TextInput * m_input_nozzle_min;
TextInput* m_input_nozzle_max;
Button * m_button_confirm;
@ -85,8 +92,15 @@ protected:
Button * m_button_close;
Button * m_clr_picker;
wxColourData * m_clrData;
wxPanel * m_panel_kn;
wxStaticText* m_k_param;
TextInput* m_input_k_val;
wxStaticText* m_n_param;
TextInput* m_input_n_val;
#ifdef __APPLE__
wxComboBox *m_comboBox_filament_mac;
wxComboBox *m_comboBox_filament;
#else
ComboBox *m_comboBox_filament;
#endif

View file

@ -382,6 +382,7 @@ wxString AMSSetting::append_title(wxString text)
{
wxString lab;
auto * widget = new wxStaticText(m_panel_body, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
widget->SetForegroundColour(*wxBLACK);
widget->Wrap(AMS_SETTING_BODY_WIDTH);
widget->SetMinSize(wxSize(AMS_SETTING_BODY_WIDTH, -1));
lab = widget->GetLabel();

View file

@ -312,7 +312,7 @@ AboutDialog::AboutDialog()
copyright_hor_sizer->Add(copyright_ver_sizer, 0, wxALL,5);
copyright_hor_sizer->Add( 0, 0, 0, wxLEFT, FromDIP(120));
wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2021-2022 Bambu Lab", wxDefaultPosition, wxDefaultSize);
wxStaticText *html_text = new wxStaticText(this, wxID_ANY, "Copyright(C) 2021-2023 Lunkuo All Rights Reserved", wxDefaultPosition, wxDefaultSize);
html_text->SetForegroundColour(wxColour(107, 107, 107));
copyright_ver_sizer->Add(html_text, 0, wxALL , 0);

View file

@ -612,6 +612,7 @@ AmsMapingTipPopup::AmsMapingTipPopup(wxWindow *parent)
wxBoxSizer *sizer_enable_ams = new wxBoxSizer(wxVERTICAL);
m_title_enable_ams = new wxStaticText(m_panel_enable_ams, wxID_ANY, _L("Enable AMS"), wxDefaultPosition, wxDefaultSize, 0);
m_title_enable_ams->SetForegroundColour(*wxBLACK);
m_title_enable_ams->SetBackgroundColour(*wxWHITE);
m_title_enable_ams->Wrap(-1);
sizer_enable_ams->Add(m_title_enable_ams, 0, 0, 0);
@ -619,6 +620,7 @@ AmsMapingTipPopup::AmsMapingTipPopup(wxWindow *parent)
m_tip_enable_ams = new wxStaticText(m_panel_enable_ams, wxID_ANY, _L("Print with filaments in the AMS"), wxDefaultPosition, wxDefaultSize, 0);
m_tip_enable_ams->SetMinSize(wxSize(FromDIP(200), FromDIP(50)));
m_tip_enable_ams->Wrap(FromDIP(200));
m_tip_enable_ams->SetForegroundColour(*wxBLACK);
m_tip_enable_ams->SetBackgroundColour(*wxWHITE);
sizer_enable_ams->Add(m_tip_enable_ams, 0, wxTOP, 8);
@ -647,12 +649,14 @@ AmsMapingTipPopup::AmsMapingTipPopup(wxWindow *parent)
m_title_disable_ams = new wxStaticText(m_panel_disable_ams, wxID_ANY, _L("Disable AMS"), wxDefaultPosition, wxDefaultSize, 0);
m_title_disable_ams->SetBackgroundColour(*wxWHITE);
m_title_disable_ams->SetForegroundColour(*wxBLACK);
m_title_disable_ams->Wrap(-1);
sizer_disable_ams->Add(m_title_disable_ams, 0, 0, 0);
m_tip_disable_ams = new wxStaticText(m_panel_disable_ams, wxID_ANY, _L("Print with the filament mounted on the back of chassis"), wxDefaultPosition, wxDefaultSize, 0);
m_tip_disable_ams->SetMinSize(wxSize(FromDIP(200), FromDIP(50)));
m_tip_disable_ams->Wrap(FromDIP(200));
m_tip_disable_ams->SetForegroundColour(*wxBLACK);
m_tip_disable_ams->SetBackgroundColour(*wxWHITE);
sizer_disable_ams->Add(m_tip_disable_ams, 0, wxTOP, FromDIP(8));
@ -694,6 +698,125 @@ void AmsMapingTipPopup::OnDismiss() {}
bool AmsMapingTipPopup::ProcessLeftDown(wxMouseEvent &event) {
return wxPopupTransientWindow::ProcessLeftDown(event); }
AmsHumidityTipPopup::AmsHumidityTipPopup(wxWindow* parent)
:wxPopupTransientWindow(parent, wxBORDER_NONE)
{
SetBackgroundColour(*wxWHITE);
wxBoxSizer* main_sizer;
main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(0, 0, 0, wxTOP, 28);
wxBoxSizer* m_sizer_body;
m_sizer_body = new wxBoxSizer(wxHORIZONTAL);
m_img = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("ams_humidity_tips", this, 125), wxDefaultPosition, wxSize(FromDIP(125), FromDIP(145)), 0);
m_sizer_body->Add(m_img, 0, wxEXPAND | wxALL, 2);
m_sizer_body->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(18));
wxBoxSizer* m_sizer_tips = new wxBoxSizer(wxVERTICAL);
m_staticText1 = new Label(this, _L("Cabin humidity"));
m_staticText1->SetForegroundColour(wxColour(0x352F2D));
m_staticText1->SetFont(::Label::Head_13);
m_staticText2 = new Label(this, _L("Green means that AMS humidity is normal, orange represent humidity is high, red represent humidity is too high.(Hygrometer: lower the better, The bars: higher the better)"));
m_staticText2->SetFont(::Label::Body_13);
m_staticText2->SetSize(wxSize(FromDIP(360), -1));
m_staticText2->SetMinSize(wxSize(FromDIP(360), -1));
m_staticText2->SetMaxSize(wxSize(FromDIP(360), -1));
m_staticText2->Wrap(FromDIP(360));
m_staticText3 = new Label(this, _L("Desiccant status"));
m_staticText3->SetForegroundColour(wxColour(0x352F2D));
m_staticText3->SetFont(::Label::Head_13);
m_staticText4 = new Label(this, _L("A desiccant status lower than two bars indicates that desiccant may be inactive. Please change the desiccant. (Higher is better)"));
m_staticText4->SetFont(::Label::Body_13);
m_staticText4->SetSize(wxSize(FromDIP(360), -1));
m_staticText4->SetMinSize(wxSize(FromDIP(360), -1));
m_staticText4->SetMaxSize(wxSize(FromDIP(360), -1));
m_staticText4->Wrap(FromDIP(360));
m_sizer_tips->Add(m_staticText1, 0, wxALL, 3);
m_sizer_tips->Add(m_staticText2, 0, wxALL, 3);
m_sizer_tips->Add(m_staticText3, 0, wxALL, 3);
m_sizer_tips->Add(m_staticText4, 0, wxALL, 3);
m_sizer_body->Add(m_sizer_tips, 0, wxEXPAND, 0);
main_sizer->Add(m_sizer_body, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(30));
m_staticText_note = new Label(this, _L("Note: When the lid is open or the desiccant pack is changed, it can take hours or a night to absorb the moisture. Low temperatures also slow down the process. During this time, the indicator may not represent the chamber accurately."));
m_staticText4->SetFont(::Label::Body_13);
m_staticText_note->SetMinSize(wxSize(FromDIP(536), -1));
m_staticText_note->SetMaxSize(wxSize(FromDIP(536), -1));
m_staticText_note->Wrap(FromDIP(536));
main_sizer->Add(m_staticText_note, 0, wxALL | wxLEFT | wxRIGHT, 34);
m_button_confirm = new Button(this, _L("OK"));
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_confirm->SetBackgroundColor(btn_bg_green);
m_button_confirm->SetBorderColor(wxColour(0, 174, 66));
m_button_confirm->SetTextColor(wxColour(0xFFFFFE));
m_button_confirm->SetSize(wxSize(FromDIP(72), FromDIP(24)));
m_button_confirm->SetMinSize(wxSize(FromDIP(72), FromDIP(24)));
m_button_confirm->SetCornerRadius(FromDIP(12));
m_button_confirm->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
Dismiss();
});
Bind(wxEVT_LEFT_UP, [this](auto& e) {
auto mouse_pos = ClientToScreen(e.GetPosition());
auto rect = m_button_confirm->ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > rect.x && mouse_pos.y > rect.y
&& mouse_pos.x < (rect.x + m_button_confirm->GetSize().x)
&& mouse_pos.y < (rect.y + m_button_confirm->GetSize().y))
{
Dismiss();
}
});
main_sizer->Add(m_button_confirm, 0, wxALIGN_CENTER | wxALL, 0);
main_sizer->Add(0, 0, 0, wxEXPAND | wxTOP, 18);
SetSizer(main_sizer);
Layout();
Fit();
Bind(wxEVT_PAINT, &AmsHumidityTipPopup::paintEvent, this);
wxGetApp().UpdateDarkUIWin(this);
}
void AmsHumidityTipPopup::paintEvent(wxPaintEvent& evt)
{
wxPaintDC dc(this);
dc.SetPen(wxColour(0xAC, 0xAC, 0xAC));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0);
}
void AmsHumidityTipPopup::OnDismiss() {}
bool AmsHumidityTipPopup::ProcessLeftDown(wxMouseEvent& event) {
return wxPopupTransientWindow::ProcessLeftDown(event);
}
AmsTutorialPopup::AmsTutorialPopup(wxWindow* parent)
:wxPopupTransientWindow(parent, wxBORDER_NONE)
{
@ -797,4 +920,89 @@ bool AmsTutorialPopup::ProcessLeftDown(wxMouseEvent& event) {
}
AmsIntroducePopup::AmsIntroducePopup(wxWindow* parent)
:wxPopupTransientWindow(parent, wxBORDER_NONE)
{
Bind(wxEVT_PAINT, &AmsIntroducePopup::paintEvent, this);
SetBackgroundColour(*wxWHITE);
SetMinSize(wxSize(FromDIP(200), FromDIP(200)));
SetMaxSize(wxSize(FromDIP(200), FromDIP(200)));
wxBoxSizer* bSizer4 = new wxBoxSizer(wxVERTICAL);
m_staticText_top = new Label(this, _L("Do not Enable AMS"));
m_staticText_top->SetFont(::Label::Head_13);
// m_staticText_top->SetForegroundColour(wxColour(0x323A3D));
m_staticText_top->Wrap(-1);
bSizer4->Add(m_staticText_top, 0, wxALL, 5);
m_staticText_bottom = new Label(this, _L("Print using materials mounted on the back of the case"));
m_staticText_bottom->Wrap(-1);
m_staticText_bottom->SetFont(::Label::Body_13);
m_staticText_bottom->SetForegroundColour(wxColour(0x6B6B6B));
bSizer4->Add(m_staticText_bottom, 0, wxALL, 5);
wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer(wxHORIZONTAL);
m_img_enable_ams = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("monitor_upgrade_ams", this, FromDIP(140)), wxDefaultPosition, wxDefaultSize, 0);
m_img_disable_ams = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("disable_ams_demo_icon", this, FromDIP(110)), wxDefaultPosition, wxDefaultSize, 0);
m_img_enable_ams->SetMinSize(wxSize(FromDIP(96), FromDIP(110)));
m_img_disable_ams->SetMinSize(wxSize(FromDIP(96), FromDIP(110)));
bSizer5->Add(m_img_enable_ams, 0, wxALIGN_CENTER, 0);
bSizer5->Add(m_img_disable_ams, 0, wxALIGN_CENTER, 0);
m_img_disable_ams->Hide();
m_img_disable_ams->Hide();
bSizer4->Add(bSizer5, 0, wxALIGN_CENTER | wxBOTTOM, FromDIP(1));
SetSizer(bSizer4);
Layout();
Fit();
wxGetApp().UpdateDarkUIWin(this);
}
void AmsIntroducePopup::set_mode(bool enable_ams)
{
if (enable_ams) {
m_staticText_top->SetLabelText(_L("Enable AMS"));
m_staticText_bottom->SetLabelText(_L("Print with filaments in ams"));
m_img_enable_ams->Show();
m_img_disable_ams->Hide();
}
else {
m_staticText_top->SetLabelText(_L("Do not Enable AMS"));
m_staticText_bottom->SetLabelText(_L("Print with filaments mounted on the back of the chassis"));
m_staticText_bottom->SetMinSize(wxSize(FromDIP(180), -1));
m_staticText_bottom->Wrap(FromDIP(180));
m_img_enable_ams->Hide();
m_img_disable_ams->Show();
}
Layout();
Fit();
}
void AmsIntroducePopup::paintEvent(wxPaintEvent& evt)
{
wxPaintDC dc(this);
dc.SetPen(wxColour(0xAC, 0xAC, 0xAC));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0);
}
void AmsIntroducePopup::OnDismiss() {}
bool AmsIntroducePopup::ProcessLeftDown(wxMouseEvent& event) {
return wxPopupTransientWindow::ProcessLeftDown(event);
}
}} // namespace Slic3r::GUI

View file

@ -161,6 +161,26 @@ public:
wxStaticText * m_tip_disable_ams;
};
class AmsHumidityTipPopup : public wxPopupTransientWindow
{
public:
AmsHumidityTipPopup(wxWindow* parent);
~AmsHumidityTipPopup() {};
void paintEvent(wxPaintEvent& evt);
virtual void OnDismiss() wxOVERRIDE;
virtual bool ProcessLeftDown(wxMouseEvent& event) wxOVERRIDE;
public:
wxStaticBitmap* m_img;
Label* m_staticText1;
Label* m_staticText2;
Label* m_staticText3;
Label* m_staticText4;
Label* m_staticText_note;
Button* m_button_confirm;
};
class AmsTutorialPopup : public wxPopupTransientWindow
{
public:
@ -183,6 +203,25 @@ public:
};
class AmsIntroducePopup : public wxPopupTransientWindow
{
public:
bool is_enable_ams = {false};
Label* m_staticText_top;
Label* m_staticText_bottom;
wxStaticBitmap* m_img_enable_ams;
wxStaticBitmap* m_img_disable_ams;
AmsIntroducePopup(wxWindow* parent);
~AmsIntroducePopup() {};
void set_mode(bool enable_ams);
void paintEvent(wxPaintEvent& evt);
virtual void OnDismiss() wxOVERRIDE;
virtual bool ProcessLeftDown(wxMouseEvent& event) wxOVERRIDE;
};
wxDECLARE_EVENT(EVT_SET_FINISH_MAPPING, wxCommandEvent);
}} // namespace Slic3r::GUI

View file

@ -1101,6 +1101,7 @@ void AuxiliaryPanel::update_all_cover()
auto m_text_designer = new wxStaticText(this, wxID_ANY, _L("Author"), wxDefaultPosition, wxSize(120, -1), 0);
m_text_designer->Wrap(-1);
m_text_designer->SetForegroundColour(*wxBLACK);
m_sizer_designer->Add(m_text_designer, 0, wxALIGN_CENTER, 0);
m_input_designer = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), FromDIP(30)), wxTE_PROCESS_ENTER);
@ -1111,6 +1112,7 @@ void AuxiliaryPanel::update_all_cover()
wxBoxSizer *m_sizer_model_name = new wxBoxSizer(wxHORIZONTAL);
auto m_text_model_name = new wxStaticText(this, wxID_ANY, _L("Model Name"), wxDefaultPosition, wxSize(120, -1), 0);
m_text_model_name->SetForegroundColour(*wxBLACK);
m_text_model_name->Wrap(-1);
m_sizer_model_name->Add(m_text_model_name, 0, wxALIGN_CENTER, 0);

View file

@ -31,8 +31,14 @@ BBLStatusBar::BBLStatusBar(wxWindow *parent, int id)
, m_object_info_sizer(new wxBoxSizer(wxHORIZONTAL))
{
m_status_text = new wxStaticText(m_self, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
m_status_text->SetForegroundColour(*wxBLACK);
m_object_info = new wxStaticText(m_self, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
m_object_info->SetForegroundColour(*wxBLACK);
m_slice_info = new wxStaticText(m_self, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
m_slice_info->SetForegroundColour(*wxBLACK);
wxStaticLine* seperator_1 = new wxStaticLine(m_self, wxID_ANY, wxDefaultPosition, wxSize(3, -1), wxLI_VERTICAL);
wxStaticLine* seperator_2 = new wxStaticLine(m_self, wxID_ANY, wxDefaultPosition, wxSize(3, -1), wxLI_VERTICAL);

View file

@ -292,8 +292,6 @@ void BBLTopbar::Init(wxFrame* parent)
wxBitmap close_bitmap = create_scaled_bitmap("topbar_close", nullptr, TOPBAR_ICON_SIZE);
wxAuiToolBarItem* close_btn = this->AddTool(wxID_CLOSE_FRAME, "", close_bitmap);
this->AddSpacer(FromDIP(6));
Realize();
// m_toolbar_h = this->GetSize().GetHeight();
m_toolbar_h = FromDIP(30);

View file

@ -41,6 +41,7 @@ namespace GUI {
m_printer_img->SetBackgroundColour(BIND_DIALOG_GREY200);
m_printer_img->Hide();
m_printer_name = new wxStaticText(m_panel_left, wxID_ANY, wxEmptyString);
m_printer_name->SetForegroundColour(*wxBLACK);
m_printer_name->SetBackgroundColour(BIND_DIALOG_GREY200);
m_printer_name->SetFont(::Label::Head_14);
m_sizere_left_v->Add(m_printer_img, 0, wxALIGN_CENTER, 0);
@ -317,6 +318,7 @@ UnBindMachineDialog::UnBindMachineDialog(Plater *plater /*= nullptr*/)
m_printer_img->Hide();
m_printer_name = new wxStaticText(m_panel_left, wxID_ANY, wxEmptyString);
m_printer_name->SetFont(::Label::Head_14);
m_printer_name->SetForegroundColour(*wxBLACK);
m_printer_name->SetBackgroundColour(BIND_DIALOG_GREY200);
m_sizere_left_v->Add(m_printer_img, 0, wxALIGN_CENTER, 0);
m_sizere_left_v->Add(0, 0, 0, wxTOP, 5);
@ -335,6 +337,7 @@ UnBindMachineDialog::UnBindMachineDialog(Plater *plater /*= nullptr*/)
m_panel_right->SetCornerRadius(FromDIP(8));
m_panel_right->SetBackgroundColor(BIND_DIALOG_GREY200);
m_user_name = new wxStaticText(m_panel_right, wxID_ANY, wxEmptyString);
m_user_name->SetForegroundColour(*wxBLACK);
m_user_name->SetBackgroundColour(BIND_DIALOG_GREY200);
m_user_name->SetFont(::Label::Head_14);
wxBoxSizer *m_sizer_right_h = new wxBoxSizer(wxHORIZONTAL);

View file

@ -161,6 +161,7 @@ wxWindow* CameraPopup::create_item_radiobox(wxString title, wxWindow* parent, wx
});
wxStaticText *text = new wxStaticText(item, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
text->SetForegroundColour(*wxBLACK);
resolution_texts.push_back(text);
text->SetPosition(wxPoint(padding_left + radiobox->GetSize().GetWidth() + 10, (item->GetSize().GetHeight() - text->GetSize().GetHeight()) / 2));
text->SetFont(Label::Body_13);

View file

@ -325,7 +325,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
config->opt_bool("enable_overhang_speed"))
{
wxString msg_text = _(L("Arachne engine only works when overhang slowing down is disabled.\n"
"This may cause decline in the quality of overhang surface when print fastly\n"));
"This may cause decline in the quality of overhang surface when print fastly")) + "\n";
if (is_global_config)
msg_text += "\n" + _(L("Disable overhang slowing down automatically? \n"
"Yes - Enable arachne and disable overhang slowing down\n"
@ -446,7 +446,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
if (is_global_config)
msg_text += "\n" + _L("Switch to rectilinear pattern?\n"
"Yes - switch to rectilinear pattern automaticlly\n"
"No - reset density to default non 100% value automaticlly\n");
"No - reset density to default non 100% value automaticlly") + "\n";
MessageDialog dialog(m_msg_dlg_parent, msg_text, "",
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
DynamicPrintConfig new_conf = *config;
@ -608,9 +608,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_field("inner_wall_line_width", have_perimeters || have_skirt || have_brim);
toggle_field("support_filament", have_support_material || have_skirt);
toggle_field("raft_contact_distance", have_raft && !have_support_soluble);
for (auto el : { "raft_expansion" })
toggle_field(el, have_raft);
toggle_line("raft_contact_distance", have_raft && !have_support_soluble);
for (auto el : { "raft_first_layer_expansion", "raft_first_layer_density"})
toggle_line(el, have_raft);
bool has_ironing = (config->opt_enum<IroningType>("ironing_type") != IroningType::NoIroning);
for (auto el : { "ironing_flow", "ironing_spacing", "ironing_speed" })

View file

@ -306,11 +306,36 @@ void MachineObject::set_access_code(std::string code)
{
this->access_code = code;
AppConfig *config = GUI::wxGetApp().app_config;
if (config) {
if (config && !code.empty()) {
GUI::wxGetApp().app_config->set_str("access_code", dev_id, code);
}
}
std::string MachineObject::get_access_code()
{
if (get_user_access_code().empty())
return access_code;
return get_user_access_code();
}
void MachineObject::set_user_access_code(std::string code)
{
this->user_access_code = code;
AppConfig* config = GUI::wxGetApp().app_config;
if (config) {
GUI::wxGetApp().app_config->set_str("user_access_code", dev_id, code);
}
}
std::string MachineObject::get_user_access_code()
{
AppConfig* config = GUI::wxGetApp().app_config;
if (config) {
return GUI::wxGetApp().app_config->get("user_access_code", dev_id);
}
return "";
}
bool MachineObject::is_lan_mode_printer()
{
bool result = false;
@ -325,7 +350,8 @@ MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string
dev_ip(ip),
subtask_(nullptr),
slice_info(nullptr),
m_is_online(false)
m_is_online(false),
vt_tray(std::to_string(VIRTUAL_TRAY_ID))
{
m_agent = agent;
@ -426,6 +452,40 @@ void MachineObject::_parse_print_option_ack(int option)
xcam_auto_recovery_step_loss = ((option >> (int)PRINT_OP_AUTO_RECOVERY) & 0x01) != 0;
}
bool MachineObject::is_in_extrusion_cali()
{
auto curr_time = std::chrono::system_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - last_extrusion_cali_start_time);
if (diff.count() < EXTRUSION_OMIT_TIME) {
mc_print_percent = 0;
return true;
}
if (is_in_printing_status(print_status)
&& print_type == "system"
&& boost::contains(m_gcode_file, "extrusion_cali")
)
{
return true;
}
return false;
}
bool MachineObject::is_extrusion_cali_finished()
{
auto curr_time = std::chrono::system_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - last_extrusion_cali_start_time);
if (diff.count() < EXTRUSION_OMIT_TIME) {
return false;
}
if (boost::contains(m_gcode_file, "extrusion_cali")
&& this->mc_print_percent == 100)
return true;
else
return false;
}
void MachineObject::_parse_tray_now(std::string tray_now)
{
m_tray_now = tray_now;
@ -1284,6 +1344,12 @@ void MachineObject::parse_version_func()
is_support_ai_monitoring = true;
is_support_ams_humidity = true;
}
local_use_ssl = ota_version->second.sw_ver.compare("01.03.01.04") >= 0;
}
} else if (printer_type == "C11") {
local_use_ssl = true;
if (ota_version != module_vers.end()) {
is_support_send_to_sdcard = ota_version->second.sw_ver.compare("01.02.00.00") >= 0;
}
}
}
@ -1470,7 +1536,7 @@ int MachineObject::command_ams_switch(int tray_index, int old_temp, int new_temp
// unload gcode
gcode = "M620 S255\nM104 S250\nG28 X\nG91\nG1 Z3.0 F1200\nG90\n"
"G1 X70 F12000\nG1 Y245\nG1 Y265 F3000\nM109 S250\nG1 X120 F12000\n"
"G1 X20 Y50 F12000\nG1 Y-3\nT255\nM104 S25\nG1 X165 F5000\nG1 Y245\n"
"G1 X20 Y50 F12000\nG1 Y-3\nT255\nM104 S0\nG1 X165 F5000\nG1 Y245\n"
"G91\nG1 Z-3.0 F1200\nG90\nM621 S255\n";
} else {
// load gcode
@ -1546,21 +1612,22 @@ int MachineObject::command_ams_calibrate(int ams_id)
return this->publish_gcode(gcode_cmd);
}
int MachineObject::command_ams_filament_settings(int ams_id, int tray_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max)
int MachineObject::command_ams_filament_settings(int ams_id, int tray_id, std::string filament_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max)
{
BOOST_LOG_TRIVIAL(info) << "command_ams_filament_settings, ams_id = " << ams_id << ", tray_id = " << tray_id << ", tray_color = " << tray_color
<< ", tray_type = " << tray_type;
<< ", tray_type = " << tray_type << ", setting_id = " << setting_id;
json j;
j["print"]["command"] = "ams_filament_setting";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["ams_id"] = ams_id;
j["print"]["tray_id"] = tray_id;
j["print"]["tray_info_idx"] = setting_id;
j["print"]["command"] = "ams_filament_setting";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["ams_id"] = ams_id;
j["print"]["tray_id"] = tray_id;
j["print"]["tray_info_idx"] = filament_id;
j["print"]["setting_id"] = setting_id;
// format "FFFFFFFF" RGBA
j["print"]["tray_color"] = tray_color;
j["print"]["tray_color"] = tray_color;
j["print"]["nozzle_temp_min"] = nozzle_temp_min;
j["print"]["nozzle_temp_max"] = nozzle_temp_max;
j["print"]["tray_type"] = tray_type;
j["print"]["nozzle_temp_max"] = nozzle_temp_max;
j["print"]["tray_type"] = tray_type;
return this->publish_json(j.dump());
}
@ -1623,6 +1690,57 @@ int MachineObject::command_set_work_light(LIGHT_EFFECT effect, int on_time, int
return this->publish_json(j.dump());
}
int MachineObject::command_start_extrusion_cali(int tray_index, int nozzle_temp, int bed_temp, float max_volumetric_speed, std::string setting_id)
{
BOOST_LOG_TRIVIAL(info) << "extrusion_cali: tray_id = " << tray_index << ", nozzle_temp = " << nozzle_temp << ", bed_temp = " << bed_temp
<< ", max_volumetric_speed = " << max_volumetric_speed;
json j;
j["print"]["command"] = "extrusion_cali";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["tray_id"] = tray_index;
//j["print"]["setting_id"] = setting_id;
//j["print"]["name"] = "";
j["print"]["nozzle_temp"] = nozzle_temp;
j["print"]["bed_temp"] = bed_temp;
j["print"]["max_volumetric_speed"] = max_volumetric_speed;
// enter extusion cali
last_extrusion_cali_start_time = std::chrono::system_clock::now();
return this->publish_json(j.dump());
}
int MachineObject::command_stop_extrusion_cali()
{
BOOST_LOG_TRIVIAL(info) << "extrusion_cali: stop";
if (is_in_extrusion_cali()) {
return command_task_abort();
}
return 0;
}
int MachineObject::command_extrusion_cali_set(int tray_index, std::string setting_id, std::string name, float k, float n, int bed_temp, int nozzle_temp, float max_volumetric_speed)
{
BOOST_LOG_TRIVIAL(info) << "extrusion_cali: tray_id = " << tray_index << ", setting_id = " << setting_id << ", k = " << k
<< ", n = " << n;
json j;
j["print"]["command"] = "extrusion_cali_set";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["tray_id"] = tray_index;
//j["print"]["setting_id"] = setting_id;
//j["print"]["name"] = name;
j["print"]["k_value"] = k;
j["print"]["n_coef"] = 1.4f; // fixed n
//j["print"]["n_coef"] = n;
if (bed_temp >= 0 && nozzle_temp >= 0 && max_volumetric_speed >= 0) {
j["print"]["bed_temp"] = bed_temp;
j["print"]["nozzle_temp"] = nozzle_temp;
j["print"]["max_volumetric_speed"] = max_volumetric_speed;
}
return this->publish_json(j.dump());
}
int MachineObject::command_set_printing_speed(PrintingSpeedLevel lvl)
{
json j;
@ -2081,6 +2199,14 @@ bool MachineObject::is_function_supported(PrinterFunction func)
case FUNC_CHAMBER_FAN:
func_name = "FUNC_CHAMBER_FAN";
break;
case FUNC_EXTRUSION_CALI:
if (!ams_support_virtual_tray)
return false;
func_name = "FUNC_EXTRUSION_CALI";
break;
case FUNC_PRINT_ALL:
func_name = "FUNC_PRINT_ALL";
break;
default:
return true;
}
@ -2279,6 +2405,19 @@ int MachineObject::parse_json(std::string payload)
if (jj.contains("subtask_name")) {
subtask_name = jj["subtask_name"].get<std::string>();
}
if (jj.contains("layer_num")) {
curr_layer = jj["layer_num"].get<int>();
}
if (jj.contains("total_layer_num")) {
total_layers = jj["total_layer_num"].get<int>();
if (total_layers == 0)
is_support_layer_num = false;
else
is_support_layer_num = true;
} else {
is_support_layer_num = false;
}
if (jj.contains("gcode_state")) {
this->set_print_state(jj["gcode_state"].get<std::string>());
}
@ -2924,15 +3063,34 @@ int MachineObject::parse_json(std::string payload)
} else {
curr_tray->remain = -1;
}
int ams_id_int = 0;
int tray_id_int = 0;
try {
if (!ams_id.empty() && !curr_tray->id.empty()) {
int ams_id_int = atoi(ams_id.c_str());
int tray_id_int = atoi(curr_tray->id.c_str());
ams_id_int = atoi(ams_id.c_str());
tray_id_int = atoi(curr_tray->id.c_str());
curr_tray->is_exists = (tray_exist_bits & (1 << (ams_id_int * 4 + tray_id_int))) != 0 ? true : false;
}
}
catch (...) {
}
if (tray_it->contains("setting_id")) {
curr_tray->filament_setting_id = (*tray_it)["setting_id"].get<std::string>();
}
auto curr_time = std::chrono::system_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - extrusion_cali_set_hold_start);
if (diff.count() > HOLD_TIMEOUT || diff.count() < 0
|| ams_id_int != (extrusion_cali_set_tray_id / 4)
|| tray_id_int != (extrusion_cali_set_tray_id % 4)) {
if (tray_it->contains("k")) {
curr_tray->k = (*tray_it)["k"].get<float>();
}
if (tray_it->contains("n")) {
curr_tray->n = (*tray_it)["n"].get<float>();
}
}
}
// remove not in trayList
for (auto tray_it = tray_id_set.begin(); tray_it != tray_id_set.end(); tray_it++) {
@ -2956,6 +3114,29 @@ int MachineObject::parse_json(std::string payload)
}
}
}
/* vitrual tray*/
try {
if (jj.contains("vt_tray")) {
if (jj["vt_tray"].contains("id"))
vt_tray.id = jj["vt_tray"]["id"].get<std::string>();
auto curr_time = std::chrono::system_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(curr_time - extrusion_cali_set_hold_start);
if (diff.count() > HOLD_TIMEOUT || diff.count() < 0
|| extrusion_cali_set_tray_id != VIRTUAL_TRAY_ID) {
if (jj["vt_tray"].contains("k"))
vt_tray.k = jj["vt_tray"]["k"].get<float>();
if (jj["vt_tray"].contains("n"))
vt_tray.n = jj["vt_tray"]["n"].get<float>();
}
ams_support_virtual_tray = true;
} else {
ams_support_virtual_tray = false;
}
}
catch (...) {
;
}
#pragma endregion
} else if (jj["command"].get<std::string>() == "gcode_line") {
@ -3036,7 +3217,7 @@ int MachineObject::parse_json(std::string payload)
}
}
}
}else if(jj["command"].get<std::string>() == "print_option") {
} else if(jj["command"].get<std::string>() == "print_option") {
try {
if (jj.contains("option")) {
if (jj["option"].is_number()) {
@ -3050,6 +3231,49 @@ int MachineObject::parse_json(std::string payload)
}
catch(...) {
}
} else if (jj["command"].get<std::string>() == "extrusion_cali") {
if (jj.contains("result") && jj["result"].get<std::string>() == "success") {
// enter extrusion cali
}
} else if (jj["command"].get<std::string>() == "extrusion_cali_set") {
int ams_id = -1;
int tray_id = -1;
int curr_tray_id = -1;
if (jj.contains("tray_id")) {
try {
curr_tray_id = jj["tray_id"].get<int>();
if (curr_tray_id == VIRTUAL_TRAY_ID)
tray_id = curr_tray_id;
else if (curr_tray_id >= 0 && curr_tray_id < 16){
ams_id = curr_tray_id / 4;
tray_id = curr_tray_id % 4;
} else {
BOOST_LOG_TRIVIAL(trace) << "extrusion_cali_set: unsupported tray_id = " << curr_tray_id;
}
}
catch(...) {
;
}
}
if (tray_id == VIRTUAL_TRAY_ID) {
if (jj.contains("k_value"))
vt_tray.k = jj["k_value"].get<float>();
if (jj.contains("n_coef"))
vt_tray.n = jj["n_coef"].get<float>();
} else {
auto ams_item = this->amsList.find(std::to_string(ams_id));
if (ams_item != this->amsList.end()) {
auto tray_item = ams_item->second->trayList.find(std::to_string(tray_id));
if (tray_item != ams_item->second->trayList.end()) {
if (jj.contains("k_value"))
tray_item->second->k = jj["k_value"].get<float>();
if (jj.contains("n_coef"))
tray_item->second->n = jj["n_coef"].get<float>();
}
}
}
extrusion_cali_set_tray_id = curr_tray_id;
extrusion_cali_set_hold_start = std::chrono::system_clock::now();
}
}
}
@ -3403,6 +3627,11 @@ void DeviceManager::on_machine_alive(std::string json_str)
BOOST_LOG_TRIVIAL(debug) << "SsdpDiscovery:: Update Machine Info, printer_sn = " << dev_id << ", signal = " << printer_signal;
obj->last_alive = Slic3r::Utils::get_current_time_utc();
obj->m_is_online = true;
/* if (!obj->dev_ip.empty()) {
Slic3r::GUI::wxGetApp().app_config->set_str("ip_address", obj->dev_id, obj->dev_ip);
Slic3r::GUI::wxGetApp().app_config->save();
}*/
}
else {
/* insert a new machine */
@ -3415,10 +3644,15 @@ void DeviceManager::on_machine_alive(std::string json_str)
//load access code
AppConfig* config = Slic3r::GUI::wxGetApp().app_config;
if (config) {
obj->access_code = Slic3r::GUI::wxGetApp().app_config->get("access_code", dev_id);
obj->set_access_code(Slic3r::GUI::wxGetApp().app_config->get("access_code", dev_id));
}
localMachineList.insert(std::make_pair(dev_id, obj));
/* if (!obj->dev_ip.empty()) {
Slic3r::GUI::wxGetApp().app_config->set_str("ip_address", obj->dev_id, obj->dev_ip);
Slic3r::GUI::wxGetApp().app_config->save();
}*/
BOOST_LOG_TRIVIAL(debug) << "SsdpDiscovery::New Machine, ip = " << dev_ip << ", printer_name= " << dev_name << ", printer_type = " << printer_type_str << ", signal = " << printer_signal;
}
@ -3680,6 +3914,7 @@ void DeviceManager::parse_user_print_info(std::string body)
if (m_agent) {
obj->set_bind_status(m_agent->get_user_name());
}
obj->dev_ip = Slic3r::GUI::wxGetApp().app_config->get("ip_address", dev_id);
userMachineList.insert(std::make_pair(dev_id, obj));
}

View file

@ -20,6 +20,8 @@
#define TIMEOUT_FOR_STRAT 20000.f // milliseconds
#define REQUEST_PUSH_MIN_TIME 15000.f // milliseconds
#define REQUEST_START_MIN_TIME 15000.f // milliseconds
#define EXTRUSION_OMIT_TIME 20000.f // milliseconds
#define HOLD_TIMEOUT 10000.f // milliseconds
#define FILAMENT_MAX_TEMP 300
#define FILAMENT_DEF_TEMP 220
@ -30,6 +32,7 @@
#define HOLD_COUNT_CAMERA 6
#define GET_VERSION_RETRYS 10
#define RETRY_INTERNAL 2000
#define VIRTUAL_TRAY_ID 254
inline int correct_filament_temperature(int filament_temp)
{
@ -85,6 +88,8 @@ enum PrinterFunction {
FUNC_SEND_TO_SDCARD,
FUNC_AUTO_SWITCH_FILAMENT,
FUNC_CHAMBER_FAN,
FUNC_EXTRUSION_CALI,
FUNC_PRINT_ALL,
FUNC_MAX
};
@ -178,8 +183,9 @@ public:
}
std::string id;
std::string tag_uid; // tag_uid
std::string setting_id; // tray_info_idx
std::string tag_uid; // tag_uid
std::string setting_id; // tray_info_idx
std::string filament_setting_id; // setting_id
std::string type;
std::string sub_brands;
std::string color;
@ -193,6 +199,8 @@ public:
std::string nozzle_temp_min;
std::string xcam_info;
std::string uuid;
float k = 0.0f; // k range: 0 ~ 0.5
float n = 0.0f; // k range: 0.6 ~ 2.0
wxColour wx_color;
bool is_bbl;
@ -313,6 +321,9 @@ private:
bool check_valid_ip();
void _parse_print_option_ack(int option);
std::string access_code;
std::string user_access_code;
public:
enum LIGHT_EFFECT {
@ -364,6 +375,15 @@ public:
SDCARD_STATE_NUM = 3
};
class ExtrusionRatioInfo
{
public:
std::string name;
std::string setting_id;
float k = 0.0;
float n = 0.0;
};
/* static members and functions */
static inline int m_sequence_id = 20000;
static std::string parse_printer_type(std::string type_str);
@ -380,11 +400,15 @@ public:
std::string dev_name;
std::string dev_ip;
std::string dev_id;
std::string access_code;
bool local_use_ssl { false };
std::string dev_connection_type; /* lan | cloud */
std::string connection_type() { return dev_connection_type; }
void set_dev_ip(std::string ip) {dev_ip = ip;};
bool has_access_right() { return !access_code.empty(); }
void set_access_code(std::string code);
std::string get_access_code();
void set_user_access_code(std::string code);
std::string get_user_access_code();
bool is_lan_mode_printer();
//PRINTER_TYPE printer_type = PRINTER_3DPrinter_UKNOWN;
std::string printer_type; /* model_id */
@ -414,6 +438,7 @@ public:
/* ams properties */
std::map<std::string, Ams*> amsList; // key: ams[id], start with 0
AmsTray vt_tray; // virtual tray
long ams_exist_bits = 0;
long tray_exist_bits = 0;
long tray_is_bbl_bits = 0;
@ -427,6 +452,7 @@ public:
bool ams_auto_switch_filament_flag { false };
bool ams_support_use_ams { false };
bool ams_support_remain { true };
bool ams_support_virtual_tray { true };
int ams_humidity;
int ams_user_setting_hold_count = 0;
AmsStatusMain ams_status_main;
@ -436,6 +462,14 @@ public:
std::string m_tray_id; // local tray id : "0" ~ "3"
std::string m_tray_now; // tray_now : "0" ~ "15" or "255"
std::string m_tray_tar; // tray_tar : "0" ~ "15" or "255"
int extrusion_cali_hold_count = 0;
std::chrono::system_clock::time_point last_extrusion_cali_start_time;
int extrusion_cali_set_tray_id = -1;
std::chrono::system_clock::time_point extrusion_cali_set_hold_start;
bool is_in_extrusion_cali();
bool is_extrusion_cali_finished();
void _parse_tray_now(std::string tray_now);
bool is_filament_move() { return atoi(m_tray_now.c_str()) == 255 ? false : true; };
bool is_ams_need_update;
@ -507,6 +541,7 @@ public:
int get_version_retry = 0;
std::map<std::string, ModuleVersionInfo> module_vers;
std::map<std::string, ModuleVersionInfo> new_ver_list;
std::map<std::string, ExtrusionRatioInfo> extrusion_ratio_map;
bool m_new_ver_list_exist = false;
int upgrade_err_code = 0;
std::vector<FirmwareInfo> firmware_list;
@ -523,10 +558,9 @@ public:
/* printing */
std::string print_type;
float nozzle { 0.0f };
float nozzle { 0.0f }; // default is 0.0f as initial value
bool is_220V_voltage { false };
int mc_print_stage;
int mc_print_sub_stage;
int mc_print_error_code;
@ -538,6 +572,9 @@ public:
int hw_switch_state;
bool is_system_printing();
int print_error;
int curr_layer = 0;
int total_layers = 0;
bool is_support_layer_num { false };
std::vector<int> stage_list_info;
int stage_curr = 0;
@ -592,7 +629,7 @@ public:
/*not support U2*/
bool is_support_1080dpi {false};
bool is_support_ai_monitoring {false};
bool is_support_ams_humidity {false};
bool is_support_ams_humidity {true};
/* sdcard */
MachineObject::SdcardState sdcard_state { NO_SDCARD };
@ -663,12 +700,15 @@ public:
int command_ams_user_settings(int ams_id, AmsOptionType op, bool value);
int command_ams_switch_filament(bool switch_filament);
int command_ams_calibrate(int ams_id);
int command_ams_filament_settings(int ams_id, int tray_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max);
int command_ams_filament_settings(int ams_id, int tray_id, std::string filament_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max);
int command_ams_select_tray(std::string tray_id);
int command_ams_refresh_rfid(std::string tray_id);
int command_ams_control(std::string action);
int command_set_chamber_light(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000);
int command_set_work_light(LIGHT_EFFECT effect, int on_time = 500, int off_time = 500, int loops = 1, int interval = 1000);
int command_start_extrusion_cali(int tray_index, int nozzle_temp, int bed_temp, float max_volumetric_speed, std::string setting_id = "");
int command_stop_extrusion_cali();
int command_extrusion_cali_set(int tray_index, std::string setting_id, std::string name, float k, float n, int bed_temp = -1, int nozzle_temp = -1, float max_volumetric_speed = -1);
// set printing speed
int command_set_printing_speed(PrintingSpeedLevel lvl);

View file

@ -67,6 +67,7 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title)
wxBoxSizer* sizer_download_failed = new wxBoxSizer(wxVERTICAL);
auto m_statictext_download_failed = new wxStaticText(m_panel_download_failed, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_statictext_download_failed->SetForegroundColour(*wxBLACK);
m_statictext_download_failed->SetLabel(format_text(m_statictext_download_failed, download_failed_msg, FromDIP(360)));
m_statictext_download_failed->Wrap(FromDIP(360));
@ -87,6 +88,7 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title)
wxBoxSizer* sizer_install_failed = new wxBoxSizer(wxVERTICAL);
auto m_statictext_install_failed = new wxStaticText(m_panel_install_failed, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_statictext_install_failed->SetForegroundColour(*wxBLACK);
m_statictext_install_failed->SetLabel(format_text(m_statictext_install_failed, install_failed_msg,FromDIP(360)));
m_statictext_install_failed->Wrap(FromDIP(360));

View file

@ -0,0 +1,839 @@
#include "ExtrusionCalibration.hpp"
#include "GUI_App.hpp"
#include "MsgDialog.hpp"
#include "libslic3r/Preset.hpp"
#include "I18N.hpp"
#include <wx/dcgraph.h>
namespace Slic3r { namespace GUI {
ExtrusionCalibration::ExtrusionCalibration(wxWindow *parent, wxWindowID id)
: DPIDialog(parent, id, _L("Dynamic flow calibration"), wxDefaultPosition, wxDefaultSize, (wxSYSTEM_MENU |
wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX | wxCAPTION |wxCLIP_CHILDREN))
{
create();
wxGetApp().UpdateDlgDarkUI(this);
}
void ExtrusionCalibration::init_bitmaps()
{
auto lan = wxGetApp().app_config->get_language_code();
if (lan == "zh-cn") {
m_is_zh = true;
m_calibration_tips_bmp_zh = create_scaled_bitmap("extrusion_calibration_tips_zh", nullptr, 256);
}
else{
m_is_zh = false;
m_calibration_tips_bmp_en = create_scaled_bitmap("extrusion_calibration_tips_en", nullptr, 256);
}
m_calibration_tips_open_btn_bmp = create_scaled_bitmap("extrusion_calibrati_open_button", nullptr, 16);
}
void ExtrusionCalibration::create()
{
init_bitmaps();
SetBackgroundColour(*wxWHITE);
wxBoxSizer* sizer_main = new wxBoxSizer(wxVERTICAL);
m_step_1_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_step_1_panel->SetBackgroundColour(*wxWHITE);
wxBoxSizer* step_1_sizer = new wxBoxSizer(wxVERTICAL);
m_step_1_panel->SetSizer(step_1_sizer);
step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
// filament title
wxString intro_text = _L("The nozzle temp and max volumetric speed will affect the calibration results. Please fill in the same values as the actual printing. They can be auto-filled by selecting a filament preset.");
m_filament_preset_title = new Label(m_step_1_panel, intro_text);
m_filament_preset_title->SetFont(Label::Body_12);
m_filament_preset_title->SetForegroundColour(EXTRUSION_CALIBRATION_GREY800);
m_filament_preset_title->Wrap(this->GetSize().x);
step_1_sizer->Add(m_filament_preset_title, 0, wxEXPAND);
step_1_sizer->AddSpacer(FromDIP(12));
auto select_sizer = new wxBoxSizer(wxVERTICAL);
auto nozzle_dia_sel_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Nozzle Diameter"), wxDefaultPosition, wxDefaultSize, 0);
select_sizer->Add(nozzle_dia_sel_text, 0, wxALIGN_LEFT);
select_sizer->AddSpacer(FromDIP(4));
#ifdef __APPLE__
m_comboBox_nozzle_dia = new wxComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY);
#else
m_comboBox_nozzle_dia = new ComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY);
#endif
m_comboBox_nozzle_dia->AppendString("0.2");
m_comboBox_nozzle_dia->AppendString("0.4");
m_comboBox_nozzle_dia->AppendString("0.6");
m_comboBox_nozzle_dia->AppendString("0.8");
select_sizer->Add(m_comboBox_nozzle_dia, 0, wxEXPAND);
select_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
auto filament_sel_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Filament"), wxDefaultPosition, wxDefaultSize, 0);
select_sizer->Add(filament_sel_text, 0, wxALIGN_LEFT);
select_sizer->AddSpacer(FromDIP(4));
#ifdef __APPLE__
m_comboBox_filament = new wxComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY);
#else
m_comboBox_filament = new ComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY);
#endif
select_sizer->Add(m_comboBox_filament, 0, wxEXPAND);
select_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
auto bed_type_sel_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Bed Type"), wxDefaultPosition, wxDefaultSize, 0);
select_sizer->Add(bed_type_sel_text, 0, wxALIGN_LEFT);
select_sizer->AddSpacer(FromDIP(4));
#ifdef __APPLE__
m_comboBox_bed_type = new wxComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY);
#else
m_comboBox_bed_type = new ComboBox(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, EXTRUSION_CALIBRATION_BED_COMBOX, 0, nullptr, wxCB_READONLY);
#endif
select_sizer->Add(m_comboBox_bed_type, 0, wxEXPAND);
// get bed type
const ConfigOptionDef* bed_type_def = print_config_def.get("curr_bed_type");
if (bed_type_def && bed_type_def->enum_keys_map) {
for (auto item : *bed_type_def->enum_keys_map) {
if (item.first == "Default Plate")
continue;
m_comboBox_bed_type->AppendString(_L(item.first));
}
}
step_1_sizer->Add(select_sizer, 0, wxEXPAND);
// static line
step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
wxPanel* static_line = new wxPanel(m_step_1_panel, wxID_ANY, wxDefaultPosition, { -1, FromDIP(1) });
static_line->SetBackgroundColour(EXTRUSION_CALIBRATION_GREY300);
step_1_sizer->Add(static_line, 0, wxEXPAND);
step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
// filament info
auto info_sizer = new wxFlexGridSizer(0, 3, 0, FromDIP(16));
info_sizer->SetFlexibleDirection(wxBOTH);
info_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
auto nozzle_temp_sizer = new wxBoxSizer(wxVERTICAL);
auto nozzle_temp_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Nozzle temperature"));
auto max_input_width = std::max(std::max(std::max(wxWindow::GetTextExtent(_L("Nozzle temperature")).x,
wxWindow::GetTextExtent(_L("Bed Temperature")).x),
wxWindow::GetTextExtent(_L("Max volumetric speed")).x),
EXTRUSION_CALIBRATION_INPUT_SIZE.x);
m_nozzle_temp = new TextInput(m_step_1_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY);
nozzle_temp_sizer->Add(nozzle_temp_text, 0, wxALIGN_LEFT);
nozzle_temp_sizer->AddSpacer(FromDIP(4));
nozzle_temp_sizer->Add(m_nozzle_temp, 0, wxEXPAND);
auto bed_temp_sizer = new wxBoxSizer(wxVERTICAL);
auto bed_temp_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Bed temperature"));
m_bed_temp = new TextInput(m_step_1_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY);
bed_temp_sizer->Add(bed_temp_text, 0, wxALIGN_LEFT);
bed_temp_sizer->AddSpacer(FromDIP(4));
bed_temp_sizer->Add(m_bed_temp, 0, wxEXPAND);
auto max_flow_sizer = new wxBoxSizer(wxVERTICAL);
auto max_flow_text = new wxStaticText(m_step_1_panel, wxID_ANY, _L("Max volumetric speed"));
m_max_flow_ratio = new TextInput(m_step_1_panel, wxEmptyString, _L("mm\u00B3"), "", wxDefaultPosition, { max_input_width, EXTRUSION_CALIBRATION_INPUT_SIZE.y }, wxTE_READONLY);
max_flow_sizer->Add(max_flow_text, 0, wxALIGN_LEFT);
max_flow_sizer->AddSpacer(FromDIP(4));
max_flow_sizer->Add(m_max_flow_ratio, 0, wxEXPAND);
info_sizer->Add(nozzle_temp_sizer);
info_sizer->Add(bed_temp_sizer);
info_sizer->Add(max_flow_sizer);
step_1_sizer->Add(info_sizer, 0, wxEXPAND);
// static line
step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
wxPanel* static_line2 = new wxPanel(m_step_1_panel, wxID_ANY, wxDefaultPosition, { -1, FromDIP(1) });
static_line2->SetBackgroundColour(EXTRUSION_CALIBRATION_GREY300);
step_1_sizer->Add(static_line2, 0, wxEXPAND);
step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
auto cali_sizer = new wxBoxSizer(wxHORIZONTAL);
m_info_text = new wxStaticText(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
m_info_text->SetFont(Label::Body_12);
m_info_text->Hide();
m_error_text = new wxStaticText(m_step_1_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
m_error_text->SetFont(Label::Body_12);
m_error_text->SetForegroundColour(wxColour(208, 27, 27));
m_error_text->Hide();
m_button_cali = new Button(m_step_1_panel, _L("Start calibration"));
m_btn_bg_green = StateColor(std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Disabled), std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_cali->SetBackgroundColor(m_btn_bg_green);
m_button_cali->SetFont(Label::Body_13);
m_button_cali->SetBorderColor({ std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Disabled), std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Enabled) });
m_button_cali->SetTextColor({ std::pair<wxColour, int>(wxColour(172, 172, 172), StateColor::Disabled), std::pair<wxColour, int>(EXTRUSION_CALIBRATION_GREY200, StateColor::Enabled) });
m_button_cali->SetCornerRadius(FromDIP(12));
m_button_cali->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_cali->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_cali, this);
m_cali_cancel = new Button(m_step_1_panel, _L("Cancel"));
m_btn_bg_green = StateColor(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_cali_cancel->SetBackgroundColor(m_btn_bg_green);
m_cali_cancel->SetBorderColor(wxColour(0, 174, 66));
m_cali_cancel->SetTextColor(EXTRUSION_CALIBRATION_GREY200);
m_cali_cancel->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE);
m_cali_cancel->SetCornerRadius(FromDIP(12));
m_cali_cancel->Hide();
m_cali_cancel->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_cancel, this);
m_button_next_step = new Button(m_step_1_panel, _L("Next"));
m_btn_bg_gray = StateColor(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(*wxWHITE, StateColor::Focused),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
m_button_next_step->SetBackgroundColor(m_btn_bg_gray);
m_button_next_step->SetFont(Label::Body_13);
m_button_next_step->SetBorderColor(EXTRUSION_CALIBRATION_GREY900);
m_button_next_step->SetTextColor(EXTRUSION_CALIBRATION_GREY900);
m_button_next_step->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE);
m_button_next_step->SetCornerRadius(FromDIP(12));
m_button_next_step->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_next, this);
m_button_next_step->Hide();
cali_sizer->Add(m_info_text, 10, wxALIGN_LEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10));
cali_sizer->Add(m_error_text, 10, wxALIGN_LEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10));
cali_sizer->AddStretchSpacer();
cali_sizer->Add(m_button_cali, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10));
cali_sizer->Add(m_cali_cancel, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10));
cali_sizer->Add(m_button_next_step, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, FromDIP(10));
step_1_sizer->Add(cali_sizer, 0, wxEXPAND);
step_1_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
m_step_2_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_step_2_panel->SetBackgroundColour(*wxWHITE);
wxBoxSizer* step_2_sizer = new wxBoxSizer(wxVERTICAL);
m_step_2_panel->SetSizer(step_2_sizer);
step_2_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
// save result title and tips
wxBoxSizer* save_result_sizer = new wxBoxSizer(wxHORIZONTAL);
wxString fill_intro_text = _L("Calibration completed. Please find the most uniform extrusion line on your hot bed like the picture below, and fill the value on its left side into the factor K input box.");
m_save_cali_result_title = new Label(m_step_2_panel, fill_intro_text);
m_save_cali_result_title->SetFont(::Label::Body_12);
m_save_cali_result_title->SetForegroundColour(EXTRUSION_CALIBRATION_GREY800);
m_save_cali_result_title->Wrap(this->GetSize().x);
save_result_sizer->Add(m_save_cali_result_title, 0, wxEXPAND);
step_2_sizer->Add(save_result_sizer, 0, wxEXPAND);
step_2_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
auto content_sizer = new wxBoxSizer(wxHORIZONTAL);
m_calibration_tips_static_bmp = new wxStaticBitmap(m_step_2_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, EXTRUSION_CALIBRATION_BMP_SIZE, 0);
m_calibration_tips_static_bmp->SetMinSize(EXTRUSION_CALIBRATION_BMP_SIZE);
content_sizer->Add(m_calibration_tips_static_bmp, 1, wxEXPAND | wxSHAPED);
content_sizer->Add(EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0, 0);
// k/n input value
auto kn_sizer = new wxBoxSizer(wxVERTICAL);
auto k_val_text = new wxStaticText(m_step_2_panel, wxID_ANY, _L("Factor K"), wxDefaultPosition, wxDefaultSize, 0);
m_k_val = new TextInput(m_step_2_panel, wxEmptyString, "", "", wxDefaultPosition, wxDefaultSize);
auto n_val_text = new wxStaticText(m_step_2_panel, wxID_ANY, _L("Factor N"), wxDefaultPosition, wxDefaultSize, 0);
m_n_val = new TextInput(m_step_2_panel, wxEmptyString, "", "", wxDefaultPosition, wxDefaultSize);
// hide n
n_val_text->Hide();
m_n_val->Hide();
kn_sizer->Add(k_val_text, 0, wxALIGN_CENTER_VERTICAL);
kn_sizer->Add(m_k_val, 0, wxEXPAND);
kn_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
kn_sizer->Add(n_val_text, 0, wxALIGN_CENTER_VERTICAL);
kn_sizer->Add(m_n_val, 0, wxEXPAND);
// save button
m_button_save_result = new Button(m_step_2_panel, _L("Save"));
m_btn_bg_green = StateColor(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
m_button_save_result->SetBackgroundColor(m_btn_bg_green);
m_button_save_result->SetFont(Label::Body_13);
m_button_save_result->SetBorderColor(wxColour(0, 174, 66));
m_button_save_result->SetTextColor(EXTRUSION_CALIBRATION_GREY200);
m_button_save_result->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE);
m_button_save_result->SetCornerRadius(FromDIP(12));
m_button_save_result->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_save, this);
m_button_last_step = new Button(m_step_2_panel, _L("Last Step")); // Back for english
m_button_last_step->SetBackgroundColor(m_btn_bg_gray);
m_button_last_step->SetFont(Label::Body_13);
m_button_last_step->SetBorderColor(EXTRUSION_CALIBRATION_GREY900);
m_button_last_step->SetTextColor(EXTRUSION_CALIBRATION_GREY900);
m_button_last_step->SetMinSize(EXTRUSION_CALIBRATION_BUTTON_SIZE);
m_button_last_step->SetCornerRadius(FromDIP(12));
m_button_last_step->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_last, this);
kn_sizer->AddStretchSpacer();
kn_sizer->Add(m_button_last_step, 0);
kn_sizer->AddSpacer(FromDIP(10));
kn_sizer->Add(m_button_save_result, 0);
content_sizer->Add(kn_sizer, 0, wxEXPAND);
step_2_sizer->Add(content_sizer, 0, wxEXPAND);
step_2_sizer->Add(0, EXTRUSION_CALIBRATION_WIDGET_GAP, 0, 0);
sizer_main->Add(m_step_1_panel, 1, wxEXPAND);
sizer_main->Add(m_step_2_panel, 1, wxEXPAND);
wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL);
top_sizer->Add(FromDIP(24), 0);
top_sizer->Add(sizer_main, 1, wxEXPAND);
top_sizer->Add(FromDIP(24), 0);
SetSizer(top_sizer);
// set default nozzle
m_comboBox_nozzle_dia->SetSelection(1);
// set a default bed type
m_comboBox_bed_type->SetSelection(0);
// set to step 1
set_step(1);
Layout();
Fit();
m_k_val->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) {
input_value_finish();
e.Skip();
});
m_n_val->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& e) {
input_value_finish();
e.Skip();
});
m_calibration_tips_static_bmp->Bind(wxEVT_PAINT, &ExtrusionCalibration::paint, this);
m_calibration_tips_static_bmp->Bind(wxEVT_LEFT_UP, &ExtrusionCalibration::open_bitmap, this);
m_comboBox_filament->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_filament), NULL, this);
m_comboBox_bed_type->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_bed_type), NULL, this);
m_comboBox_nozzle_dia->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_nozzle_dia), NULL, this);
}
ExtrusionCalibration::~ExtrusionCalibration()
{
m_comboBox_filament->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_filament), NULL, this);
m_comboBox_bed_type->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_bed_type), NULL, this);
m_comboBox_nozzle_dia->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExtrusionCalibration::on_select_nozzle_dia), NULL, this);
}
void ExtrusionCalibration::paint(wxPaintEvent&) {
auto size = m_calibration_tips_static_bmp->GetSize();
wxPaintDC dc(m_calibration_tips_static_bmp);
wxGCDC gcdc(dc);
dc.DrawBitmap(m_is_zh ? m_calibration_tips_bmp_zh : m_calibration_tips_bmp_en, wxPoint(0, 0));
gcdc.SetPen(wxColour(0, 0, 0, 61));
gcdc.SetBrush(wxColour(0, 0, 0, 61));
gcdc.DrawRectangle(wxPoint(0, 0), EXTRUSION_CALIBRATION_BMP_TIP_BAR);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
int pos_offset = (EXTRUSION_CALIBRATION_BMP_TIP_BAR.y - EXTRUSION_CALIBRATION_BMP_BTN_SIZE.y) / 2;
wxPoint open_btn_pos = wxPoint(size.x - pos_offset - EXTRUSION_CALIBRATION_BMP_BTN_SIZE.x, pos_offset);
dc.DrawBitmap(m_calibration_tips_open_btn_bmp, open_btn_pos);
gcdc.SetFont(Label::Head_14);
gcdc.SetTextForeground(wxColour(255, 255, 255, 224));
wxSize text_size = wxWindow::GetTextExtent(_L("Example"));
gcdc.DrawText(_L("Example"), { (EXTRUSION_CALIBRATION_BMP_TIP_BAR.x - text_size.x) / 2, (EXTRUSION_CALIBRATION_BMP_TIP_BAR.y - text_size.y) / 2});
return;
}
void ExtrusionCalibration::open_bitmap(wxMouseEvent& event) {
auto pos = event.GetPosition();
auto size = m_calibration_tips_static_bmp->GetSize();
if (pos.x > size.x - EXTRUSION_CALIBRATION_BMP_TIP_BAR.y && pos.y > 0 &&
pos.x < size.x && pos.y < EXTRUSION_CALIBRATION_BMP_TIP_BAR.y) {
auto* popup = new wxDialog(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize);
auto bmp_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticBitmap* zoomed_bitmap = new wxStaticBitmap(popup, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
zoomed_bitmap->SetBitmap(create_scaled_bitmap(m_is_zh ? "extrusion_calibration_tips_zh" : "extrusion_calibration_tips_en", nullptr, 720));
bmp_sizer->Add(zoomed_bitmap, 1, wxEXPAND);
popup->SetSizer(bmp_sizer);
popup->Layout();
popup->Fit();
popup->CenterOnParent();
wxGetApp().UpdateDlgDarkUI(popup);
popup->ShowModal();
}
return;
}
void ExtrusionCalibration::input_value_finish()
{
;
}
void ExtrusionCalibration::show_info(bool show, bool is_error, wxString text)
{
if (show && is_error) {
m_error_text->Show();
if (m_error_text->GetLabelText().compare(text) != 0)
m_error_text->SetLabelText(text);
m_info_text->Hide();
}
else if (show && !is_error) {
m_info_text->Show();
if (m_info_text->GetLabelText().compare(text) != 0)
m_info_text->SetLabelText(text);
m_error_text->Hide();
}
else {
if (is_error) {
m_info_text->Hide();
m_error_text->Show();
if (m_error_text->GetLabelText().compare(text) != 0)
m_error_text->SetLabelText(text);
} else {
m_info_text->Show();
if (m_info_text->GetLabelText().compare(text) != 0)
m_info_text->SetLabelText(text);
m_error_text->Hide();
}
}
}
void ExtrusionCalibration::update()
{
if (obj) {
if (obj->is_in_extrusion_cali()) {
show_info(true, false, wxString::Format(_L("Calibrating... %d%%"), obj->mc_print_percent));
m_cali_cancel->Show();
m_cali_cancel->Enable();
m_button_cali->Hide();
m_button_next_step->Hide();
} else if (obj->is_extrusion_cali_finished()) {
if (m_bed_temp->GetTextCtrl()->GetValue().compare("0") == 0) {
wxString tips = get_bed_type_incompatible(false);
show_info(true, true, tips);
}
else {
get_bed_type_incompatible(true);
show_info(true, false, _L("Calibration completed"));
}
m_cali_cancel->Hide();
m_button_cali->Show();
m_button_next_step->Show();
} else {
if (m_bed_temp->GetTextCtrl()->GetValue().compare("0") == 0) {
wxString tips = get_bed_type_incompatible(false);
show_info(true, true, tips);
} else {
get_bed_type_incompatible(true);
show_info(true, false, wxEmptyString);
}
m_cali_cancel->Hide();
m_button_cali->Show();
m_button_next_step->Hide();
}
Layout();
}
}
void ExtrusionCalibration::on_click_cali(wxCommandEvent& event)
{
if (obj) {
int nozzle_temp = -1;
int bed_temp = -1;
float max_volumetric_speed = -1;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
wxString filament_name = wxString::FromUTF8(it->name);
if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) {
try {
bed_temp = get_bed_temp(&it->config);
const ConfigOptionInts* nozzle_temp_opt = it->config.option<ConfigOptionInts>("nozzle_temperature");
const ConfigOptionFloats* speed_opt = it->config.option<ConfigOptionFloats>("filament_max_volumetric_speed");
if (nozzle_temp_opt && speed_opt) {
nozzle_temp = nozzle_temp_opt->get_at(0);
max_volumetric_speed = speed_opt->get_at(0);
if (bed_temp >= 0 && nozzle_temp >= 0 && max_volumetric_speed >= 0) {
int curr_tray_id = ams_id * 4 + tray_id;
if (tray_id == VIRTUAL_TRAY_ID)
curr_tray_id = tray_id;
obj->command_start_extrusion_cali(curr_tray_id, nozzle_temp, bed_temp, max_volumetric_speed, it->setting_id);
return;
}
} else {
BOOST_LOG_TRIVIAL(error) << "cali parameters is invalid";
}
} catch(...) {
;
}
}
}
} else {
BOOST_LOG_TRIVIAL(error) << "extrusion_cali: preset_bundle is nullptr";
}
} else {
BOOST_LOG_TRIVIAL(error) << "cali obj parameters is invalid";
}
}
void ExtrusionCalibration::on_click_cancel(wxCommandEvent& event)
{
if (obj) {
BOOST_LOG_TRIVIAL(info) << "extrusion_cali: stop";
obj->command_stop_extrusion_cali();
}
}
bool ExtrusionCalibration::check_k_validation(wxString k_text)
{
if (k_text.IsEmpty())
return false;
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
if (k < 0 || k > 0.5)
return false;
return true;
}
bool ExtrusionCalibration::check_k_n_validation(wxString k_text, wxString n_text)
{
if (k_text.IsEmpty() || n_text.IsEmpty())
return false;
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
double n = 0.0;
try {
n_text.ToDouble(&n);
}
catch (...) {
;
}
if (k < 0 || k > 0.5)
return false;
if (n < 0.6 || n > 2.0)
return false;
return true;
}
void ExtrusionCalibration::on_click_save(wxCommandEvent &event)
{
wxString k_text = m_k_val->GetTextCtrl()->GetValue();
wxString n_text = m_n_val->GetTextCtrl()->GetValue();
if (!ExtrusionCalibration::check_k_validation(k_text)) {
wxString k_tips = _L("Please input a valid value (K in 0~0.5)");
wxString kn_tips = _L("Please input a valid value (K in 0~0.5, N in 0.6~2.0)");
MessageDialog msg_dlg(nullptr, k_tips, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
double n = 0.0;
try {
n_text.ToDouble(&n);
}
catch (...) {
;
}
// set values
int nozzle_temp = -1;
int bed_temp = -1;
float max_volumetric_speed = -1;
std::string setting_id;
std::string name;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) {
wxString filament_name = wxString::FromUTF8(it->name);
if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) {
if (obj) {
bed_temp = get_bed_temp(&it->config);
const ConfigOptionInts* nozzle_temp_opt = it->config.option<ConfigOptionInts>("nozzle_temperature");
const ConfigOptionFloats* speed_opt = it->config.option<ConfigOptionFloats>("filament_max_volumetric_speed");
if (nozzle_temp_opt && speed_opt) {
nozzle_temp = nozzle_temp_opt->get_at(0);
max_volumetric_speed = speed_opt->get_at(0);
}
setting_id = it->setting_id;
name = it->name;
}
}
}
}
// send command
int curr_tray_id = ams_id * 4 + tray_id;
if (tray_id == VIRTUAL_TRAY_ID)
curr_tray_id = tray_id;
obj->command_extrusion_cali_set(curr_tray_id, setting_id, name, k, n, bed_temp, nozzle_temp, max_volumetric_speed);
Close();
}
void ExtrusionCalibration::on_click_last(wxCommandEvent &event)
{
set_step(1);
}
void ExtrusionCalibration::on_click_next(wxCommandEvent& event)
{
set_step(2);
}
bool ExtrusionCalibration::Show(bool show)
{
if (show) {
m_k_val->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
m_n_val->GetTextCtrl()->SetSize(wxSize(-1, FromDIP(20)));
}
return DPIDialog::Show(show);
}
void ExtrusionCalibration::update_combobox_filaments()
{
m_comboBox_filament->SetValue(wxEmptyString);
user_filaments.clear();
int selection_idx = -1;
int filament_index = -1;
int curr_selection = -1;
wxArrayString filament_items;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle && obj) {
BOOST_LOG_TRIVIAL(trace) << "system_preset_bundle filament number=" << preset_bundle->filaments.size();
std::string printer_type = obj->printer_type;
std::set<std::string> printer_preset_list;
for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) {
// only use system printer preset
if (!printer_it->is_system) continue;
std::string model_id = printer_it->get_current_printer_type(preset_bundle);
ConfigOption* printer_nozzle_opt = printer_it->config.option("nozzle_diameter");
ConfigOptionFloats* printer_nozzle_vals = nullptr;
if (printer_nozzle_opt)
printer_nozzle_vals = dynamic_cast<ConfigOptionFloats*>(printer_nozzle_opt);
double nozzle_value = 0.4;
wxString nozzle_value_str = m_comboBox_nozzle_dia->GetValue();
try {
nozzle_value_str.ToDouble(&nozzle_value);
} catch(...) {
;
}
if (!model_id.empty() && model_id.compare(obj->printer_type) == 0
&& printer_nozzle_vals
&& abs(printer_nozzle_vals->get_at(0) - nozzle_value) < 1e-3) {
printer_preset_list.insert(printer_it->name);
BOOST_LOG_TRIVIAL(trace) << "extrusion_cali: printer_model = " << model_id;
} else {
BOOST_LOG_TRIVIAL(error) << "extrusion_cali: printer_model = " << model_id;
}
}
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
if (filament_it->setting_id.empty()) continue;
ConfigOption* printer_opt = filament_it->config.option("compatible_printers");
ConfigOptionStrings* printer_strs = dynamic_cast<ConfigOptionStrings*>(printer_opt);
for (auto printer_str : printer_strs->values) {
if (printer_preset_list.find(printer_str) != printer_preset_list.end()) {
user_filaments.push_back(&(*filament_it));
// set default filament id
filament_index++;
if (filament_it->is_system
&& !ams_filament_id.empty()
&& filament_it->filament_id == ams_filament_id
) {
curr_selection = filament_index;
}
wxString filament_name = wxString::FromUTF8(filament_it->name);
filament_items.Add(filament_name);
break;
}
}
}
m_comboBox_filament->Set(filament_items);
m_comboBox_filament->SetSelection(curr_selection);
post_select_event();
}
if (m_comboBox_filament->GetValue().IsEmpty())
m_button_cali->Disable();
else
m_button_cali->Enable();
}
wxString ExtrusionCalibration::get_bed_type_incompatible(bool incompatible)
{
if (incompatible) {
m_button_cali->Enable();
return wxEmptyString;
}
else {
m_button_cali->Disable();
std::string filament_alias = "";
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
wxString filament_name = wxString::FromUTF8(filament_it->name);
if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) {
filament_alias = filament_it->alias;
}
}
}
wxString tips = wxString::Format(_L("%s does not support %s"), m_comboBox_bed_type->GetValue(), filament_alias);
return tips;
}
}
void ExtrusionCalibration::Popup()
{
this->SetSize(EXTRUSION_CALIBRATION_DIALOG_SIZE);
update_combobox_filaments();
set_step(1);
update();
Layout();
Fit();
wxGetApp().UpdateDlgDarkUI(this);
ShowModal();
}
void ExtrusionCalibration::post_select_event() {
wxCommandEvent event(wxEVT_COMBOBOX);
event.SetEventObject(m_comboBox_filament);
wxPostEvent(m_comboBox_filament, event);
}
void ExtrusionCalibration::set_step(int step_index)
{
if (step_index == 2) {
wxString title_text = wxString::Format("%s - %s 2/2", _L("Dynamic flow Calibration"), _L("Step"));
SetTitle(title_text);
m_step_1_panel->Hide();
m_step_2_panel->Show();
} else {
wxString title_text = wxString::Format("%s - %s 1/2", _L("Dynamic flow Calibration"), _L("Step"));
SetTitle(title_text);
m_step_1_panel->Show();
m_step_2_panel->Hide();
}
this->SetMinSize(EXTRUSION_CALIBRATION_DIALOG_SIZE);
Layout();
Fit();
}
void ExtrusionCalibration::on_select_filament(wxCommandEvent &evt)
{
m_filament_type = "";
update_filament_info();
// set a default value for input values
if (m_k_val->GetTextCtrl()->GetValue().IsEmpty()) {
m_k_val->GetTextCtrl()->SetValue("0");
}
if (m_n_val->GetTextCtrl()->GetValue().IsEmpty()) {
m_n_val->GetTextCtrl()->SetValue("0");
}
}
void ExtrusionCalibration::update_filament_info()
{
if (m_comboBox_filament->GetValue().IsEmpty()) {
m_nozzle_temp->GetTextCtrl()->SetValue(wxEmptyString);
m_bed_temp->GetTextCtrl()->SetValue(wxEmptyString);
m_max_flow_ratio->GetTextCtrl()->SetValue(wxEmptyString);
return;
}
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
int bed_temp_int = -1;
if (preset_bundle) {
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
wxString filament_name = wxString::FromUTF8(filament_it->name);
if (filament_name.compare(m_comboBox_filament->GetValue()) == 0) {
m_filament_type = filament_it->name;
// update nozzle temperature
ConfigOption* opt_nozzle_temp = filament_it->config.option("nozzle_temperature");
if (opt_nozzle_temp) {
ConfigOptionInts* opt_min_ints = dynamic_cast<ConfigOptionInts*>(opt_nozzle_temp);
if (opt_min_ints) {
wxString text_nozzle_temp = wxString::Format("%d", opt_min_ints->get_at(0));
m_nozzle_temp->GetTextCtrl()->SetValue(text_nozzle_temp);
}
}
// update bed temperature
bed_temp_int = get_bed_temp(&filament_it->config);
wxString bed_temp_text = wxString::Format("%d", bed_temp_int);
m_bed_temp->GetTextCtrl()->SetValue(bed_temp_text);
// update max flow speed
ConfigOption* opt_flow_speed = filament_it->config.option("filament_max_volumetric_speed");
if (opt_flow_speed) {
ConfigOptionFloats* opt_flow_floats = dynamic_cast<ConfigOptionFloats*>(opt_flow_speed);
if (opt_flow_floats) {
wxString flow_val_text = wxString::Format("%0.2f", opt_flow_floats->get_at(0));
m_max_flow_ratio->GetTextCtrl()->SetValue(flow_val_text);
}
}
}
}
}
}
int ExtrusionCalibration::get_bed_temp(DynamicPrintConfig* config)
{
BedType curr_bed_type = BedType(m_comboBox_bed_type->GetSelection() + btDefault + 1);
const ConfigOptionInts* opt_bed_temp_ints = config->option<ConfigOptionInts>(get_bed_temp_key(curr_bed_type));
if (opt_bed_temp_ints) {
return opt_bed_temp_ints->get_at(0);
}
return -1;
}
void ExtrusionCalibration::on_select_bed_type(wxCommandEvent &evt)
{
update_filament_info();
}
void ExtrusionCalibration::on_select_nozzle_dia(wxCommandEvent &evt)
{
update_combobox_filaments();
}
void ExtrusionCalibration::on_dpi_changed(const wxRect &suggested_rect) { this->Refresh(); }
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,149 @@
#ifndef slic3r_ExtrusionCalibration_hpp_
#define slic3r_ExtrusionCalibration_hpp_
#include "libslic3r/Preset.hpp"
#include "wxExtensions.hpp"
#include "GUI_Utils.hpp"
#include "DeviceManager.hpp"
#include "wx/clrpicker.h"
#include "Widgets/RadioBox.hpp"
#include "Widgets/Button.hpp"
#include "Widgets/RoundedRectangle.hpp"
#include "Widgets/Label.hpp"
#include "Widgets/CheckBox.hpp"
#include "Widgets/ComboBox.hpp"
#include "Widgets/TextInput.hpp"
#include "ParamsDialog.hpp"
#include "GUI_App.hpp"
#include "wx/hyperlink.h"
#define EXTRUSION_CALIBRATION_DEF_COLOUR wxColour(255, 255, 255)
#define EXTRUSION_CALIBRATION_GREY900 wxColour(38, 46, 48)
#define EXTRUSION_CALIBRATION_GREY800 wxColour(50, 58, 61)
#define EXTRUSION_CALIBRATION_GREY700 wxColour(107, 107, 107)
#define EXTRUSION_CALIBRATION_GREY300 wxColour(238, 238, 238)
#define EXTRUSION_CALIBRATION_GREY200 wxColour(248, 248, 248)
#define EXTRUSION_CALIBRATION_BODY_WIDTH FromDIP(380)
#define EXTRUSION_CALIBRATION_LABEL_WIDTH FromDIP(80)
#define EXTRUSION_CALIBRATION_WIDGET_GAP FromDIP(18)
#define EXTRUSION_CALIBRATION_DIALOG_SIZE wxSize(FromDIP(400), -1)
//#define EXTRUSION_CALIBRATION_DIALOG_SIZE wxSize(FromDIP(520), -1)
#define EXTRUSION_CALIBRATION_BED_COMBOX wxSize(FromDIP(200), FromDIP(24))
#define EXTRUSION_CALIBRATION_BUTTON_SIZE wxSize(FromDIP(72), FromDIP(24))
#define EXTRUSION_CALIBRATION_INPUT_SIZE wxSize(FromDIP(100), FromDIP(24))
#define EXTRUSION_CALIBRATION_BMP_SIZE wxSize(FromDIP(256), FromDIP(256))
#define EXTRUSION_CALIBRATION_BMP_TIP_BAR wxSize(FromDIP(256), FromDIP(40))
#define EXTRUSION_CALIBRATION_BMP_BTN_SIZE wxSize(FromDIP(16), FromDIP(16))
namespace Slic3r { namespace GUI {
class ExtrusionCalibration : public DPIDialog
{
public:
ExtrusionCalibration(wxWindow *parent, wxWindowID id);
~ExtrusionCalibration();
void create();
void input_value_finish();
void update();
bool Show(bool show) override;
void Popup();
void post_select_event();
void update_machine_obj(MachineObject* obj_) { obj = obj_; };
// input is 1 or 2
void set_step(int step_index);
static bool check_k_n_validation(wxString k_text, wxString n_text);
static bool check_k_validation(wxString k_text);
MachineObject *obj { nullptr };
int ams_id { 0 }; /* 0 ~ 3 */
int tray_id { 0 }; /* 0 ~ 3 | 254 for virtual tray id*/
std::string ams_filament_id;
std::string m_filament_type;
std::vector<Preset*> user_filaments;
protected:
void init_bitmaps();
void on_dpi_changed(const wxRect &suggested_rect) override;
void paint(wxPaintEvent&);
void open_bitmap(wxMouseEvent& event);
void on_select_filament(wxCommandEvent& evt);
void on_select_bed_type(wxCommandEvent& evt);
void on_select_nozzle_dia(wxCommandEvent& evt);
void on_click_cali(wxCommandEvent& evt);
void on_click_cancel(wxCommandEvent& evt);
void on_click_save(wxCommandEvent& evt);
void on_click_last(wxCommandEvent& evt);
void on_click_next(wxCommandEvent& evt);
void update_filament_info();
void update_combobox_filaments();
wxString get_bed_type_incompatible(bool incompatible);
void show_info(bool show, bool is_error, wxString text);
int get_bed_temp(DynamicPrintConfig* config);
protected:
StateColor m_btn_bg_green;
StateColor m_btn_bg_gray;
wxPanel* m_step_1_panel;
wxPanel* m_step_2_panel;
// title of select filament preset
Label* m_filament_preset_title;
// select a filament preset
#ifdef __APPLE__
wxComboBox* m_comboBox_filament;
#else
ComboBox* m_comboBox_filament;
#endif
#ifdef __APPLE__
wxComboBox* m_comboBox_bed_type;
#else
ComboBox* m_comboBox_bed_type;
#endif
#ifdef __APPLE__
wxComboBox* m_comboBox_nozzle_dia;
#else
ComboBox* m_comboBox_nozzle_dia;
#endif
TextInput* m_nozzle_temp;
TextInput* m_bed_temp;
TextInput* m_max_flow_ratio;
Button* m_cali_cancel;
Button* m_button_cali;
Button* m_button_next_step;
Label* m_save_cali_result_title;
wxStaticText* m_fill_cali_params_tips;
wxStaticText* m_info_text;
wxStaticText* m_error_text;
wxBitmap m_calibration_tips_open_btn_bmp;
wxBitmap m_calibration_tips_bmp_zh;
wxBitmap m_calibration_tips_bmp_en;
wxStaticBitmap* m_calibration_tips_static_bmp;
// save n and k result
wxStaticText* m_k_param;
TextInput* m_k_val;
wxStaticText* m_n_param;
TextInput* m_n_val;
Button* m_button_last_step;
Button* m_button_save_result;
bool m_is_zh{ false };
};
}} // namespace Slic3r::GUI
#endif

View file

@ -325,8 +325,12 @@ void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& positi
m_world_transform = (Geometry::assemble_transform((position + m_z_offset * Vec3f::UnitZ()).cast<double>()) * Geometry::assemble_transform(m_model.get_bounding_box().size().z() * Vec3d::UnitZ(), { M_PI, 0.0, 0.0 })).cast<float>();
}
void GCodeViewer::SequentialView::Marker::update_curr_move(const GCodeProcessorResult::MoveVertex move) {
m_curr_move = move;
}
//BBS: GUI refactor: add canvas size from parameters
void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves, uint64_t curr_line_id) const
void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_height, const EViewType& view_type) const
{
if (!m_visible)
return;
@ -357,13 +361,6 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
const ImU32 text_name_clr = m_is_dark ? IM_COL32(255, 255, 255, 0.88 * 255) : IM_COL32(38, 46, 48, 255);
const ImU32 text_value_clr = m_is_dark ? IM_COL32(255, 255, 255, 0.4 * 255) : IM_COL32(144, 144, 144, 255);
auto it = std::find_if(moves.begin(), moves.end(), [&curr_line_id](auto move) {
return move.gcode_id == curr_line_id;
});
if (it == moves.end()) {
return;
}
ImGuiWrapper& imgui = *wxGetApp().imgui();
//BBS: GUI refactor: add canvas size from parameters
imgui.set_next_window_pos(0.5f * static_cast<float>(canvas_width), static_cast<float>(canvas_height), ImGuiCond_Always, 0.5f, 1.0f);
@ -418,42 +415,42 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
switch (view_type) {
case EViewType::Height: {
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.2f", height.c_str(), it->height);
sprintf(buf, "%s%.2f", height.c_str(), m_curr_move.height);
ImGui::PushItemWidth(item_size);
imgui.text(buf);
break;
}
case EViewType::Width: {
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.2f", width.c_str(), it->width);
sprintf(buf, "%s%.2f", width.c_str(), m_curr_move.width);
ImGui::PushItemWidth(item_size);
imgui.text(buf);
break;
}
case EViewType::Feedrate: {
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.0f", speed.c_str(), it->feedrate);
sprintf(buf, "%s%.0f", speed.c_str(), m_curr_move.feedrate);
ImGui::PushItemWidth(item_size);
imgui.text(buf);
break;
}
case EViewType::VolumetricRate: {
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.2f", flow.c_str(), it->volumetric_rate());
sprintf(buf, "%s%.2f", flow.c_str(), m_curr_move.volumetric_rate());
ImGui::PushItemWidth(item_size);
imgui.text(buf);
break;
}
case EViewType::FanSpeed: {
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.0f", fanspeed.c_str(), it->fan_speed);
sprintf(buf, "%s%.0f", fanspeed.c_str(), m_curr_move.fan_speed);
ImGui::PushItemWidth(item_size);
imgui.text(buf);
break;
}
case EViewType::Temperature: {
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.0f", temperature.c_str(), it->temperature);
sprintf(buf, "%s%.0f", temperature.c_str(), m_curr_move.temperature);
ImGui::PushItemWidth(item_size);
imgui.text(buf);
break;
@ -461,7 +458,7 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
case EViewType::LayerTime:
case EViewType::LayerTimeLog: {
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.1f", layer_time.c_str(), it->layer_duration);
sprintf(buf, "%s%.1f", layer_time.c_str(), m_curr_move.layer_duration);
ImGui::PushItemWidth(item_size);
imgui.text(buf);
break;
@ -485,7 +482,7 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he
imgui.text(buf);
ImGui::SameLine(window_padding + item_size + item_spacing);
sprintf(buf, "%s%.0f", speed.c_str(), it->feedrate);
sprintf(buf, "%s%.0f", speed.c_str(), m_curr_move.feedrate);
ImGui::PushItemWidth(item_size);
imgui.text(buf);
}
@ -703,10 +700,10 @@ void GCodeViewer::SequentialView::GCodeWindow::stop_mapping_file()
}
}
//BBS: GUI refactor: move to the right
void GCodeViewer::SequentialView::render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves) const
void GCodeViewer::SequentialView::render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, const EViewType& view_type) const
{
if (has_render_path)
marker.render(canvas_width, canvas_height, view_type, moves, static_cast<uint64_t>(gcode_ids[current.last]));
marker.render(canvas_width, canvas_height, view_type);
//float bottom = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_height();
// BBS
#if 0
@ -1291,7 +1288,7 @@ void GCodeViewer::render(int canvas_width, int canvas_height, int right_margin)
m_sequential_view.marker.set_world_position(m_sequential_view.current_position);
m_sequential_view.marker.set_world_offset(m_sequential_view.current_offset);
//BBS fixed buttom margin. m_moves_slider.pos_y
m_sequential_view.render(!m_no_render_path, legend_height, canvas_width - right_margin * m_scale, canvas_height - bottom_margin * m_scale, m_view_type, m_gcode_result->moves);
m_sequential_view.render(!m_no_render_path, legend_height, canvas_width - right_margin * m_scale, canvas_height - bottom_margin * m_scale, m_view_type);
//}
#if ENABLE_GCODE_VIEWER_STATISTICS
render_statistics();
@ -1797,6 +1794,14 @@ void GCodeViewer::update_layers_slider_mode()
// TODO m_layers_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder);
}
void GCodeViewer::update_marker_curr_move() {
auto it = std::find_if(m_gcode_result->moves.begin(), m_gcode_result->moves.end(), [this](auto move) {
return move.gcode_id == static_cast<uint64_t>(m_sequential_view.gcode_ids[m_sequential_view.current.last]);
});
m_sequential_view.marker.update_curr_move(*it);
}
bool GCodeViewer::is_toolpath_move_type_visible(EMoveType type) const
{
size_t id = static_cast<size_t>(buffer_id(type));
@ -2458,14 +2463,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
std::vector<float> options_zs;
size_t seams_count = 0;
std::vector<size_t> seams_ids;
std::vector<size_t> biased_seams_ids;
// toolpaths data -> extract vertices from result
for (size_t i = 0; i < m_moves_count; ++i) {
const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i];
if (curr.type == EMoveType::Seam) {
++seams_count;
seams_ids.push_back(i);
biased_seams_ids.push_back(i - biased_seams_ids.size() - 1);
}
size_t move_id = i - seams_count;
@ -2555,17 +2560,23 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":b=%1%, vertex buffer count %2%\n")
%b %v_multibuffer.size();
}*/
auto extract_move_id = [&seams_ids](size_t id) {
for (int i = seams_ids.size() - 1; i >= 0; --i) {
if (seams_ids[i] < id + i + 1)
return id + (size_t)i + 1;
}
return id;
auto extract_move_id = [&biased_seams_ids](size_t id) {
size_t new_id = size_t(-1);
auto it = std::lower_bound(biased_seams_ids.begin(), biased_seams_ids.end(), id);
if (it == biased_seams_ids.end())
new_id = id + biased_seams_ids.size();
else {
if (it == biased_seams_ids.begin() && *it < id)
new_id = id;
else if (it != biased_seams_ids.begin())
new_id = id + std::distance(biased_seams_ids.begin(), it);
}
return (new_id == size_t(-1)) ? id : new_id;
};
//BBS: generate map from ssid to move id in advance to reduce computation
m_ssid_to_moveid_map.clear();
m_ssid_to_moveid_map.reserve( m_moves_count - seams_ids.size());
for (size_t i = 0; i < m_moves_count - seams_ids.size(); i++)
m_ssid_to_moveid_map.reserve( m_moves_count - biased_seams_ids.size());
for (size_t i = 0; i < m_moves_count - biased_seams_ids.size(); i++)
m_ssid_to_moveid_map.push_back(extract_move_id(i));
//BBS: smooth toolpaths corners for the given TBuffer using triangles
@ -2767,7 +2778,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result, const
}
// dismiss, no more needed
std::vector<size_t>().swap(seams_ids);
std::vector<size_t>().swap(biased_seams_ids);
for (MultiVertexBuffer& v_multibuffer : vertices) {
for (VertexBuffer& v_buffer : v_multibuffer) {
@ -4841,10 +4852,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
PartialTimes items;
std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z;
// BBS
int extruders_count = wxGetApp().filaments_cnt();
std::vector<Color> last_color(extruders_count);
for (int i = 0; i < extruders_count; ++i) {
std::vector<Color> last_color(m_extruders_count);
for (size_t i = 0; i < m_extruders_count; ++i) {
last_color[i] = m_tools.m_tool_colors[i];
}
int last_extruder_id = 1;

View file

@ -466,9 +466,8 @@ class GCodeViewer
size_t first{ 0 };
size_t last{ 0 };
bool operator == (const Endpoints& other) const {
return first == other.first && last == other.last;
}
bool operator == (const Endpoints& other) const { return first == other.first && last == other.last; }
bool operator != (const Endpoints& other) const { return !operator==(other); }
};
private:
@ -497,9 +496,8 @@ class GCodeViewer
bool operator != (const Layers& other) const {
if (m_zs != other.m_zs)
return true;
if (!(m_endpoints == other.m_endpoints))
if (m_endpoints != other.m_endpoints)
return true;
return false;
}
};
@ -620,6 +618,7 @@ public:
// see implementation of render() method
Vec3f m_world_offset;
float m_z_offset{ 0.5f };
GCodeProcessorResult::MoveVertex m_curr_move;
bool m_visible{ true };
bool m_is_dark = false;
@ -637,8 +636,10 @@ public:
void set_visible(bool visible) { m_visible = visible; }
//BBS: GUI refactor: add canvas size
void render(int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves, uint64_t curr_line_id) const;
void render(int canvas_width, int canvas_height, const EViewType& view_type) const;
void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; }
void update_curr_move(const GCodeProcessorResult::MoveVertex move);
};
class GCodeWindow
@ -698,7 +699,7 @@ public:
float m_scale = 1.0;
//BBS: GUI refactor: add canvas size
void render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, const EViewType& view_type, const std::vector<GCodeProcessorResult::MoveVertex>& moves) const;
void render(const bool has_render_path, float legend_height, int canvas_width, int canvas_height, const EViewType& view_type) const;
};
struct ETools
@ -833,6 +834,7 @@ public:
void enable_moves_slider(bool enable) const;
void update_moves_slider(bool set_to_max = false);
void update_layers_slider_mode();
void update_marker_curr_move();
bool is_contained_in_bed() const { return m_contained_in_bed; }
//BBS: add only gcode mode

View file

@ -3282,7 +3282,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() && ! wxGetApp().is_gcode_viewer()) {
else if (keyCode == WXK_TAB && evt.ShiftDown() && !evt.ControlDown() && ! wxGetApp().is_gcode_viewer()) {
// Collapse side-panel with Shift+Tab
post_event(SimpleEvent(EVT_GLCANVAS_COLLAPSE_SIDEBAR));
}
@ -6608,12 +6608,14 @@ void GLCanvas3D::_render_gcode(int canvas_width, int canvas_height)
}
layers_slider->set_as_dirty(false);
post_event(SimpleEvent(EVT_GLCANVAS_UPDATE));
m_gcode_viewer.update_marker_curr_move();
}
if (moves_slider->is_dirty()) {
moves_slider->set_as_dirty(false);
m_gcode_viewer.update_sequential_view_current((moves_slider->GetLowerValueD() - 1.0), static_cast<unsigned int>(moves_slider->GetHigherValueD() - 1.0));
post_event(SimpleEvent(EVT_GLCANVAS_UPDATE));
m_gcode_viewer.update_marker_curr_move();
}
}

View file

@ -2327,6 +2327,8 @@ bool GUI_App::on_init_inner()
Bind(EVT_USER_LOGIN, &GUI_App::on_user_login, this);
Bind(EVT_SHOW_IP_DIALOG, &GUI_App::show_ip_address_enter_dialog_handler, this);
copy_network_if_available();
on_init_network();
@ -4630,6 +4632,54 @@ void GUI_App::update_mode()
plater()->canvas3D()->update_gizmos_on_off_state();
}
void GUI_App::show_ip_address_enter_dialog(wxString title)
{
auto evt = new wxCommandEvent(EVT_SHOW_IP_DIALOG);
evt->SetString(title);
wxQueueEvent(this, evt);
}
bool GUI_App::show_modal_ip_address_enter_dialog(wxString title)
{
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return false;
if (!dev->get_selected_machine()) return false;
auto obj = dev->get_selected_machine();
InputIpAddressDialog dlg(nullptr);
dlg.set_machine_obj(obj);
if (!title.empty()) dlg.update_title(title);
dlg.Bind(EVT_ENTER_IP_ADDRESS, [this, obj](wxCommandEvent& e) {
auto selection_data_arr = wxSplit(e.GetString().ToStdString(), '|');
if (selection_data_arr.size() == 2) {
auto ip_address = selection_data_arr[0];
auto access_code = selection_data_arr[1];
BOOST_LOG_TRIVIAL(info) << "User enter IP address is " << ip_address;
if (!ip_address.empty()) {
wxGetApp().app_config->set_str("ip_address", obj->dev_id, ip_address.ToStdString());
wxGetApp().app_config->save();
obj->dev_ip = ip_address.ToStdString();
obj->set_user_access_code(access_code.ToStdString());
}
}
});
if (dlg.ShowModal() == wxID_YES) {
return true;
}
return false;
}
void GUI_App::show_ip_address_enter_dialog_handler(wxCommandEvent& evt)
{
wxString title = evt.GetString();
show_modal_ip_address_enter_dialog(title);
}
//void GUI_App::add_config_menu(wxMenuBar *menu)
//void GUI_App::add_config_menu(wxMenu *menu)
//{

View file

@ -438,6 +438,9 @@ public:
ConfigOptionMode get_mode();
void save_mode(const /*ConfigOptionMode*/int mode) ;
void update_mode();
void show_ip_address_enter_dialog(wxString title = wxEmptyString);
void show_ip_address_enter_dialog_handler(wxCommandEvent &evt);
bool show_modal_ip_address_enter_dialog(wxString title = wxEmptyString);
// BBS
//void add_config_menu(wxMenuBar *menu);

View file

@ -305,7 +305,7 @@ static ObjectDataViewModel* list_model()
static const Selection& get_selection()
{
return plater()->canvas3D()->get_selection();
return plater()->get_current_canvas3D(true)->get_selection();
}
// category -> vector ( option ; label )
@ -747,7 +747,7 @@ void MenuFactory::append_menu_items_flush_options(wxMenu* menu)
DynamicPrintConfig& global_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
ModelConfig& select_object_config = object_list->object(selection.get_object_idx())->config;
auto keys = select_object_config.keys();
for (auto key : FREQ_SETTINGS_BUNDLE_FFF["Flush options"]) {
if (find(keys.begin(), keys.end(), key) == keys.end()) {

View file

@ -361,13 +361,13 @@ void ObjectList::create_objects_ctrl()
colFilament, m_columns_width[colFilament] * em, wxALIGN_CENTER_HORIZONTAL, 0));
// BBS
AppendBitmapColumn(" ", colSupportPaint, wxDATAVIEW_CELL_INERT, m_columns_width[colSupportPaint] * em,
AppendBitmapColumn(" ", colSupportPaint, wxOSX ? wxDATAVIEW_CELL_EDITABLE : wxDATAVIEW_CELL_INERT, m_columns_width[colSupportPaint] * em,
wxALIGN_CENTER_HORIZONTAL, 0);
AppendBitmapColumn(" ", colColorPaint, wxDATAVIEW_CELL_INERT, m_columns_width[colColorPaint] * em,
AppendBitmapColumn(" ", colColorPaint, wxOSX ? wxDATAVIEW_CELL_EDITABLE : wxDATAVIEW_CELL_INERT, m_columns_width[colColorPaint] * em,
wxALIGN_CENTER_HORIZONTAL, 0);
// column ItemEditing of the view control:
AppendBitmapColumn(" ", colEditing, wxDATAVIEW_CELL_INERT, m_columns_width[colEditing] * em,
AppendBitmapColumn(" ", colEditing, wxOSX ? wxDATAVIEW_CELL_EDITABLE : wxDATAVIEW_CELL_INERT, m_columns_width[colEditing] * em,
wxALIGN_CENTER_HORIZONTAL, 0);
//for (int cn = colName; cn < colCount; cn++) {
@ -4854,15 +4854,45 @@ void ObjectList::OnEditingStarted(wxDataViewEvent &event)
#else
event.Veto(); // Not edit with NSTableView's text
auto col = event.GetColumn();
auto item = event.GetItem();
if (col == colPrint) {
toggle_printable_state();
return;
} else if (col == colSupportPaint) {
ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID();
if (node->HasSupportPainting()) {
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager();
if (gizmos_mgr.get_current_type() != GLGizmosManager::EType::FdmSupports)
gizmos_mgr.open_gizmo(GLGizmosManager::EType::FdmSupports);
else
gizmos_mgr.reset_all_states();
}
return;
}
else if (col == colColorPaint) {
ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID();
if (node->HasColorPainting()) {
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager();
if (gizmos_mgr.get_current_type() != GLGizmosManager::EType::MmuSegmentation)
gizmos_mgr.open_gizmo(GLGizmosManager::EType::MmuSegmentation);
else
gizmos_mgr.reset_all_states();
}
return;
}
else if (col == colEditing) {
//show_context_menu(evt_context_menu);
int obj_idx, vol_idx;
get_selected_item_indexes(obj_idx, vol_idx, item);
//wxGetApp().plater()->PopupObjectTable(obj_idx, vol_idx, mouse_pos);
dynamic_cast<TabPrintModel*>(wxGetApp().get_model_tab(vol_idx >= 0))->reset_model_config();
return;
}
if (col != colFilament && col != colName)
return;
auto column = GetColumn(col);
const auto renderer = column->GetRenderer();
auto item = event.GetItem();
if (!renderer->GetEditorCtrl()) {
renderer->StartEditing(item, GetItemRect(item, column));
if (col == colName) // TODO: for colName editing, disable shortcuts

View file

@ -436,11 +436,12 @@ void GridCellChoiceEditor::BeginEdit(int row, int col, wxGrid *grid)
//Combo()->Popup();
#endif
if (evtHandler) {
if (evtHandler)
{
// When dropping down the menu, a kill focus event
// happens after this point, so we can't reset the flag yet.
#if !defined(__WXGTK20__)
evtHandler->SetInSetFocus(false);
//evtHandler->SetInSetFocus(false);
#endif
}
}

View file

@ -497,6 +497,9 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
double height = m_height;
ImGui::PushItemWidth(caption_size);
ImGui::AlignTextToFramePadding();
// only allow setting height when cut plane is horizontal
Vec3d plane_normal = get_plane_normal();
m_imgui->disabled_begin(std::abs(plane_normal(0)) > EPSILON || std::abs(plane_normal(1)) > EPSILON);
m_imgui->text(_L("Height") + " ");
ImGui::SameLine(caption_size + 1 * space_size);
ImGui::PushItemWidth(3 * unit_size + 2 * space_size);
@ -513,6 +516,7 @@ void GLGizmoAdvancedCut::on_render_input_window(float x, float y, float bottom_l
m_buffered_height = height;
}
ImGui::PopStyleVar(1);
m_imgui->disabled_end();
ImGui::Separator();
// Part selection
m_imgui->bbl_checkbox(_L("Keep upper part"), m_keep_upper);

View file

@ -1217,14 +1217,23 @@ void TriangleSelectorPatch::update_triangles_per_patch()
return touching_triangles;
};
auto calc_fragment_area = [this](const TrianglePatch& patch, float max_limit_area) {
auto calc_fragment_area = [this](const TrianglePatch& patch, float max_limit_area, int stride) {
double total_area = 0.f;
const std::vector<int>& ti = patch.triangle_indices;
for (int i = 0; i < ti.size() / 3; i++) {
/*for (int i = 0; i < ti.size() / 3; i++) {
total_area += std::abs((m_vertices[ti[i]].v - m_vertices[ti[i + 1]].v)
.cross(m_vertices[ti[i]].v - m_vertices[ti[i + 2]].v).norm()) / 2;
if (total_area >= max_limit_area)
break;
}*/
const std::vector<float>& vertices = patch.patch_vertices;
for (int i = 0; i < ti.size(); i+=3) {
stl_vertex v0(vertices[ti[i] * stride], vertices[ti[i] * stride + 1], vertices[ti[i] * stride + 2]);
stl_vertex v1(vertices[ti[i + 1] * stride], vertices[ti[i + 1] * stride + 1], vertices[ti[i + 1] * stride + 2]);
stl_vertex v2(vertices[ti[i + 2] * stride], vertices[ti[i + 2] * stride + 1], vertices[ti[i + 2] * stride + 2]);
total_area += std::abs((v0 - v1).cross(v0 - v2).norm()) / 2;
if (total_area >= max_limit_area)
break;
}
return total_area;
@ -1301,7 +1310,7 @@ void TriangleSelectorPatch::update_triangles_per_patch()
visited[current_facet] = true;
}
patch.area = calc_fragment_area(patch, GapAreaMax);
patch.area = calc_fragment_area(patch, GapAreaMax, using_wireframe?6:3);
patch.type = start_facet_state;
m_triangle_patches.emplace_back(std::move(patch));
}

View file

@ -333,6 +333,9 @@ bool GLGizmosManager::open_gizmo(EType type)
if (m_gizmos[idx]->is_activable()
&& activate_gizmo(m_current == idx ? Undefined : (EType)idx)) {
update_data();
#ifdef __WXOSX__
m_parent.post_event(SimpleEvent(wxEVT_PAINT));
#endif
return true;
}
return false;

View file

@ -31,6 +31,7 @@ HMSNotifyItem::HMSNotifyItem(wxWindow *parent, HMSItem& item)
m_bitmap_notify->SetBitmap(get_notify_bitmap());
m_hms_content = new wxStaticText(m_panel_hms, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
m_hms_content->SetForegroundColour(*wxBLACK);
m_hms_content->SetSize(HMS_NOTIFY_ITEM_TEXT_SIZE);
m_hms_content->SetMinSize(HMS_NOTIFY_ITEM_TEXT_SIZE);
m_hms_content->SetLabelText(_L(wxGetApp().get_hms_query()->query_hms_msg(m_hms_item.get_long_error_code())));

View file

@ -164,6 +164,7 @@ void PrintJob::process()
// local print access
params.dev_ip = m_dev_ip;
params.use_ssl = m_local_use_ssl;
params.username = "bblp";
params.password = m_access_code;
wxString error_text;

View file

@ -16,6 +16,7 @@ public:
int plate_idx;
fs::path _3mf_path;
fs::path _3mf_config_path;
fs::path _temp_path;
PrintPrepareData() {
plate_idx = 0;
}
@ -39,6 +40,7 @@ public:
std::string m_project_name;
std::string m_dev_ip;
bool m_local_use_ssl { true };
std::string m_access_code;
std::string task_bed_type;
bool task_bed_leveling;

View file

@ -104,11 +104,43 @@ inline std::string get_transform_string(int bytes)
void SendJob::process()
{
/* display info */
BBL::PrintParams params;
wxString msg;
int curr_percent = 10;
NetworkAgent* m_agent = wxGetApp().getAgent();
AppConfig* config = wxGetApp().app_config;
int result = -1;
unsigned int http_code;
std::string http_body;
// local print access
params.dev_ip = m_dev_ip;
params.username = "bblp";
params.password = m_access_code;
params.use_ssl = m_local_use_ssl;
// check access code and ip address
if (m_is_check_mode) {
params.dev_id = m_dev_id;
params.project_name = "verify_job";
params.filename = job_data._temp_path.string();
params.connection_type = this->connection_type;
result = m_agent->start_send_gcode_to_sdcard(params, nullptr, nullptr);
if (result != 0) {
BOOST_LOG_TRIVIAL(error) << "access code is invalid";
m_enter_ip_address_fun_fail();
}
else {
m_enter_ip_address_fun_success();
}
m_job_finished = true;
return;
}
/* display info */
if (this->connection_type == "lan") {
msg = _L("Sending gcode file over LAN");
@ -117,10 +149,6 @@ void SendJob::process()
msg = _L("Sending gcode file through cloud service");
}
int result = -1;
unsigned int http_code;
std::string http_body;
int total_plate_num = m_plater->get_partplate_list().get_plate_count();
PartPlate* plate = m_plater->get_partplate_list().get_plate(job_data.plate_idx);
@ -148,7 +176,6 @@ void SendJob::process()
else if (job_data.plate_idx == PLATE_CURRENT_IDX)
curr_plate_idx = m_plater->get_partplate_list().get_curr_plate_index() + 1;
BBL::PrintParams params;
params.dev_id = m_dev_id;
params.project_name = m_project_name + ".gcode.3mf";
params.preset_name = wxGetApp().preset_bundle->prints.get_selected_preset_name();
@ -163,6 +190,7 @@ void SendJob::process()
params.dev_ip = m_dev_ip;
params.username = "bblp";
params.password = m_access_code;
params.use_ssl = m_local_use_ssl;
wxString error_text;
wxString msg_text;
@ -309,12 +337,15 @@ void SendJob::process()
msg_text += wxString::Format("[%s]", error_text);
}
}
if (result == BAMBU_NETWORK_ERR_WRONG_IP_ADDRESS) {
msg_text = _L("Failed uploading print file. Please enter ip address again.");
}
update_status(curr_percent, msg_text);
BOOST_LOG_TRIVIAL(error) << "send_job: failed, result = " << result;
} else {
BOOST_LOG_TRIVIAL(error) << "send_job: send ok.";
//m_success_fun();
wxCommandEvent* evt = new wxCommandEvent(m_print_job_completed_id);
evt->SetString(from_u8(params.project_name));
wxQueueEvent(m_plater, evt);
@ -327,6 +358,16 @@ void SendJob::on_success(std::function<void()> success)
m_success_fun = success;
}
void SendJob::on_check_ip_address_fail(std::function<void()> func)
{
m_enter_ip_address_fun_fail = func;
}
void SendJob::on_check_ip_address_success(std::function<void()> func)
{
m_enter_ip_address_fun_success = func;
}
void SendJob::finalize() {
if (was_canceled()) return;

View file

@ -20,7 +20,10 @@ class SendJob : public PlaterJob
std::string m_dev_id;
bool m_job_finished{ false };
int m_print_job_completed_id = 0;
bool m_is_check_mode{false};
std::function<void()> m_success_fun{nullptr};
std::function<void()> m_enter_ip_address_fun_fail{nullptr};
std::function<void()> m_enter_ip_address_fun_success{nullptr};
protected:
@ -33,6 +36,7 @@ public:
std::string m_project_name;
std::string m_dev_ip;
std::string m_access_code;
bool m_local_use_ssl{false};
std::string task_bed_type;
std::string task_ams_mapping;
std::string connection_type;
@ -49,9 +53,12 @@ public:
}
wxString get_http_error_msg(unsigned int status, std::string body);
void set_check_mode() {m_is_check_mode = true;};
bool is_finished() { return m_job_finished; }
void process() override;
void on_success(std::function<void()> success);
void on_check_ip_address_fail(std::function<void()> func);
void on_check_ip_address_success(std::function<void()> func);
void finalize() override;
void set_project_name(std::string name);
};

View file

@ -72,6 +72,7 @@ namespace GUI {
wxDEFINE_EVENT(EVT_SELECT_TAB, wxCommandEvent);
wxDEFINE_EVENT(EVT_HTTP_ERROR, wxCommandEvent);
wxDEFINE_EVENT(EVT_USER_LOGIN, wxCommandEvent);
wxDEFINE_EVENT(EVT_SHOW_IP_DIALOG, wxCommandEvent);
wxDEFINE_EVENT(EVT_UPDATE_PRESET_CB, SimpleEvent);
// BBS: backup
@ -195,8 +196,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
panel_topbar->Layout();
#endif
//wxAuiToolBar* toolbar = new wxAuiToolBar();
/*
#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
@ -1450,7 +1449,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_option_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event)
{
SidePopup* p = new SidePopup(this);
if (wxGetApp().preset_bundle
&& !wxGetApp().preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(wxGetApp().preset_bundle)) {
// ThirdParty Buttons
@ -1524,15 +1523,15 @@ wxBoxSizer* MainFrame::create_side_tools()
});
SideButton* send_to_printer_all_btn = new SideButton(p, _L("Send all"), "");
send_to_printer_all_btn->SetCornerRadius(0);
send_to_printer_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Send all"));
m_print_select = eSendToPrinterAll;
m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable);
this->Layout();
p->Dismiss();
});
send_to_printer_all_btn->SetCornerRadius(0);
send_to_printer_all_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Send all"));
m_print_select = eSendToPrinterAll;
m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable);
this->Layout();
p->Dismiss();
});
export_sliced_file_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Export plate sliced file"));
@ -3236,7 +3235,7 @@ void MainFrame::on_select_default_preset(SimpleEvent& evt)
"It contains the following information:\n"
"1. The Process presets\n"
"2. The Filament presets\n"
"3. The Printer presets\n"),
"3. The Printer presets"),
_L("Synchronization"),
wxCENTER |
wxYES_DEFAULT | wxYES_NO |

View file

@ -380,6 +380,7 @@ public:
wxDECLARE_EVENT(EVT_HTTP_ERROR, wxCommandEvent);
wxDECLARE_EVENT(EVT_USER_LOGIN, wxCommandEvent);
wxDECLARE_EVENT(EVT_SHOW_IP_DIALOG, wxCommandEvent);
wxDECLARE_EVENT(EVT_UPDATE_PRESET_CB, SimpleEvent);
} // GUI

View file

@ -181,7 +181,7 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj)
m_supported = true;
m_lan_mode = obj->is_lan_mode_printer();
m_lan_ip = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->dev_ip : "";
m_lan_passwd = obj->access_code;
m_lan_passwd = obj->get_access_code();
m_tutk_support = obj->is_function_supported(PrinterFunction::FUNC_REMOTE_TUNNEL);
} else {
m_supported = false;

View file

@ -35,7 +35,7 @@ MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl2 *media_ctrl, const w
m_button_play = new Button(this, "", "media_play", wxBORDER_NONE);
m_button_play->SetCanFocus(false);
m_label_status = new Label(this, "", LB_HYPERLINK);
m_label_status = new Label(this, "");
m_label_status->SetForegroundColour(wxColour("#2C2C2E"));
m_button_play->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) { TogglePlay(); });
@ -85,17 +85,19 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj)
m_camera_exists = obj->has_ipcam;
m_lan_mode = obj->is_lan_mode_printer();
m_lan_ip = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->dev_ip : "";
m_lan_passwd = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->access_code : "";
m_lan_passwd = obj->is_function_supported(PrinterFunction::FUNC_LOCAL_TUNNEL) ? obj->get_access_code() : "";
m_tutk_support = obj->is_function_supported(PrinterFunction::FUNC_REMOTE_TUNNEL);
m_device_busy = obj->is_in_prepare();
} else {
m_camera_exists = false;
m_lan_mode = false;
m_lan_ip.clear();
m_lan_passwd.clear();
m_tutk_support = true;
m_device_busy = false;
}
if (machine == m_machine) {
if (m_last_state == MEDIASTATE_IDLE && m_next_retry.IsValid() && wxDateTime::Now() >= m_next_retry)
if (m_last_state == MEDIASTATE_IDLE)
Play();
return;
}
@ -110,29 +112,28 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj)
}
if (m_last_state != MEDIASTATE_IDLE)
Stop();
if (m_next_retry.IsValid())
Play();
if (m_next_retry.IsValid()) // Try open 2 seconds later, to avoid state conflict
m_next_retry = wxDateTime::Now() + wxTimeSpan::Seconds(2 * m_failed_retry);
else
SetStatus("", false);
}
void MediaPlayCtrl::Play()
{
if (!m_next_retry.IsValid())
if (!m_next_retry.IsValid() || wxDateTime::Now() < m_next_retry)
return;
if (!IsShownOnScreen())
return;
if (m_last_state != MEDIASTATE_IDLE) {
return;
}
m_failed_code = 0;
if (m_machine.empty()) {
Stop();
SetStatus(_L("Initialize failed (No Device)!"));
Stop(_L("Initialize failed (No Device)!"));
return;
}
if (!m_camera_exists) {
Stop();
SetStatus(_L("Initialize failed (No Camera Device)!"));
Stop(_L("Initialize failed (No Camera Device)!"));
return;
}
@ -140,7 +141,7 @@ void MediaPlayCtrl::Play()
m_button_play->SetIcon("media_stop");
SetStatus(_L("Initializing..."));
if (!m_lan_ip.empty() && (!m_lan_mode || !m_lan_passwd.empty())) {
if (!m_lan_ip.empty() && (!m_lan_mode || !m_lan_passwd.empty()) && !m_device_busy) {
m_url = "bambu:///local/" + m_lan_ip + ".?port=6000&user=" + m_lan_user + "&passwd=" + m_lan_passwd;
m_last_state = MEDIASTATE_LOADING;
SetStatus(_L("Loading..."));
@ -161,16 +162,21 @@ void MediaPlayCtrl::Play()
}
if (m_lan_mode) {
Stop();
SetStatus(m_lan_passwd.empty()
m_failed_code = 1;
Stop(m_lan_passwd.empty()
? _L("Initialize failed (Not supported with LAN-only mode)!")
: _L("Initialize failed (Not accessible in LAN-only mode)!"));
return;
}
if (!m_tutk_support) { // not support tutk
Stop();
SetStatus(m_lan_ip.empty()
if (m_device_busy) {
Stop(_L("Printer is busy downloading, Please wait for the downloading to finish."));
m_failed_retry = 0;
return;
}
m_failed_code = 1;
Stop(m_lan_ip.empty()
? _L("Initialize failed (Missing LAN ip of printer)!")
: _L("Initialize failed (Not supported by printer)!"));
return;
@ -206,7 +212,7 @@ void MediaPlayCtrl::Play()
}
}
void MediaPlayCtrl::Stop()
void MediaPlayCtrl::Stop(wxString const &msg)
{
if (m_last_state != MEDIASTATE_IDLE) {
m_media_ctrl->InvalidateBestSize();
@ -215,14 +221,26 @@ void MediaPlayCtrl::Stop()
m_tasks.push_back("<stop>");
m_cond.notify_all();
m_last_state = MEDIASTATE_IDLE;
if (m_failed_code)
if (!msg.IsEmpty())
SetStatus(msg, false);
else if (m_failed_code)
SetStatus(_L("Stopped [%d]!"), true);
else
SetStatus(_L("Stopped."), false);
if (m_failed_code >= 100) // not keep retry on local error
m_next_retry = wxDateTime();
} else if (!msg.IsEmpty()) {
SetStatus(msg, false);
}
++m_failed_retry;
if (m_failed_code != 0 && !m_tutk_support && m_failed_retry > 1) {
m_next_retry = wxDateTime(); // stop retry
if (wxGetApp().show_modal_ip_address_enter_dialog(_L("LAN Connection Failed (Failed to start liveview)"))) {
m_failed_retry = 0;
m_next_retry = wxDateTime::Now();
return;
}
}
if (m_next_retry.IsValid())
m_next_retry = wxDateTime::Now() + wxTimeSpan::Seconds(5 * m_failed_retry);
}
@ -317,6 +335,48 @@ void MediaPlayCtrl::ToggleStream()
});
}
void MediaPlayCtrl::onStateChanged(wxMediaEvent &event)
{
auto last_state = m_last_state;
auto state = m_media_ctrl->GetState();
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: " << state << ", last_state: " << last_state;
if ((int) state < 0) return;
{
boost::unique_lock lock(m_mutex);
if (!m_tasks.empty()) {
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: skip when task not finished";
return;
}
}
if ((last_state == MEDIASTATE_IDLE || last_state == MEDIASTATE_INITIALIZING) && state == wxMEDIASTATE_STOPPED) { return; }
if ((last_state == wxMEDIASTATE_PAUSED || last_state == wxMEDIASTATE_PLAYING) && state == wxMEDIASTATE_STOPPED) {
m_failed_code = m_media_ctrl->GetLastError();
Stop();
return;
}
if (last_state == MEDIASTATE_LOADING && state == wxMEDIASTATE_STOPPED) {
wxSize size = m_media_ctrl->GetVideoSize();
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: size: " << size.x << "x" << size.y;
m_failed_code = m_media_ctrl->GetLastError();
if (size.GetWidth() > 1000) {
m_last_state = state;
SetStatus(_L("Playing..."), false);
m_failed_retry = 0;
m_failed_code = 0;
boost::unique_lock lock(m_mutex);
m_tasks.push_back("<play>");
m_cond.notify_all();
} else if (event.GetId()) {
Stop();
if (m_failed_code == 0)
m_failed_code = 2;
SetStatus(_L("Load failed [%d]!"));
}
} else {
m_last_state = state;
}
}
void MediaPlayCtrl::SetStatus(wxString const &msg2, bool hyperlink)
{
auto msg = wxString::Format(msg2, m_failed_code);
@ -342,6 +402,7 @@ void MediaPlayCtrl::on_show_hide(wxShowEvent &evt)
{
evt.Skip();
if (m_isBeingDeleted) return;
m_failed_retry = 0;
IsShownOnScreen() ? Play() : Stop();
}
@ -358,7 +419,9 @@ void MediaPlayCtrl::media_proc()
break;
}
else if (url == "<stop>") {
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: start stop";
m_media_ctrl->Stop();
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: end stop";
}
else if (url == "<exit>") {
break;
@ -492,57 +555,15 @@ bool MediaPlayCtrl::get_stream_url(std::string *url)
return url == nullptr;
}
void MediaPlayCtrl::onStateChanged(wxMediaEvent& event)
{
auto last_state = m_last_state;
auto state = m_media_ctrl->GetState();
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: " << state << ", last_state: " << last_state;
if ((int) state < 0)
return;
{
boost::unique_lock lock(m_mutex);
if (!m_tasks.empty()) {
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: skip when task not finished";
return;
}
}
if ((last_state == MEDIASTATE_IDLE || last_state == MEDIASTATE_INITIALIZING) && state == wxMEDIASTATE_STOPPED) {
return;
}
if ((last_state == wxMEDIASTATE_PAUSED || last_state == wxMEDIASTATE_PLAYING) &&
state == wxMEDIASTATE_STOPPED) {
m_failed_code = m_media_ctrl->GetLastError();
Stop();
return;
}
if (last_state == MEDIASTATE_LOADING && state == wxMEDIASTATE_STOPPED) {
wxSize size = m_media_ctrl->GetVideoSize();
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: size: " << size.x << "x" << size.y;
m_failed_code = m_media_ctrl->GetLastError();
if (size.GetWidth() > 1000) {
m_last_state = state;
SetStatus(_L("Playing..."), false);
m_failed_retry = 0;
boost::unique_lock lock(m_mutex);
m_tasks.push_back("<play>");
m_cond.notify_all();
}
else if (event.GetId()) {
Stop();
if (m_failed_code == 0)
m_failed_code = 2;
SetStatus(_L("Load failed [%d]!"));
}
} else {
m_last_state = state;
}
}
}}
void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
#ifdef __WXMAC__
wxWindow::DoSetSize(x, y, width, height, sizeFlags);
#else
wxMediaCtrl::DoSetSize(x, y, width, height, sizeFlags);
#endif
if (sizeFlags & wxSIZE_USE_EXISTING) return;
wxSize size = GetVideoSize();
if (size.GetWidth() <= 0)

View file

@ -44,7 +44,7 @@ protected:
void Play();
void Stop();
void Stop(wxString const &msg = {});
void TogglePlay();
@ -74,6 +74,7 @@ private:
bool m_camera_exists = false;
bool m_lan_mode = false;
bool m_tutk_support = false;
bool m_device_busy = false;
wxString m_url;
std::deque<wxString> m_tasks;

View file

@ -324,7 +324,7 @@ void MonitorPanel::on_printer_clicked(wxMouseEvent &event)
wxPoint pos = m_side_tools->ClientToScreen(wxPoint(0, 0));
pos.y += m_side_tools->GetRect().height;
//pos.x = pos.x < 0? 0:pos.x;
m_select_machine.Position(pos, wxSize(0, 0));
m_select_machine.Move(pos);
#ifdef __linux__
m_select_machine.SetSize(wxSize(m_side_tools->GetSize().x, -1));

View file

@ -26,8 +26,6 @@
namespace Slic3r {
namespace GUI {
wxDEFINE_EVENT(EVT_CHECKBOX_CHANGE, wxCommandEvent);
MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, long style, wxBitmap bitmap)
: DPIDialog(parent ? parent : dynamic_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, title, wxDefaultPosition, wxSize(360, -1),wxDEFAULT_DIALOG_STYLE)
, boldfont(wxGetApp().normal_font())

View file

@ -3,7 +3,6 @@
#include <string>
#include <unordered_map>
#include "GUI_Utils.hpp"
#include <wx/dialog.h>
#include <wx/font.h>
@ -14,6 +13,7 @@
#include <wx/statline.h>
#include "Widgets/Button.hpp"
#include "Widgets/CheckBox.hpp"
#include "Widgets/TextInput.hpp"
#include "BBLStatusBar.hpp"
#include "BBLStatusBarSend.hpp"
@ -93,7 +93,7 @@ protected:
MsgButtonsHash m_buttons;
CheckBox* m_checkbox_dsa{nullptr};
};
wxDECLARE_EVENT(EVT_CHECKBOX_CHANGE, wxCommandEvent);
// Generic error dialog, used for displaying exceptions
class ErrorDialog : public MsgDialog
@ -372,6 +372,7 @@ private:
wxString msg;
};
}
}

View file

@ -258,5 +258,14 @@ void Notebook::Init()
m_showEffect = m_hideEffect = wxSHOW_EFFECT_NONE;
m_showTimeout = m_hideTimeout = 0;
/* On Linux, Gstreamer wxMediaCtrl does not seem to get along well with
* 32-bit X11 visuals (the overlay does not work). Is this a wxWindows
* bug? Is this a Gstreamer bug? No idea, but it is our problem ...
* and anyway, this transparency thing just isn't all that interesting,
* so we just don't do it on Linux.
*/
#ifndef __WXGTK__
SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
#endif
}

View file

@ -36,7 +36,7 @@
namespace Slic3r {
namespace GUI {
#define BORDER_W 10
#define BORDER_W FromDIP(10)
//------------------------------------------
// PhysicalPrinterDialog

View file

@ -240,8 +240,10 @@ SlicedInfo::SlicedInfo(wxWindow *parent) :
auto init_info_label = [this, parent, grid_sizer](wxString text_label) {
auto *text = new wxStaticText(parent, wxID_ANY, text_label);
text->SetForegroundColour(*wxBLACK);
text->SetFont(wxGetApp().small_font());
auto info_label = new wxStaticText(parent, wxID_ANY, "N/A");
info_label->SetForegroundColour(*wxBLACK);
info_label->SetFont(wxGetApp().small_font());
grid_sizer->Add(text, 0);
grid_sizer->Add(info_label, 0);
@ -1849,7 +1851,7 @@ struct Plater::priv
bool is_view3D_layers_editing_enabled() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_layers_editing_enabled(); }
void set_current_canvas_as_dirty();
GLCanvas3D* get_current_canvas3D();
GLCanvas3D* get_current_canvas3D(bool exclude_preview = false);
void unbind_canvas_event_handlers();
void reset_canvas_volumes();
@ -2039,7 +2041,6 @@ struct Plater::priv
void on_action_print_all(SimpleEvent&);
void on_action_export_gcode(SimpleEvent&);
void on_action_send_gcode(SimpleEvent&);
void on_action_upload_gcode(SimpleEvent&);
void on_action_export_sliced_file(SimpleEvent&);
void on_action_export_all_sliced_file(SimpleEvent&);
void on_action_select_sliced_plate(wxCommandEvent& evt);
@ -2449,7 +2450,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
q->Bind(EVT_GLTOOLBAR_PRINT_ALL, &priv::on_action_print_all, this);
q->Bind(EVT_GLTOOLBAR_EXPORT_GCODE, &priv::on_action_export_gcode, this);
q->Bind(EVT_GLTOOLBAR_SEND_GCODE, &priv::on_action_send_gcode, this);
q->Bind(EVT_GLTOOLBAR_UPLOAD_GCODE, &priv::on_action_upload_gcode, this);
q->Bind(EVT_GLTOOLBAR_EXPORT_SLICED_FILE, &priv::on_action_export_sliced_file, this);
q->Bind(EVT_GLTOOLBAR_EXPORT_ALL_SLICED_FILE, &priv::on_action_export_all_sliced_file, this);
q->Bind(EVT_GLTOOLBAR_SEND_TO_PRINTER, &priv::on_action_export_to_sdcard, this);
@ -3092,8 +3092,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}
} else if (load_config && (file_version > app_version)) {
if (config_substitutions.unrecogized_keys.size() > 0) {
wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Found following keys unrecognized:\n"),
wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Found following keys unrecognized:"),
file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string());
text += "\n";
bool first = true;
// std::string context = into_u8(text);
wxString context = text;
@ -3112,8 +3113,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
else {
//if the minor version is not matched
if (file_version.min() != app_version.min()) {
wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your software.\n"),
wxString text = wxString::Format(_L("The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your software."),
file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string());
text += "\n";
show_info(q, text, _L("Newer 3mf version"));
}
}
@ -6105,19 +6107,11 @@ void Plater::priv::on_action_export_gcode(SimpleEvent&)
}
}
void Plater::priv::on_action_upload_gcode(SimpleEvent&)
{
if (q != nullptr) {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n";
q->send_gcode_legacy(-1, nullptr, true);
}
}
void Plater::priv::on_action_send_gcode(SimpleEvent&)
{
if (q != nullptr) {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n" ;
q->send_gcode_legacy(-1, nullptr, false);
q->send_gcode_legacy();
}
}
@ -6593,6 +6587,8 @@ void Plater::get_print_job_data(PrintPrepareData* data)
data->plate_idx = p->m_print_job_data.plate_idx;
data->_3mf_path = p->m_print_job_data._3mf_path;
data->_3mf_config_path = p->m_print_job_data._3mf_config_path;
std::string temp_file = Slic3r::resources_dir() + "/check_access_code.txt";
data->_temp_path = encode_path(temp_file.c_str());
}
}
@ -6621,11 +6617,11 @@ void Plater::priv::set_current_canvas_as_dirty()
assemble_view->set_as_dirty();
}
GLCanvas3D* Plater::priv::get_current_canvas3D()
GLCanvas3D* Plater::priv::get_current_canvas3D(bool exclude_preview)
{
if (current_panel == view3D)
return view3D->get_canvas3d();
else if (current_panel == preview)
else if (!exclude_preview && (current_panel == preview))
return preview->get_canvas3d();
else if (current_panel == assemble_view)
return assemble_view->get_canvas3d();
@ -9914,7 +9910,7 @@ void Plater::reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &
// and let the background processing start.
this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
}
void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn, bool upload_only)
void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn)
{
// if physical_printer is selected, send gcode for this printer
// DynamicPrintConfig* physical_printer_config = wxGetApp().preset_bundle->physical_printers.get_selected_printer_config();
@ -10449,9 +10445,9 @@ GLCanvas3D* Plater::get_assmeble_canvas3D()
return nullptr;
}
GLCanvas3D* Plater::get_current_canvas3D()
GLCanvas3D* Plater::get_current_canvas3D(bool exclude_preview)
{
return p->get_current_canvas3D();
return p->get_current_canvas3D(exclude_preview);
}
void Plater::arrange()
@ -11135,6 +11131,8 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click)
PartPlate* curr_plate = p->partplate_list.get_curr_plate();
dlg.sync_bed_type(curr_plate->get_bed_type(false));
dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index](wxCommandEvent& e) {
PartPlate *curr_plate = p->partplate_list.get_curr_plate();
BedType old_bed_type = curr_plate->get_bed_type(false);
auto type = (BedType)(e.GetInt());
p->partplate_list.get_curr_plate()->set_bed_type(type);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side")%type %plate_index;
@ -11308,7 +11306,8 @@ void Plater::post_process_string_object_exception(StringObjectException &err)
break;
}
}
err.string = format(L("Plate %d: %s does not support filament %s (%s).\n"), err.params[0], err.params[1], err.params[2], filament_name);
err.string = format(_L("Plate %d: %s does not support filament %s (%s)."), err.params[0], err.params[1], err.params[2], filament_name);
err.string += "\n";
}
} catch (...) {
;

View file

@ -350,7 +350,7 @@ public:
/* -1: send current gcode if not specified
* -2: send all gcode to target machine */
int send_gcode(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
void send_gcode_legacy(int plate_idx = -1, Export3mfProgressFn proFn = nullptr, bool upload_only = false);
void send_gcode_legacy(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
int export_config_3mf(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
//BBS jump to nonitor after print job finished
void print_job_finished(wxCommandEvent &evt);
@ -406,7 +406,7 @@ public:
bool is_single_full_object_selection() const;
GLCanvas3D* canvas3D();
const GLCanvas3D * canvas3D() const;
GLCanvas3D* get_current_canvas3D();
GLCanvas3D* get_current_canvas3D(bool exclude_preview = false);
GLCanvas3D* get_view3D_canvas3D();
GLCanvas3D* get_preview_canvas3D();
GLCanvas3D* get_assmeble_canvas3D();

View file

@ -108,7 +108,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
if (post_actions.has(PrintHostPostUploadAction::StartSimulation)) {
// Using wxID_MORE as a button identifier to be different from the other buttons, wxID_MORE has no other meaning here.
auto* btn_simulate = add_button(wxID_MORE, false, _L("Upload and Simulate"));
auto* btn_simulate = add_button(wxID_MORE, false, _L("Simulate"));
btn_simulate->Bind(wxEVT_BUTTON, [this, validate_path](wxCommandEvent&) {
if (validate_path(txt_filename->GetValue())) {
post_upload_action = PrintHostPostUploadAction::StartSimulation;

View file

@ -21,6 +21,15 @@
extern "C" {
#endif // __cplusplus
#ifndef __cplusplus
#include <stdbool.h>
/* We need these workarounds since we're compiling C source, not C++. */
typedef enum Bambu_StreamType Bambu_StreamType;
typedef struct Bambu_StreamInfo Bambu_StreamInfo;
typedef struct Bambu_Sample Bambu_Sample;
#endif
#ifdef _WIN32
typedef wchar_t tchar;
#else

View file

@ -921,3 +921,7 @@ StaticBambuLib &StaticBambuLib::get()
lib.Bambu_Create = Fake_Bambu_Create;
return lib;
}
extern "C" struct BambuLib *bambulib_get() {
return &StaticBambuLib::get();
}

View file

@ -0,0 +1,558 @@
/* bambusrc for gstreamer
* integration with proprietary Bambu Lab blob for getting raw h.264 video
*
* Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gst/gst.h>
#include "gstbambusrc.h"
#include <stdio.h>
#include <unistd.h>
#ifndef EXTERNAL_GST_PLUGIN
#define BAMBU_DYNAMIC
#endif
#include "BambuTunnel.h"
#ifdef BAMBU_DYNAMIC
// From PrinterFileSystem.
#ifdef __cplusplus
extern "C"
#else
extern
#endif
struct BambuLib *bambulib_get();
static struct BambuLib *_lib = NULL;
#define BAMBULIB(x) (_lib->x)
#else
#define BAMBULIB(x) (x)
#endif
GST_DEBUG_CATEGORY_STATIC (gst_bambusrc_debug);
#define GST_CAT_DEFAULT gst_bambusrc_debug
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS("video/x-h264,framerate=0/1,parsed=(boolean)false,stream-format=(string)byte-stream"));
enum
{
PROP_0,
PROP_LOCATION,
};
static void gst_bambusrc_uri_handler_init (gpointer g_iface,
gpointer iface_data);
static void gst_bambusrc_finalize (GObject * gobject);
static void gst_bambusrc_dispose (GObject * gobject);
static void gst_bambusrc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_bambusrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_bambusrc_change_state (GstElement *
element, GstStateChange transition);
static GstFlowReturn gst_bambusrc_create (GstPushSrc * psrc,
GstBuffer ** outbuf);
static gboolean gst_bambusrc_start (GstBaseSrc * bsrc);
static gboolean gst_bambusrc_stop (GstBaseSrc * bsrc);
static gboolean gst_bambusrc_is_seekable (GstBaseSrc * bsrc);
static gboolean gst_bambusrc_query (GstBaseSrc * bsrc, GstQuery * query);
static gboolean gst_bambusrc_unlock (GstBaseSrc * bsrc);
static gboolean gst_bambusrc_unlock_stop (GstBaseSrc * bsrc);
static gboolean gst_bambusrc_set_location (GstBambuSrc * src,
const gchar * uri, GError ** error);
#define gst_bambusrc_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstBambuSrc, gst_bambusrc, GST_TYPE_PUSH_SRC,
G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
gst_bambusrc_uri_handler_init));
static void
gst_bambusrc_class_init (GstBambuSrcClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseSrcClass *gstbasesrc_class;
GstPushSrcClass *gstpushsrc_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesrc_class = (GstBaseSrcClass *) klass;
gstpushsrc_class = (GstPushSrcClass *) klass;
gobject_class->set_property = gst_bambusrc_set_property;
gobject_class->get_property = gst_bambusrc_get_property;
gobject_class->finalize = gst_bambusrc_finalize;
gobject_class->dispose = gst_bambusrc_dispose;
g_object_class_install_property (gobject_class,
PROP_LOCATION,
g_param_spec_string ("location", "Location",
"URI to pass to Bambu Lab blobs", "",
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
gst_element_class_set_static_metadata (gstelement_class, "Bambu Lab source",
"Source/Network",
"Receive data as a client over the network using the proprietary Bambu Lab blobs",
"Joshua Wise <joshua@accelerated.tech>");
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_bambusrc_change_state);
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_bambusrc_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_bambusrc_stop);
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_bambusrc_unlock);
gstbasesrc_class->unlock_stop =
GST_DEBUG_FUNCPTR (gst_bambusrc_unlock_stop);
gstbasesrc_class->is_seekable =
GST_DEBUG_FUNCPTR (gst_bambusrc_is_seekable);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_bambusrc_query);
gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_bambusrc_create);
GST_DEBUG_CATEGORY_INIT (gst_bambusrc_debug, "bambusrc", 0,
"Bambu Lab src");
}
static void
gst_bambusrc_reset (GstBambuSrc * src)
{
gst_caps_replace (&src->src_caps, NULL);
if (src->tnl) {
BAMBULIB(Bambu_Close)(src->tnl);
BAMBULIB(Bambu_Destroy)(src->tnl);
src->tnl = NULL;
}
}
static void
gst_bambusrc_init (GstBambuSrc * src)
{
src->location = NULL;
src->tnl = NULL;
gst_base_src_set_automatic_eos (GST_BASE_SRC (src), FALSE);
gst_base_src_set_live(GST_BASE_SRC(src), TRUE);
gst_bambusrc_reset (src);
}
static void
gst_bambusrc_dispose (GObject * gobject)
{
GstBambuSrc *src = GST_BAMBUSRC (gobject);
GST_DEBUG_OBJECT (src, "dispose");
G_OBJECT_CLASS (parent_class)->dispose (gobject);
}
static void
gst_bambusrc_finalize (GObject * gobject)
{
GstBambuSrc *src = GST_BAMBUSRC (gobject);
GST_DEBUG_OBJECT (src, "finalize");
g_free (src->location);
if (src->tnl) {
BAMBULIB(Bambu_Close)(src->tnl);
BAMBULIB(Bambu_Destroy)(src->tnl);
}
G_OBJECT_CLASS (parent_class)->finalize (gobject);
}
static void
gst_bambusrc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstBambuSrc *src = GST_BAMBUSRC (object);
switch (prop_id) {
case PROP_LOCATION:
{
const gchar *location;
location = g_value_get_string (value);
if (location == NULL) {
GST_WARNING ("location property cannot be NULL");
goto done;
}
if (!gst_bambusrc_set_location (src, location, NULL)) {
GST_WARNING ("badly formatted location");
goto done;
}
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
done:
return;
}
static void
gst_bambusrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstBambuSrc *src = GST_BAMBUSRC (object);
switch (prop_id) {
case PROP_LOCATION:
g_value_set_string (value, src->location);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GstFlowReturn
gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf)
{
GstBambuSrc *src;
src = GST_BAMBUSRC (psrc);
(void) src;
GST_DEBUG_OBJECT (src, "create()");
int rv;
struct Bambu_Sample sample;
if (!src->tnl) {
return GST_FLOW_ERROR;
}
while ((rv = BAMBULIB(Bambu_ReadSample)(src->tnl, &sample)) == Bambu_would_block) {
GST_DEBUG_OBJECT(src, "create would block");
usleep(33333); /* 30Hz */
}
if (rv == Bambu_stream_end) {
return GST_FLOW_EOS;
}
if (rv != Bambu_success) {
return GST_FLOW_ERROR;
}
#if GLIB_CHECK_VERSION(2,68,0)
gpointer sbuf = g_memdup2(sample.buffer, sample.size);
#else
gpointer sbuf = g_memdup(sample.buffer, sample.size);
#endif
*outbuf = gst_buffer_new_wrapped_full(0, sbuf, sample.size, 0, sample.size, sbuf, g_free);
/* The NAL data already contains a timestamp (I think?), but we seem to
* need to feed this in too -- otherwise the GStreamer pipeline gets upset
* and starts triggering QoS events.
*/
if (!src->sttime) {
src->sttime = sample.decode_time * 100ULL;
}
GST_BUFFER_DTS(*outbuf) = sample.decode_time * 100ULL - src->sttime;
GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE;
return GST_FLOW_OK;
}
static void _log(void *ctx, int lvl, const char *msg) {
GstBambuSrc *src = (GstBambuSrc *) ctx;
GST_DEBUG_OBJECT(src, "bambu: %s", msg);
BAMBULIB(Bambu_FreeLogMsg)(msg);
}
static gboolean
gst_bambusrc_start (GstBaseSrc * bsrc)
{
GstBambuSrc *src = GST_BAMBUSRC (bsrc);
GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location);
if (src->tnl) {
BAMBULIB(Bambu_Close)(src->tnl);
BAMBULIB(Bambu_Destroy)(src->tnl);
src->tnl = NULL;
}
#ifdef BAMBU_DYNAMIC
if (!_lib) {
_lib = bambulib_get();
if (!_lib->Bambu_Open) {
return FALSE;
}
}
#endif
if (BAMBULIB(Bambu_Create)(&src->tnl, src->location) != Bambu_success) {
return FALSE;
}
BAMBULIB(Bambu_SetLogger)(src->tnl, _log, (void *)src);
if (BAMBULIB(Bambu_Open)(src->tnl) != Bambu_success) {
BAMBULIB(Bambu_Destroy)(src->tnl);
src->tnl = NULL;
return FALSE;
}
int rv;
while ((rv = BAMBULIB(Bambu_StartStream)(src->tnl, 1 /* video */)) == Bambu_would_block) {
usleep(100000);
}
if (rv != Bambu_success) {
BAMBULIB(Bambu_Close)(src->tnl);
BAMBULIB(Bambu_Destroy)(src->tnl);
src->tnl = NULL;
return FALSE;
}
src->sttime = 0;
return TRUE;
}
static gboolean
gst_bambusrc_stop (GstBaseSrc * bsrc)
{
GstBambuSrc *src;
src = GST_BAMBUSRC (bsrc);
GST_DEBUG_OBJECT (src, "stop()");
if (src->tnl) {
BAMBULIB(Bambu_Close)(src->tnl);
BAMBULIB(Bambu_Destroy)(src->tnl);
src->tnl = NULL;
}
return TRUE;
}
static GstStateChangeReturn
gst_bambusrc_change_state (GstElement * element, GstStateChange transition)
{
GstStateChangeReturn ret;
GstBambuSrc *src;
src = GST_BAMBUSRC (element);
(void) src;
switch (transition) {
case GST_STATE_CHANGE_READY_TO_NULL:
//gst_bambusrc_session_close (src);
break;
default:
break;
}
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
return ret;
}
/* Interrupt a blocking request. */
static gboolean
gst_bambusrc_unlock (GstBaseSrc * bsrc)
{
GstBambuSrc *src;
src = GST_BAMBUSRC (bsrc);
GST_DEBUG_OBJECT (src, "unlock()");
return TRUE;
}
/* Interrupt interrupt. */
static gboolean
gst_bambusrc_unlock_stop (GstBaseSrc * bsrc)
{
GstBambuSrc *src;
src = GST_BAMBUSRC (bsrc);
GST_DEBUG_OBJECT (src, "unlock_stop()");
return TRUE;
}
static gboolean
gst_bambusrc_is_seekable (GstBaseSrc * bsrc)
{
GstBambuSrc *src = GST_BAMBUSRC (bsrc);
(void) src;
return FALSE;
}
static gboolean
gst_bambusrc_query (GstBaseSrc * bsrc, GstQuery * query)
{
GstBambuSrc *src = GST_BAMBUSRC (bsrc);
gboolean ret;
GstSchedulingFlags flags;
gint minsize, maxsize, align;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_URI:
gst_query_set_uri (query, src->location);
ret = TRUE;
break;
default:
ret = FALSE;
break;
}
if (!ret)
ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_SCHEDULING:
gst_query_parse_scheduling (query, &flags, &minsize, &maxsize, &align);
flags = (GstSchedulingFlags)((int)flags | (int)GST_SCHEDULING_FLAG_SEQUENTIAL);
gst_query_set_scheduling (query, flags, minsize, maxsize, align);
break;
default:
break;
}
return ret;
}
static gboolean
gst_bambusrc_set_location (GstBambuSrc * src, const gchar * uri,
GError ** error)
{
if (src->location) {
g_free (src->location);
src->location = NULL;
}
if (uri == NULL)
return FALSE;
src->location = g_strdup (uri);
return TRUE;
}
static GstURIType
gst_bambusrc_uri_get_type (GType type)
{
return GST_URI_SRC;
}
static const gchar *const *
gst_bambusrc_uri_get_protocols (GType type)
{
static const gchar *protocols[] = { "bambu", NULL };
return protocols;
}
static gchar *
gst_bambusrc_uri_get_uri (GstURIHandler * handler)
{
GstBambuSrc *src = GST_BAMBUSRC (handler);
/* FIXME: make thread-safe */
return g_strdup (src->location);
}
static gboolean
gst_bambusrc_uri_set_uri (GstURIHandler * handler, const gchar * uri,
GError ** error)
{
GstBambuSrc *src = GST_BAMBUSRC (handler);
return gst_bambusrc_set_location (src, uri, error);
}
static void
gst_bambusrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
iface->get_type = gst_bambusrc_uri_get_type;
iface->get_protocols = gst_bambusrc_uri_get_protocols;
iface->get_uri = gst_bambusrc_uri_get_uri;
iface->set_uri = gst_bambusrc_uri_set_uri;
}
static gboolean gstbambusrc_init(GstPlugin *plugin)
{
return gst_element_register(plugin, "bambusrc", GST_RANK_PRIMARY, GST_TYPE_BAMBUSRC);
}
#ifndef EXTERNAL_GST_PLUGIN
// for use inside of Bambu Slicer
void gstbambusrc_register()
{
static int did_register = 0;
if (did_register)
return;
did_register = 1;
gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, "bambusrc", "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "BambuStudio", "https://github.com/bambulab/BambuStudio");
}
#else
#ifndef PACKAGE
#define PACKAGE "bambusrc"
#endif
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, bambusrc, "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "https://github.com/bambulab/BambuStudio")
#endif

View file

@ -0,0 +1,73 @@
/* bambusrc for gstreamer
* integration with proprietary Bambu Lab blob for getting raw h.264 video
*
* Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_BAMBUSRC_H__
#define __GST_BAMBUSRC_H__
#include <gst/gst.h>
#include <gst/base/gstpushsrc.h>
#include <glib.h>
G_BEGIN_DECLS
#define GST_TYPE_BAMBUSRC (gst_bambusrc_get_type())
G_DECLARE_FINAL_TYPE (GstBambuSrc, gst_bambusrc,
GST, BAMBUSRC, GstPushSrc)
typedef void *Bambu_Tunnel;
struct _GstBambuSrc
{
GstPushSrc element;
GstCaps *src_caps;
gchar *location;
Bambu_Tunnel tnl;
GstClockTime sttime;
};
extern void gstbambusrc_register();
G_END_DECLS
#endif /* __GST_BAMBUSRC_H__ */

View file

@ -22,6 +22,8 @@ RecenterDialog::RecenterDialog(wxWindow* parent, wxWindowID id, const wxString&
init_bitmap();
SetBackgroundColour(*wxWHITE);
auto* main_sizer = new wxBoxSizer(wxVERTICAL);
auto* button_sizer = new wxBoxSizer(wxHORIZONTAL);

View file

@ -26,6 +26,10 @@ namespace Slic3r { namespace GUI {
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_CONFIRM, wxCommandEvent);
wxDEFINE_EVENT(EVT_SECONDARY_CHECK_CANCEL, wxCommandEvent);
wxDEFINE_EVENT(EVT_CHECKBOX_CHANGE, wxCommandEvent);
wxDEFINE_EVENT(EVT_ENTER_IP_ADDRESS, wxCommandEvent);
wxDEFINE_EVENT(EVT_CLOSE_IPADDRESS_DLG, wxCommandEvent);
wxDEFINE_EVENT(EVT_CHECK_IP_ADDRESS_FAILED, wxCommandEvent);
ReleaseNoteDialog::ReleaseNoteDialog(Plater *plater /*= nullptr*/)
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Release Note"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
@ -90,6 +94,7 @@ void ReleaseNoteDialog::update_release_note(wxString release_note, std::string v
m_text_up_info->SetLabel(wxString::Format(_L("version %s update information :"), version));
wxBoxSizer * sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
auto m_staticText_release_note = new wxStaticText(m_vebview_release_note, wxID_ANY, release_note, wxDefaultPosition, wxDefaultSize, 0);
m_staticText_release_note->SetForegroundColour(*wxBLACK);
m_staticText_release_note->Wrap(FromDIP(530));
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
m_vebview_release_note->SetSizer(sizer_text_release_note);
@ -492,6 +497,7 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve
m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version));
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
auto m_staticText_release_note = new wxStaticText(m_scrollwindows_release_note, wxID_ANY, release_note, wxDefaultPosition, wxDefaultSize, 0);
m_staticText_release_note->SetForegroundColour(*wxBLACK);
m_staticText_release_note->Wrap(FromDIP(530));
sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5);
m_scrollwindows_release_note->SetSizer(sizer_text_release_note);
@ -523,7 +529,7 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_vebview_release_note->SetScrollRate(0, 5);
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_vebview_release_note->SetBackgroundColour(*wxWHITE);
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), FromDIP(280)));
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
@ -603,11 +609,15 @@ SecondaryCheckDialog::SecondaryCheckDialog(wxWindow* parent, wxWindowID id, cons
void SecondaryCheckDialog::update_text(wxString text)
{
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
auto m_staticText_release_note = new Label(m_vebview_release_note, text);
m_staticText_release_note->Wrap(FromDIP(260));
if (!m_staticText_release_note) {
m_staticText_release_note = new Label(m_vebview_release_note, text);
}
m_staticText_release_note->SetLabelText(text);
m_staticText_release_note->SetSize(wxSize(FromDIP(260), -1));
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(260), -1));
m_staticText_release_note->SetMinSize(wxSize(FromDIP(260), -1));
m_staticText_release_note->Wrap(FromDIP(260));
wxBoxSizer* top_blank_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* bottom_blank_sizer = new wxBoxSizer(wxVERTICAL);
@ -696,7 +706,7 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
m_vebview_release_note = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_vebview_release_note->SetScrollRate(0, 5);
m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8));
m_vebview_release_note->SetBackgroundColour(*wxWHITE);
m_vebview_release_note->SetMinSize(wxSize(FromDIP(280), FromDIP(280)));
m_sizer_right->Add(m_vebview_release_note, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(35));
@ -776,7 +786,10 @@ ConfirmBeforeSendDialog::ConfirmBeforeSendDialog(wxWindow* parent, wxWindowID id
void ConfirmBeforeSendDialog::update_text(wxString text)
{
wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL);
auto m_staticText_release_note = new Label(m_vebview_release_note, text);
if (!m_staticText_release_note)
m_staticText_release_note = new Label(m_vebview_release_note, text);
else
m_staticText_release_note->SetLabelText(text);
m_staticText_release_note->Wrap(FromDIP(260));
m_staticText_release_note->SetSize(wxSize(FromDIP(260), -1));
m_staticText_release_note->SetMaxSize(wxSize(FromDIP(260), -1));
@ -862,4 +875,413 @@ void ConfirmBeforeSendDialog::rescale()
m_button_cancel->Rescale();
}
InputIpAddressDialog::InputIpAddressDialog(wxWindow* parent)
:DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, _L("LAN Connection Failed (Sending print file)"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
{
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
SetBackgroundColour(*wxWHITE);
wxBoxSizer* m_sizer_body = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* m_sizer_main = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* m_sizer_main_left = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* m_sizer_main_right = new wxBoxSizer(wxVERTICAL);
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
comfirm_before_enter_text = _L("Step 1, please confirm Bambu Studio and your printer are in the same LAN.");
comfirm_after_enter_text = _L("Step 2, if the IP and Access Code below are different from the actual values on your printer, please correct them.");
m_tip1 = new Label(this, comfirm_before_enter_text);
m_tip1->SetFont(::Label::Body_13);
m_tip1->SetMinSize(wxSize(FromDIP(352), -1));
m_tip1->SetMaxSize(wxSize(FromDIP(352), -1));
m_tip1->Wrap(FromDIP(352));
auto m_line_tips = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_tips->SetBackgroundColour(wxColour(0xEEEEEE));
m_tip2 = new Label(this, comfirm_after_enter_text);
m_tip2->SetFont(::Label::Body_13);
m_tip2->SetMinSize(wxSize(FromDIP(352), -1));
m_tip2->SetMaxSize(wxSize(FromDIP(352), -1));
m_tip2->Wrap(FromDIP(352));
auto m_input_tip_area = new wxBoxSizer(wxHORIZONTAL);
auto m_input_area = new wxBoxSizer(wxHORIZONTAL);
m_tips_ip = new Label(this, _L("IP"));
m_tips_ip->SetMinSize(wxSize(FromDIP(168), -1));
m_tips_ip->SetMaxSize(wxSize(FromDIP(168), -1));
m_input_ip = new TextInput(this, wxEmptyString, wxEmptyString);
m_input_ip->Bind(wxEVT_TEXT, &InputIpAddressDialog::on_text, this);
m_input_ip->SetMinSize(wxSize(FromDIP(168), FromDIP(28)));
m_input_ip->SetMaxSize(wxSize(FromDIP(168), FromDIP(28)));
m_tips_access_code = new Label(this, _L("Access Code"));
m_tips_access_code->SetMinSize(wxSize(FromDIP(168),-1));
m_tips_access_code->SetMaxSize(wxSize(FromDIP(168),-1));
m_input_access_code = new TextInput(this, wxEmptyString, wxEmptyString);
m_input_access_code->Bind(wxEVT_TEXT, &InputIpAddressDialog::on_text, this);
m_input_access_code->SetMinSize(wxSize(FromDIP(168), FromDIP(28)));
m_input_access_code->SetMaxSize(wxSize(FromDIP(168), FromDIP(28)));
m_input_tip_area->Add(m_tips_ip, 0, wxALIGN_CENTER, 0);
m_input_tip_area->Add(0, 0, 0, wxLEFT, FromDIP(16));
m_input_tip_area->Add(m_tips_access_code, 0, wxALIGN_CENTER, 0);
m_input_area->Add(m_input_ip, 0, wxALIGN_CENTER, 0);
m_input_area->Add(0, 0, 0, wxLEFT, FromDIP(16));
m_input_area->Add(m_input_access_code, 0, wxALIGN_CENTER, 0);
m_error_msg = new Label(this, wxEmptyString);
m_error_msg->SetFont(::Label::Body_13);
m_error_msg->SetForegroundColour(wxColour(208,27,27));
m_error_msg->Hide();
m_tip3 = new Label(this, _L("Where to find your printer's IP and Access Code?"));
m_tip3->SetFont(::Label::Body_12);
m_tip3->SetMinSize(wxSize(FromDIP(352), -1));
m_tip3->SetMaxSize(wxSize(FromDIP(352), -1));
m_tip3->Wrap(FromDIP(352));
m_img_help1 = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("input_accesscode_help1", this, 198), wxDefaultPosition, wxSize(FromDIP(352), FromDIP(198)), 0);
m_img_help2 = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("input_accesscode_help2", this, 118), wxDefaultPosition, wxSize(FromDIP(352), FromDIP(118)), 0);
m_img_help1->Hide();
m_img_help2->Hide();
auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
m_button_ok = new Button(this, _L("OK"));
m_button_ok->SetBackgroundColor(btn_bg_green);
m_button_ok->SetBorderColor(*wxWHITE);
m_button_ok->SetTextColor(wxColour(0xFFFFFE));
m_button_ok->SetFont(Label::Body_12);
m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
m_button_ok->SetCornerRadius(FromDIP(12));
m_button_ok->Bind(wxEVT_LEFT_DOWN, &InputIpAddressDialog::on_ok, this);
auto m_button_cancel = new Button(this, _L("Cancel"));
m_button_cancel->SetBackgroundColor(btn_bg_white);
m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
m_button_cancel->SetFont(Label::Body_12);
m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
m_button_cancel->SetCornerRadius(FromDIP(12));
m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
on_cancel();
});
sizer_button->AddStretchSpacer();
sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
m_status_bar = std::make_shared<BBLStatusBarSend>(this);
m_status_bar->get_panel()->Hide();
auto m_step_icon_panel1 = new wxWindow(this, wxID_ANY);
auto m_step_icon_panel2 = new wxWindow(this, wxID_ANY);
m_step_icon_panel1->SetBackgroundColour(*wxWHITE);
m_step_icon_panel2->SetBackgroundColour(*wxWHITE);
auto m_sizer_step_icon_panel1 = new wxBoxSizer(wxVERTICAL);
auto m_sizer_step_icon_panel2 = new wxBoxSizer(wxVERTICAL);
m_img_step1 = new wxStaticBitmap(m_step_icon_panel1, wxID_ANY, create_scaled_bitmap("ip_address_step", this, 6), wxDefaultPosition, wxSize(FromDIP(6), FromDIP(6)), 0);
auto m_line_tips_left = new wxPanel(m_step_icon_panel1, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_tips_left->SetBackgroundColour(wxColour(0xEEEEEE));
m_img_step2 = new wxStaticBitmap(m_step_icon_panel2, wxID_ANY, create_scaled_bitmap("ip_address_step", this, 6), wxDefaultPosition, wxSize(FromDIP(6), FromDIP(6)), 0);
m_sizer_step_icon_panel1->Add(m_img_step1, 0, wxALIGN_CENTER|wxALL, FromDIP(5));
m_step_icon_panel1->SetSizer(m_sizer_step_icon_panel1);
m_step_icon_panel1->Layout();
m_step_icon_panel1->Fit();
m_step_icon_panel2->SetSizer(m_sizer_step_icon_panel2);
m_step_icon_panel2->Layout();
m_step_icon_panel2->Fit();
m_sizer_step_icon_panel2->Add(m_img_step2, 0, wxALIGN_CENTER|wxALL, FromDIP(5));
m_step_icon_panel1->SetMinSize(wxSize(-1, m_tip1->GetSize().y));
m_step_icon_panel1->SetMaxSize(wxSize(-1, m_tip1->GetSize().y));
m_sizer_main_left->Add(m_step_icon_panel1, 0, wxEXPAND, 0);
m_sizer_main_left->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_main_left->Add(m_line_tips_left, 1, wxEXPAND, 0);
m_sizer_main_left->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_main_left->Add(m_step_icon_panel2, 0, wxEXPAND, 0);
m_sizer_main_right->Add(m_tip1, 0, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_main_right->Add(m_line_tips, 0, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_main_right->Add(m_tip2, 0, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(12));
m_sizer_main_right->Add(m_input_tip_area, 0, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(4));
m_sizer_main_right->Add(m_input_area, 0, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(m_error_msg, 0, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main_right->Add(m_tip3, 0, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(4));
m_sizer_main_right->Add(m_img_help1, 0, 0, 0);
m_sizer_main_right->Add(m_img_help2, 0, 0, 0);
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(30));
m_sizer_main_right->Add(sizer_button, 1, wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Add(0, 0, 0, wxTOP, FromDIP(16));
m_sizer_main_right->Add(m_status_bar->get_panel(), 0,wxRIGHT|wxEXPAND, FromDIP(18));
m_sizer_main_right->Layout();
auto str_ip = m_input_ip->GetTextCtrl()->GetValue();
auto str_access_code = m_input_access_code->GetTextCtrl()->GetValue();
if (isIp(str_ip.ToStdString()) && str_access_code.Length() == 8) {
m_button_ok->Enable(true);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
m_button_ok->SetTextColor(StateColor::darkModeColorFor("#FFFFFE"));
m_button_ok->SetBackgroundColor(btn_bg_green);
}
else {
m_button_ok->Enable(false);
m_button_ok->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
m_button_ok->SetBorderColor(wxColour(0x90, 0x90, 0x90));
}
m_sizer_main->Add(m_sizer_main_left, 0, wxLEFT, FromDIP(18));
m_sizer_main->Add(m_sizer_main_right, 0, wxLEFT|wxEXPAND, FromDIP(4));
m_sizer_main->Layout();
m_sizer_body->Add(m_line_top, 0, wxEXPAND, 0);
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_body->Add(m_sizer_main, 0, wxEXPAND, 0);
SetSizer(m_sizer_body);
Layout();
Fit();
CentreOnParent(wxBOTH);
Move(wxPoint(GetScreenPosition().x, GetScreenPosition().y - FromDIP(50)));
wxGetApp().UpdateDlgDarkUI(this);
Bind(EVT_CHECK_IP_ADDRESS_FAILED, &InputIpAddressDialog::on_check_ip_address_failed, this);
Bind(EVT_CLOSE_IPADDRESS_DLG, [this](auto& e) {
m_status_bar->reset();
EndModal(wxID_YES);
});
Bind(wxEVT_CLOSE_WINDOW, [this](auto& e) {on_cancel();});
}
void InputIpAddressDialog::on_cancel()
{
if (m_send_job) {
if (m_send_job->is_running()) {
m_send_job->cancel();
m_send_job->join();
}
}
this->EndModal(wxID_CANCEL);
}
void InputIpAddressDialog::update_title(wxString title)
{
SetTitle(title);
}
void InputIpAddressDialog::set_machine_obj(MachineObject* obj)
{
m_obj = obj;
m_input_ip->GetTextCtrl()->SetLabelText(m_obj->dev_ip);
m_input_access_code->GetTextCtrl()->SetLabelText(m_obj->get_access_code());
if (m_obj->printer_type == "C11") {
m_img_help1->Hide();
m_img_help2->Show();
}
else if (m_obj->printer_type == "BL-P001" || m_obj->printer_type == "BL-P002") {
m_img_help1->Show();
m_img_help2->Hide();
}
Layout();
Fit();
}
void InputIpAddressDialog::update_error_msg(wxString msg)
{
if (msg.empty()) {
m_error_msg->Hide();
}
else {
m_error_msg->Show();
m_error_msg->SetLabelText(msg);
m_error_msg->SetMinSize(wxSize(FromDIP(352), -1));
m_error_msg->SetMaxSize(wxSize(FromDIP(352), -1));
m_error_msg->Wrap(FromDIP(352));
}
Layout();
Fit();
}
bool InputIpAddressDialog::isIp(std::string ipstr)
{
istringstream ipstream(ipstr);
int num[4];
char point[3];
string end;
ipstream >> num[0] >> point[0] >> num[1] >> point[1] >> num[2] >> point[2] >> num[3] >> end;
for (int i = 0; i < 3; ++i) {
if (num[i] < 0 || num[i]>255) return false;
if (point[i] != '.') return false;
}
if (num[3] < 0 || num[3]>255) return false;
if (!end.empty()) return false;
return true;
}
void InputIpAddressDialog::on_ok(wxMouseEvent& evt)
{
wxString ip = m_input_ip->GetTextCtrl()->GetValue();
wxString str_access_code = m_input_access_code->GetTextCtrl()->GetValue();
//check support function
if (!m_obj) return;
if (!m_obj->is_function_supported(PrinterFunction::FUNC_SEND_TO_SDCARD)) {
wxString input_str = wxString::Format("%s|%s", ip, str_access_code);
auto event = wxCommandEvent(EVT_ENTER_IP_ADDRESS);
event.SetString(input_str);
event.SetEventObject(this);
wxPostEvent(this, event);
auto event_close = wxCommandEvent(EVT_CLOSE_IPADDRESS_DLG);
event_close.SetEventObject(this);
wxPostEvent(this, event_close);
return;
}
m_button_ok->Enable(false);
m_button_ok->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
m_button_ok->SetBorderColor(wxColour(0x90, 0x90, 0x90));
if (m_send_job) {
m_send_job->join();
}
m_status_bar->reset();
m_status_bar->set_prog_block();
m_status_bar->set_cancel_callback_fina([this]() {
BOOST_LOG_TRIVIAL(info) << "print_job: enter canceled";
if (m_send_job) {
if (m_send_job->is_running()) {
BOOST_LOG_TRIVIAL(info) << "send_job: canceled";
m_send_job->cancel();
}
m_send_job->join();
}
});
m_send_job = std::make_shared<SendJob>(m_status_bar, wxGetApp().plater(), m_obj->dev_id);
m_send_job->m_dev_ip = ip.ToStdString();
m_send_job->m_access_code = str_access_code.ToStdString();
m_send_job->m_local_use_ssl = m_obj->local_use_ssl;
m_send_job->connection_type = m_obj->connection_type();
m_send_job->cloud_print_only = true;
m_send_job->has_sdcard = m_obj->has_sdcard();
m_send_job->set_check_mode();
m_send_job->set_project_name("verify_job");
m_send_job->on_check_ip_address_fail([this]() {
this->check_ip_address_failed();
});
m_send_job->on_check_ip_address_success([this, ip, str_access_code]() {
wxString input_str = wxString::Format("%s|%s", ip, str_access_code);
auto event = wxCommandEvent(EVT_ENTER_IP_ADDRESS);
event.SetString(input_str);
event.SetEventObject(this);
wxPostEvent(this, event);
auto event_close = wxCommandEvent(EVT_CLOSE_IPADDRESS_DLG);
event_close.SetEventObject(this);
wxPostEvent(this, event_close);
});
m_send_job->start();
}
void InputIpAddressDialog::check_ip_address_failed()
{
auto evt = new wxCommandEvent(EVT_CHECK_IP_ADDRESS_FAILED);
wxQueueEvent(this, evt);
}
void InputIpAddressDialog::on_check_ip_address_failed(wxCommandEvent& evt)
{
update_error_msg(_L("Error: IP or Access Code are not correct"));
m_button_ok->Enable(true);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
m_button_ok->SetTextColor(StateColor::darkModeColorFor("#FFFFFE"));
m_button_ok->SetBackgroundColor(btn_bg_green);
}
void InputIpAddressDialog::on_text(wxCommandEvent& evt)
{
auto str_ip = m_input_ip->GetTextCtrl()->GetValue();
auto str_access_code = m_input_access_code->GetTextCtrl()->GetValue();
if (isIp(str_ip.ToStdString()) && str_access_code.Length() == 8) {
m_button_ok->Enable(true);
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed), std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
m_button_ok->SetTextColor(StateColor::darkModeColorFor("#FFFFFE"));
m_button_ok->SetBackgroundColor(btn_bg_green);
}
else {
m_button_ok->Enable(false);
m_button_ok->SetBackgroundColor(wxColour(0x90, 0x90, 0x90));
m_button_ok->SetBorderColor(wxColour(0x90, 0x90, 0x90));
}
}
InputIpAddressDialog::~InputIpAddressDialog()
{
}
void InputIpAddressDialog::on_dpi_changed(const wxRect& suggested_rect)
{
}
}} // namespace Slic3r::GUI

View file

@ -122,6 +122,7 @@ public:
~SecondaryCheckDialog();
void on_dpi_changed(const wxRect& suggested_rect);
Label* m_staticText_release_note {nullptr};
wxBoxSizer* m_sizer_main;
wxScrolledWindow *m_vebview_release_note {nullptr};
Button* m_button_ok;
@ -160,6 +161,7 @@ public:
wxBoxSizer* m_sizer_main;
wxScrolledWindow* m_vebview_release_note{ nullptr };
wxStaticText* m_staticText_release_note{ nullptr };
Button* m_button_ok;
Button* m_button_cancel;
wxCheckBox* m_show_again_checkbox;
@ -167,6 +169,54 @@ public:
std::string show_again_config_text = "";
};
class InputIpAddressDialog : public DPIDialog
{
public:
wxString comfirm_before_enter_text;
wxString comfirm_after_enter_text;
std::string m_ip;
Label* m_tip1{ nullptr };
Label* m_tip2{ nullptr };
Label* m_tip3{ nullptr };
InputIpAddressDialog(wxWindow* parent = nullptr);
~InputIpAddressDialog();
MachineObject* m_obj{nullptr};
Button* m_button_ok{ nullptr };
Label* m_tips_ip{ nullptr };
Label* m_tips_access_code{ nullptr };
Label* m_error_msg{ nullptr };
TextInput* m_input_ip{ nullptr };
TextInput* m_input_access_code{ nullptr };
wxStaticBitmap* m_img_help1{ nullptr };
wxStaticBitmap* m_img_help2{ nullptr };
wxStaticBitmap* m_img_step1{ nullptr };
wxStaticBitmap* m_img_step2{ nullptr };
bool m_show_access_code{ false };
std::shared_ptr<SendJob> m_send_job{nullptr};
std::shared_ptr<BBLStatusBarSend> m_status_bar;
void on_cancel();
void update_title(wxString title);
void set_machine_obj(MachineObject* obj);
void update_error_msg(wxString msg);
bool isIp(std::string ipstr);
void check_ip_address_failed();
void on_check_ip_address_failed(wxCommandEvent& evt);
void on_ok(wxMouseEvent& evt);
void on_text(wxCommandEvent& evt);
void on_dpi_changed(const wxRect& suggested_rect) override;
};
wxDECLARE_EVENT(EVT_CLOSE_IPADDRESS_DLG, wxCommandEvent);
wxDECLARE_EVENT(EVT_CHECKBOX_CHANGE, wxCommandEvent);
wxDECLARE_EVENT(EVT_ENTER_IP_ADDRESS, wxCommandEvent);
wxDECLARE_EVENT(EVT_CHECK_IP_ADDRESS_FAILED, wxCommandEvent);
}} // namespace Slic3r::GUI
#endif

View file

@ -92,6 +92,8 @@ std::string get_print_status_info(PrintDialogStatus status)
return "PrintStatusNoSdcard";
case PrintStatusTimelapseNoSdcard:
return "PrintStatusTimelapseNoSdcard";
case PrintStatusNotSupportedPrintAll:
return "PrintStatusNotSupportedPrintAll";
}
return "unknown";
}
@ -1148,9 +1150,11 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
select_bed->Show(true);
select_flow->Show(true);
select_timelapse->Show(false);
select_timelapse->Show(true);
select_use_ams->Show(true);
m_sizer_select->Layout();
// line schedule
m_line_schedule = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_schedule->SetBackgroundColour(wxColour(238, 238, 238));
@ -1440,6 +1444,8 @@ void SelectMachineDialog::update_select_layout(MachineObject *obj)
} else {
select_timelapse->Hide();
}
m_sizer_select->Layout();
Fit();
}
@ -1885,6 +1891,11 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxSt
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
} else if (status == PrintDialogStatus::PrintStatusNotSupportedPrintAll) {
wxString msg_text = _L("This printer does not support printing all plates");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(false);
Enable_Refresh_Button(true);
}
}
@ -1963,13 +1974,13 @@ void SelectMachineDialog::show_errors(wxString &info)
void SelectMachineDialog::on_ok_btn(wxCommandEvent &event)
{
std::vector<wxString> confirm_text;
confirm_text.push_back(_L("Please check the following infomation and click Confirm to continue sending print:\n"));
confirm_text.push_back(_L("Please check the following infomation and click Confirm to continue sending print:") + "\n");
#if 0
//Check Printer Model Id
bool is_same_printer_type = is_same_printer_model();
if (!is_same_printer_type)
confirm_text.push_back(_L("The printer type used to generate G-code is not the same type as the currently selected physical printer. It is recommend to re-slice by selecting the same printer type.\n"));
confirm_text.push_back(_L("The printer type used to generate G-code is not the same type as the currently selected physical printer. It is recommend to re-slice by selecting the same printer type.") + "\n");
#else
bool is_same_printer_type = true;
#endif
@ -2146,7 +2157,8 @@ void SelectMachineDialog::on_ok()
m_print_job = std::make_shared<PrintJob>(m_status_bar, m_plater, m_printer_last_select);
m_print_job->m_dev_ip = obj_->dev_ip;
m_print_job->m_access_code = obj_->access_code;
m_print_job->m_access_code = obj_->get_access_code();
m_print_job->m_local_use_ssl = obj_->local_use_ssl;
m_print_job->connection_type = obj_->connection_type();
m_print_job->set_project_name(m_current_project_name.utf8_string());
@ -2627,6 +2639,12 @@ void SelectMachineDialog::update_show_status()
reset_timeout();
update_ams_check(obj_);
if (!obj_->is_function_supported(PrinterFunction::FUNC_PRINT_ALL) && m_print_plate_idx == PLATE_ALL_IDX) {
show_status(PrintDialogStatus::PrintStatusNotSupportedPrintAll);
return;
}
// do ams mapping if no ams result
if (obj_->has_ams() && m_ams_mapping_result.empty()) {
if (obj_->ams_support_use_ams) {

View file

@ -260,6 +260,7 @@ enum PrintDialogStatus {
PrintStatusNeedForceUpgrading,
PrintStatusNeedConsistencyUpgrading,
PrintStatusNotSupportedSendToSDCard,
PrintStatusNotSupportedPrintAll,
PrintStatusBlankPlate
};

View file

@ -30,6 +30,7 @@ namespace GUI {
wxDEFINE_EVENT(EVT_UPDATE_USER_MACHINE_LIST, wxCommandEvent);
wxDEFINE_EVENT(EVT_PRINT_JOB_CANCEL, wxCommandEvent);
wxDEFINE_EVENT(EVT_SEND_JOB_SUCCESS, wxCommandEvent);
wxDEFINE_EVENT(EVT_CLEAR_IPADDRESS, wxCommandEvent);
void SendToPrinterDialog::stripWhiteSpace(std::string& str)
@ -249,6 +250,7 @@ SendToPrinterDialog::SendToPrinterDialog(Plater *plater)
m_statictext_printer_msg = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
m_statictext_printer_msg->SetFont(::Label::Body_13);
m_statictext_printer_msg->SetForegroundColour(*wxBLACK);
m_statictext_printer_msg->Hide();
// line schedule
@ -336,6 +338,7 @@ SendToPrinterDialog::SendToPrinterDialog(Plater *plater)
rename_sizer_h = new wxBoxSizer(wxHORIZONTAL);
m_rename_text = new wxStaticText(m_rename_normal_panel, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0);
m_rename_text->SetForegroundColour(*wxBLACK);
m_rename_text->SetFont(::Label::Body_13);
m_rename_text->SetMaxSize(wxSize(FromDIP(390), -1));
m_rename_button = new Button(m_rename_normal_panel, "", "ams_editable", wxBORDER_NONE, FromDIP(10));
@ -531,6 +534,7 @@ void SendToPrinterDialog::init_model()
void SendToPrinterDialog::init_bind()
{
Bind(wxEVT_TIMER, &SendToPrinterDialog::on_timer, this);
Bind(EVT_CLEAR_IPADDRESS, &SendToPrinterDialog::clear_ip_address_config, this);
}
void SendToPrinterDialog::init_timer()
@ -645,18 +649,23 @@ void SendToPrinterDialog::on_ok(wxCommandEvent &event)
m_send_job = std::make_shared<SendJob>(m_status_bar, m_plater, m_printer_last_select);
m_send_job->m_dev_ip = obj_->dev_ip;
m_send_job->m_access_code = obj_->access_code;
m_send_job->m_access_code = obj_->get_access_code();
m_send_job->m_local_use_ssl = obj_->local_use_ssl;
m_send_job->connection_type = obj_->connection_type();
m_send_job->cloud_print_only = true;
m_send_job->has_sdcard = obj_->has_sdcard();
m_send_job->set_project_name(m_current_project_name.utf8_string());
/*m_send_job->on_check_ip_address_success([this, obj_]() {
wxCommandEvent* evt = new wxCommandEvent(EVT_CLEAR_IPADDRESS);
wxQueueEvent(this, evt);
});*/
m_send_job->on_success([this]() {
//enable_prepare_mode = true;enable_prepare_mode
m_status_bar->reset();
prepare_mode();
//EndModal(wxID_CLOSE);
m_send_job->on_check_ip_address_fail([this]() {
wxCommandEvent* evt = new wxCommandEvent(EVT_CLEAR_IPADDRESS);
wxQueueEvent(this, evt);
wxGetApp().show_ip_address_enter_dialog();
});
enable_prepare_mode = false;
@ -664,6 +673,20 @@ void SendToPrinterDialog::on_ok(wxCommandEvent &event)
BOOST_LOG_TRIVIAL(info) << "send_job: send print job";
}
void SendToPrinterDialog::clear_ip_address_config(wxCommandEvent& e)
{
enable_prepare_mode = true;
prepare_mode();
/*DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
if (!dev->get_selected_machine()) return;
auto obj = dev->get_selected_machine();
Slic3r::GUI::wxGetApp().app_config->set_str("ip_address", obj->dev_id, "");
Slic3r::GUI::wxGetApp().app_config->save();
wxGetApp().show_ip_address_enter_dialog();*/
}
void SendToPrinterDialog::update_user_machine_list()
{
NetworkAgent* m_agent = wxGetApp().getAgent();
@ -845,6 +868,17 @@ void SendToPrinterDialog::on_selection_changed(wxCommandEvent &event)
return;
}
//check ip address
if (obj->is_function_supported(PrinterFunction::FUNC_SEND_TO_SDCARD)) {
if (obj->dev_ip.empty() || obj->get_access_code().empty()) {
BOOST_LOG_TRIVIAL(info) << "MachineObject IP is empty ";
std::string app_config_dev_ip = Slic3r::GUI::wxGetApp().app_config->get("ip_address", obj->dev_id);
if (app_config_dev_ip.empty() || obj->get_access_code().empty()) {
wxGetApp().show_ip_address_enter_dialog();
}
}
}
update_show_status();
}

View file

@ -157,6 +157,7 @@ protected:
void update_printer_combobox(wxCommandEvent& event);
void on_cancel(wxCloseEvent& event);
void on_ok(wxCommandEvent& event);
void clear_ip_address_config(wxCommandEvent& e);
void on_refresh(wxCommandEvent& event);
void on_print_job_cancel(wxCommandEvent& evt);
void set_default();
@ -170,6 +171,7 @@ protected:
std::vector<std::string> sort_string(std::vector<std::string> strArray);
};
wxDECLARE_EVENT(EVT_CLEAR_IPADDRESS, wxCommandEvent);
}
}

View file

@ -506,10 +506,17 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent)
panel_button_block->SetSize(wxSize(TASK_BUTTON_SIZE.x * 2 + FromDIP(5) * 2, -1));
panel_button_block->SetBackgroundColour(*wxWHITE);
m_staticText_layers = new wxStaticText(penel_text, wxID_ANY, _L("Layers: N/A"));
m_staticText_layers->SetFont(wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC")));
m_staticText_layers->SetForegroundColour(wxColour(146, 146, 146));
m_staticText_layers->Hide();
//bSizer_text->Add(m_staticText_progress_percent, 0, wxALL, 0);
bSizer_text->Add(sizer_percent, 0, wxEXPAND, 0);
bSizer_text->Add(sizer_percent_icon, 0, wxEXPAND, 0);
bSizer_text->Add(0, 0, 1, wxEXPAND, 0);
bSizer_text->Add(m_staticText_layers, 0, wxALIGN_CENTER | wxALL, 0);
bSizer_text->Add(0, 0, 0, wxLEFT, FromDIP(20));
bSizer_text->Add(m_staticText_progress_left, 0, wxALIGN_CENTER | wxALL, 0);
penel_text->SetMaxSize(wxSize(FromDIP(600), -1));
@ -645,27 +652,31 @@ wxBoxSizer *StatusBasePanel::create_temp_axis_group(wxWindow *parent)
box->SetBorderColor(box_border_colour);
box->SetCornerRadius(5);
box->SetMinSize(wxSize(FromDIP(530), -1));
box->SetMaxSize(wxSize(FromDIP(530), -1));
box->SetMinSize(wxSize(FromDIP(578), -1));
box->SetMaxSize(wxSize(FromDIP(578), -1));
wxBoxSizer *content_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_temp_ctrl = create_temp_control(box);
content_sizer->Add(m_temp_ctrl, 0, wxEXPAND | wxALL, FromDIP(5));
m_temp_extruder_line = new StaticLine(box, true);
m_temp_extruder_line->SetLineColour(STATIC_BOX_LINE_COL);
content_sizer->Add(m_temp_extruder_line, 0, wxEXPAND, 1);
content_sizer->Add(FromDIP(9), 0, 0, wxEXPAND, 1);
auto m_axis_sizer = create_axis_control(box);
content_sizer->Add(m_axis_sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
wxBoxSizer *bed_sizer = create_bed_control(box);
content_sizer->Add(bed_sizer, 0, wxEXPAND | wxLEFT | wxTOP| wxBOTTOM, FromDIP(12));
content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(12));
wxBoxSizer *extruder_sizer = create_extruder_control(box);
content_sizer->Add(m_temp_ctrl, 0, wxEXPAND | wxALL, FromDIP(5));
content_sizer->Add(m_temp_extruder_line, 0, wxEXPAND, 1);
content_sizer->Add(FromDIP(9), 0, 0, wxEXPAND, 1);
content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18));
content_sizer->Add(m_axis_sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18));
content_sizer->Add(bed_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, FromDIP(12));
content_sizer->Add(0, 0, 0, wxLEFT, FromDIP(18));
content_sizer->Add(extruder_sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(12));
box->SetSizer(content_sizer);
@ -745,6 +756,7 @@ wxBoxSizer *StatusBasePanel::create_misc_control(wxWindow *parent)
m_switch_speed = new ImageSwitchButton(parent, m_bitmap_speed_active, m_bitmap_speed);
m_switch_speed->SetLabels(_L("100%"), _L("100%"));
m_switch_speed->SetMinSize(MISC_BUTTON_SIZE);
m_switch_speed->SetMaxSize(MISC_BUTTON_SIZE);
m_switch_speed->SetPadding(FromDIP(3));
m_switch_speed->SetBorderWidth(FromDIP(2));
m_switch_speed->SetFont(Label::Head_13);
@ -761,6 +773,7 @@ wxBoxSizer *StatusBasePanel::create_misc_control(wxWindow *parent)
m_switch_lamp = new ImageSwitchButton(parent, m_bitmap_lamp_on, m_bitmap_lamp_off);
m_switch_lamp->SetLabels(_L("Lamp"), _L("Lamp"));
m_switch_lamp->SetMinSize(MISC_BUTTON_SIZE);
m_switch_lamp->SetMaxSize(MISC_BUTTON_SIZE);
m_switch_lamp->SetPadding(FromDIP(3));
m_switch_lamp->SetBorderWidth(FromDIP(2));
m_switch_lamp->SetFont(Label::Head_13);
@ -997,7 +1010,6 @@ wxBoxSizer *StatusBasePanel::create_extruder_control(wxWindow *parent)
bSizer_e_ctrl->Add(0, 0, 1, wxEXPAND, 0);
bSizer_e_ctrl->Add(m_button_unload, 0, wxALIGN_CENTER_HORIZONTAL| wxTOP|wxBOTTOM, FromDIP(5));
bSizer_e_ctrl->Add(0, FromDIP(9), 0, wxEXPAND, 0);
m_staticText_e = new wxStaticText(panel, wxID_ANY, _L("Extruder"), wxDefaultPosition, wxDefaultSize, 0);
@ -1027,7 +1039,7 @@ wxBoxSizer *StatusBasePanel::create_ams_group(wxWindow *parent)
m_ams_control_box->SetBorderColor(box_border_colour);
m_ams_control_box->SetCornerRadius(5);
m_ams_control_box->SetMinSize(wxSize(FromDIP(530), -1));
m_ams_control_box->SetMinSize(wxSize(FromDIP(578), -1));
m_ams_control_box->SetBackgroundColour(*wxWHITE);
#if !BBL_RELEASE_TO_PUBLIC
m_ams_debug = new wxStaticText(m_ams_control_box, wxID_ANY, _L("Debug Info"), wxDefaultPosition, wxDefaultSize, 0);
@ -1048,11 +1060,13 @@ wxBoxSizer *StatusBasePanel::create_ams_group(wxWindow *parent)
return sizer;
}
void StatusBasePanel::show_ams_group(bool show)
void StatusBasePanel::show_ams_group(bool show, bool support_virtual_tray)
{
m_ams_control->Show(true);
m_ams_control_box->Show(true);
m_ams_control->show_noams_mode(show, support_virtual_tray);
if (m_show_ams_group != show) {
m_ams_control->Show(show);
m_ams_control_box->Show(show);
Fit();
}
m_show_ams_group = show;
@ -1143,7 +1157,7 @@ void StatusPanel::update_camera_state(MachineObject* obj)
StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
: StatusBasePanel(parent, id, pos, size, style)
, m_fan_control_popup(FanControlPopup(this))
, m_fan_control_popup(new FanControlPopup(this))
{
create_tasklist_info();
update_tasklist_info();
@ -1213,12 +1227,14 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co
m_bpButton_e_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_up_10), NULL, this);
m_bpButton_e_down_10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_axis_ctrl_e_down_10), NULL, this);
m_button_unload->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_unload), NULL, this);
Bind(EVT_AMS_EXTRUSION_CALI, &StatusPanel::on_filament_extrusion_cali, this);
Bind(EVT_AMS_LOAD, &StatusPanel::on_ams_load, this);
Bind(EVT_AMS_UNLOAD, &StatusPanel::on_ams_unload, this);
Bind(EVT_AMS_SETTINGS, &StatusPanel::on_ams_setting_click, this);
Bind(EVT_AMS_REFRESH_RFID, &StatusPanel::on_ams_refresh_rfid, this);
Bind(EVT_AMS_ON_SELECTED, &StatusPanel::on_ams_selected, this);
Bind(EVT_AMS_ON_FILAMENT_EDIT, &StatusPanel::on_filament_edit, this);
Bind(EVT_VAMS_ON_FILAMENT_EDIT, &StatusPanel::on_ext_spool_edit, this);
Bind(EVT_AMS_GUIDE_WIKI, &StatusPanel::on_ams_guide, this);
Bind(EVT_AMS_RETRY, &StatusPanel::on_ams_retry, this);
Bind(EVT_FAN_CHANGED, &StatusPanel::on_fan_changed, this);
@ -1282,7 +1298,7 @@ void StatusPanel::init_scaled_buttons()
//m_button_abort->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
//m_button_abort->SetCornerRadius(FromDIP(12));
m_button_clean->SetMinSize(wxSize(FromDIP(48), FromDIP(24)));
m_button_clean->SetCornerRadius(FromDIP(12));
m_button_clean->SetCornerRadius(FromDIP(12));
m_button_unload->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_unload->SetCornerRadius(FromDIP(12));
m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE);
@ -1455,6 +1471,15 @@ void StatusPanel::update(MachineObject *obj)
update_cali(obj);
if (obj) {
// update extrusion calibration
if (obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) {
if (m_extrusion_cali_dlg) {
m_extrusion_cali_dlg->update_machine_obj(obj);
m_extrusion_cali_dlg->update();
}
}
// update calibration status
if (calibration_dlg == nullptr) {
calibration_dlg = new CalibrationDialog();
calibration_dlg->update_machine_obj(obj);
@ -1737,7 +1762,9 @@ void StatusPanel::update_misc_ctrl(MachineObject *obj)
int speed = round(obj->cooling_fan_speed / float(25.5));
m_switch_nozzle_fan->SetValue(speed > 0 ? true : false);
m_switch_nozzle_fan->setFanValue(speed * 10);
m_fan_control_popup.update_fan_data(MachineObject::FanType::COOLING_FAN, obj);
if (m_fan_control_popup) {
m_fan_control_popup->update_fan_data(MachineObject::FanType::COOLING_FAN, obj);
}
}
// printing fan
@ -1747,7 +1774,9 @@ void StatusPanel::update_misc_ctrl(MachineObject *obj)
int speed = round(obj->big_fan1_speed / float(25.5));
m_switch_printing_fan->SetValue(speed > 0 ? true : false);
m_switch_printing_fan->setFanValue(speed * 10);
m_fan_control_popup.update_fan_data(MachineObject::FanType::BIG_COOLING_FAN, obj);
if (m_fan_control_popup) {
m_fan_control_popup->update_fan_data(MachineObject::FanType::BIG_COOLING_FAN, obj);
}
}
// cham fan
@ -1757,7 +1786,9 @@ void StatusPanel::update_misc_ctrl(MachineObject *obj)
int speed = round(obj->big_fan2_speed / float(25.5));
m_switch_cham_fan->SetValue(speed > 0 ? true : false);
m_switch_cham_fan->setFanValue(speed * 10);
m_fan_control_popup.update_fan_data(MachineObject::FanType::CHAMBER_FAN, obj);
if (m_fan_control_popup) {
m_fan_control_popup->update_fan_data(MachineObject::FanType::CHAMBER_FAN, obj);
}
}
bool light_on = obj->chamber_light != MachineObject::LIGHT_EFFECT::LIGHT_EFFECT_OFF;
@ -1817,64 +1848,64 @@ void StatusPanel::update_ams(MachineObject *obj)
}
if (m_filament_setting_dlg) { m_filament_setting_dlg->obj = obj; }
if (!obj || !obj->is_connected()) {
last_tray_exist_bits = -1;
last_ams_exist_bits = -1;
last_tray_is_bbl_bits = -1;
last_read_done_bits = -1;
last_reading_bits = -1;
last_ams_version = -1;
m_ams_control->EnterNoneAMSMode();
show_ams_group(false);
BOOST_LOG_TRIVIAL(trace) << "machine object" << obj->dev_name << " was disconnected, set show_ams_group is false";
return;
}
if (obj->amsList.empty() || obj->ams_exist_bits == 0) {
m_ams_control->EnterNoneAMSMode();
show_ams_group(false);
BOOST_LOG_TRIVIAL(trace) << "machine object" << obj->dev_name << " ams nonexistent, set show_ams_group is false";
return;
} else {
show_ams_group(true);
if (m_filament_setting_dlg) m_filament_setting_dlg->update();
std::vector<AMSinfo> ams_info;
for (auto ams = obj->amsList.begin(); ams != obj->amsList.end(); ams++) {
AMSinfo info;
info.ams_id = ams->first;
if (ams->second->is_exists && info.parse_ams_info(ams->second, obj->ams_calibrate_remain_flag, obj->is_support_ams_humidity)) ams_info.push_back(info);
if (!obj
|| !obj->is_connected()
|| obj->amsList.empty()
|| obj->ams_exist_bits == 0) {
if (!obj || !obj->is_connected()) {
last_tray_exist_bits = -1;
last_ams_exist_bits = -1;
last_tray_is_bbl_bits = -1;
last_read_done_bits = -1;
last_reading_bits = -1;
last_ams_version = -1;
BOOST_LOG_TRIVIAL(trace) << "machine object" << obj->dev_name << " was disconnected, set show_ams_group is false";
}
//if (obj->ams_exist_bits != last_ams_exist_bits || obj->tray_exist_bits != last_tray_exist_bits || obj->tray_is_bbl_bits != last_tray_is_bbl_bits ||
// obj->tray_read_done_bits != last_read_done_bits || obj->ams_version != last_ams_version) {
// m_ams_control->UpdateAms(ams_info, false);
// // select current ams
// //if (!obj->m_ams_id.empty()) m_ams_control->SwitchAms(obj->m_ams_id);
bool is_support_extrusion_cali = obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI);
if (is_support_extrusion_cali) {
m_ams_control->update_vams_kn_value(obj->vt_tray);
}
show_ams_group(false, obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI));
return;
}
// last_tray_exist_bits = obj->tray_exist_bits;
// last_ams_exist_bits = obj->ams_exist_bits;
// last_tray_is_bbl_bits = obj->tray_is_bbl_bits;
// last_read_done_bits = obj->tray_read_done_bits;
// last_ams_version = obj->ams_version;
//}
bool is_support_extrusion_cali = obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI);
if (is_support_extrusion_cali) {
m_ams_control->update_vams_kn_value(obj->vt_tray);
}
show_ams_group(true, obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI));
if (m_filament_setting_dlg) m_filament_setting_dlg->update();
std::vector<AMSinfo> ams_info;
for (auto ams = obj->amsList.begin(); ams != obj->amsList.end(); ams++) {
AMSinfo info;
info.ams_id = ams->first;
if (ams->second->is_exists && info.parse_ams_info(ams->second, obj->ams_calibrate_remain_flag, obj->is_support_ams_humidity)) ams_info.push_back(info);
}
//if (obj->ams_exist_bits != last_ams_exist_bits || obj->tray_exist_bits != last_tray_exist_bits || obj->tray_is_bbl_bits != last_tray_is_bbl_bits ||
// obj->tray_read_done_bits != last_read_done_bits || obj->ams_version != last_ams_version) {
// m_ams_control->UpdateAms(ams_info, false);
// // select current ams
// //if (!obj->m_ams_id.empty()) m_ams_control->SwitchAms(obj->m_ams_id);
// last_tray_exist_bits = obj->tray_exist_bits;
// last_ams_exist_bits = obj->ams_exist_bits;
// last_tray_is_bbl_bits = obj->tray_is_bbl_bits;
// last_read_done_bits = obj->tray_read_done_bits;
// last_ams_version = obj->ams_version;
//}
// select current ams
// if (!obj->m_ams_id.empty()) m_ams_control->SwitchAms(obj->m_ams_id);
// must select a current can
m_ams_control->UpdateAms(ams_info, false, is_support_extrusion_cali);
m_ams_control->UpdateAms(ams_info, false);
last_tray_exist_bits = obj->tray_exist_bits;
last_ams_exist_bits = obj->ams_exist_bits;
last_tray_is_bbl_bits = obj->tray_is_bbl_bits;
last_read_done_bits = obj->tray_read_done_bits;
last_reading_bits = obj->tray_reading_bits;
last_ams_version = obj->ams_version;
}
if (!obj->is_ams_unload()) {
; // TODO set filament step to load
} else {
; // TODO set filament step to unload
}
last_tray_exist_bits = obj->tray_exist_bits;
last_ams_exist_bits = obj->ams_exist_bits;
last_tray_is_bbl_bits = obj->tray_is_bbl_bits;
last_read_done_bits = obj->tray_read_done_bits;
last_reading_bits = obj->tray_reading_bits;
last_ams_version = obj->ams_version;
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id);
@ -1976,20 +2007,33 @@ void StatusPanel::update_ams(MachineObject *obj)
}
} catch (...) {}
}
// update rfid button style
update_ams_control_state(curr_ams_id, is_support_extrusion_cali);
}
void StatusPanel::update_ams_control_state(std::string ams_id, bool is_support_virtual_tray)
{
// update load/unload enable state
if (obj->is_in_printing() && !obj->can_resume()) {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING);
} else {
if (obj->is_in_extrusion_cali()) {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_CALI, is_support_virtual_tray);
}
else if (!obj->has_ams()) {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_NOAMS, is_support_virtual_tray);
}
else if (obj->is_in_printing() && !obj->can_resume()) {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING, is_support_virtual_tray);
}
else {
if (obj->ams_status_main != AMS_STATUS_MAIN_FILAMENT_CHANGE) {
if (obj->m_tray_now == "255") {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_LOAD);
} else {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_NORMAL);
m_ams_control->SetActionState(AMSAction::AMS_ACTION_LOAD, is_support_virtual_tray);
}
} else {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING);
else {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_NORMAL, is_support_virtual_tray);
}
}
else {
m_ams_control->SetActionState(AMSAction::AMS_ACTION_PRINTING, is_support_virtual_tray);
}
}
}
@ -2074,6 +2118,13 @@ void StatusPanel::update_subtask(MachineObject *obj)
{
if (!obj) return;
if (obj->is_support_layer_num) {
m_staticText_layers->Show();
}
else {
m_staticText_layers->Hide();
}
if (obj->is_system_printing()
|| obj->is_in_calibration()) {
reset_printing_values();
@ -2099,7 +2150,7 @@ void StatusPanel::update_subtask(MachineObject *obj)
m_staticText_progress_percent->SetLabelText(NA_STR);
m_staticText_progress_percent_icon->SetLabelText(wxEmptyString);
m_staticText_progress_left->SetLabel(NA_STR);
m_staticText_progress_left->SetLabelText(NA_STR);
m_staticText_layers->SetLabelText(wxString::Format(_L("Layers: %s"), NA_STR));
wxString subtask_text = wxString::Format("%s", GUI::from_u8(obj->subtask_name));
m_staticText_subtask_value->SetLabelText(subtask_text);
update_basic_print_data(false);
@ -2128,10 +2179,13 @@ void StatusPanel::update_subtask(MachineObject *obj)
m_gauge_progress->SetValue(obj->subtask_->task_progress);
m_staticText_progress_percent->SetLabelText(wxString::Format("%d", obj->subtask_->task_progress));
m_staticText_progress_percent_icon->SetLabelText("%");
m_staticText_layers->SetLabelText(wxString::Format(_L("Layers: %d/%d"), obj->curr_layer, obj->total_layers));
} else {
m_gauge_progress->SetValue(0);
m_staticText_progress_percent->SetLabelText(NA_STR);
m_staticText_progress_percent_icon->SetLabelText(wxEmptyString);
m_staticText_layers->SetLabelText(wxString::Format(_L("Layers: %s"), NA_STR));
}
}
wxString subtask_text = wxString::Format("%s", GUI::from_u8(obj->subtask_name));
@ -2209,6 +2263,7 @@ void StatusPanel::reset_printing_values()
update_basic_print_data(false);
m_printing_stage_value->SetLabelText("");
m_staticText_progress_left->SetLabelText(NA_STR);
m_staticText_layers->SetLabelText(wxString::Format(_L("Layers: %s"), NA_STR));
m_staticText_progress_percent->SetLabelText(NA_STR);
m_staticText_progress_percent_icon->SetLabelText(wxEmptyString);
m_bitmap_thumbnail->SetBitmap(m_thumbnail_placeholder.bmp());
@ -2443,12 +2498,72 @@ void StatusPanel::on_ams_setting_click(SimpleEvent &event)
m_ams_setting_dlg->update_insert_material_read_mode(obj->ams_insert_flag);
m_ams_setting_dlg->update_starting_read_mode(obj->ams_power_on_flag);
std::string ams_id = m_ams_control->GetCurentAms();
if (ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) {
wxString txt = _L("AMS settings are not supported for external spool");
MessageDialog msg_dlg(nullptr, txt, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
} else {
try {
int ams_id_int = atoi(ams_id.c_str());
m_ams_setting_dlg->ams_id = ams_id_int;
m_ams_setting_dlg->ams_support_remain = obj->ams_support_remain;
m_ams_setting_dlg->Show();
}
catch (...) {
;
}
}
}
}
void StatusPanel::on_filament_extrusion_cali(wxCommandEvent &event)
{
if (!m_extrusion_cali_dlg)
m_extrusion_cali_dlg = new ExtrusionCalibration((wxWindow*)this, wxID_ANY);
if (obj) {
m_extrusion_cali_dlg->obj = obj;
std::string ams_id = m_ams_control->GetCurentAms();
std::string tray_id = m_ams_control->GetCurrentCan(ams_id);
if (tray_id.empty() && ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) != 0) {
wxString txt = _L("Please select an AMS slot before calibration");
MessageDialog msg_dlg(nullptr, txt, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
int ams_id_int = 0;
int tray_id_int = 0;
// set ams_filament id is is bbl filament
if (ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) {
tray_id_int = VIRTUAL_TRAY_ID;
m_extrusion_cali_dlg->ams_filament_id = "";
}
else {
ams_id_int = atoi(ams_id.c_str());
tray_id_int = atoi(tray_id.c_str());
auto it = obj->amsList.find(ams_id);
if (it != obj->amsList.end()) {
auto tray_it = it->second->trayList.find(tray_id);
if (tray_it != it->second->trayList.end()) {
if (MachineObject::is_bbl_filament(tray_it->second->tag_uid))
m_extrusion_cali_dlg->ams_filament_id = tray_it->second->setting_id;
else
m_extrusion_cali_dlg->ams_filament_id = "";
}
}
}
try {
int ams_id_int = atoi(ams_id.c_str());
m_ams_setting_dlg->ams_id = ams_id_int;
m_ams_setting_dlg->ams_support_remain = obj->ams_support_remain;
m_ams_setting_dlg->Show();
} catch (...) {
m_extrusion_cali_dlg->ams_id = ams_id_int;
m_extrusion_cali_dlg->tray_id = tray_id_int;
m_extrusion_cali_dlg->SetPosition(m_staticText_control->GetScreenPosition());
m_extrusion_cali_dlg->Popup();
} catch(...) {
;
}
}
@ -2461,36 +2576,77 @@ void StatusPanel::on_filament_edit(wxCommandEvent &event)
if (obj) {
m_filament_setting_dlg->obj = obj;
std::string ams_id = m_ams_control->GetCurentAms();
std::string tray_id = event.GetString().ToStdString(); // m_ams_control->GetCurrentCan(ams_id);
try {
int ams_id_int = atoi(ams_id.c_str());
int tray_id_int = atoi(tray_id.c_str());
m_filament_setting_dlg->ams_id = ams_id_int;
int ams_id_int = 0;
int tray_id_int = 0;
if (ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) {
tray_id_int = VIRTUAL_TRAY_ID;
m_filament_setting_dlg->ams_id = ams_id_int;
m_filament_setting_dlg->tray_id = tray_id_int;
m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition());
wxString k_val;
wxString n_val;
k_val = wxString::Format("%.3f", obj->vt_tray.k);
n_val = wxString::Format("%.3f", obj->vt_tray.n);
m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition());
m_filament_setting_dlg->Popup(wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString, k_val, n_val);
} else {
std::string tray_id = event.GetString().ToStdString(); // m_ams_control->GetCurrentCan(ams_id);
try {
ams_id_int = atoi(ams_id.c_str());
tray_id_int = atoi(tray_id.c_str());
m_filament_setting_dlg->ams_id = ams_id_int;
m_filament_setting_dlg->tray_id = tray_id_int;
std::string sn_number;
std::string filament;
std::string temp_max;
std::string temp_min;
auto it = obj->amsList.find(ams_id);
if (it != obj->amsList.end()) {
auto tray_it = it->second->trayList.find(tray_id);
if (tray_it != it->second->trayList.end()) {
wxColor color = AmsTray::decode_color(tray_it->second->color);
m_filament_setting_dlg->set_color(color);
m_filament_setting_dlg->ams_filament_id = tray_it->second->setting_id;
m_filament_setting_dlg->m_is_third = !MachineObject::is_bbl_filament(tray_it->second->tag_uid);
if (!m_filament_setting_dlg->m_is_third) {
sn_number = tray_it->second->uuid;
filament = tray_it->second->sub_brands;
temp_max = tray_it->second->nozzle_temp_max;
temp_min = tray_it->second->nozzle_temp_min;
std::string sn_number;
std::string filament;
std::string temp_max;
std::string temp_min;
wxString k_val;
wxString n_val;
auto it = obj->amsList.find(ams_id);
if (it != obj->amsList.end()) {
auto tray_it = it->second->trayList.find(tray_id);
if (tray_it != it->second->trayList.end()) {
k_val = wxString::Format("%.3f", tray_it->second->k);
n_val = wxString::Format("%.3f", tray_it->second->n);
wxColor color = AmsTray::decode_color(tray_it->second->color);
m_filament_setting_dlg->set_color(color);
m_filament_setting_dlg->ams_filament_id = tray_it->second->setting_id;
m_filament_setting_dlg->m_is_third = !MachineObject::is_bbl_filament(tray_it->second->tag_uid);
if (!m_filament_setting_dlg->m_is_third) {
sn_number = tray_it->second->uuid;
filament = tray_it->second->sub_brands;
temp_max = tray_it->second->nozzle_temp_max;
temp_min = tray_it->second->nozzle_temp_min;
}
}
}
m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition());
m_filament_setting_dlg->Popup(filament, sn_number, temp_min, temp_max, k_val, n_val);
}
catch (...) {
;
}
}
}
}
void StatusPanel::on_ext_spool_edit(wxCommandEvent &event)
{
// update params
if (!m_filament_setting_dlg) m_filament_setting_dlg = new AMSMaterialsSetting((wxWindow*)this, wxID_ANY);
if (obj) {
m_filament_setting_dlg->obj = obj;
try {
m_filament_setting_dlg->tray_id = VIRTUAL_TRAY_ID;
wxString k_val;
wxString n_val;
k_val = wxString::Format("%.3f", obj->vt_tray.k);
n_val = wxString::Format("%.3f", obj->vt_tray.n);
m_filament_setting_dlg->SetPosition(m_ams_control->GetScreenPosition());
m_filament_setting_dlg->Popup(filament, sn_number, temp_min, temp_max);
} catch (...) {
m_filament_setting_dlg->Popup(wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString, k_val, n_val);
}
catch (...) {
;
}
}
@ -2511,6 +2667,10 @@ void StatusPanel::on_ams_refresh_rfid(wxCommandEvent &event)
}
std::string curr_ams_id = m_ams_control->GetCurentAms();
// do not support refresh rfid for VIRTUAL_TRAY_ID
if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) {
return;
}
std::string curr_can_id = event.GetString().ToStdString();
std::map<std::string, Ams *>::iterator it = obj->amsList.find(curr_ams_id);
@ -2537,27 +2697,31 @@ void StatusPanel::on_ams_selected(wxCommandEvent &event)
{
if (obj) {
std::string curr_ams_id = m_ams_control->GetCurentAms();
std::string curr_can_id = event.GetString().ToStdString();
std::map<std::string, Ams *>::iterator it = obj->amsList.find(curr_ams_id);
if (it == obj->amsList.end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
if (curr_ams_id.compare(std::to_string(VIRTUAL_TRAY_ID)) == 0) {
update_ams_control_state(curr_ams_id, true);
return;
} else {
std::string curr_can_id = event.GetString().ToStdString();
std::map<std::string, Ams *>::iterator it = obj->amsList.find(curr_ams_id);
if (it == obj->amsList.end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_ams_id << " failed";
return;
}
auto tray_it = it->second->trayList.find(curr_can_id);
if (tray_it == it->second->trayList.end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_can_id << " failed";
return;
}
try {
int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str());
obj->command_ams_select_tray(std::to_string(tray_index));
} catch (...) {
;
}
update_ams_control_state(curr_ams_id, obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI));
}
auto tray_it = it->second->trayList.find(curr_can_id);
if (tray_it == it->second->trayList.end()) {
BOOST_LOG_TRIVIAL(trace) << "ams: find " << curr_can_id << " failed";
return;
}
try {
int tray_index = atoi(curr_ams_id.c_str()) * 4 + atoi(tray_it->second->id.c_str());
obj->command_ams_select_tray(std::to_string(tray_index));
} catch (...) {
;
}
}
}
void StatusPanel::on_ams_guide(wxCommandEvent& event)
@ -2698,10 +2862,28 @@ void StatusPanel::on_printing_fan_switch(wxCommandEvent &event)
void StatusPanel::on_nozzle_fan_switch(wxCommandEvent &event)
{
m_fan_control_popup->Destroy();
m_fan_control_popup = new FanControlPopup(this);
auto pos = m_switch_nozzle_fan->GetScreenPosition();
pos.y = pos.y + m_switch_nozzle_fan->GetSize().y;
m_fan_control_popup.SetPosition(pos);
m_fan_control_popup.Popup();
int display_idx = wxDisplay::GetFromWindow(this);
auto display = wxDisplay(display_idx).GetClientArea();
wxSize screenSize = wxSize(display.GetWidth(), display.GetHeight());
auto fan_popup_size = m_fan_control_popup->GetSize();
if (screenSize.y - fan_popup_size.y < FromDIP(300)) {
pos.x += FromDIP(50);
pos.y = (screenSize.y - fan_popup_size.y) / 2;
}
m_fan_control_popup->SetPosition(pos);
m_fan_control_popup->Popup();

View file

@ -19,6 +19,7 @@
#include "Calibration.hpp"
#include "PrintOptionsDialog.hpp"
#include "AMSMaterialsSetting.hpp"
#include "ExtrusionCalibration.hpp"
#include "ReleaseNote.hpp"
#include "Widgets/SwitchButton.hpp"
#include "Widgets/AxisCtrlButton.hpp"
@ -137,6 +138,7 @@ protected:
wxStaticText * m_staticText_progress_percent;
wxStaticText * m_staticText_progress_percent_icon;
wxStaticText * m_staticText_progress_left;
wxStaticText * m_staticText_layers;
Button * m_button_report;
ScalableButton *m_button_pause_resume;
ScalableButton *m_button_abort;
@ -250,7 +252,7 @@ public:
wxBoxSizer *create_ams_group(wxWindow *parent);
wxBoxSizer *create_settings_group(wxWindow *parent);
void show_ams_group(bool show = true);
void show_ams_group(bool show = true, bool support_virtual_tray = true);
};
@ -268,11 +270,14 @@ protected:
PrintOptionsDialog* print_options_dlg { nullptr };
CalibrationDialog* calibration_dlg {nullptr};
AMSMaterialsSetting *m_filament_setting_dlg{nullptr};
SecondaryCheckDialog* m_print_error_dlg = nullptr;
SecondaryCheckDialog* abort_dlg = nullptr;
SecondaryCheckDialog* ctrl_e_hint_dlg = nullptr;
SecondaryCheckDialog* sdcard_hint_dlg = nullptr;
FanControlPopup m_fan_control_popup{nullptr};
FanControlPopup* m_fan_control_popup{nullptr};
ExtrusionCalibration *m_extrusion_cali_dlg{nullptr};
wxString m_request_url;
bool m_start_loading_thumbnail = false;
@ -334,6 +339,8 @@ protected:
void on_ams_unload(SimpleEvent &event);
void on_ams_setting_click(SimpleEvent &event);
void on_filament_edit(wxCommandEvent &event);
void on_ext_spool_edit(wxCommandEvent &event);
void on_filament_extrusion_cali(wxCommandEvent &event);
void on_ams_refresh_rfid(wxCommandEvent &event);
void on_ams_selected(wxCommandEvent &event);
void on_ams_guide(wxCommandEvent &event);
@ -372,6 +379,7 @@ protected:
void update_misc_ctrl(MachineObject *obj);
void update_ams(MachineObject* obj);
void update_extruder_status(MachineObject* obj);
void update_ams_control_state(std::string ams_id, bool is_support_virtual_tray);
void update_cali(MachineObject* obj);
void reset_printing_values();

View file

@ -1497,7 +1497,8 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
void Tab::show_timelapse_warning_dialog() {
if (!m_is_timelapse_wipe_tower_already_prompted) {
wxString msg_text = _(L("When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n"
"by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\".\n"));
"by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\"."));
msg_text += "\n";
MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK);
dialog.ShowModal();
m_is_timelapse_wipe_tower_already_prompted = true;
@ -1964,6 +1965,7 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Raft"), L"param_raft");
optgroup->append_single_option_line("raft_layers");
optgroup->append_single_option_line("raft_contact_distance");
optgroup->append_single_option_line("raft_first_layer_density");
optgroup->append_single_option_line("raft_first_layer_expansion");
@ -2602,7 +2604,7 @@ void TabFilament::build()
DynamicPrintConfig& filament_config = wxGetApp().preset_bundle->filaments.get_edited_preset().config;
update_dirty();
if (opt_key == "cool_plate_temp" || opt_key == "cool_plate_temp_initial_layer") {
/*if (opt_key == "cool_plate_temp" || opt_key == "cool_plate_temp_initial_layer") {
m_config_manipulation.check_bed_temperature_difference(BedType::btPC, &filament_config);
}
else if (opt_key == "eng_plate_temp" || opt_key == "eng_plate_temp_initial_layer") {
@ -2614,7 +2616,7 @@ void TabFilament::build()
else if (opt_key == "textured_plate_temp" || opt_key == "textured_plate_temp_initial_layer") {
m_config_manipulation.check_bed_temperature_difference(BedType::btPTE, &filament_config);
}
else if (opt_key == "nozzle_temperature") {
else */if (opt_key == "nozzle_temperature") {
m_config_manipulation.check_nozzle_temperature_range(&filament_config);
}
else if (opt_key == "nozzle_temperature_initial_layer") {

View file

@ -24,16 +24,20 @@ static wxString FILAMENT_LOAD_STEP_STRING[LOAD_STEP_COUNT] = {
static wxString FILAMENT_UNLOAD_STEP_STRING[UNLOAD_STEP_COUNT] = {_L("Heat the nozzle"), _L("Cut filament"), _L("Pull back current filament")};
wxDEFINE_EVENT(EVT_AMS_EXTRUSION_CALI, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_LOAD, SimpleEvent);
wxDEFINE_EVENT(EVT_AMS_UNLOAD, SimpleEvent);
wxDEFINE_EVENT(EVT_AMS_SETTINGS, SimpleEvent);
wxDEFINE_EVENT(EVT_AMS_REFRESH_RFID, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_ON_SELECTED, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_ON_FILAMENT_EDIT, wxCommandEvent);
wxDEFINE_EVENT(EVT_VAMS_ON_FILAMENT_EDIT, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_CLIBRATION_AGAIN, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_CLIBRATION_CANCEL, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_GUIDE_WIKI, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_RETRY, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_SHOW_HUMIDITY_TIPS, wxCommandEvent);
wxDEFINE_EVENT(EVT_AMS_UNSELETED_VAMS, wxCommandEvent);
bool AMSinfo::parse_ams_info(Ams *ams, bool remain_flag, bool humidity_flag)
{
@ -69,11 +73,10 @@ bool AMSinfo::parse_ams_info(Ams *ams, bool remain_flag, bool humidity_flag)
info.material_state = AMSCanType::AMS_CAN_TYPE_THIRDBRAND;
}
if (!remain_flag) {
if (!MachineObject::is_bbl_filament(it->second->tag_uid) || !remain_flag) {
info.material_remain = 100;
}
else {
info.material_remain = it->second->remain < 0 ? 100 : it->second->remain;
} else {
info.material_remain = it->second->remain < 0 ? 0 : it->second->remain;
info.material_remain = it->second->remain > 100 ? 100 : info.material_remain;
}
@ -85,6 +88,10 @@ bool AMSinfo::parse_ams_info(Ams *ams, bool remain_flag, bool humidity_flag)
info.material_state = AMSCanType::AMS_CAN_TYPE_THIRDBRAND;
wxColour(255, 255, 255);
}
info.k = it->second->k;
info.n = it->second->n;
} else {
info.can_id = i;
info.material_state = AMSCanType::AMS_CAN_TYPE_EMPTY;
@ -477,14 +484,24 @@ void AMSLib::on_left_down(wxMouseEvent &evt)
if (m_info.material_state != AMSCanType::AMS_CAN_TYPE_EMPTY && m_info.material_state != AMSCanType::AMS_CAN_TYPE_NONE) {
auto size = GetSize();
auto pos = evt.GetPosition();
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND) {
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND ||
m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL) {
auto left = FromDIP(20);
auto top = (size.y - FromDIP(10) - m_bitmap_editable_light.GetBmpSize().y);
auto right = size.x - FromDIP(20);
auto bottom = size.y - FromDIP(10);
if (pos.x >= left && pos.x <= right && pos.y >= top && top <= bottom) {
post_event(wxCommandEvent(EVT_AMS_ON_FILAMENT_EDIT));
if (m_selected) {
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL) {
post_event(wxCommandEvent(EVT_VAMS_ON_FILAMENT_EDIT));
}
else {
post_event(wxCommandEvent(EVT_AMS_ON_FILAMENT_EDIT));
}
} else {
BOOST_LOG_TRIVIAL(trace) << "current amslib is not selected";
}
}
}
}
@ -539,10 +556,17 @@ void AMSLib::render(wxDC &dc)
dc.SetTextForeground(temp_text_colour);
auto libsize = GetSize();
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND) {
if (m_info.material_name.empty()) {
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND
|| m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND
|| m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL) {
if (m_info.material_name.empty() && m_info.material_state != AMSCanType::AMS_CAN_TYPE_VIRTUAL) {
auto tsize = dc.GetMultiLineTextExtent("?");
auto pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3));
auto pot = wxPoint(0, 0);
if (m_show_kn) {
pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(9));
} else {
pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3));
}
dc.DrawText(L("?"), pot);
} else {
auto tsize = dc.GetMultiLineTextExtent(m_info.material_name);
@ -563,10 +587,28 @@ void AMSLib::render(wxDC &dc)
dc.DrawText(line_bottom, pot_bottom);
} else {
auto pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3));
auto pot = wxPoint(0, 0);
if (m_show_kn) {
pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(9));
} else {
pot = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 + FromDIP(3));
}
dc.DrawText(m_info.material_name, pot);
}
}
//draw k&n
if (m_show_kn) {
wxString str_k = wxString::Format("K %1.3f", m_info.k);
wxString str_n = wxString::Format("N %1.3f", m_info.n);
dc.SetFont(::Label::Body_11);
auto tsize = dc.GetMultiLineTextExtent(str_k);
auto pot_k = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(9) + tsize.y);
dc.DrawText(str_k, pot_k);
//auto pot_n = wxPoint((libsize.x - tsize.x) / 2, (libsize.y - tsize.y) / 2 - FromDIP(18) + tsize.y * 2);
//dc.DrawText(str_n, pot_n);
}
}
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_EMPTY) {
@ -711,7 +753,7 @@ void AMSLib::doRender(wxDC &dc)
// edit icon
if (m_info.material_state != AMSCanType::AMS_CAN_TYPE_EMPTY && m_info.material_state != AMSCanType::AMS_CAN_TYPE_NONE)
{
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND)
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL)
dc.DrawBitmap(temp_bitmap_third.bmp(), (size.x - temp_bitmap_third.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap_third.GetBmpSize().y));
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND)
dc.DrawBitmap(temp_bitmap_brand.bmp(), (size.x - temp_bitmap_brand.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap_brand.GetBmpSize().y));
@ -757,7 +799,8 @@ bool AMSLib::Enable(bool enable) { return wxWindow::Enable(enable); }
Description:AMSRoad
**************************************************/
AMSRoad::AMSRoad() : m_road_def_color(AMS_CONTROL_GRAY500), m_road_color(AMS_CONTROL_GRAY500) {}
AMSRoad::AMSRoad(wxWindow *parent, wxWindowID id, Caninfo info, int canindex, int maxcan, const wxPoint &pos, const wxSize &size) : AMSRoad()
AMSRoad::AMSRoad(wxWindow *parent, wxWindowID id, Caninfo info, int canindex, int maxcan, const wxPoint &pos, const wxSize &size)
: AMSRoad()
{
m_info = info;
m_canindex = canindex;
@ -772,6 +815,9 @@ AMSRoad::AMSRoad(wxWindow *parent, wxWindowID id, Caninfo info, int canindex, in
} else if (m_canindex == (maxcan - 1)) {
m_rode_mode = AMSRoadMode::AMS_ROAD_MODE_LEFT;
}
else {
m_rode_mode = AMSRoadMode::AMS_ROAD_MODE_NONE_ANY_ROAD;
}
ams_humidity_0 = ScalableBitmap(this, "ams_humidity_0", 18);
ams_humidity_1 = ScalableBitmap(this, "ams_humidity_1", 18);
@ -782,6 +828,19 @@ AMSRoad::AMSRoad(wxWindow *parent, wxWindowID id, Caninfo info, int canindex, in
create(parent, id, pos, size);
Bind(wxEVT_PAINT, &AMSRoad::paintEvent, this);
wxWindow::SetBackgroundColour(AMS_CONTROL_DEF_BLOCK_BK_COLOUR);
Bind(wxEVT_MOTION, [this](wxMouseEvent& e) {
if (m_canindex == 3 && m_show_humidity) {
auto mouse_pos = ClientToScreen(e.GetPosition());
auto rect = ClientToScreen(wxPoint(0, 0));
if (mouse_pos.x > rect.x + GetSize().x - FromDIP(20) &&
mouse_pos.y > rect.y + GetSize().y - FromDIP(40)) {
wxCommandEvent event(EVT_AMS_SHOW_HUMIDITY_TIPS);
wxPostEvent(GetParent()->GetParent(), event);
}
}
});
}
void AMSRoad::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) { wxWindow::Create(parent, id, pos, size); }
@ -908,6 +967,10 @@ void AMSRoad::doRender(wxDC &dc)
}
if (m_canindex == 3) {
if (m_amsinfo.ams_humidity >= 1 && m_amsinfo.ams_humidity <= 5) {m_show_humidity = true;}
else {m_show_humidity = false;}
if (m_amsinfo.ams_humidity == 5) {
dc.DrawBitmap(ams_humidity_4.bmp(), wxPoint(size.x - ams_humidity_4.GetBmpSize().x - FromDIP(4), size.y - ams_humidity_4.GetBmpSize().y - FromDIP(8)));
}
@ -915,6 +978,7 @@ void AMSRoad::doRender(wxDC &dc)
dc.DrawBitmap(ams_humidity_3.bmp(), wxPoint(size.x - ams_humidity_3.GetBmpSize().x - FromDIP(4), size.y - ams_humidity_3.GetBmpSize().y - FromDIP(8)));
}
else if (m_amsinfo.ams_humidity == 3) {
dc.DrawBitmap(ams_humidity_2.bmp(), wxPoint(size.x - ams_humidity_2.GetBmpSize().x - FromDIP(4), size.y - ams_humidity_2.GetBmpSize().y - FromDIP(8)));
}
else if (m_amsinfo.ams_humidity == 2) {
@ -1240,6 +1304,9 @@ void AmsCans::AddCan(Caninfo caninfo, int canindex, int maxcan)
for (auto i = 0; i < m_can_lib_list.GetCount(); i++) {
CanLibs *lib = m_can_lib_list[i];
if (lib->canLib->m_can_index == m_canlib_selection) {
wxCommandEvent evt(EVT_AMS_UNSELETED_VAMS);
evt.SetString(m_info.ams_id);
wxPostEvent(GetParent()->GetParent(), evt);
lib->canLib->OnSelected();
} else {
lib->canLib->UnSelected();
@ -1275,6 +1342,18 @@ void AmsCans::AddCan(Caninfo caninfo, int canindex, int maxcan)
m_can_road_list.Add(canroad);
}
void AmsCans::SetDefSelectCan()
{
if (m_can_lib_list.GetCount() > 0) {
CanLibs* lib = m_can_lib_list[0];
m_canlib_selection =lib->canLib->m_can_index;
m_canlib_id = lib->canLib->m_info.can_id;
SelectCan(m_canlib_id);
}
}
void AmsCans::SelectCan(std::string canid)
{
for (auto i = 0; i < m_can_lib_list.GetCount(); i++) {
@ -1287,6 +1366,9 @@ void AmsCans::SelectCan(std::string canid)
for (auto i = 0; i < m_can_lib_list.GetCount(); i++) {
CanLibs *lib = m_can_lib_list[i];
if (lib->canLib->m_info.can_id == m_canlib_id) {
wxCommandEvent evt(EVT_AMS_UNSELETED_VAMS);
evt.SetString(m_info.ams_id);
wxPostEvent(GetParent()->GetParent(), evt);
lib->canLib->OnSelected();
} else {
lib->canLib->UnSelected();
@ -1400,6 +1482,14 @@ void AmsCans::msw_rescale()
}
}
void AmsCans::show_sn_value(bool show)
{
for (auto i = 0; i < m_can_lib_list.GetCount(); i++) {
CanLibs* lib = m_can_lib_list[i];
lib->canLib->show_kn_value(show);
}
}
//wxColour AmsCans::GetCanColour(wxString canid)
//{
// wxColour col = *wxWHITE;
@ -1414,7 +1504,10 @@ void AmsCans::msw_rescale()
Description:AMSControl
**************************************************/
// WX_DEFINE_OBJARRAY(AmsItemsHash);
AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) : wxSimplebook(parent, wxID_ANY, pos, size)
AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size)
: wxSimplebook(parent, wxID_ANY, pos, size)
, m_Humidity_tip_popup(AmsHumidityTipPopup(this))
, m_ams_introduce_popup(AmsIntroducePopup(this))
{
SetBackgroundColour(*wxWHITE);
// normal mode
@ -1450,6 +1543,28 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizer_left = new wxBoxSizer(wxVERTICAL);
m_sizer_ams_tips = new wxBoxSizer(wxHORIZONTAL);
auto m_ams_tip = new wxStaticText(m_amswin, wxID_ANY, _L("AMS"));
m_ams_tip->SetFont(::Label::Body_12);
m_ams_tip->SetBackgroundColour(*wxWHITE);
auto img_amsmapping_tip = new wxStaticBitmap(m_amswin, wxID_ANY, create_scaled_bitmap("enable_ams", this, 16), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)), 0);
img_amsmapping_tip->SetBackgroundColour(*wxWHITE);
m_sizer_ams_tips->Add(m_ams_tip, 0, wxALIGN_CENTER, 0);
m_sizer_ams_tips->Add(img_amsmapping_tip, 0, wxALL, FromDIP(2));
img_amsmapping_tip->Bind(wxEVT_ENTER_WINDOW, [this, img_amsmapping_tip](auto& e) {
wxPoint img_pos = img_amsmapping_tip->ClientToScreen(wxPoint(0, 0));
wxPoint popup_pos(img_pos.x, img_pos.y + img_amsmapping_tip->GetRect().height);
m_ams_introduce_popup.set_mode(true);
m_ams_introduce_popup.Position(popup_pos, wxSize(0, 0));
m_ams_introduce_popup.Popup();
});
img_amsmapping_tip->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) {
m_ams_introduce_popup.Dismiss();
});
m_panel_can = new StaticBox(m_amswin, wxID_ANY, wxDefaultPosition, AMS_CANS_SIZE, wxBORDER_NONE);
m_panel_can->SetMinSize(AMS_CANS_SIZE);
m_panel_can->SetCornerRadius(FromDIP(10));
@ -1468,11 +1583,25 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
// none ams mode
m_none_ams_panel = new wxPanel(m_simplebook_ams, wxID_ANY, wxDefaultPosition, AMS_CANS_WINDOW_SIZE, 0);
m_none_ams_panel->SetBackgroundColour(AMS_CONTROL_DEF_BLOCK_BK_COLOUR);
m_none_ams_panel->SetDoubleBuffered(true);
//m_none_ams_panel->SetDoubleBuffered(true);
wxBoxSizer *sizer_ams_panel = new wxBoxSizer(wxHORIZONTAL);
AMSinfo none_ams = AMSinfo{"0", std::vector<Caninfo>{Caninfo{"0", wxEmptyString, *wxWHITE, AMSCanType::AMS_CAN_TYPE_EMPTY}}};
auto amscans = new AmsCans(m_none_ams_panel, wxID_ANY, none_ams);
auto m_tip_none_ams = new wxStaticText(m_none_ams_panel, wxID_ANY, _L("AMS not connected"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL);
m_tip_none_ams->SetMinSize(wxSize(AMS_CANS_SIZE.x - FromDIP(20), -1));
m_tip_none_ams->SetFont(::Label::Head_16);
m_tip_none_ams->SetForegroundColour(AMS_CONTROL_DISABLE_COLOUR);
wxBoxSizer *sizer_ams_panel_v = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizer_ams_panel_h = new wxBoxSizer(wxHORIZONTAL);
sizer_ams_panel_v->Add(m_tip_none_ams, 0, wxALIGN_CENTER, 0);
sizer_ams_panel_h->Add(sizer_ams_panel_v, 0, wxALIGN_CENTER, 0);
m_none_ams_panel->SetSizer(sizer_ams_panel_h);
m_none_ams_panel->Layout();
/*wxBoxSizer *sizer_ams_panel = new wxBoxSizer(wxHORIZONTAL);
AMSinfo none_ams = AMSinfo{ "0", std::vector<Caninfo>{Caninfo{"0", wxEmptyString, *wxWHITE, AMSCanType::AMS_CAN_TYPE_EMPTY}} };
auto amscans = new AmsCans(m_none_ams_panel, wxID_ANY, none_ams);
sizer_ams_panel->Add(amscans, 0, wxALL, 0);
sizer_ams_panel->Add(0, 0, 0, wxLEFT, 20);
auto m_tip_none_ams = new wxStaticText(m_none_ams_panel, wxID_ANY, _L("Click the pencil icon to edit the filament."), wxDefaultPosition, wxDefaultSize, 0);
@ -1482,7 +1611,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
m_tip_none_ams->SetMinSize({150, -1});
sizer_ams_panel->Add(m_tip_none_ams, 0, wxALIGN_CENTER, 0);
m_none_ams_panel->SetSizer(sizer_ams_panel);
m_none_ams_panel->Layout();
m_none_ams_panel->Layout();*/
m_simplebook_ams->AddPage(m_simplebook_cans, wxEmptyString, true);
m_simplebook_ams->AddPage(m_none_ams_panel, wxEmptyString, false);
@ -1491,6 +1620,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
m_panel_can->Layout();
m_sizer_cans->Fit(m_panel_can);
m_sizer_left->Add(m_sizer_ams_tips, 0, wxALIGN_CENTER, 0);
m_sizer_left->Add(m_panel_can, 1, wxEXPAND, 0);
wxBoxSizer *m_sizer_left_bottom = new wxBoxSizer(wxHORIZONTAL);
@ -1506,8 +1636,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
m_sizer_left_bottom->Add(extruder_pane, 0, wxLEFT, FromDIP(10));
m_sizer_left_bottom->Add(0, 0, 0, wxEXPAND, 0);
m_sizer_left_bottom->Add(0, 0, 0, wxALL | wxLEFT, FromDIP(26));
//m_sizer_left_bottom->Add(0, 0, 0, wxEXPAND, 0);
StateColor btn_bg_green(std::pair<wxColour, int>(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled),std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed), std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal));
@ -1519,25 +1648,130 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
StateColor btn_bd_green(std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Enabled));
StateColor btn_bd_white(std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
StateColor btn_text_green(std::pair<wxColour, int>(*wxBLACK, StateColor::Disabled), std::pair<wxColour, int>(AMS_CONTROL_WHITE_COLOUR, StateColor::Enabled));
m_sizer_left_bottom->AddStretchSpacer();
m_button_extruder_feed = new Button(m_amswin, _L("Load Filament"));
//m_sizer_left_bottom->AddStretchSpacer();
m_button_area = new wxWindow(m_amswin, wxID_ANY);
m_button_area->SetBackgroundColour(m_amswin->GetBackgroundColour());
wxBoxSizer *m_sizer_button_area = new wxBoxSizer(wxHORIZONTAL);
m_button_extrusion_cali = new Button(m_button_area, _L("Cali"));
m_button_extrusion_cali->SetToolTip(_L("Calibration of extrusion"));
m_button_extrusion_cali->SetBackgroundColor(btn_bg_green);
m_button_extrusion_cali->SetBorderColor(btn_bd_green);
m_button_extrusion_cali->SetTextColor(btn_text_green);
m_button_extrusion_cali->SetFont(Label::Body_13);
m_button_extruder_feed = new Button(m_button_area, _L("Load Filament"));
m_button_extruder_feed->SetBackgroundColor(btn_bg_green);
m_button_extruder_feed->SetBorderColor(btn_bd_green);
m_button_extruder_feed->SetTextColor(wxColour("#FFFFFE"));
m_button_extruder_feed->SetFont(Label::Body_13);
m_button_extruder_back = new Button(m_amswin, _L("Unload Filament"));
m_button_extruder_back = new Button(m_button_area, _L("Unload Filament"));
m_button_extruder_back->SetBackgroundColor(btn_bg_white);
m_button_extruder_back->SetBorderColor(btn_bd_white);
m_button_extruder_back->SetFont(Label::Body_13);
m_sizer_left_bottom->Add(m_button_extruder_feed, 0, wxTOP, FromDIP(20));
m_sizer_left_bottom->Add(0, 0, 0, wxALL | wxLEFT, FromDIP(10));
m_sizer_left_bottom->Add(m_button_extruder_back, 0, wxTOP, FromDIP(20));
m_sizer_button_area->Add(0, 0, 1, wxEXPAND, 0);
m_sizer_button_area->Add(m_button_extrusion_cali, 0, wxLEFT, FromDIP(5));
m_sizer_button_area->Add(m_button_extruder_back, 0, wxLEFT, FromDIP(6));
m_sizer_button_area->Add(m_button_extruder_feed, 0, wxLEFT, FromDIP(6));
m_button_area->SetSizer(m_sizer_button_area);
m_button_area->Layout();
m_button_area->Fit();
m_sizer_left_bottom->Add(0, 0, 1, wxEXPAND, 0);
m_sizer_left_bottom->Add(m_button_area, 0, wxEXPAND | wxTOP, FromDIP(18));
m_sizer_left->Add(m_sizer_left_bottom, 0, wxEXPAND, 0);
//virtual ams
m_panel_virtual = new StaticBox(m_amswin, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
m_panel_virtual->SetBackgroundColor(StateColor(std::pair<wxColour, int>(AMS_CONTROL_DEF_BLOCK_BK_COLOUR, StateColor::Normal)));
m_panel_virtual->SetMinSize(wxSize(AMS_CAN_LIB_SIZE.x + FromDIP(16), AMS_CANS_SIZE.y));
m_panel_virtual->SetMaxSize(wxSize(AMS_CAN_LIB_SIZE.x + FromDIP(16), AMS_CANS_SIZE.y));
m_vams_info.material_state = AMSCanType::AMS_CAN_TYPE_VIRTUAL;
m_vams_info.can_id = wxString::Format("%d", VIRTUAL_TRAY_ID).ToStdString();
auto vams_panel = new wxWindow(m_panel_virtual, wxID_ANY);
vams_panel->SetBackgroundColour(AMS_CONTROL_DEF_BLOCK_BK_COLOUR);
//m_vams_refresh = new AMSrefresh(vams_panel, wxID_ANY, 0, m_vams_info);
m_vams_lib = new AMSLib(vams_panel, wxID_ANY, m_vams_info);
m_vams_road = new AMSRoad(vams_panel, wxID_ANY, m_vams_info, -1, -1, wxDefaultPosition, AMS_CAN_ROAD_SIZE);
m_vams_lib->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
//clear all selected
m_current_ams = m_vams_info.can_id;
m_vams_lib->OnSelected();
SwitchAms(m_current_ams);
for (auto i = 0; i < m_ams_cans_list.GetCount(); i++) {
AmsCansWindow* cans = m_ams_cans_list[i];
cans->amsCans->SelectCan(m_current_ams);
}
e.Skip();
});
Bind(EVT_AMS_UNSELETED_VAMS, [this](wxCommandEvent& e) {
m_current_ams = e.GetString().ToStdString();
SwitchAms(m_current_ams);
m_vams_lib->UnSelected();
e.Skip();
});
wxBoxSizer* m_sizer_vams = new wxBoxSizer(wxVERTICAL);
m_sizer_vams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(14));
//m_sizer_vams->Add(m_vams_refresh, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_sizer_vams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(2) + AMS_REFRESH_SIZE.y);
m_sizer_vams->Add(m_vams_lib, 1, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(4));
m_sizer_vams->Add(m_vams_road, 0, wxALL, 0);
vams_panel->SetSizer(m_sizer_vams);
vams_panel->Layout();
vams_panel->Fit();
wxBoxSizer* m_sizer_vams_panel = new wxBoxSizer(wxVERTICAL);
m_sizer_vams_panel->Add(vams_panel, 0, wxALIGN_CENTER_HORIZONTAL, 0);
m_panel_virtual->SetSizer(m_sizer_vams_panel);
m_panel_virtual->Layout();
m_panel_virtual->Fit();
//virtual ams
m_vams_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer_vams_tips = new wxBoxSizer(wxHORIZONTAL);
auto m_vams_tip = new wxStaticText(m_amswin, wxID_ANY, _L("Ext Spool"));
m_vams_tip->SetFont(::Label::Body_12);
m_vams_tip->SetBackgroundColour(*wxWHITE);
auto img_vams_tip = new wxStaticBitmap(m_amswin, wxID_ANY, create_scaled_bitmap("enable_ams", this, 16), wxDefaultPosition, wxSize(FromDIP(16), FromDIP(16)), 0);
img_vams_tip->SetBackgroundColour(*wxWHITE);
img_vams_tip->Bind(wxEVT_ENTER_WINDOW, [this, img_vams_tip](auto& e) {
wxPoint img_pos = img_vams_tip->ClientToScreen(wxPoint(0, 0));
wxPoint popup_pos(img_pos.x, img_pos.y + img_vams_tip->GetRect().height);
m_ams_introduce_popup.set_mode(false);
m_ams_introduce_popup.Position(popup_pos, wxSize(0, 0));
m_ams_introduce_popup.Popup();
});
img_vams_tip->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) {
m_ams_introduce_popup.Dismiss();
});
m_sizer_vams_tips->Add(m_vams_tip, 0, wxALIGN_CENTER, 0);
m_sizer_vams_tips->Add(img_vams_tip, 0, wxALL, FromDIP(2));
m_vams_sizer->Add(m_sizer_vams_tips, 0, wxALIGN_CENTER, 0);
m_vams_sizer->Add(m_panel_virtual, 0, wxALIGN_CENTER, 0);
m_sizer_bottom->Add(m_vams_sizer, 0, wxEXPAND, 0);
m_sizer_bottom->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(10));
m_sizer_bottom->Add(m_sizer_left, 0, wxEXPAND, 0);
m_sizer_bottom->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(43));
m_sizer_bottom->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(23));
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxVERTICAL);
m_simplebook_right = new wxSimplebook(m_amswin, wxID_ANY);
@ -1606,7 +1840,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
m_sizer_body->Add(m_simplebook_amsitems, 0, wxEXPAND, 0);
m_sizer_body->Add(0, 0, 1, wxEXPAND | wxTOP, FromDIP(18));
m_sizer_body->Add(m_sizer_bottom, 0, wxEXPAND | wxLEFT, FromDIP(11));
m_sizer_body->Add(m_sizer_bottom, 0, wxEXPAND | wxLEFT, FromDIP(6));
init_scaled_buttons();
m_amswin->SetSizer(m_sizer_body);
@ -1689,22 +1923,31 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
UpdateStepCtrl();
m_button_extrusion_cali->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_extrusion_cali), NULL, this);
m_button_extruder_feed->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_filament_load), NULL, this);
m_button_extruder_back->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AMSControl::on_filament_unload), NULL, this);
m_button_ams_setting->Bind(wxEVT_LEFT_DOWN, &AMSControl::on_ams_setting_click, this);
m_button_ams_setting->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& e) {
m_button_ams_setting->SetBitmap(m_button_ams_setting_hover.bmp());
e.Skip();
});
});
m_button_ams_setting->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
m_button_ams_setting->SetBitmap(m_button_ams_setting_press.bmp());
on_ams_setting_click(e);
e.Skip();
});
});
m_button_ams_setting->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& e) {
m_button_ams_setting->SetBitmap(m_button_ams_setting_normal.bmp());
e.Skip();
});
});
Bind(EVT_AMS_SHOW_HUMIDITY_TIPS, [this](wxCommandEvent& evt) {
wxPoint img_pos = ClientToScreen(wxPoint(0, 0));
wxPoint popup_pos(img_pos.x, img_pos.y + GetRect().height);
m_Humidity_tip_popup.Position(popup_pos, wxSize(0, 0));
m_Humidity_tip_popup.Popup();
});
m_button_guide->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
@ -1721,6 +1964,8 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
void AMSControl::init_scaled_buttons()
{
m_button_extrusion_cali->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extrusion_cali->SetCornerRadius(FromDIP(12));
m_button_extruder_feed->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extruder_feed->SetCornerRadius(FromDIP(12));
m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24)));
@ -1764,44 +2009,86 @@ wxColour AMSControl::GetCanColour(std::string amsid, std::string canid)
return col;
}
void AMSControl::SetActionState(AMSAction action)
void AMSControl::SetActionState(AMSAction action, bool support_virtual_tray)
{
m_button_area->Layout();
m_button_area->Fit();
switch (action) {
case Slic3r::GUI::AMSAction::AMS_ACTION_NONE: break;
case Slic3r::GUI::AMSAction::AMS_ACTION_LOAD:
m_button_extrusion_cali->Enable();
m_button_extruder_feed->Enable();
m_button_extruder_back->Disable();
break;
case Slic3r::GUI::AMSAction::AMS_ACTION_UNLOAD:
m_button_extrusion_cali->Enable();
m_button_extruder_feed->Disable();
m_button_extruder_back->Enable();
break;
case Slic3r::GUI::AMSAction::AMS_ACTION_PRINTING:
m_button_extrusion_cali->Disable();
m_button_extruder_feed->Disable();
m_button_extruder_back->Disable();
break;
case Slic3r::GUI::AMSAction::AMS_ACTION_NORMAL:
m_button_extrusion_cali->Enable();
m_button_extruder_feed->Enable();
m_button_extruder_back->Enable();
break;
case Slic3r::GUI::AMSAction::AMS_ACTION_CALI:
m_button_extrusion_cali->Enable();
m_button_extruder_feed->Disable();
m_button_extruder_back->Disable();
break;
case Slic3r::GUI::AMSAction::AMS_ACTION_NOAMS:
if (support_virtual_tray)
m_button_extrusion_cali->Enable();
else
m_button_extrusion_cali->Disable();
m_button_extruder_feed->Disable();
m_button_extruder_back->Disable();
break;
default: break;
}
}
void AMSControl::EnterNoneAMSMode()
{
m_simplebook_amsitems->Hide();
m_panel_top->Hide();
m_simplebook_amsitems->SetSelection(1);
m_simplebook_ams->SetSelection(1);
m_extruder->Hide();
m_button_ams_setting->Hide();
m_button_guide->Hide();
m_button_retry->Hide();
m_button_extruder_feed->Hide();
m_button_extruder_back->Hide();
ShowFilamentTip(false);
m_amswin->Layout();
m_amswin->Fit();
Layout();
m_is_none_ams_mode = true;
}
void AMSControl::ExitNoneAMSMode()
{
m_simplebook_amsitems->Show();
m_panel_top->Show();
m_simplebook_ams->SetSelection(0);
m_simplebook_amsitems->SetSelection(0);
m_extruder->Show();
m_button_ams_setting->Show();
m_button_guide->Show();
m_button_retry->Show();
m_button_extruder_feed->Show();
m_button_extruder_back->Show();
ShowFilamentTip(true);
m_amswin->Layout();
m_amswin->Fit();
Layout();
m_is_none_ams_mode = false;
}
void AMSControl::EnterCalibrationMode(bool read_to_calibration)
@ -1857,8 +2144,9 @@ void AMSControl::msw_rescale()
m_button_ams_setting->SetBitmap(m_button_ams_setting_normal.bmp());
m_extruder->msw_rescale();
m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extrusion_cali->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extruder_feed->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_extruder_back->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_ams_setting->SetMinSize(wxSize(FromDIP(25), FromDIP(24)));
m_button_guide->SetMinSize(wxSize(-1, FromDIP(24)));
m_button_retry->SetMinSize(wxSize(-1, FromDIP(24)));
@ -1916,12 +2204,56 @@ void AMSControl::Reset()
m_current_senect = "";
}
void AMSControl::show_noams_mode(bool show, bool support_virtual_tray)
{
show_vams(support_virtual_tray);
m_sizer_ams_tips->Show(support_virtual_tray);
if (!support_virtual_tray)
m_button_extrusion_cali->Hide();
else {
m_button_extrusion_cali->Show();
}
void AMSControl::UpdateAms(std::vector<AMSinfo> info, bool keep_selection)
show?ExitNoneAMSMode() : EnterNoneAMSMode();
}
void AMSControl::show_vams(bool show)
{
m_panel_virtual->Show(show);
m_vams_sizer->Show(show);
show_vams_kn_value(show);
Layout();
if (show && m_is_none_ams_mode) {
if (m_current_ams == "") {
wxMouseEvent event(wxEVT_LEFT_DOWN);
event.SetEventObject(m_vams_lib);
wxPostEvent(m_vams_lib, event);
}
}
}
void AMSControl::show_vams_kn_value(bool show)
{
m_vams_lib->show_kn_value(show);
}
void AMSControl::update_vams_kn_value(AmsTray tray)
{
m_vams_info.k = tray.k;
m_vams_info.n = tray.n;
m_vams_lib->m_info.k = tray.k;
m_vams_lib->m_info.n = tray.n;
m_vams_lib->Refresh();
}
void AMSControl::UpdateAms(std::vector<AMSinfo> info, bool keep_selection, bool has_extrusion_cali)
{
std::string curr_ams_id = GetCurentAms();
std::string curr_can_id = GetCurrentCan(curr_ams_id);
if (info.size() > 0) ExitNoneAMSMode();
m_button_area->Layout();
m_button_area->Fit();
// update item
m_ams_info = info;
@ -1956,6 +2288,7 @@ void AMSControl::UpdateAms(std::vector<AMSinfo> info, bool keep_selection)
if (i < info.size()) {
cans->amsCans->m_info = m_ams_info[i];
cans->amsCans->Update(m_ams_info[i]);
cans->amsCans->show_sn_value(has_extrusion_cali);
}
}
@ -2016,6 +2349,16 @@ void AMSControl::SwitchAms(std::string ams_id)
if (item->amsItem->m_amsinfo.ams_id == ams_id) {
item->amsItem->OnSelected();
//item->amsItem->ShowHumidity();
if (m_current_ams == std::to_string(VIRTUAL_TRAY_ID)) {
for (auto i = 0; i < m_ams_cans_list.GetCount(); i++) {
AmsCansWindow* ams = m_ams_cans_list[i];
if (ams->amsCans->m_info.ams_id == ams_id) {
ams->amsCans->SetDefSelectCan();
}
}
}
m_current_senect = ams_id;
} else {
item->amsItem->UnSelected();
@ -2107,8 +2450,9 @@ bool AMSControl::Enable(bool enable)
AmsCansWindow *cans = m_ams_cans_list[i];
cans->amsCans->Enable(enable);
}
m_button_extruder_back->Enable(enable);
m_button_extrusion_cali->Enable(enable);
m_button_extruder_feed->Enable(enable);
m_button_extruder_back->Enable(enable);
m_button_ams_setting->Enable(enable);
m_filament_load_step->Enable(enable);
@ -2162,7 +2506,7 @@ void AMSControl::SetAmsStep(std::string ams_id, std::string canid, AMSPassRoadTy
}
if (type == AMSPassRoadType::AMS_ROAD_TYPE_LOAD) {
SetActionState(AMSAction::AMS_ACTION_LOAD);
SetActionState(AMSAction::AMS_ACTION_LOAD);
}
if (type == AMSPassRoadType::AMS_ROAD_TYPE_UNLOAD) {
@ -2179,6 +2523,14 @@ void AMSControl::on_filament_load(wxCommandEvent &event)
post_event(SimpleEvent(EVT_AMS_LOAD));
}
void AMSControl::on_extrusion_cali(wxCommandEvent &event)
{
for (auto i = 0; i < m_ams_info.size(); i++) {
if (m_ams_info[i].ams_id == m_current_ams) { m_ams_info[i].current_action = AMSAction::AMS_ACTION_CALI; }
}
post_event(SimpleEvent(EVT_AMS_EXTRUSION_CALI));
}
void AMSControl::on_filament_unload(wxCommandEvent &event)
{
m_button_extruder_feed->Disable();
@ -2190,6 +2542,9 @@ void AMSControl::on_filament_unload(wxCommandEvent &event)
void AMSControl::on_ams_setting_click(wxMouseEvent &event)
{
for (auto i = 0; i < m_ams_info.size(); i++) {
if (m_ams_info[i].ams_id == m_current_ams) { m_ams_info[i].current_action = AMSAction::AMS_ACTION_CALI; }
}
post_event(SimpleEvent(EVT_AMS_SETTINGS));
}

View file

@ -7,6 +7,7 @@
#include "Button.hpp"
#include "../DeviceManager.hpp"
#include "slic3r/GUI/Event.hpp"
#include "slic3r/GUI/AmsMappingPopup.hpp"
#include <wx/simplebook.h>
#include <wx/hyperlink.h>
#include <wx/animate.h>
@ -40,6 +41,7 @@ enum class AMSRoadMode : int {
AMS_ROAD_MODE_END,
AMS_ROAD_MODE_END_ONLY,
AMS_ROAD_MODE_NONE,
AMS_ROAD_MODE_NONE_ANY_ROAD,
};
enum class AMSPassRoadMode : int {
@ -55,8 +57,10 @@ enum class AMSAction : int {
AMS_ACTION_NONE,
AMS_ACTION_LOAD,
AMS_ACTION_UNLOAD,
AMS_ACTION_CALI,
AMS_ACTION_PRINTING,
AMS_ACTION_NORMAL,
AMS_ACTION_NOAMS,
};
enum class AMSPassRoadSTEP : int {
@ -81,6 +85,7 @@ enum class AMSCanType : int {
AMS_CAN_TYPE_BRAND,
AMS_CAN_TYPE_THIRDBRAND,
AMS_CAN_TYPE_EMPTY,
AMS_CAN_TYPE_VIRTUAL,
};
enum FilamentStep {
@ -113,6 +118,8 @@ struct Caninfo
wxColour material_colour = {*wxWHITE};
AMSCanType material_state;
int material_remain = 100;
float k = 0.0f;
float n = 0.0f;
};
struct AMSinfo
@ -236,6 +243,7 @@ public:
virtual bool Enable(bool enable = true);
void post_event(wxCommandEvent &&event);
Caninfo m_info;
void show_kn_value(bool show) { m_show_kn = show; };
protected:
wxStaticBitmap *m_edit_bitmp = {nullptr};
@ -248,6 +256,7 @@ protected:
bool m_enable = {false};
bool m_selected = {false};
bool m_hover = {false};
bool m_show_kn = {false};
double m_radius = {4};
wxColour m_border_color;
@ -383,12 +392,14 @@ public:
void Update(AMSinfo info);
void create(wxWindow *parent, wxWindowID id, AMSinfo info, const wxPoint &pos, const wxSize &size);
void AddCan(Caninfo caninfo, int canindex, int maxcan);
void SetDefSelectCan();
void SelectCan(std::string canid);
void SetAmsStep(wxString canid, AMSPassRoadType type, AMSPassRoadSTEP step);
//wxColour GetCanColour(wxString canid);
void PlayRridLoading(wxString canid);
void StopRridLoading(wxString canid);
void msw_rescale();
void show_sn_value(bool show);
std::string GetCurrentCan();
@ -452,6 +463,8 @@ protected:
AMSextruder *m_extruder = {nullptr};
AmsIntroducePopup m_ams_introduce_popup;
wxSimplebook *m_simplebook_right = {nullptr};
wxSimplebook *m_simplebook_calibration = {nullptr};
wxSimplebook *m_simplebook_amsitems = {nullptr};
@ -465,11 +478,20 @@ protected:
wxWindow * m_none_ams_panel = {nullptr};
wxWindow * m_panel_top = {nullptr};
wxWindow * m_amswin = {nullptr};
wxBoxSizer* m_vams_sizer = {nullptr};
wxBoxSizer* m_sizer_vams_tips = {nullptr};
Caninfo m_vams_info;
StaticBox* m_panel_virtual = {nullptr};
AMSrefresh* m_vams_refresh = {nullptr};
AMSLib* m_vams_lib = {nullptr};
AMSRoad* m_vams_road = {nullptr};
StaticBox * m_panel_can = {nullptr};
wxBoxSizer *m_sizer_top = {nullptr};
wxBoxSizer *m_sizer_cans = {nullptr};
wxBoxSizer *m_sizer_right_tip = {nullptr};
wxBoxSizer* m_sizer_ams_tips = {nullptr};
::StepIndicator *m_filament_load_step = {nullptr};
::StepIndicator *m_filament_unload_step = {nullptr};
@ -480,17 +502,20 @@ protected:
ScalableBitmap m_button_ams_setting_normal;
ScalableBitmap m_button_ams_setting_hover;
ScalableBitmap m_button_ams_setting_press;
Button *m_button_extrusion_cali= {nullptr};
Button *m_button_guide = {nullptr};
Button *m_button_retry = {nullptr};
wxWindow* m_button_area = {nullptr};
wxHyperlinkCtrl *m_hyperlink = {nullptr};
AmsHumidityTipPopup m_Humidity_tip_popup;
public:
std::string GetCurentAms();
std::string GetCurrentCan(std::string amsid);
wxColour GetCanColour(std::string amsid, std::string canid);
void SetActionState(AMSAction action);
bool m_is_none_ams_mode{false};
void SetActionState(AMSAction action, bool support_virtual_tray = true);
void EnterNoneAMSMode();
void ExitNoneAMSMode();
@ -509,7 +534,7 @@ public:
void SetHumidity(std::string amsid, int humidity);
void UpdateStepCtrl();
void CreateAms();
void UpdateAms(std::vector<AMSinfo> info, bool keep_selection = true);
void UpdateAms(std::vector<AMSinfo> info, bool keep_selection = true, bool has_extrusion_cali = true);
void AddAms(AMSinfo info, bool refresh = true);
void SetAmsStep(std::string ams_id, std::string canid, AMSPassRoadType type, AMSPassRoadSTEP step);
void SwitchAms(std::string ams_id);
@ -518,10 +543,17 @@ public:
void on_filament_load(wxCommandEvent &event);
void on_filament_unload(wxCommandEvent &event);
void on_ams_setting_click(wxMouseEvent &event);
void on_extrusion_cali(wxCommandEvent &event);
void on_ams_setting_click(wxCommandEvent &event);
void on_clibration_again_click(wxMouseEvent &event);
void on_clibration_cancel_click(wxMouseEvent &event);
void Reset();
void show_noams_mode(bool show, bool support_virtual_tray);
void show_vams(bool show);
void show_vams_kn_value(bool show);
void update_vams_kn_value(AmsTray tray);
void post_event(wxEvent &&event);
virtual bool Enable(bool enable = true);
@ -530,16 +562,20 @@ public:
std::string m_current_senect;
};
wxDECLARE_EVENT(EVT_AMS_EXTRUSION_CALI, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_LOAD, SimpleEvent);
wxDECLARE_EVENT(EVT_AMS_UNLOAD, SimpleEvent);
wxDECLARE_EVENT(EVT_AMS_SETTINGS, SimpleEvent);
wxDECLARE_EVENT(EVT_AMS_REFRESH_RFID, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_ON_SELECTED, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_ON_FILAMENT_EDIT, wxCommandEvent);
wxDECLARE_EVENT(EVT_VAMS_ON_FILAMENT_EDIT, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_CLIBRATION_AGAIN, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_CLIBRATION_CANCEL, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_GUIDE_WIKI, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_RETRY, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_SHOW_HUMIDITY_TIPS, wxCommandEvent);
wxDECLARE_EVENT(EVT_AMS_UNSELETED_VAMS, wxCommandEvent);
}} // namespace Slic3r::GUI

View file

@ -312,6 +312,7 @@ void FanSwitchButton::render(wxDC& dc)
dc.SetTextForeground(text_color.colorForStates(states));
pt.x = (size.x - dc.GetTextExtent(speed).x) / 2;
pt.y -= FromDIP(5);
dc.DrawText(speed, pt);
}

View file

@ -225,7 +225,9 @@ Label::Label(wxWindow *parent, wxFont const &font, wxString const &text, long st
{
this->font = font;
SetFont(font);
SetForegroundColour(*wxBLACK);
SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent));
SetForegroundColour("#262E30");
if (style & LB_PROPAGATE_MOUSE_EVENT) {
for (auto evt : {
wxEVT_LEFT_UP, wxEVT_LEFT_DOWN})

View file

@ -8,7 +8,7 @@
BEGIN_EVENT_TABLE(SpinInput, wxPanel)
EVT_KEY_DOWN(SpinInput::keyPressed)
EVT_MOUSEWHEEL(SpinInput::mouseWheelMoved)
//EVT_MOUSEWHEEL(SpinInput::mouseWheelMoved)
EVT_PAINT(SpinInput::paintEvent)

View file

@ -38,7 +38,7 @@ static std::map<wxColour, wxColour> gDarkColors{
{"#2B3436", "#808080"},
{"#ABABAB", "#ABABAB"},
{"#D9D9D9", "#2D2D32"},
//{"#F0F0F0", "#3E3E44"},
//{"#F0F0F0", "#4C4C54"},
};
std::map<wxColour, wxColour> const & StateColor::GetDarkMap()

View file

@ -7,6 +7,10 @@
#include <shellapi.h>
#endif
#ifdef __LINUX__
#include "Printer/gstbambusrc.h"
#endif
wxMediaCtrl2::wxMediaCtrl2(wxWindow *parent)
{
#ifdef __WIN32__
@ -24,6 +28,10 @@ wxMediaCtrl2::wxMediaCtrl2(wxWindow *parent)
}
#endif
wxMediaCtrl::Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxMEDIACTRLPLAYERCONTROLS_NONE);
#ifdef __LINUX__
/* Register only after we have created the wxMediaCtrl, since only then are we guaranteed to have fired up Gstreamer's plugin registry. */
gstbambusrc_register();
#endif
}
#define CLSID_BAMBU_SOURCE L"{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}"
@ -75,7 +83,7 @@ void wxMediaCtrl2::Load(wxURI url)
wxMessageBox(_L("Missing BambuSource component registered for media playing! Please re-install BambuStutio or seek after-sales help."), _L("Error"), wxOK);
});
}
m_error = clsid != L"{233E64FB-2041-4A6C-AFAB-FF9BCF83E7AA}" ? 101 : path.empty() ? 102 : 103;
m_error = clsid != CLSID_BAMBU_SOURCE ? 101 : path.empty() ? 102 : 103;
wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
event.SetId(GetId());
event.SetEventObject(this);
@ -94,6 +102,42 @@ void wxMediaCtrl2::Load(wxURI url)
}
url = wxURI(url.BuildURI().append("&hwnd=").append(
boost::lexical_cast<std::string>(GetHandle())));
#endif
#ifdef __WXGTK3__
GstElementFactory *factory;
int hasplugins = 1;
factory = gst_element_factory_find("h264parse");
if (!factory) {
hasplugins = 0;
} else {
gst_object_unref(factory);
}
factory = gst_element_factory_find("openh264dec");
if (!factory) {
factory = gst_element_factory_find("avdec_h264");
}
if (!factory) {
factory = gst_element_factory_find("vaapih264dec");
}
if (!factory) {
hasplugins = 0;
} else {
gst_object_unref(factory);
}
if (!hasplugins) {
Slic3r::GUI::wxGetApp().CallAfter([] {
wxMessageBox(_L("Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Bambu Studio?)"), _L("Error"), wxOK);
});
m_error = 101;
wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
event.SetId(GetId());
event.SetEventObject(this);
wxPostEvent(this, event);
return;
}
#endif
m_error = 0;
wxMediaCtrl::Load(url);
@ -105,7 +149,14 @@ void wxMediaCtrl2::Stop() { wxMediaCtrl::Stop(); }
wxSize wxMediaCtrl2::GetVideoSize() const
{
#ifdef __LINUX__
// Gstreamer doesn't give us a VideoSize until we're playing, which
// confuses the MediaPlayCtrl into claiming that it is stuck
// "Loading...". Fake it out for now.
return wxSize(1280, 720);
#else
return m_imp ? m_imp->GetVideoSize() : wxSize(0, 0);
#endif
}
wxSize wxMediaCtrl2::DoGetBestSize() const

View file

@ -35,12 +35,12 @@ namespace BBL {
#define BAMBU_NETWORK_ERR_GET_MODEL_PUBLISH_PAGE -26
#define BAMBU_NETWORK_ERR_GET_MODEL_MALL_HOME_PAGE -27
#define BAMBU_NETWORK_ERR_GET_USER_INFO -28
#define BAMBU_NETWORK_ERR_WRONG_IP_ADDRESS -29
#define BAMBU_NETWORK_LIBRARY "bambu_networking"
#define BAMBU_NETWORK_AGENT_NAME "bambu_network_agent"
#define BAMBU_NETWORK_AGENT_VERSION "01.04.01.01"
#define BAMBU_NETWORK_AGENT_VERSION "01.04.02.02"
//iot preset type strings
#define IOT_PRINTER_TYPE_STRING "printer"
@ -128,6 +128,7 @@ struct PrintParams {
/* access options */
std::string dev_ip;
bool use_ssl;
std::string username;
std::string password;

View file

@ -15,6 +15,8 @@
#include <string.h>
#include <time.h>
#ifdef __cplusplus
#include <algorithm>
#include <array>
#include <atomic>
@ -194,3 +196,5 @@
#ifdef _WIN32
#include "GUI/format.hpp"
#endif // _WIN32
#endif // __cplusplus