Merge branch 'master-remote' into SoftFever

This commit is contained in:
SoftFever 2022-10-14 20:40:22 +08:00
commit 834d43af1d
38 changed files with 432 additions and 158 deletions

View file

@ -3,6 +3,7 @@ set -e # exit on first error
export ROOT=`pwd`
export NCORES=`nproc --all`
export CMAKE_BUILD_PARALLEL_LEVEL=${NCORES}
FOUND_GTK2=$(dpkg -l libgtk* | grep gtk2)
FOUND_GTK3=$(dpkg -l libgtk* | grep gtk-3)
@ -192,6 +193,8 @@ then
if [[ -n "$BUILD_DEBUG" ]]
then
BUILD_ARGS="${BUILD_ARGS} -DCMAKE_BUILD_TYPE=Debug"
else
BUILD_ARGS="${BUILD_ARGS} -DBBL_RELEASE_TO_PUBLIC=1"
fi
# cmake

View file

@ -1,14 +1,24 @@
# Build Bambu Slicer in a container
#
# Build an AppImage:
# rm -rf build; sudo podman build .. -t bambu-studio && sudo podman run --rm localhost/bambu-studio /bin/bash -c 'tar -c $(find build | grep ubu64.AppImage | head -1)' | tar -xv
# rm -rf build; sudo podman build . -t bambu-studio && sudo podman run --rm localhost/bambu-studio /bin/bash -c 'tar -c $(find build | grep ubu64.AppImage | head -1)' | tar -xv
#
# Troubleshooting:
# sudo podman run -it localhost/bambu-studio /bin/bash
# Troubleshooting the build container:
# sudo podman run -it --name bambu-studio localhost/bambu-studio /bin/bash
#
# Debugging the resulting AppImage:
# 1) Install `gdb`
# 2) In a terminal in the same directory as the AppImage, start it with following:
# echo -e "run\nbt\nquit" | gdb ./BambuStudio_ubu64.AppImage
# 3) Find related issue using backtrace output for clues and add backtrace to it on github
FROM docker.io/ubuntu:kinetic
FROM docker.io/ubuntu:20.04
LABEL maintainer "DeftDawg <DeftDawg@gmail.com>"
# Disable interactive package configuration
RUN apt-get update && \
echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
# Add a deb-src
RUN echo deb-src http://archive.ubuntu.com/ubuntu \
$(cat /etc/*release | grep VERSION_CODENAME | cut -d= -f2) main universe>> /etc/apt/sources.list
@ -16,13 +26,24 @@ RUN echo deb-src http://archive.ubuntu.com/ubuntu \
RUN apt-get update && apt-get install -y \
git \
build-essential \
autoconf \
cmake \
libglu1-mesa-dev \
autoconf pkgconf m4 \
cmake extra-cmake-modules \
libglu1-mesa-dev libglu1-mesa-dev \
libwayland-dev libxkbcommon-dev wayland-protocols \
eglexternalplatform-dev libglew-dev \
libgtk-3-dev \
libdbus-1-dev \
libcairo2-dev \
libgtk-3-dev libwebkit2gtk-4.0-dev \
libsoup2.4-dev \
libgstreamer1.0-dev libgstreamer-plugins-good1.0-dev libgstreamer-plugins-base1.0-dev libgstreamerd-3-dev \
libmspack-dev \
libosmesa6-dev \
libssl-dev libcurl4-openssl-dev libsecret-1-dev \
libudev-dev \
curl \
wget \
file \
sudo
COPY ../BambuStudio BambuStudio

View file

@ -9,6 +9,7 @@
"2"
],
"compatible_printers": [
"Bambu Lab X1 Carbon 0.2 nozzle"
"Bambu Lab X1 Carbon 0.2 nozzle",
"Bambu Lab X1 0.2 nozzle"
]
}

View file

@ -9,6 +9,7 @@
"2"
],
"compatible_printers": [
"Bambu Lab X1 Carbon 0.2 nozzle"
"Bambu Lab X1 Carbon 0.2 nozzle",
"Bambu Lab X1 0.2 nozzle"
]
}

View file

@ -9,6 +9,7 @@
"1"
],
"compatible_printers": [
"Bambu Lab X1 Carbon 0.2 nozzle"
"Bambu Lab X1 Carbon 0.2 nozzle",
"Bambu Lab X1 0.2 nozzle"
]
}

View file

@ -12,6 +12,7 @@
"; filament start gcode\n{if (bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >30)||(bed_temperature_initial_layer[current_extruder] >30)}M106 P3 S180\n{endif}"
],
"compatible_printers": [
"Bambu Lab X1 Carbon 0.2 nozzle"
"Bambu Lab X1 Carbon 0.2 nozzle",
"Bambu Lab X1 0.2 nozzle"
]
}

View file

@ -9,6 +9,7 @@
"15"
],
"compatible_printers": [
"Bambu Lab X1 Carbon 0.2 nozzle"
"Bambu Lab X1 Carbon 0.2 nozzle",
"Bambu Lab X1 0.2 nozzle"
]
}

View file

@ -9,6 +9,7 @@
"1"
],
"compatible_printers": [
"Bambu Lab X1 Carbon 0.2 nozzle"
"Bambu Lab X1 Carbon 0.2 nozzle",
"Bambu Lab X1 0.2 nozzle"
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2,6 +2,8 @@
#define FIRSTFIT_HPP
#include "selection_boilerplate.hpp"
// for writing SVG
//#include "../tools/svgtools.hpp"
namespace libnest2d { namespace selections {
@ -60,14 +62,11 @@ public:
pconfig.m_excluded_items.emplace_back(itm);
});
// If the packed_items array is not empty we have to create as many
// placers as there are elements in packed bins and preload each item
// into the appropriate placer
//for(ItemGroup& ig : fixed_bins) {
// placers.emplace_back(bin);
// placers.back().configure(pconfig);
// placers.back().preload(ig);
//}
#ifdef SVGTOOLS_HPP
svg::SVGWriter<RawShape> svgwriter;
std::for_each(first, last, [this,&svgwriter](Item &itm) { svgwriter.writeShape(itm, "none", "blue"); });
svgwriter.save(boost::filesystem::path("SVG") / "all_items.svg");
#endif
std::function<bool(Item& i1, Item& i2)> sortfunc;
if (pconfig.sortfunc)

View file

@ -20,6 +20,50 @@ namespace Slic3r {
const static bool g_wipe_into_objects = false;
void dfs_get_all_sorted_extruders(const std::vector<std::vector<float>> & wipe_volumes,
const std::vector<unsigned int> & all_extruders,
std::vector<unsigned int> & sorted_extruders,
float flush_volume,
std::map<float, std::vector<unsigned int>> &volumes_to_extruder_order)
{
if (sorted_extruders.size() == all_extruders.size()) {
volumes_to_extruder_order.insert(std::pair(flush_volume, sorted_extruders));
return;
}
for (auto extruder_id : all_extruders) {
if (sorted_extruders.empty()) {
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
sorted_extruders.pop_back();
} else {
auto itor = std::find(sorted_extruders.begin(), sorted_extruders.end(), extruder_id);
if (itor == sorted_extruders.end()) {
float delta_flush_volume = wipe_volumes[sorted_extruders.back()][extruder_id];
flush_volume += delta_flush_volume;
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
flush_volume -= delta_flush_volume;
sorted_extruders.pop_back();
}
}
}
}
std::vector<unsigned int> get_extruders_order(const std::vector<std::vector<float>> &wipe_volumes, std::vector<unsigned int> all_extruders, unsigned int start_extruder_id)
{
if (all_extruders.size() > 1) {
std::vector<unsigned int> sorted_extruders;
auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id);
if (iter != all_extruders.end()) { sorted_extruders.push_back(start_extruder_id); }
std::map<float, std::vector<unsigned int>> volumes_to_extruder_order;
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, 0, volumes_to_extruder_order);
if (volumes_to_extruder_order.size() > 0) return volumes_to_extruder_order.begin()->second;
}
return all_extruders;
}
// Returns true in case that extruder a comes before b (b does not have to be present). False otherwise.
bool LayerTools::is_extruder_order(unsigned int a, unsigned int b) const
{
@ -471,6 +515,9 @@ void ToolOrdering::reorder_extruders(unsigned int last_extruder_id)
assert(extruder_id > 0);
-- extruder_id;
}
// reorder the extruders for minimum flush volume
reorder_extruders_for_minimum_flush_volume();
}
// BBS
@ -539,6 +586,9 @@ void ToolOrdering::reorder_extruders(std::vector<unsigned int> tool_order_layer0
assert(extruder_id > 0);
--extruder_id;
}
// reorder the extruders for minimum flush volume
reorder_extruders_for_minimum_flush_volume();
}
void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height)
@ -670,6 +720,28 @@ void ToolOrdering::collect_extruder_statistics(bool prime_multi_material)
}
}
void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
{
if (!m_print_config_ptr || m_layer_tools.empty())
return;
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
std::vector<float> flush_matrix(cast<float>(m_print_config_ptr->flush_volumes_matrix.values));
const unsigned int number_of_extruders = (unsigned int) (sqrt(flush_matrix.size()) + EPSILON);
// Extract purging volumes for each extruder pair:
std::vector<std::vector<float>> wipe_volumes;
for (unsigned int i = 0; i < number_of_extruders; ++i)
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
unsigned int current_extruder_id = -1;
for (LayerTools& lt : m_layer_tools) {
if (lt.extruders.empty())
continue;
lt.extruders = get_extruders_order(wipe_volumes, lt.extruders, current_extruder_id);
current_extruder_id = lt.extruders.back();
}
}
// Layers are marked for infinite skirt aka draft shield. Not all the layers have to be printed.
void ToolOrdering::mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height)
{

View file

@ -194,6 +194,7 @@ private:
void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height);
void mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height);
void collect_extruder_statistics(bool prime_multi_material);
void reorder_extruders_for_minimum_flush_volume();
// BBS
std::vector<unsigned int> generate_first_layer_tool_order(const Print& print);

View file

@ -38,54 +38,6 @@ PrintRegion::PrintRegion(PrintRegionConfig &&config) : PrintRegion(std::move(con
//BBS
float Print::min_skirt_length = 0;
void dfs_get_all_sorted_extruders(const std::vector<std::vector<float>>& wipe_volumes,
const std::vector<unsigned int>& all_extruders,
std::vector<unsigned int> & sorted_extruders,
float flush_volume,
std::map<float, std::vector<unsigned int>> & volumes_to_extruder_order)
{
if (sorted_extruders.size() == all_extruders.size()) {
volumes_to_extruder_order.insert(std::pair(flush_volume, sorted_extruders));
return;
}
for (auto extruder_id : all_extruders) {
if (sorted_extruders.empty()) {
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
sorted_extruders.pop_back();
} else {
auto itor = std::find(sorted_extruders.begin(), sorted_extruders.end(), extruder_id);
if (itor == sorted_extruders.end()) {
float delta_flush_volume = wipe_volumes[sorted_extruders.back()][extruder_id];
flush_volume += delta_flush_volume;
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
flush_volume -= delta_flush_volume;
sorted_extruders.pop_back();
}
}
}
}
std::vector<unsigned int> get_extruders_order(const std::vector<std::vector<float>> &wipe_volumes,
std::vector<unsigned int> all_extruders,
unsigned int start_extruder_id)
{
if (all_extruders.size() > 1) {
std::vector<unsigned int> sorted_extruders;
auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id);
if (iter != all_extruders.end()) {
sorted_extruders.push_back(start_extruder_id);
}
std::map<float, std::vector<unsigned int>> volumes_to_extruder_order;
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, 0, volumes_to_extruder_order);
if(volumes_to_extruder_order.size() > 0)
return volumes_to_extruder_order.begin()->second;
}
return all_extruders;
}
void Print::clear()
{
std::scoped_lock<std::mutex> lock(this->state_mutex());
@ -490,11 +442,11 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
//juedge the exclude area
if (!intersection(exclude_polys, convex_hull_no_offset).empty()) {
if (single_object_exception.string.empty()) {
single_object_exception.string = (boost::format(L("%1% is too close to exclusion area, there will be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.string = (boost::format(L("%1% is too close to exclusion area, there may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.object = instance.model_instance->get_object();
}
else {
single_object_exception.string += (boost::format(L("\n%1% is too close to exclusion area, there will be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.string += (boost::format(L("\n%1% is too close to exclusion area, there may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.object = nullptr;
}
//if (polygons) {
@ -694,14 +646,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 will 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 will 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 will 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();
}*/
}
@ -739,7 +691,7 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
}
if (!intersection(exclude_polys, convex_hulls_temp).empty()) {
/*if (warning) {
warning->string += L("Prime Tower is too close to exclusion area, there will be collisions when printing.\n");
warning->string += L("Prime Tower is too close to exclusion area, there may be collisions when printing.\n");
}*/
return {L("Prime Tower") + L(" is too close to exclusion area, and collisions will be caused.\n")};
}
@ -1903,8 +1855,6 @@ void Print::_make_wipe_tower()
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id, false);
layer_tools.extruders = get_extruders_order(wipe_volumes, layer_tools.extruders, current_extruder_id);
for (const auto extruder_id : layer_tools.extruders) {
// BBS: priming logic is removed, so no need to do toolchange for first extruder
if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */extruder_id != current_extruder_id) {

View file

@ -2271,11 +2271,9 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
for (Node* p_node : layer_contact_nodes)
{
if (p_node->type == ePolygon) {
Node* next_node = new Node(*p_node);
next_node->distance_to_top++;
next_node->support_roof_layers_below--;
next_node->print_z -= m_object->get_layer(layer_nr)->height;
next_node->to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[layer_nr], next_node->position);
const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[layer_nr], p_node->position);
Node * next_node = new Node(p_node->position, p_node->distance_to_top + 1, p_node->skin_direction, p_node->support_roof_layers_below - 1, to_buildplate, p_node,
m_object->get_layer(layer_nr - 1)->print_z, m_object->get_layer(layer_nr - 1)->height);
contact_nodes[layer_nr - 1].emplace_back(next_node);
}
}
@ -2607,6 +2605,20 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
}
}
// delete nodes with no children (means either it's a single layer nodes, or the branch has been deleted but not completely)
for (size_t layer_nr = contact_nodes.size() - 1; layer_nr > 0; layer_nr--){
auto layer_contact_nodes = contact_nodes[layer_nr];
for (Node *p_node : layer_contact_nodes) {
if (p_node->child==nullptr) {
std::vector<Node *>::iterator to_erase = std::find(contact_nodes[layer_nr].begin(), contact_nodes[layer_nr].end(), p_node);
if (to_erase != contact_nodes[layer_nr].end()) {
to_free_node_set.insert(*to_erase);
contact_nodes[layer_nr].erase(to_erase);
}
}
}
}
BOOST_LOG_TRIVIAL(debug) << "after m_avoidance_cache.size()=" << m_ts_data->m_avoidance_cache.size();
for (Node *node : to_free_node_set)

View file

@ -222,7 +222,7 @@ public:
, height(0.0)
{}
Node(const Point position, const size_t distance_to_top, const bool skin_direction, const int support_roof_layers_below, const bool to_buildplate, Node* const parent,
Node(const Point position, const size_t distance_to_top, const bool skin_direction, const int support_roof_layers_below, const bool to_buildplate, Node* parent,
coordf_t print_z_, coordf_t height_)
: distance_to_top(distance_to_top)
, position(position)
@ -233,7 +233,13 @@ public:
, parent(parent)
, print_z(print_z_)
, height(height_)
{}
{
if (parent) {
type = parent->type;
overhang = parent->overhang;
parent->child = this;
}
}
#ifdef DEBUG // Clear the delete node's data so if there's invalid access after, we may get a clue by inspecting that node.
~Node()
@ -294,6 +300,7 @@ public:
* the entire branch needs to be known.
*/
Node *parent;
Node *child = nullptr;
/*!
* \brief All neighbours (on the same layer) that where merged into this node.

View file

@ -34,7 +34,20 @@ echo -n "[9/9] Generating Linux app..."
## find package/resources/localization -name "*.po" -type f -delete ## FIXME: DD - do we need this?
# create bin
echo -e '#!/bin/bash\nDIR=$(readlink -f "$0" | xargs dirname)\nexport LD_LIBRARY_PATH="$DIR/bin"\nexec "$DIR/bin/@SLIC3R_APP_CMD@" "$@"' >@SLIC3R_APP_CMD@
cat << EOF >@SLIC3R_APP_CMD@
#!/bin/bash
DIR=\$(readlink -f "\$0" | xargs dirname)
export LD_LIBRARY_PATH="\$DIR/bin"
# FIXME: BambuStudio segfault workarounds
# 1) BambuStudio will segfault on systems where locale info is not as expected (i.e. Holo-ISO arch-based distro)
# 2) BambuStudio will segfault with a boost logging error if ~/.config/BambuStudio doesn't exist on first run
export LC_ALL=C
mkdir -p \${HOME}/.config/BambuStudio/ 2> /dev/null
exec "\$DIR/bin/@SLIC3R_APP_CMD@" "\$@"
EOF
chmod ug+x @SLIC3R_APP_CMD@
cp -f @SLIC3R_APP_CMD@ package/@SLIC3R_APP_CMD@
pushd package

View file

@ -1140,6 +1140,7 @@ bool MachineObject::has_recording()
int MachineObject::command_get_version()
{
BOOST_LOG_TRIVIAL(info) << "command_get_version";
json j;
j["info"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["info"]["command"] = "get_version";
@ -1716,6 +1717,9 @@ bool MachineObject::is_function_supported(PrinterFunction func)
case FUNC_LOCAL_TUNNEL:
func_name = "FUNC_LOCAL_TUNNEL";
break;
case FUNC_PRINT_WITHOUT_SD:
func_name = "FUNC_PRINT_WITHOUT_SD";
break;
default:
return true;
}
@ -2177,6 +2181,13 @@ int MachineObject::parse_json(std::string payload)
camera_timelapse = false;
}
}
if (jj["ipcam"].contains("ipcam_dev")) {
if (jj["ipcam"]["ipcam_dev"].get<std::string>() == "1") {
has_ipcam = true;
} else {
has_ipcam = false;
}
}
}
}
catch (...) {
@ -2673,8 +2684,12 @@ void MachineObject::update_slice_info(std::string project_id, std::string profil
void MachineObject::get_firmware_info()
{
m_firmware_valid = false;
if (m_firmware_thread_started)
return;
boost::thread update_info_thread = Slic3r::create_thread(
[&] {
m_firmware_thread_started = true;
int result = 0;
unsigned int http_code;
std::string http_body;
@ -2745,6 +2760,7 @@ void MachineObject::get_firmware_info()
catch (...) {
return;
}
m_firmware_thread_started = false;
m_firmware_valid = true;
}
);

View file

@ -69,6 +69,7 @@ enum PrinterFunction {
FUNC_MEDIA_FILE,
FUNC_REMOTE_TUNNEL,
FUNC_LOCAL_TUNNEL,
FUNC_PRINT_WITHOUT_SD,
FUNC_MAX
};
@ -492,6 +493,7 @@ public:
PrintingSpeedLevel _parse_printing_speed_lvl(int lvl);
/* camera */
bool has_ipcam { false };
bool camera_recording { false };
bool camera_timelapse { false };
bool camera_has_sdcard { false };
@ -617,6 +619,7 @@ public:
void update_slice_info(std::string project_id, std::string profile_id, std::string subtask_id, int plate_idx);
bool m_firmware_valid { false };
bool m_firmware_thread_started { false };
void get_firmware_info();
bool is_firmware_info_valid();
};

View file

@ -165,6 +165,31 @@ static std::string convert_studio_language_to_api(std::string lang_code)
return "en";*/
}
#ifdef _WIN32
bool is_associate_files(std::wstring extend)
{
wchar_t app_path[MAX_PATH];
::GetModuleFileNameW(nullptr, app_path, sizeof(app_path));
std::wstring prog_id = L" Bambu.Studio.1";
std::wstring reg_base = L"Software\\Classes";
std::wstring reg_extension = reg_base + L"\\." + extend;
wchar_t szValueCurrent[1000];
DWORD dwType;
DWORD dwSize = sizeof(szValueCurrent);
int iRC = ::RegGetValueW(HKEY_CURRENT_USER, reg_extension.c_str(), nullptr, RRF_RT_ANY, &dwType, szValueCurrent, &dwSize);
bool bDidntExist = iRC == ERROR_FILE_NOT_FOUND;
if (!bDidntExist && ::wcscmp(szValueCurrent, prog_id.c_str()) == 0)
return true;
return false;
}
#endif
class BBLSplashScreen : public wxSplashScreen
{
public:
@ -1793,6 +1818,20 @@ void GUI_App::init_app_config()
// Save orig_version here, so its empty if no app_config existed before this run.
m_last_config_version = app_config->orig_version();//parse_semver_from_ini(app_config->config_path());
}
else {
#ifdef _WIN32
// update associate files from registry information
if (is_associate_files(L"3mf")) {
app_config->set("associate_3mf", "true");
}
if (is_associate_files(L"stl")) {
app_config->set("associate_stl", "true");
}
if (is_associate_files(L"step") && is_associate_files(L"stp")) {
app_config->set("associate_step", "true");
}
#endif // _WIN32
}
}
// returns true if found newer version and user agreed to use it
@ -2021,8 +2060,10 @@ bool GUI_App::on_init_inner()
associate_files(L"3mf");
if (app_config->get("associate_stl") == "true")
associate_files(L"stl");
if (app_config->get("associate_step") == "true")
if (app_config->get("associate_step") == "true") {
associate_files(L"step");
associate_files(L"stp");
}
if (app_config->get("associate_gcode") == "true")
associate_files(L"gcode");
#endif // __WXMSW__
@ -2270,7 +2311,7 @@ bool GUI_App::on_init_inner()
//#ifdef __linux__
// if (!m_post_initialized && m_opengl_initialized) {
//#else
if (!m_post_initialized) {
if (!m_post_initialized && !m_adding_script_handler) {
//#endif
m_post_initialized = true;
#ifdef WIN32
@ -4269,8 +4310,10 @@ void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_
associate_files(L"3mf");
if (app_config->get("associate_stl") == "true")
associate_files(L"stl");
if (app_config->get("associate_step") == "true")
if (app_config->get("associate_step") == "true") {
associate_files(L"step");
associate_files(L"stp");
}
}
else {
if (app_config->get("associate_gcode") == "true")

View file

@ -273,6 +273,8 @@ private:
boost::thread m_sync_update_thread;
bool enable_sync = false;
bool m_adding_script_handler { false };
public:
bool OnInit() override;
bool initialized() const { return m_initialized; }
@ -463,6 +465,8 @@ public:
//BBS
void load_url(wxString url);
void run_script(wxString js);
bool is_adding_script_handler() { return m_adding_script_handler; }
void set_adding_script_handler(bool status) { m_adding_script_handler = status; }
// Parameters extracted from the command line to be passed to GUI after initialization.
GUI_InitParams* init_params { nullptr };

View file

@ -113,9 +113,19 @@ public:
MonitorPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
~MonitorPanel();
enum PrinterTab {
PT_STATUS = 0,
PT_MEDIA = 1,
PT_UPDATE = 2,
PT_HMS = 3,
PT_DEBUG = 4,
PT_MAX_NUM = 5
};
void init_bitmap();
void init_timer();
void init_tabpanel();
Tabbook* get_tabpanel() { return m_tabpanel; };
void set_default();
wxWindow* create_side_tools();

View file

@ -555,11 +555,22 @@ Sidebar::Sidebar(Plater *parent)
AppConfig *app_config = wxGetApp().app_config;
std::string str_bed_type = app_config->get("curr_bed_type");
m_bed_type_list->Select(atoi(str_bed_type.c_str()));
int bed_type_value = atoi(str_bed_type.c_str());
m_bed_type_list->Select(bed_type_value);
bed_type_sizer->Add(bed_type_title, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
bed_type_sizer->Add(m_bed_type_list, 1, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(10));
vsizer_printer->Add(bed_type_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
auto& project_config = wxGetApp().preset_bundle->project_config;
/*const t_config_enum_values* keys_map = print_config_def.get("curr_bed_type")->enum_keys_map;
BedType bed_type = btCount;
for (auto item : *keys_map) {
if (item.first == str_bed_type)
bed_type = (BedType)item.second;
}*/
BedType bed_type = (BedType)bed_type_value;
project_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
p->m_panel_printer_content->SetSizer(vsizer_printer);
p->m_panel_printer_content->Layout();
scrolled_sizer->Add(p->m_panel_printer_content, 0, wxTOP | wxEXPAND, FromDIP(14));
@ -9057,6 +9068,10 @@ void Plater::print_job_finished(wxCommandEvent &evt)
p->hide_select_machine_dlg();
p->main_frame->request_select_tab(MainFrame::TabPosition::tpMonitor);
//jump to monitor and select device status panel
MonitorPanel* curr_monitor = p->main_frame->m_monitor;
if(curr_monitor)
curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS);
}
// Called when the Eject button is pressed.

View file

@ -691,6 +691,7 @@ wxWindow* PreferencesDialog::create_general_page()
auto title_sync_settings = create_item_title(_L("User sync"), page, _L("User sync"));
auto item_user_sync = create_item_checkbox(_L("Auto sync user presets(Printer/Filament/Process)"), page, _L("User Sync"), 50, "sync_user_preset");
#ifdef _WIN32
auto title_associate_file = create_item_title(_L("Associate files to BambuStudio"), page, _L("Associate files to BambuStudio"));
// associate file
@ -700,6 +701,7 @@ wxWindow* PreferencesDialog::create_general_page()
_L("If enabled, sets BambuStudio as default application to open .stl files"), 50, "associate_stl");
auto item_associate_step = create_item_checkbox(_L("Associate .step/.stp files to BambuStudio"), page,
_L("If enabled, sets BambuStudio as default application to open .step files"), 50, "associate_step");
#endif // _WIN32
auto title_backup = create_item_title(_L("Backup"), page, _L("Backup"));
@ -713,10 +715,12 @@ wxWindow* PreferencesDialog::create_general_page()
sizer_page->Add(item_currency, 0, wxTOP, FromDIP(3));
sizer_page->Add(title_sync_settings, 0, wxTOP | wxEXPAND, FromDIP(20));
sizer_page->Add(item_user_sync, 0, wxTOP, FromDIP(3));
#ifdef _WIN32
sizer_page->Add(title_associate_file, 0, wxTOP| wxEXPAND, FromDIP(20));
sizer_page->Add(item_associate_3mf, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_associate_stl, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_associate_step, 0, wxTOP, FromDIP(3));
#endif // _WIN32
sizer_page->Add(title_backup, 0, wxTOP| wxEXPAND, FromDIP(20));
sizer_page->Add(item_backup, 0, wxTOP,FromDIP(3));
sizer_page->Add(item_backup_interval, 0, wxTOP,FromDIP(3));

View file

@ -40,6 +40,59 @@ wxDEFINE_EVENT(EVT_EDIT_PRINT_NAME, wxCommandEvent);
static wxString task_canceled_text = _L("Task canceled");
std::string get_print_status_info(PrintDialogStatus status)
{
switch(status) {
case PrintStatusInit:
return "PrintStatusInit";
case PrintStatusNoUserLogin:
return "PrintStatusNoUserLogin";
case PrintStatusInvalidPrinter:
return "PrintStatusInvalidPrinter";
case PrintStatusConnectingServer:
return "PrintStatusConnectingServer";
case PrintStatusReading:
return "PrintStatusReading";
case PrintStatusReadingFinished:
return "PrintStatusReadingFinished";
case PrintStatusReadingTimeout:
return "PrintStatusReadingTimeout";
case PrintStatusInUpgrading:
return "PrintStatusInUpgrading";
case PrintStatusNeedUpgradingAms:
return "PrintStatusNeedUpgradingAms";
case PrintStatusInSystemPrinting:
return "PrintStatusInSystemPrinting";
case PrintStatusInPrinting:
return "PrintStatusInPrinting";
case PrintStatusDisableAms:
return "PrintStatusDisableAms";
case PrintStatusAmsMappingSuccess:
return "PrintStatusAmsMappingSuccess";
case PrintStatusAmsMappingInvalid:
return "PrintStatusAmsMappingInvalid";
case PrintStatusAmsMappingU0Invalid:
return "PrintStatusAmsMappingU0Invalid";
case PrintStatusAmsMappingValid:
return "PrintStatusAmsMappingValid";
case PrintStatusAmsMappingByOrder:
return "PrintStatusAmsMappingByOrder";
case PrintStatusRefreshingMachineList:
return "PrintStatusRefreshingMachineList";
case PrintStatusSending:
return "PrintStatusSending";
case PrintStatusSendingCanceled:
return "PrintStatusSendingCanceled";
case PrintStatusLanModeNoSdcard:
return "PrintStatusLanModeNoSdcard";
case PrintStatusNoSdcard:
return "PrintStatusNoSdcard";
}
return "unknown";
}
MachineListModel::MachineListModel() : wxDataViewVirtualListModel(INITIAL_NUMBER_OF_MACHINES) { ; }
void MachineListModel::display_machines(std::map<std::string, MachineObject *> list)
@ -1414,7 +1467,7 @@ void SelectMachineDialog::update_print_status_msg(wxString msg, bool is_warning,
void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxString> params)
{
if (m_print_status != status)
BOOST_LOG_TRIVIAL(info) << "select_machine_dialog: show_status = " << status;
BOOST_LOG_TRIVIAL(info) << "select_machine_dialog: show_status = " << status << "(" << get_print_status_info(status) << ")";
m_print_status = status;
// m_comboBox_printer
@ -1524,7 +1577,7 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxSt
} else if (status == PrintDialogStatus::PrintStatusSendingCanceled) {
Enable_Send_Button(true);
Enable_Refresh_Button(true);
} else if (status == PrintDialogStatus::PrintStatusNoSdcard) {
} else if (status == PrintDialogStatus::PrintStatusLanModeNoSdcard) {
wxString msg_text = _L("An SD card needs to be inserted before printing via LAN.");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(true);
@ -1534,6 +1587,11 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxSt
update_print_status_msg(msg_text, false, false);
Enable_Send_Button(true);
Enable_Refresh_Button(true);
} else if (status == PrintDialogStatus::PrintStatusNoSdcard) {
wxString msg_text = _L("An SD card needs to be inserted before printing.");
update_print_status_msg(msg_text, true, true);
Enable_Send_Button(true);
Enable_Refresh_Button(true);
}
}
@ -1913,6 +1971,7 @@ void SelectMachineDialog::on_selection_changed(wxCommandEvent &event)
if (obj) {
obj->command_get_version();
obj->command_request_push_all();
dev->set_selected_machine(m_printer_last_select);
update_select_layout(obj);
} else {
@ -2016,11 +2075,17 @@ void SelectMachineDialog::update_show_status()
show_status(PrintDialogStatus::PrintStatusInPrinting);
return;
}
else if (!obj_->is_function_supported(PrinterFunction::FUNC_PRINT_WITHOUT_SD)) {
show_status(PrintDialogStatus::PrintStatusNoSdcard);
return;
}
// check sdcard when if lan mode printer
if (obj_->is_lan_mode_printer()) {
if (!obj_->has_sdcard()) {
show_status(PrintDialogStatus::PrintStatusNoSdcard);
show_status(PrintDialogStatus::PrintStatusLanModeNoSdcard);
return;
}
}

View file

@ -248,9 +248,12 @@ enum PrintDialogStatus {
PrintStatusRefreshingMachineList,
PrintStatusSending,
PrintStatusSendingCanceled,
PrintStatusLanModeNoSdcard,
PrintStatusNoSdcard
};
std::string get_print_status_info(PrintDialogStatus status);
class SelectMachineDialog : public DPIDialog
{
private:

View file

@ -1341,7 +1341,7 @@ void StatusPanel::update(MachineObject *obj)
m_timelapse_button->Hide();
}
if (obj->is_function_supported(PrinterFunction::FUNC_RECORDING)) {
if (obj->is_function_supported(PrinterFunction::FUNC_RECORDING) || obj->has_ipcam) {
m_recording_button->Show();
} else {
m_recording_button->Hide();
@ -1397,6 +1397,10 @@ void StatusPanel::update_error_message()
wxGetApp().get_hms_query()->query_print_error_msg(obj->print_error),
print_error_str);
show_error_message(error_msg);
//hint dialog
ConfirmHintDialog print_error_dlg(this->GetParent(), wxID_ANY, _L("Warning"));
print_error_dlg.SetHint(error_msg);
print_error_dlg.ShowModal();
}
before_error_code = obj->print_error;
}

View file

@ -13,10 +13,6 @@ namespace GUI {
static const wxColour TEXT_NORMAL_CLR = wxColour(0, 174, 66);
static const wxColour TEXT_FAILED_CLR = wxColour(255, 111, 0);
wxString normal_upgrade_hint = _L("Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating.");
wxString force_upgrade_hint = _L("An important update was detected and needs to be run before printing can continue. Do you want to update now? You can also update later from 'Upgrade firmware'.");
wxString consistency_upgrade_hint = _L("The firmware version is abnormal. Repairing and updating are required before printing. Do you want to update now? You can also update later on printer or update next time starting the studio.");
MachineInfoPanel::MachineInfoPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
:wxPanel(parent, id, pos, size, style)
{
@ -503,6 +499,11 @@ void MachineInfoPanel::update_ams(MachineObject *obj)
ams_sn = "-";
ams_ver = "-";
} else {
if (m_obj->upgrade_display_state == (int)MachineObject::UpgradingDisplayState::UpgradingInProgress) {
ams_ver = "-";
amspanel->m_ams_new_version_img->Hide();
}
else {
// update ams img
wxString ams_text = wxString::Format("AMS%s", std::to_string(ams_id + 1));
ams_name = ams_text;
@ -547,6 +548,7 @@ void MachineInfoPanel::update_ams(MachineObject *obj)
}
}
}
}
// update ams sn
if (it->second.sn.empty()) {
@ -658,7 +660,9 @@ void MachineInfoPanel::upgrade_firmware_internal() {
void MachineInfoPanel::on_upgrade_firmware(wxCommandEvent &event)
{
ConfirmHintDialog* confirm_dlg = new ConfirmHintDialog(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
confirm_dlg->SetHint(normal_upgrade_hint);
confirm_dlg->SetHint(_L(
"Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating."
));
confirm_dlg->Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
if (m_obj){
m_obj->command_upgrade_confirm();
@ -671,7 +675,9 @@ void MachineInfoPanel::on_upgrade_firmware(wxCommandEvent &event)
void MachineInfoPanel::on_consisitency_upgrade_firmware(wxCommandEvent &event)
{
ConfirmHintDialog* confirm_dlg = new ConfirmHintDialog(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
confirm_dlg->SetHint(normal_upgrade_hint);
confirm_dlg->SetHint(_L(
"Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating."
));
confirm_dlg->Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
if (m_obj){
m_obj->command_consistency_upgrade_confirm();
@ -794,7 +800,9 @@ void UpgradePanel::update(MachineObject *obj)
if (m_obj->upgrade_force_upgrade) {
m_show_forced_hint = false; //lock hint
ConfirmHintDialog* force_dlg = new ConfirmHintDialog(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"));
force_dlg->SetHint(force_upgrade_hint);
force_dlg->SetHint(_L(
"An important update was detected and needs to be run before printing can continue. Do you want to update now? You can also update later from 'Upgrade firmware'."
));
force_dlg->Bind(EVT_CONFIRM_HINT, &MachineInfoPanel::on_upgrade_firmware, m_push_upgrade_panel);
if (force_dlg->ShowModal())
delete force_dlg;
@ -810,7 +818,9 @@ void UpgradePanel::update(MachineObject *obj)
if (m_obj->upgrade_consistency_request) {
m_show_consistency_hint = false;
ConfirmHintDialog* consistency_dlg = new ConfirmHintDialog(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"));
consistency_dlg->SetHint(consistency_upgrade_hint);
consistency_dlg->SetHint(_L(
"The firmware version is abnormal. Repairing and updating are required before printing. Do you want to update now? You can also update later on printer or update next time starting the studio."
));
consistency_dlg->Bind(EVT_CONFIRM_HINT, &MachineInfoPanel::on_consisitency_upgrade_firmware, m_push_upgrade_panel);
if (consistency_dlg->ShowModal())
delete consistency_dlg;

View file

@ -35,7 +35,7 @@ namespace Slic3r { namespace GUI {
json m_ProfileJson;
GuideFrame::GuideFrame(GUI_App *pGUI, long style)
: wxDialog((wxWindow *) (pGUI->mainframe), wxID_ANY, "BambuStudio", wxDefaultPosition, wxDefaultSize, style),
: DPIDialog((wxWindow *) (pGUI->mainframe), wxID_ANY, "BambuStudio", wxDefaultPosition, wxDefaultSize, style),
m_appconfig_new()
{
// INI

View file

@ -34,7 +34,7 @@
namespace Slic3r { namespace GUI {
class GuideFrame : public wxDialog
class GuideFrame : public DPIDialog
{
public:
GuideFrame(GUI_App *pGUI, long style = wxCAPTION | wxCLOSE_BOX | wxSYSTEM_MENU);
@ -92,6 +92,8 @@ public:
int InstallPlugin();
int ShowPluginStatus(int status, int percent, bool &cancel);
void on_dpi_changed(const wxRect &suggested_rect) {}
private:
GUI_App *m_MainPtr;
AppConfig m_appconfig_new;

View file

@ -185,11 +185,21 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int
m_sizer_main->Add(m_simplebook, 1, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28));
} else {
m_msg = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x, -1), 0);
wxScrolledWindow* m_msg_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL );
m_msg_scrolledWindow->SetScrollRate(0,5);
m_msg_scrolledWindow->SetMinSize(wxSize(FromDIP(80), FromDIP(300)));
wxBoxSizer* m_msg_sizer= new wxBoxSizer(wxVERTICAL);
m_msg = new wxStaticText(m_msg_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x, -1), 0);
m_msg->Wrap(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x);
m_msg->SetFont(::Label::Body_13);
m_msg->SetForegroundColour(PROGRESSDIALOG_GREY_700);
m_sizer_main->Add(m_msg, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28));
m_msg_sizer->Add( m_msg, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(5) );
m_msg_scrolledWindow->SetSizer(m_msg_sizer);
m_msg_scrolledWindow->Layout();
m_msg_sizer->Fit(m_msg_scrolledWindow);
m_sizer_main->Add(m_msg_scrolledWindow, 0, wxEXPAND | wxALL, FromDIP(28));
}
@ -237,7 +247,7 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int
}
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(16));
m_sizer_main->Add(m_sizer_bottom, 1, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28));
m_sizer_main->Add(m_sizer_bottom, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28));
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(10));
SetSizer(m_sizer_main);

View file

@ -107,8 +107,12 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, wxString const & url)
#ifndef __WIN32__
Slic3r::GUI::wxGetApp().CallAfter([webView] {
#endif
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": begin to add script message handler for wx.";
Slic3r::GUI::wxGetApp().set_adding_script_handler(true);
if (!webView->AddScriptMessageHandler("wx"))
wxLogError("Could not add script message handler");
Slic3r::GUI::wxGetApp().set_adding_script_handler(false);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": finished add script message handler for wx.";
#ifndef __WIN32__
});
#endif