Merge branch 'main' into datalist-row-color

This commit is contained in:
yw4z
2025-11-19 13:53:36 +03:00
committed by GitHub
1154 changed files with 386333 additions and 2885 deletions
+41 -2
View File
@@ -3182,7 +3182,7 @@ int CLI::run(int argc, char **argv)
if (filament_options_with_variant.find(opt_key) != filament_options_with_variant.end()) {
std::vector<int> temp_variant_indice;
temp_variant_indice.resize(new_variant_count, -1);
opt_vec_dst->set_with_restore_2(opt_vec_src, temp_variant_indice, old_start_indice[filament_index - 1], old_variant_count);
opt_vec_dst->set_with_restore_2(opt_vec_src, temp_variant_indice, old_start_indice[filament_index - 1], old_variant_count, true);
if (opt_key == "filament_extruder_variant")
new_variant_counts[filament_index - 1] = opt_vec_src->size();
@@ -3508,6 +3508,7 @@ int CLI::run(int argc, char **argv)
m_print_config.option<ConfigOptionEnum<PrinterTechnology>>("printer_technology", true)->value = printer_technology;
bool has_wipe_tower_position = m_print_config.option<ConfigOptionFloats>("wipe_tower_x") && m_print_config.option<ConfigOptionFloats>("wipe_tower_y");
// Initialize full print configs for both the FFF and SLA technologies.
FullPrintConfig fff_print_config;
//SLAFullPrintConfig sla_print_config;
@@ -4737,7 +4738,7 @@ int CLI::run(int argc, char **argv)
bool is_seq_print = false;
get_print_sequence(cur_plate, m_print_config, is_seq_print);
if (!is_seq_print && assemble_plate.filaments_count > 1)
if (!is_seq_print && (assemble_plate.filaments_count > 1) && !has_wipe_tower_position)
{
//prepare the wipe tower
auto printer_structure_opt = m_print_config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure");
@@ -5741,6 +5742,7 @@ int CLI::run(int argc, char **argv)
mode = m_extra_config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode")->value;
else
mode = part_plate->get_real_filament_map_mode(m_print_config);
BOOST_LOG_TRIVIAL(info) << boost::format("%1% :filament map mode is %2% ") % __LINE__ %(int)mode;
if (mode < FilamentMapMode::fmmManual) {
std::vector<int> conflict_filament_vector;
for (int index = 0; index < new_extruder_count; index++)
@@ -5777,6 +5779,43 @@ int CLI::run(int argc, char **argv)
std::vector<int> filament_maps;
if (m_extra_config.option<ConfigOptionInts>("filament_map")) {
filament_maps = m_extra_config.option<ConfigOptionInts>("filament_map")->values;
int default_value = -1;
bool has_invalid_value = false;
for (int f_index = 0; f_index < filament_maps.size(); f_index++)
{
if (filament_maps[f_index] != -1)
{
if (default_value == -1)
default_value = filament_maps[f_index];
else
continue;
}
else
has_invalid_value = true;
if (has_invalid_value && (default_value != -1))
break;
}
BOOST_LOG_TRIVIAL(info) << boost::format("%1% :filament map default_value %2%, has_invalid_value %3% ") % __LINE__ %default_value %has_invalid_value;
if (has_invalid_value)
{
for (int f_index = 0; f_index < filament_maps.size(); f_index++)
{
if (filament_maps[f_index] == -1)
{
if (default_value != -1) {
filament_maps[f_index] = default_value;
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% : set filament_map of filament %2% to first value %3%.")% (index + 1) %(f_index+1) %default_value;
}
else {
filament_maps[f_index] = 1;
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% : set filament_map of filament %2% to default value 1.")% (index + 1) %(f_index+1);
}
}
}
m_extra_config.option<ConfigOptionInts>("filament_map")->values = filament_maps;
}
part_plate->set_filament_maps(filament_maps);
}
else
+5
View File
@@ -9,6 +9,8 @@
#include <boost/format.hpp>
#include <mutex>
#include "libslic3r_version.h"
static std::string g_log_folder;
static std::atomic<int> g_crash_log_count = 0;
static std::mutex g_dump_mutex;
@@ -35,6 +37,9 @@ CBaseException::CBaseException(HANDLE hProcess, WORD wPID, LPCTSTR lpSymbolPath,
auto crash_log_path = boost::filesystem::path(log_folder / buf.str()).make_preferred();
std::string log_filename = crash_log_path.string();
output_file->open(log_filename, std::ios::out | std::ios::app);
// Output app build info in crash log so we could look for the correct PDB files
OutputString(_T("%s\n\n"), _T(SLIC3R_APP_NAME " " SoftFever_VERSION " Build " GIT_COMMIT_HASH));
}
}
+7 -4
View File
@@ -646,14 +646,16 @@ std::string AppConfig::load()
for (auto cali_it = calis_j["presets"].begin(); cali_it != calis_j["presets"].end(); cali_it++) {
CaliPresetInfo preset_info;
preset_info.tray_id = cali_it.value()["tray_id"].get<int>();
preset_info.nozzle_diameter = cali_it.value()["nozzle_diameter"].get<float>();
preset_info.filament_id = cali_it.value()["filament_id"].get<std::string>();
preset_info.setting_id = cali_it.value()["setting_id"].get<std::string>();
preset_info.name = cali_it.value()["name"].get<std::string>();
if (cali_it.value().contains("extruder_id"))
preset_info.extruder_id = cali_it.value()["extruder_id"].get<int>();
if (cali_it.value().contains("nozzle_volume_type"))
preset_info.nozzle_volume_type = NozzleVolumeType(cali_it.value()["nozzle_volume_type"].get<int>());
preset_info.nozzle_diameter = cali_it.value()["nozzle_diameter"].get<float>();
preset_info.filament_id = cali_it.value()["filament_id"].get<std::string>();
preset_info.setting_id = cali_it.value()["setting_id"].get<std::string>();
preset_info.name = cali_it.value()["name"].get<std::string>();
if (cali_it.value().contains("bed_type"))
preset_info.bed_type = BedType(cali_it.value()["bed_type"].get<int>());
cali_info.selected_presets.push_back(preset_info);
}
}
@@ -796,6 +798,7 @@ void AppConfig::save()
preset_json["tray_id"] = filament_preset.tray_id;
preset_json["extruder_id"] = filament_preset.extruder_id;
preset_json["nozzle_volume_type"] = int(filament_preset.nozzle_volume_type);
preset_json["bed_type"] = int(filament_preset.bed_type);
preset_json["nozzle_diameter"] = filament_preset.nozzle_diameter;
preset_json["filament_id"] = filament_preset.filament_id;
preset_json["setting_id"] = filament_preset.setting_id;
+1
View File
@@ -16,6 +16,7 @@ namespace Slic3r
ntStainlessSteel,
ntTungstenCarbide,
ntBrass,
ntE3D,
ntCount
};
}
+18 -7
View File
@@ -21,6 +21,7 @@
#include <boost/format/format_fwd.hpp>
#include <boost/functional/hash.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <boost/log/trivial.hpp>
#include <cereal/access.hpp>
#include <cereal/types/base_class.hpp>
@@ -350,7 +351,7 @@ public:
virtual void append(const ConfigOption *rhs) = 0;
virtual void set(const ConfigOption* rhs, size_t start, size_t len) = 0;
virtual void set_with_restore(const ConfigOptionVectorBase* rhs, std::vector<int>& restore_index, int stride) = 0;
virtual void set_with_restore_2(const ConfigOptionVectorBase* rhs, std::vector<int>& restore_index, int start, int len) = 0;
virtual void set_with_restore_2(const ConfigOptionVectorBase* rhs, std::vector<int>& restore_index, int start, int len, bool skip_error = false) = 0;
virtual void set_only_diff(const ConfigOptionVectorBase* rhs, std::vector<int>& diff_index, int stride) = 0;
virtual void set_with_nil(const ConfigOptionVectorBase* rhs, const ConfigOptionVectorBase* inherits, int stride) = 0;
// Resize the vector of values, copy the newly added values from opt_default if provided.
@@ -508,7 +509,7 @@ public:
//restore_index: which index in this vector need to be restored
//start: which index in this vector need to be replaced
//count: how many items in this vector need to be replaced
virtual void set_with_restore_2(const ConfigOptionVectorBase* rhs, std::vector<int>& restore_index, int start, int len) override
virtual void set_with_restore_2(const ConfigOptionVectorBase* rhs, std::vector<int>& restore_index, int start, int len, bool skip_error = false) override
{
if (rhs->type() == this->type()) {
//backup original ones
@@ -527,10 +528,16 @@ public:
}
// Assign the new value from the rhs vector.
auto other = static_cast<const ConfigOptionVector<T>*>(rhs);
auto other = const_cast<ConfigOptionVector<T>*>(static_cast<const ConfigOptionVector<T>*>(rhs));
if (other->values.size() != (restore_index.size()))
throw ConfigurationError("ConfigOptionVector::set_with_restore_2(): Assigning from an vector with invalid restore_index size");
if (other->values.size() != (restore_index.size())) {
if (skip_error) {
T default_v = other->values.front();
other->values.resize(restore_index.size(), default_v);
}
else
throw ConfigurationError("ConfigOptionVector::set_with_restore_2(): Assigning from an vector with invalid restore_index size");
}
for (size_t i = 0; i < restore_index.size(); i++) {
if ((restore_index[i] != -1)&&(restore_index[i] < backup_values.size())) {
@@ -560,7 +567,7 @@ public:
if (diff_index[i] != -1) {
for (size_t j = 0; j < stride; j++)
{
if (!other->is_nil(diff_index[i]))
if (!other->is_nil(diff_index[i] * stride))
this->values[i * stride +j] = other->values[diff_index[i] * stride +j];
}
}
@@ -2508,7 +2515,11 @@ public:
TYPE* option(const t_config_option_key &opt_key, bool create = false)
{
ConfigOption *opt = this->optptr(opt_key, create);
return (opt == nullptr || opt->type() != TYPE::static_type()) ? nullptr : static_cast<TYPE*>(opt);
if (opt != nullptr && opt->type() != TYPE::static_type()) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": attempt to access option with wrong type: " << opt_key;
return nullptr;
}
return static_cast<TYPE*>(opt);
}
ConfigOption* option_throw(const t_config_option_key &opt_key, bool create = false)
+6 -4
View File
@@ -64,8 +64,10 @@ void EdgeGrid::Grid::create(const std::vector<Points> &polygons, coord_t resolut
open = false;
-- end;
}
} else
assert(*begin != end[-1]);
} else {
//assert(*begin != end[-1]);
}
m_contours.emplace_back(begin, end, open);
}
@@ -142,8 +144,8 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
assert(resolution > 0);
// 1) Measure the bounding box.
for (const Contour &contour : m_contours) {
assert(contour.num_segments() > 0);
assert(*contour.begin() != contour.end()[-1]);
//assert(contour.num_segments() > 0);
//assert(*contour.begin() != contour.end()[-1]);
for (const Slic3r::Point &pt : contour)
m_bbox.merge(pt);
}
+12 -2
View File
@@ -317,6 +317,7 @@ static constexpr const char* NOZZLE_TYPE_ATTR = "nozzle_types";
static constexpr const char* NOZZLE_DIAMETERS_ATTR = "nozzle_diameters";
static constexpr const char* SLICE_PREDICTION_ATTR = "prediction";
static constexpr const char* SLICE_WEIGHT_ATTR = "weight";
static constexpr const char* FIRST_LAYER_TIME_ATTR = "first_layer_time";
static constexpr const char* TIMELAPSE_TYPE_ATTR = "timelapse_type";
static constexpr const char* OUTSIDE_ATTR = "outside";
static constexpr const char* SUPPORT_USED_ATTR = "support_used";
@@ -1837,8 +1838,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
else if (boost::algorithm::iequals(name, BBS_MODEL_CONFIG_FILE)) {
// extract slic3r model config file
if (!_extract_xml_from_archive(archive, stat, _handle_start_config_xml_element, _handle_end_config_xml_element)) {
add_error("Archive does not contain a valid model config");
return false;
if (m_is_bbl_3mf) {
add_error("Archive does not contain a valid model config");
return false;
}
}
}
else if (_is_svg_shape_file(name)) {
@@ -2338,6 +2341,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
XML_SetUserData(m_xml_parser, (void*)this);
XML_SetElementHandler(m_xml_parser, start_handler, end_handler);
XML_SetCharacterDataHandler(m_xml_parser, _BBS_3MF_Importer::_handle_xml_characters);
XML_SetEntityDeclHandler(m_xml_parser, nullptr);
XML_SetExternalEntityRefHandler(m_xml_parser, nullptr);
void* parser_buffer = XML_GetBuffer(m_xml_parser, (int)stat.m_uncomp_size);
if (parser_buffer == nullptr) {
@@ -2379,6 +2384,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
XML_SetUserData(m_xml_parser, (void*)this);
XML_SetElementHandler(m_xml_parser, _BBS_3MF_Importer::_handle_start_model_xml_element, _BBS_3MF_Importer::_handle_end_model_xml_element);
XML_SetCharacterDataHandler(m_xml_parser, _BBS_3MF_Importer::_handle_xml_characters);
XML_SetEntityDeclHandler(m_xml_parser, nullptr);
XML_SetExternalEntityRefHandler(m_xml_parser, nullptr);
struct CallbackData
{
@@ -5493,6 +5500,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
XML_SetUserData(object_xml_parser, (void*)this);
XML_SetElementHandler(object_xml_parser, _BBS_3MF_Importer::ObjectImporter::_handle_object_start_model_xml_element, _BBS_3MF_Importer::ObjectImporter::_handle_object_end_model_xml_element);
XML_SetCharacterDataHandler(object_xml_parser, _BBS_3MF_Importer::ObjectImporter::_handle_object_xml_characters);
XML_SetEntityDeclHandler(object_xml_parser, nullptr);
XML_SetExternalEntityRefHandler(object_xml_parser, nullptr);
struct CallbackData
{
@@ -7909,6 +7918,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << TIMELAPSE_TYPE_ATTR << "\" " << VALUE_ATTR << "=\"" << timelapse_type << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_PREDICTION_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->get_gcode_prediction_str() << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_WEIGHT_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->get_gcode_weight_str() << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << FIRST_LAYER_TIME_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->first_layer_time << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << OUTSIDE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->toolpath_outside << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SUPPORT_USED_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->is_support_used << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << LABEL_OBJECT_ENABLED_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->is_label_object_enabled << "\"/>\n";
+1
View File
@@ -85,6 +85,7 @@ struct PlateData
std::string pattern_bbox_file;
std::string gcode_prediction;
std::string gcode_weight;
std::string first_layer_time;
std::string plate_name;
std::vector<FilamentInfo> slice_filaments_info;
std::vector<size_t> skipped_objects;
+186 -87
View File
@@ -748,8 +748,6 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcode += gcodegen.unretract();
}
// BBS: if needed, write the gcode_label_objects_end then priming tower, if the retract, didn't did it.
gcodegen.m_writer.add_object_end_labels(gcode);
double current_z = gcodegen.writer().get_position().z();
if (z == -1.) // in case no specific z was provided, print at current_z pos
@@ -761,6 +759,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
}
// Process the end filament gcode.
bool add_change_filament_624 = false;
std::string end_filament_gcode_str;
if (gcodegen.writer().filament() != nullptr) {
// Process the custom filament_end_gcode in case of single_extruder_multi_material.
@@ -769,7 +768,12 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
if (gcodegen.writer().filament() != nullptr && !filament_end_gcode.empty()) {
DynamicConfig config;
config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index));
end_filament_gcode_str = gcodegen.placeholder_parser_process("filament_end_gcode", filament_end_gcode, old_filament_id, &config);
if (!gcodegen.m_filament_instances_code.empty()) {
end_filament_gcode_str += ("M624 " + gcodegen.m_filament_instances_code + "\n");
gcodegen.m_filament_instances_code = "";
add_change_filament_624 = true;
}
end_filament_gcode_str += gcodegen.placeholder_parser_process("filament_end_gcode", filament_end_gcode, old_filament_id, &config);
check_add_eol(end_filament_gcode_str);
}
}
@@ -785,9 +789,13 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
auto_lift_type = LiftType::SpiralLift;
// BBS: should be placed before toolchange parsing
std::string toolchange_retract_str = gcodegen.retract(tcr.is_tool_change && !is_nozzle_change, false, auto_lift_type);
std::string toolchange_retract_str = gcodegen.retract(tcr.is_tool_change && !is_nozzle_change, false, auto_lift_type, true);
check_add_eol(toolchange_retract_str);
//BBS: if needed, write the gcode_label_objects_end then priming tower, if the retract, didn't did it.
std::string object_end_label_temp;
gcodegen.m_writer.add_object_end_labels(object_end_label_temp);
// Process the custom change_filament_gcode. If it is empty, provide a simple Tn command to change the filament.
// Otherwise, leave control to the user completely.
std::string change_filament_gcode = gcodegen.config().change_filament_gcode.value;
@@ -809,12 +817,14 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcodegen.m_wipe.reset_path();
for (const Vec2f& wipe_pt : tcr.nozzle_change_result.wipe_path)
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt) + plate_origin_2d));
nozzle_change_gcode_trans += gcodegen.retract(tcr.is_tool_change, false, auto_lift_type);
nozzle_change_gcode_trans += gcodegen.retract(tcr.is_tool_change, false, auto_lift_type, true);
end_filament_gcode_str = nozzle_change_gcode_trans + end_filament_gcode_str;
}
end_filament_gcode_str = toolchange_retract_str + end_filament_gcode_str;
end_filament_gcode_str = toolchange_retract_str + object_end_label_temp + end_filament_gcode_str;
std::string wipe_next_start_point_str;
bool need_travel_after_change_filament_gcode = false; // travel need be after the filament changed to get the correct "m_curr_extruder_id"
if (! change_filament_gcode.empty()) {
DynamicConfig config;
int old_filament_id = gcodegen.writer().filament() ? (int)gcodegen.writer().filament()->id() : -1;
@@ -934,48 +944,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcodegen.writer().set_position(pos);
}
}
// move to start_pos for wiping after toolchange
if (!is_used_travel_avoid_perimeter) {
std::string start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d), erMixed, "Move to start pos");
check_add_eol(start_pos_str);
toolchange_gcode_str += start_pos_str;
} else {
// BBS:change travel_path
Vec3f gcode_last_pos;
GCodeProcessor::get_last_position_from_gcode(toolchange_gcode_str, gcode_last_pos);
Vec2f gcode_last_pos2d{gcode_last_pos[0], gcode_last_pos[1]};
Point gcode_last_pos2d_object = gcodegen.gcode_to_point(gcode_last_pos2d.cast<double>() + plate_origin_2d.cast<double>());
Point start_wipe_pos = wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d);
BoundingBox avoid_bbx, printer_bbx;
{
//set printer_bbx
Pointfs bed_pointsf = gcodegen.m_config.printable_area.values;
Points bed_points;
for (auto p : bed_pointsf) {
bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast<float>() + plate_origin_2d));
}
printer_bbx = BoundingBox(bed_points);
}
{
//set avoid_bbx
avoid_bbx = scaled(m_wipe_tower_bbx);
Polygon avoid_points = avoid_bbx.polygon();
for (auto& p : avoid_points.points) {
Vec2f pp = transform_wt_pt(unscale(p).cast<float>());
p = wipe_tower_point_to_object_point(gcodegen, pp + plate_origin_2d);
}
avoid_bbx = BoundingBox(avoid_points.points);
}
std::string travel_to_wipe_tower_gcode;
Polyline travel_polyline = generate_path_to_wipe_tower(gcode_last_pos2d_object, start_wipe_pos, avoid_bbx, printer_bbx);
for (const auto &p : travel_polyline.points) {
travel_to_wipe_tower_gcode += gcodegen.travel_to(p, erMixed, "Move to start pos");
check_add_eol(travel_to_wipe_tower_gcode);
}
toolchange_gcode_str += travel_to_wipe_tower_gcode;
gcodegen.set_last_pos(start_wipe_pos);
}
need_travel_after_change_filament_gcode = true;
}
std::string toolchange_command;
@@ -987,6 +956,55 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
// We have informed the m_writer about the current extruder_id, we can ignore the generated G-code.
}
if (need_travel_after_change_filament_gcode) {
// move to start_pos for wiping after toolchange
if (!is_used_travel_avoid_perimeter) {
std::string start_pos_str = gcodegen.travel_to(wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d), erMixed, "Move to start pos");
check_add_eol(start_pos_str);
wipe_next_start_point_str = start_pos_str;
} else {
// BBS:change travel_path
Vec3f gcode_last_pos;
GCodeProcessor::get_last_position_from_gcode(toolchange_gcode_str, gcode_last_pos);
Vec2f gcode_last_pos2d{gcode_last_pos[0], gcode_last_pos[1]};
Point gcode_last_pos2d_object = gcodegen.gcode_to_point(gcode_last_pos2d.cast<double>() + plate_origin_2d.cast<double>());
Point start_wipe_pos = wipe_tower_point_to_object_point(gcodegen, tool_change_start_pos + plate_origin_2d);
BoundingBox avoid_bbx, printer_bbx;
{
// set printer_bbx
Pointfs bed_pointsf = gcodegen.m_config.printable_area.values;
Points bed_points;
for (auto p : bed_pointsf) { bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast<float>() + plate_origin_2d)); }
printer_bbx = BoundingBox(bed_points);
}
{
// set avoid_bbx
avoid_bbx = scaled(m_wipe_tower_bbx);
Polygon avoid_points = avoid_bbx.polygon();
for (auto &p : avoid_points.points) {
Vec2f pp = transform_wt_pt(unscale(p).cast<float>());
p = wipe_tower_point_to_object_point(gcodegen, pp + plate_origin_2d);
}
avoid_bbx = BoundingBox(avoid_points.points);
}
std::string travel_to_wipe_tower_gcode;
Polyline travel_polyline = generate_path_to_wipe_tower(gcode_last_pos2d_object, start_wipe_pos, avoid_bbx, printer_bbx);
for (size_t i = 0; i < travel_polyline.points.size(); ++i) {
const auto &p = travel_polyline.points[i];
if (i == travel_polyline.points.size() - 1) {
wipe_next_start_point_str = gcodegen.travel_to(p, erMixed, "Move to start pos");
check_add_eol(wipe_next_start_point_str);
break;
}
travel_to_wipe_tower_gcode += gcodegen.travel_to(p, erMixed, "Move to start pos");
check_add_eol(travel_to_wipe_tower_gcode);
}
toolchange_gcode_str += travel_to_wipe_tower_gcode;
gcodegen.set_last_pos(start_wipe_pos);
}
}
// do unretract after setting current extruder_id
std::string toolchange_unretract_str = gcodegen.unretract();
check_add_eol(toolchange_unretract_str);
@@ -1005,10 +1023,14 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
DynamicConfig config;
config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_filament_id));
start_filament_gcode_str = gcodegen.placeholder_parser_process("filament_start_gcode", filament_start_gcode, new_filament_id, &config);
if (add_change_filament_624) {
start_filament_gcode_str += "M625\n";
add_change_filament_624 = false;
}
check_add_eol(start_filament_gcode_str);
}
start_filament_gcode_str = start_filament_gcode_str + toolchange_unretract_str;
start_filament_gcode_str = start_filament_gcode_str + wipe_next_start_point_str + toolchange_unretract_str;
// Insert the end filament, toolchange, and start filament gcode into the generated gcode.
DynamicConfig config;
@@ -1042,7 +1064,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
gcodegen.m_wipe.reset_path();
for (const Vec2f &wipe_pt : tcr.wipe_path)
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt)));
gcode += gcodegen.retract(false, false, auto_lift_type);
gcode += gcodegen.retract(false, false, auto_lift_type, true);
}
// Let the planner know we are traveling between objects.
@@ -1972,7 +1994,6 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
if(is_BBL_Printer())
result->label_object_enabled = m_enable_exclude_object;
// Write the profiler measurements to file
PROFILE_UPDATE();
PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str());
@@ -2276,6 +2297,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_enable_cooling_markers = true;
this->apply_print_config(print.config());
m_config.apply(print.default_object_config());
m_config.apply(print.default_region_config());
//m_volumetric_speed = DoExport::autospeed_volumetric_limit(print);
print.throw_if_canceled();
@@ -2454,7 +2477,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
//resize
first_non_support_filaments.resize(print.config().nozzle_diameter.size(), -1);
first_filaments.resize(print.config().nozzle_diameter.size(), -1);
float max_additional_fan = 0.f;
if (print.config().print_sequence == PrintSequence::ByObject) {
// Order object instances for sequential print.
print_object_instances_ordering = sort_object_instances_by_model_order(print);
@@ -2467,6 +2490,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id);
tool_ordering.sort_and_build_data(*(*print_object_instance_sequential_active)->print_object,initial_extruder_id);
float temp_max_additional_fan = tool_ordering.cal_max_additional_fan(print.config());
if(temp_max_additional_fan > max_additional_fan )
max_additional_fan = temp_max_additional_fan;
if (!find_fist_non_support_filament && tool_ordering.first_extruder() != (unsigned int) -1) {
//BBS: try to find the non-support filament extruder if is multi color and initial_extruder is support filament
if (initial_extruder_id == (unsigned int) -1) {
@@ -2490,6 +2516,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
tool_ordering = print.tool_ordering();
tool_ordering.assign_custom_gcodes(print);
float temp_max_additional_fan = tool_ordering.cal_max_additional_fan(print.config());
if(temp_max_additional_fan > max_additional_fan )
max_additional_fan = temp_max_additional_fan;
if (tool_ordering.all_extruders().empty())
// No object to print was found, cancel the G-code export.
throw Slic3r::SlicingError(_(L("No object can be printed. Maybe too small")));
@@ -2587,6 +2616,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->placeholder_parser().set("retraction_distances_when_ec", new ConfigOptionFloatsNullable(m_config.retraction_distances_when_ec));
this->placeholder_parser().set("long_retractions_when_ec",new ConfigOptionBoolsNullable(m_config.long_retractions_when_ec));
this->placeholder_parser().set("max_additional_fan", max_additional_fan);
this->placeholder_parser().set("first_x_layer_fan_speed", 0); // TODO: Orca hack to support BBL profiles
auto flush_v_speed = m_config.filament_flush_volumetric_speed.values;
auto flush_temps = m_config.filament_flush_temp.values;
for (size_t idx = 0; idx < flush_v_speed.size(); ++idx) {
@@ -2785,6 +2817,46 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->placeholder_parser().set("scan_first_layer", new ConfigOptionBool(false));
}
}
{ // hold chamber temp for flat print: Flag
double print_area_sum_threshold = 40000.0, pring_hight_threshold = 0.3; // thresholds in mm^2 and mm as units
double area_sum_temp = 0.0;
coordf_t max_hight_temp = -1.0;
for (ObjectID print_object_ID_t : print.print_object_ids()) {
const PrintObject *print_object = print.get_object(print_object_ID_t);
// object hight
if (!print_object->layers().empty() && print_object->layers().back()->print_z > max_hight_temp) max_hight_temp = print_object->layers().back()->print_z;
// object area
if (!print_object->layers().empty() && print_object->layers().front()->print_z < print.config().initial_layer_print_height + EPSILON &&
!print_object->layers().front()->lslices.empty()) {
ExPolygons temp_Expolys = print_object->layers().front()->lslices;
for (ExPolygon &temp_Expoly : temp_Expolys) { area_sum_temp += temp_Expoly.area(); }
}
// suport area
if (!print_object->support_layers().empty() && print_object->support_layers().front()->print_z < print.config().initial_layer_print_height + EPSILON &&
!print_object->support_layers().front()->support_islands.empty()) {
ExPolygons temp_Expolys = print_object->support_layers().front()->support_islands;
for (ExPolygon &temp_Expoly : temp_Expolys) { area_sum_temp += temp_Expoly.area(); }
}
// brim area
if (print.m_brimMap.find(print_object_ID_t) != print.m_brimMap.end() && !print.m_brimMap.at(print_object_ID_t).entities.empty()) { // contain brim
for (const ExtrusionEntity *entities_temp : print.m_brimMap.at(print_object_ID_t).entities) {
Polygons temp_Expolys;
entities_temp->polygons_covered_by_spacing(temp_Expolys, 0.0f);
for (Polygon &temp_Expoly : temp_Expolys) { area_sum_temp += temp_Expoly.area(); }
}
}
}
// wipe tower area
if (has_wipe_tower) {
Polygon temp_Expoly = print.wipe_tower_data().wipe_tower_mesh_data->bottom;
area_sum_temp += temp_Expoly.area();
}
bool hold_chamber_temp_for_flat_print = max_hight_temp > 0 && max_hight_temp < pring_hight_threshold && area_sum_temp > print_area_sum_threshold * 1.0e10;
this->placeholder_parser().set("hold_chamber_temp_for_flat_print", new ConfigOptionBool(hold_chamber_temp_for_flat_print));
}
std::string machine_start_gcode = this->placeholder_parser_process("machine_start_gcode", print.config().machine_start_gcode.value, initial_extruder_id);
if (print.config().gcode_flavor != gcfKlipper) {
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
@@ -2966,10 +3038,14 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (m_writer.need_toolchange(initial_extruder_id)) {
const PrintObjectConfig& object_config = object.config();
coordf_t initial_layer_print_height = print.config().initial_layer_print_height.value;
if (m_enable_exclude_object && print.config().support_object_skip_flush.value) {
m_filament_instances_code = _encode_label_ids_to_base64({(*print_object_instance_sequential_active)->model_instance->get_labeled_id()});
}
file.write(this->set_extruder(initial_extruder_id, initial_layer_print_height, true));
prime_extruder = true;
}
else {
} else {
file.write(this->retract());
}
file.write(m_writer.travel_to_z(m_max_layer_z + m_writer.config.z_hop.get_at(initial_extruder_id)));
@@ -3134,6 +3210,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
//BBS
config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position()(2) - m_config.z_offset.value));
config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z));
if (print.config().single_extruder_multi_material) {
// Process the filament_end_gcode for the active filament only.
int extruder_id = m_writer.filament()->id();
@@ -3373,6 +3450,7 @@ void GCode::process_layers(
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & fan_mover & pa_processor_filter & output);
else
tbb::parallel_pipeline(12, generator & cooling & fan_mover & pa_processor_filter & output);
}
// Process all layers of a single object instance (sequential mode) with a parallel pipeline:
@@ -4614,27 +4692,25 @@ LayerResult GCode::process_layer(
auto objects_by_extruder_it = by_extruder.find(filament_id);
if (objects_by_extruder_it == by_extruder.end()) continue;
bool has_prime_tower = print.config().enable_prime_tower && print.extruders().size() > 1 &&
((print.config().print_sequence == PrintSequence::ByLayer && print.config().print_order == PrintOrder::Default) ||
(print.config().print_sequence == PrintSequence::ByObject && print.objects().size() == 1));
if (has_prime_tower) {
int plate_idx = print.get_plate_index();
Point wt_pos(print.config().wipe_tower_x.get_at(plate_idx), print.config().wipe_tower_y.get_at(plate_idx));
int plate_idx = print.get_plate_index();
Point wt_pos(print.config().wipe_tower_x.get_at(plate_idx), print.config().wipe_tower_y.get_at(plate_idx));
std::vector<GCode::ObjectByExtruder> &objects_by_extruder = objects_by_extruder_it->second;
std::vector<const PrintObject *> print_objects;
for (int obj_idx = 0; obj_idx < objects_by_extruder.size(); obj_idx++) {
auto &object_by_extruder = objects_by_extruder[obj_idx];
if (object_by_extruder.islands.empty() && (object_by_extruder.support == nullptr || object_by_extruder.support->empty())) continue;
std::vector<GCode::ObjectByExtruder> &objects_by_extruder = objects_by_extruder_it->second;
std::vector<const PrintObject *> print_objects;
for (int obj_idx = 0; obj_idx < objects_by_extruder.size(); obj_idx++) {
auto &object_by_extruder = objects_by_extruder[obj_idx];
if (object_by_extruder.islands.empty() && (object_by_extruder.support == nullptr || object_by_extruder.support->empty())) continue;
print_objects.push_back(print.get_object(obj_idx));
}
print_objects.push_back(print.get_object(obj_idx));
}
std::vector<const PrintInstance *> new_ordering = chain_print_object_instances(print_objects, &wt_pos);
std::reverse(new_ordering.begin(), new_ordering.end());
filament_to_print_instances[filament_id] = sort_print_object_instances(objects_by_extruder_it->second, layers, &new_ordering, single_object_instance_idx);
} else {
std::vector<const PrintInstance *> new_ordering = chain_print_object_instances(print_objects, &wt_pos);
std::reverse(new_ordering.begin(), new_ordering.end());
if (print.config().print_sequence == PrintSequence::ByObject) {
filament_to_print_instances[filament_id] = sort_print_object_instances(objects_by_extruder_it->second, layers, ordering, single_object_instance_idx);
} else {
filament_to_print_instances[filament_id] = sort_print_object_instances(objects_by_extruder_it->second, layers, &new_ordering, single_object_instance_idx);
}
}
}
@@ -4707,7 +4783,7 @@ LayerResult GCode::process_layer(
if (!need_insert_timelapse_gcode_for_traditional) { // Equivalent to the timelapse gcode placed in layer_change_gcode
if (FILAMENT_CONFIG(retract_when_changing_layer)) {
gcode += this->retract(false, false, auto_lift_type);
gcode += this->retract(false, false, auto_lift_type, true);
}
gcode += insert_timelapse_gcode();
}
@@ -4746,6 +4822,12 @@ LayerResult GCode::process_layer(
gcode += generate_skirt(print, print.skirt(), Point(0, 0), layer.object()->config().skirt_start_angle, layer_tools, layer,
extruder_id);
if (print.config().print_sequence == PrintSequence::ByLayer && m_enable_exclude_object && print.config().support_object_skip_flush.value) {
std::vector<size_t> filament_instances_id;
for (InstanceToPrint &instance : filament_to_print_instances[extruder_id]) filament_instances_id.emplace_back(instance.label_object_id);
m_filament_instances_code = _encode_label_ids_to_base64(filament_instances_id);
}
std::string gcode_toolchange;
if (has_wipe_tower) {
if (!m_wipe_tower->is_empty_wipe_tower_gcode(*this, extruder_id, extruder_id == layer_tools.extruders.back())) {
@@ -4758,7 +4840,7 @@ LayerResult GCode::process_layer(
}
if (should_insert) {
gcode += this->retract(false, false, auto_lift_type);
gcode += this->retract(false, false, auto_lift_type, true);
m_writer.add_object_change_labels(gcode);
gcode += insert_timelapse_gcode();
@@ -4767,17 +4849,20 @@ LayerResult GCode::process_layer(
}
if (print.config().enable_wrapping_detection && !has_insert_wrapping_detection_gcode) {
gcode += this->retract(false, false, auto_lift_type);
gcode += this->retract(false, false, auto_lift_type, true);
gcode += insert_wrapping_detection_gcode();
has_insert_wrapping_detection_gcode = true;
}
gcode_toolchange = m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back());
}
} else {
if (m_writer.need_toolchange(extruder_id) &&
m_config.nozzle_diameter.values.size() == 2 && writer().filament() &&
if (need_insert_timelapse_gcode_for_traditional &&
!has_insert_timelapse_gcode &&
m_writer.need_toolchange(extruder_id) &&
m_config.nozzle_diameter.values.size() == 2 &&
writer().filament() &&
(get_extruder_id(writer().filament()->id()) == most_used_extruder)) {
gcode += this->retract(false, false, auto_lift_type);
gcode += this->retract(false, false, auto_lift_type, true);
m_writer.add_object_change_labels(gcode);
gcode += insert_timelapse_gcode();
@@ -4785,7 +4870,7 @@ LayerResult GCode::process_layer(
}
if (print.config().enable_wrapping_detection && !has_insert_wrapping_detection_gcode) {
gcode += this->retract(false, false, auto_lift_type);
gcode += this->retract(false, false, auto_lift_type, true);
gcode += insert_wrapping_detection_gcode();
has_insert_wrapping_detection_gcode = true;
}
@@ -4860,6 +4945,7 @@ LayerResult GCode::process_layer(
// To control print speed of the 1st object layer printed over raft interface.
bool object_layer_over_raft = layer_to_print.object_layer && layer_to_print.object_layer->id() > 0 &&
instance_to_print.print_object.slicing_parameters().raft_layers() == layer_to_print.object_layer->id();
m_config.apply(print.default_region_config());
m_config.apply(instance_to_print.print_object.config(), true);
m_layer = layer_to_print.layer();
m_object_layer_over_raft = object_layer_over_raft;
@@ -4989,7 +5075,7 @@ LayerResult GCode::process_layer(
gcode += this->extrude_perimeters(print, by_region_specific, first_layer, false);
if (!has_wipe_tower && need_insert_timelapse_gcode_for_traditional && printer_structure == PrinterStructure::psI3
&& !has_insert_timelapse_gcode && has_infill(by_region_specific)) {
gcode += this->retract(false, false, auto_lift_type);
gcode += this->retract(false, false, auto_lift_type, true);
gcode += insert_timelapse_gcode();
has_insert_timelapse_gcode = true;
@@ -5074,7 +5160,7 @@ LayerResult GCode::process_layer(
m_support_traditional_timelapse = false;
}
if (FILAMENT_CONFIG(retract_when_changing_layer)) {
gcode += this->retract(false, false, auto_lift_type);
gcode += this->retract(false, false, auto_lift_type, true);
}
m_writer.add_object_change_labels(gcode);
@@ -6811,7 +6897,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
m_wipe.reset_path();*/
Point last_post_before_retract = this->last_pos();
gcode += this->retract(false, false, lift_type, role);
gcode += this->retract(false, false, lift_type, false, role);
// When "Wipe while retracting" is enabled, then extruder moves to another position, and travel from this position can cross perimeters.
// Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction()
// FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations.
@@ -6890,7 +6976,7 @@ LiftType GCode::to_lift_type(ZHopType z_hop_types) {
case ZHopType::zhtNormal:
return LiftType::NormalLift;
case ZHopType::zhtSlope:
return LiftType::LazyLift;
return LiftType::SlopeLift;
case ZHopType::zhtSpiral:
return LiftType::SpiralLift;
default:
@@ -6981,7 +7067,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
//Better way is judging whether the travel move direction is same with last extrusion move.
if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter) {
if (ZHopType(FILAMENT_CONFIG(z_hop_types)) == ZHopType::zhtAuto) {
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift;
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::SlopeLift;
}
else {
lift_type = to_lift_type(ZHopType(FILAMENT_CONFIG(z_hop_types)));
@@ -7015,7 +7101,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
// retract if reduce_infill_retraction is disabled or doesn't apply when role is perimeter
if (ZHopType(FILAMENT_CONFIG(z_hop_types)) == ZHopType::zhtAuto) {
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift;
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::SlopeLift;
}
else {
lift_type = to_lift_type(ZHopType(FILAMENT_CONFIG(z_hop_types)));
@@ -7023,7 +7109,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
return true;
}
std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type, ExtrusionRole role)
std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type, bool apply_instantly, ExtrusionRole role)
{
std::string gcode;
@@ -7072,7 +7158,10 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li
}
if (needs_lift && can_lift) {
gcode += m_writer.lift(lift_type, m_spiral_vase != nullptr);
if (apply_instantly)
gcode += m_writer.eager_lift(lift_type);
else
gcode += m_writer.lazy_lift(lift_type, m_spiral_vase != nullptr);
}
return gcode;
@@ -7131,6 +7220,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
if (by_object)
m_writer.add_object_change_labels(gcode);
bool add_change_filament_624 = false;
if (m_writer.filament() != nullptr) {
// Process the custom filament_end_gcode. set_extruder() is only called if there is no wipe tower
// so it should not be injected twice.
@@ -7142,6 +7232,11 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position().z() - m_config.z_offset.value));
config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z));
config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(get_extruder_id(old_filament_id))));
if (!m_filament_instances_code.empty()) {
gcode += ("M624 " + m_filament_instances_code + "\n");
m_filament_instances_code = "";
add_change_filament_624 = true;
}
gcode += placeholder_parser_process("filament_end_gcode", filament_end_gcode, old_filament_id, &config);
check_add_eol(gcode);
}
@@ -7286,7 +7381,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
std::string change_filament_gcode = m_config.change_filament_gcode.value;
// Move the lift gcode here which is in the change_filament_gcode originally
change_filament_gcode = this->retract(false, false, LiftType::SpiralLift) + change_filament_gcode;
change_filament_gcode = this->retract(false, false, LiftType::SpiralLift, true) + change_filament_gcode;
std::string toolchange_gcode_parsed;
//Orca: Ignore change_filament_gcode if is the first call for a tool change and manual_filament_change is enabled
@@ -7353,6 +7448,10 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z));
config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(new_filament_id)));
gcode += this->placeholder_parser_process("filament_start_gcode", filament_start_gcode, new_filament_id, &config);
if (add_change_filament_624) {
gcode += "M625\n";
add_change_filament_624 = false;
}
check_add_eol(gcode);
}
// Set the new extruder to the operating temperature.
+2 -1
View File
@@ -246,7 +246,7 @@ public:
std::string travel_to(const Point& point, ExtrusionRole role, std::string comment, double z = DBL_MAX);
bool needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type);
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::NormalLift, ExtrusionRole role = erNone);
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::NormalLift, bool apply_instantly = false, ExtrusionRole role = erNone);
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
std::string set_extruder(unsigned int extruder_id, double print_z, bool by_object=false);
bool is_BBL_Printer();
@@ -631,6 +631,7 @@ private:
coordf_t m_nominal_z;
bool m_need_change_layer_lift_z = false;
int m_start_gcode_filament = -1;
std::string m_filament_instances_code;
std::set<unsigned int> m_initial_layer_extruders;
std::vector<std::vector<unsigned int>> m_sorted_layer_filaments;
+3
View File
@@ -288,6 +288,9 @@ ConflictComputeOpt ConflictChecker::line_intersect(const LineWithID &l1, const L
constexpr double SUPPORT_THRESHOLD = 100; // this large almost disables conflict check of supports
constexpr double OTHER_THRESHOLD = 0.01;
if (l1._id == l2._id) { return {}; } // return true if lines are from same object
double overlap_length = 0.;
bool overlap = l1._line.overlap(l2._line, overlap_length);
if (overlap && overlap_length > scaled(OTHER_THRESHOLD)) return std::make_optional<ConflictComputeResult>(l1._id, l2._id);
Point inter;
bool intersect = l1._line.intersection(l2._line, &inter);
+2 -1
View File
@@ -33,8 +33,9 @@ struct ExtrusionLayer
enum class ExtrusionLayersType { INFILL, PERIMETERS, SUPPORT, WIPE_TOWER };
struct ExtrusionLayers : public std::vector<ExtrusionLayer>
class ExtrusionLayers : public std::vector<ExtrusionLayer>
{
public:
ExtrusionLayersType type;
};
+10 -1
View File
@@ -2440,6 +2440,13 @@ void GCodeProcessor::process_file(const std::string& filename, std::function<voi
// thus a probability of incorrect substitution is low and the G-code viewer is a consumer-only anyways.
config.load_from_gcode_file(filename, ForwardCompatibilitySubstitutionRule::EnableSilent);
// Get the correct printer vendor based on the `printer_model` field
auto printer_model_opt = config.opt<ConfigOptionString>("printer_model");
if (printer_model_opt && !printer_model_opt->value.empty()) {
// TODO: Orca hack, proper vendor check?
GCodeProcessor::s_IsBBLPrinter = boost::starts_with(printer_model_opt->value, "Bambu Lab");
}
ConfigOptionStrings *filament_color = config.opt<ConfigOptionStrings>("filament_colour");
ConfigOptionInts *filament_map = config.opt<ConfigOptionInts>("filament_map", true);
if (filament_color && filament_color->size() != filament_map->size()) {
@@ -2524,11 +2531,13 @@ void GCodeProcessor::finalize(bool post_process)
auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [](const std::pair<ExtrusionRole, float>& item) { return erCustom == item.first; });
auto prepare_time = (it != time_mode.roles_times.end()) ? it->second : 0.0f;
std::vector<float>& layer_times = m_result.print_statistics.modes[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].layers_times;
m_result.initial_layer_time = layer_times.size() > 0 ? std::max(float(0.0), layer_times[0] - prepare_time) : 0;
//update times for results
for (size_t i = 0; i < m_result.moves.size(); i++) {
//field layer_duration contains the layer id for the move in which the layer_duration has to be set.
size_t layer_id = size_t(m_result.moves[i].layer_duration);
std::vector<float>& layer_times = m_result.print_statistics.modes[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].layers_times;
if (layer_times.size() > layer_id - 1 && layer_id > 0)
m_result.moves[i].layer_duration = layer_id == 1 ? std::max(0.f,layer_times[layer_id - 1] - prepare_time) : layer_times[layer_id - 1];
else
+2
View File
@@ -161,6 +161,7 @@ class Print;
ConflictResultOpt conflict_result;
GCodeCheckResult gcode_check_result;
FilamentPrintableResult filament_printable_reuslt;
float initial_layer_time;
struct SettingsIds
{
@@ -300,6 +301,7 @@ class Print;
filament_printable_reuslt = other.filament_printable_reuslt;
layer_filaments = other.layer_filaments;
filament_change_count_map = other.filament_change_count_map;
initial_layer_time = other.initial_layer_time;
#if ENABLE_GCODE_VIEWER_STATISTICS
time = other.time;
#endif
+2
View File
@@ -78,6 +78,7 @@ struct PlateBBoxData
int first_extruder = 0;
float nozzle_diameter = 0.4;
std::string bed_type;
float first_layer_time;
// version 1: use view type ColorPrint (filament color)
// version 2: use view type FilamentId (filament id)
int version = 2;
@@ -91,6 +92,7 @@ struct PlateBBoxData
j["nozzle_diameter"] = nozzle_diameter;
j["version"] = version;
j["bed_type"] = bed_type;
j["first_layer_time"] = first_layer_time;
for (const auto& bbox : bbox_objs) {
nlohmann::json j_bbox;
bbox.to_json(j_bbox);
+31 -8
View File
@@ -380,19 +380,42 @@ namespace Slic3r {
std::priority_queue<CandidatePoint> max_heap;
double min_distance = std::numeric_limits<double>::max();
Point nearest_point = DefaultTimelapsePos;
const double candidate_point_segment = scale_(5), weight_of_camera=1./3.;
auto penaltyFunc = [&weight_of_camera](const Point &curr_post, const Point &CameraPos, const Point &candidatet) -> double {
// move distance + Camera occlusion penalty function
double ret_pen = (curr_post - candidatet).cwiseAbs().sum() - weight_of_camera * (CameraPos - candidatet).cwiseAbs().sum();
return ret_pen;
};
for (const auto& expoly : safe_areas) {
Polygons polys = to_polygons(expoly);
for (auto& poly : polys) {
for (size_t idx = 0; idx < poly.points.size(); ++idx) {
Line line(poly.points[idx], poly.points[next_idx_modulo(idx, poly.points)]);
Point candidate;
double dist = line.distance_to_squared(curr_pos, &candidate);
max_heap.push({ dist,candidate });
if (max_heap.size() > MAX_CANDIDATE_SIZE)
max_heap.pop();
double best_penalty = std::numeric_limits<double>::max();
Point best_candidate = DefaultTimelapsePos; // the best candidate form current line
//std::vector<Point> candidate_source;
if ((poly.points[idx] - poly.points[next_idx_modulo(idx, poly.points)]).cwiseAbs().sum() < candidate_point_segment) {
best_candidate = poly.points[idx]; // only check the start point if the line is short
best_penalty = penaltyFunc(curr_pos, DefaultCameraPos, best_candidate);
}else{
Point direct_of_line = poly.points[next_idx_modulo(idx, poly.points)] - poly.points[idx];
double length_L1 = direct_of_line.cwiseAbs().sum();
int num_steps = static_cast<int>(length_L1 / candidate_point_segment); // for long line use 5mm segmentation to check
// devide by length_L1 instead of steps, prevent lose accuracy for the step length
direct_of_line.x() = static_cast<coord_t>(static_cast<double> (direct_of_line.x()) * candidate_point_segment / length_L1);
direct_of_line.y() = static_cast<coord_t>(static_cast<double> (direct_of_line.y()) * candidate_point_segment / length_L1);
Point candidate;
for (int line_seg_i = 0; line_seg_i <= num_steps; ++line_seg_i) {
candidate=poly.points[idx] + direct_of_line * line_seg_i;
double dist = penaltyFunc(curr_pos, DefaultCameraPos, candidate);
if (dist < best_penalty) {
best_penalty = dist;
best_candidate = candidate;
}//only push the best point into heap for the whole line
}
}
max_heap.push({best_penalty, best_candidate});
if (max_heap.size() > MAX_CANDIDATE_SIZE) max_heap.pop();
}
}
}
+16
View File
@@ -928,6 +928,22 @@ void ToolOrdering::cal_most_used_extruder(const PrintConfig &config)
}
}
float ToolOrdering::cal_max_additional_fan(const PrintConfig &config)
{
// record
float max_fan = 0;
for (LayerTools &layer_tools : m_layer_tools) {
std::vector<unsigned int> filaments = layer_tools.extruders;
std::set<int> layer_extruder_count;
// count once only
for (unsigned int &filament : filaments)
if (max_fan < config.additional_cooling_fan_speed.get_at(filament))
max_fan = config.additional_cooling_fan_speed.get_at(filament);
}
return max_fan;
}
//BBS: find first non support filament
bool ToolOrdering::cal_non_support_filaments(const PrintConfig &config,
unsigned int & first_non_support_filament,
+1
View File
@@ -246,6 +246,7 @@ public:
// should be called after doing reorder
FilamentChangeStats get_filament_change_stats(FilamentChangeMode mode);
void cal_most_used_extruder(const PrintConfig &config);
float cal_max_additional_fan(const PrintConfig &config);
bool cal_non_support_filaments(const PrintConfig &config,
unsigned int & first_non_support_filament,
std::vector<int> & initial_non_support_filaments,
+3 -2
View File
@@ -3771,9 +3771,10 @@ void WipeTower::plan_tower_new()
}
update_all_layer_depth(max_depth);
m_rib_length = std::max({m_rib_length, sqrt(m_wipe_tower_depth * m_wipe_tower_depth + m_wipe_tower_width * m_wipe_tower_width)});
float diagonal = sqrt(m_wipe_tower_depth * m_wipe_tower_depth + m_wipe_tower_width * m_wipe_tower_width);
m_rib_length = std::max({m_rib_length, diagonal});
m_rib_length += m_extra_rib_length;
m_rib_length = std::max(0.f, m_rib_length);
m_rib_length = std::max(diagonal, m_rib_length);
m_rib_width = std::min(m_rib_width, std::min(m_wipe_tower_depth, m_wipe_tower_width) / 2.f); // Ensure that the rib wall of the wipetower are attached to the infill.
}
+67 -30
View File
@@ -528,6 +528,71 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
return w.string();
}
/* If this method is called more than once before calling unlift(),
it will not perform subsequent lifts, even if Z was raised manually
(i.e. with travel_to_z()) and thus _lifted was reduced. */
std::string GCodeWriter::lazy_lift(LiftType lift_type, bool spiral_vase)
{
// check whether the above/below conditions are met
double target_lift = 0;
{
//BBS
int extruder_id = filament()->extruder_id();
int filament_id = filament()->id();
double above = this->config.retract_lift_above.get_at(extruder_id);
double below = this->config.retract_lift_below.get_at(extruder_id);
if (m_pos.z() >= above && m_pos.z() <= below)
target_lift = this->config.z_hop.get_at(filament_id);
}
// BBS
if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) {
if (spiral_vase) {
m_lifted = target_lift;
return this->_travel_to_z(m_pos(2) + target_lift, "lift Z");
}
else {
m_to_lift = target_lift;
m_to_lift_type = lift_type;
}
}
return "";
}
// BBS: immediately execute an undelayed lift move with a spiral lift pattern
// designed specifically for subsequent gcode injection (e.g. timelapse)
std::string GCodeWriter::eager_lift(const LiftType type) {
std::string lift_move;
double target_lift = 0;
{
//BBS
int extruder_id = filament()->extruder_id();
int filament_id = filament()->id();
double above = this->config.retract_lift_above.get_at(extruder_id);
double below = this->config.retract_lift_below.get_at(extruder_id);
if (m_pos.z() >= above && m_pos.z() <= below)
target_lift = this->config.z_hop.get_at(filament_id);
}
// BBS: spiral lift only safe with known position
// TODO: check the arc will move within bed area
if (type == LiftType::SpiralLift && this->is_current_position_clear()) {
double radius = target_lift / (2 * PI * atan(filament()->travel_slope()));
// static spiral alignment when no move in x,y plane.
// spiral centra is a radius distance to the right (y=0)
Vec2d ij_offset = { radius, 0 };
if (target_lift > 0) {
lift_move = this->_spiral_travel_to_z(m_pos(2) + target_lift, ij_offset, "spiral lift Z");
}
}
//BBS: if position is unknown use normal lift
else if (target_lift > 0) {
lift_move = _travel_to_z(m_pos(2) + target_lift, "normal lift Z");
}
m_lifted = target_lift;
m_to_lift = 0;
return lift_move;
}
std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment, bool force_z)
{
// FIXME: This function was not being used when travel_speed_z was separated (bd6badf).
@@ -573,8 +638,8 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
ij_offset = { -ij_offset(1), ij_offset(0) };
slop_move = this->_spiral_travel_to_z(target(2), ij_offset, "spiral lift Z");
}
//BBS: LazyLift
else if (m_to_lift_type == LiftType::LazyLift &&
//BBS: SlopeLift
else if (m_to_lift_type == LiftType::SlopeLift &&
this->is_current_position_clear() &&
atan2(delta(2), delta_no_z.norm()) < this->filament()->travel_slope()) {
//BBS: check whether we can make a travel like
@@ -871,34 +936,6 @@ std::string GCodeWriter::unretract()
return gcode;
}
/* If this method is called more than once before calling unlift(),
it will not perform subsequent lifts, even if Z was raised manually
(i.e. with travel_to_z()) and thus _lifted was reduced. */
std::string GCodeWriter::lift(LiftType lift_type, bool spiral_vase)
{
// check whether the above/below conditions are met
double target_lift = 0;
{
int extruder_id = filament()->extruder_id();
int filament_id = filament()->id();
double above = this->config.retract_lift_above.get_at(extruder_id);
double below = this->config.retract_lift_below.get_at(extruder_id);
if (m_pos(2) >= above && (below == 0 || m_pos(2) <= below))
target_lift = this->config.z_hop.get_at(filament_id);
}
// BBS
if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) {
if (spiral_vase) {
m_lifted = target_lift;
return this->_travel_to_z(m_pos(2) + target_lift, "lift Z");
}
else {
m_to_lift = target_lift;
m_to_lift_type = lift_type;
}
}
return "";
}
std::string GCodeWriter::unlift()
{
+4 -1
View File
@@ -83,7 +83,10 @@ public:
std::string retract(bool before_wipe = false, double retract_length = 0);
std::string retract_for_toolchange(bool before_wipe = false, double retract_length = 0);
std::string unretract();
std::string lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
// do lift instantly
std::string eager_lift(const LiftType type);
// record a lift request, do realy lift in next travel
std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
std::string unlift();
const Vec3d& get_position() const { return m_pos; }
Vec3d& get_position() { return m_pos; }
+2 -2
View File
@@ -123,8 +123,8 @@ inline bool segments_intersect(
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
const Slic3r::Point &jp1, const Slic3r::Point &jp2)
{
assert(ip1 != ip2);
assert(jp1 != jp2);
//assert(ip1 != ip2);
//assert(jp1 != jp2);
auto segments_could_intersect = [](
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
+14 -1
View File
@@ -76,7 +76,20 @@ bool Line::parallel_to(const Line& line) const
const Vec2d v2 = (line.b - line.a).cast<double>();
return sqr(cross2(v1, v2)) < sqr(EPSILON) * v1.squaredNorm() * v2.squaredNorm();
}
bool Line::overlap(const Line &line, double &overlap_length) const
{
if (!this->parallel_to(line)) return false;
Line line_(this->a, line.a);
if (line_.length() > scaled(EPSILON) && !this->parallel_to(line_)) return false;
coord_t a_min = std::min(this->a.x(), this->b.x());
coord_t a_max = std::max(this->a.x(), this->b.x());
coord_t b_min = std::min(line.a.x(), line.b.x());
coord_t b_max = std::max(line.a.x(), line.b.x());
if (a_min>b_max||a_max<b_min) return false;
overlap_length = std::max((coord_t)0, std::min(a_max, b_max) - std::max(a_min, b_min));
overlap_length /= ((double) a_max - a_min) / this->length();
return true;
}
bool Line::perpendicular_to(double angle) const
{
return Slic3r::Geometry::directions_perpendicular(this->direction(), angle);
+1 -1
View File
@@ -183,7 +183,7 @@ public:
bool clip_with_bbox(const BoundingBox &bbox);
// Extend the line from both sides by an offset.
void extend(double offset);
bool overlap(const Line &line, double &overlap_length) const;
static inline double distance_to_squared(const Point &point, const Point &a, const Point &b) { return line_alg::distance_to_squared(Line{a, b}, Vec<2, coord_t>{point}); }
static double distance_to(const Point &point, const Point &a, const Point &b) { return sqrt(distance_to_squared(point, a, b)); }
+16 -3
View File
@@ -1015,7 +1015,7 @@ static std::vector<std::string> s_Preset_printer_options {
"printhost_cafile","printhost_port","printhost_authorization_type",
"printhost_user", "printhost_password", "printhost_ssl_ignore_revoke", "thumbnails", "thumbnails_format",
"use_relative_e_distances", "extruder_type", "use_firmware_retraction", "printer_notes",
"grab_length", "physical_extruder_map",
"grab_length", "support_object_skip_flush", "physical_extruder_map",
"cooling_tube_retraction",
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "purge_in_prime_tower", "enable_filament_ramming",
"z_offset",
@@ -1280,8 +1280,8 @@ void PresetCollection::load_presets(
preset.filament_id = key_values[BBL_JSON_KEY_FILAMENT_ID];
if (key_values.find(BBL_JSON_KEY_DESCRIPTION) != key_values.end())
preset.description = key_values[BBL_JSON_KEY_DESCRIPTION];
if (key_values.find("instantiation") != key_values.end())
preset.is_visible = key_values["instantiation"] != "false";
if (key_values.find(BBL_JSON_KEY_INSTANTIATION) != key_values.end())
preset.is_visible = key_values[BBL_JSON_KEY_INSTANTIATION] != "false";
//Orca: find and use the inherit config as the base
Preset* inherit_preset = nullptr;
@@ -1329,6 +1329,18 @@ void PresetCollection::load_presets(
<< "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed";
}
if (preset.type == Preset::TYPE_FILAMENT && preset.is_user() && preset.inherits().empty()) {
auto compatible_printers = dynamic_cast<ConfigOptionStrings *>(preset.config.option("compatible_printers", true));
if (compatible_printers && compatible_printers->values.empty()) {
size_t at_pos = name.find('@');
if (at_pos != std::string::npos && at_pos + 1 < name.length()) {
compatible_printers->values.push_back(name.substr(at_pos + 1));
preset.save(nullptr);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " added compatible_printers for preset: " << name;
}
}
}
preset.loaded = true;
//BBS: add some workaround for previous incorrect settings
if ((!preset.setting_id.empty())&&(preset.setting_id == preset.base_id))
@@ -1358,6 +1370,7 @@ void PresetCollection::load_presets(
if (fs::exists(file_path))
fs::remove(file_path);
}
presets_loaded.emplace_back(preset);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " load config successful and preset name is:" << preset.name;
} catch (const std::runtime_error &err) {
+2
View File
@@ -62,6 +62,7 @@
#define BBL_JSON_KEY_BED_TEXTURE "bed_texture"
#define BBL_JSON_KEY_IMAGE_BED_TYPE "image_bed_type"
#define BBL_JSON_KEY_BOTTOM_TEXTURE_END_NAME "bottom_texture_end_name"
#define BBL_JSON_KEY_USE_DOUBLE_EXTRUDER_DEFAULT_TEXTURE "use_double_extruder_default_texture"
#define BBL_JSON_KEY_BOTTOM_TEXTURE_RECT "bottom_texture_rect"
#define BBL_JSON_KEY_MIDDLE_TEXTURE_RECT "middle_texture_rect"
@@ -127,6 +128,7 @@ public:
std::string bed_texture;
std::string image_bed_type;
std::string bottom_texture_end_name;
std::string use_double_extruder_default_texture;
std::string bottom_texture_rect;
std::string middle_texture_rect;
std::string hotend_model;
+17 -10
View File
@@ -2189,7 +2189,7 @@ void PresetBundle::set_num_filaments(unsigned int n, std::vector<std::string> ne
}
void PresetBundle::set_num_filaments(unsigned int n, std::string new_color)
{
int old_filament_count = this->filament_presets.size();
unsigned old_filament_count = this->filament_presets.size();
if (n > old_filament_count && old_filament_count != 0)
filament_presets.resize(n, filament_presets.back());
else {
@@ -2208,7 +2208,7 @@ void PresetBundle::set_num_filaments(unsigned int n, std::string new_color)
//BBS set new filament color to new_color
if (old_filament_count < n) {
if (!new_color.empty()) {
for (int i = old_filament_count; i < n; i++) {
for (unsigned i = old_filament_count; i < n; i++) {
filament_color->values[i] = new_color;
filament_multi_color->values[i] = new_color;
filament_color_type->values[i] = "1"; // default color type
@@ -2221,7 +2221,7 @@ void PresetBundle::set_num_filaments(unsigned int n, std::string new_color)
void PresetBundle::update_num_filaments(unsigned int to_del_flament_id)
{
int old_filament_count = this->filament_presets.size();
unsigned old_filament_count = this->filament_presets.size();
assert(to_del_flament_id < old_filament_count);
filament_presets.erase(filament_presets.begin() + to_del_flament_id);
@@ -2543,21 +2543,26 @@ unsigned int PresetBundle::sync_ams_list(std::vector<std::pair<DynamicPrintConfi
exist_multi_color_filment.push_back(need_append_colors[i].mutli_filament_color);
}
}
filament_color->resize(exist_colors.size());
filament_color->values = exist_colors;
filament_color_type->resize(exist_colors.size());
filament_color_type->values = exist_color_types;
ams_multi_color_filment = exist_multi_color_filment;
this->filament_presets = exist_filament_presets;
filament_map->values.resize(exist_filament_presets.size(), 1);
}
else {//overwrite
filament_color->resize(ams_filament_presets.size());
else {//overwrite;
filament_color->values = ams_filament_colors;
filament_color_type->resize(ams_filament_presets.size());
filament_color_type->values = ams_filament_color_types;
this->filament_presets = ams_filament_presets;
filament_map->values.resize(ams_filament_colors.size(), 1);
auto& print_config = this->prints.get_edited_preset().config;
auto support_filament_opt = print_config.option<ConfigOptionInt>("support_filament");
auto support_interface_filament_opt = print_config.option<ConfigOptionInt>("support_interface_filament");
if (support_filament_opt->value > ams_filament_color_types.size())
support_filament_opt->value = 0;
if (support_interface_filament_opt->value > ams_filament_color_types.size())
support_interface_filament_opt->value = 0;
}
// Update ams_multi_color_filment
update_filament_multi_color();
@@ -2776,7 +2781,7 @@ Preset *PresetBundle::get_similar_printer_preset(std::string printer_model, std:
//BBS: check whether this is the only edited filament
bool PresetBundle::is_the_only_edited_filament(unsigned int filament_index)
{
int n = this->filament_presets.size();
unsigned n = this->filament_presets.size();
if (filament_index >= n)
return false;
@@ -2785,7 +2790,7 @@ bool PresetBundle::is_the_only_edited_filament(unsigned int filament_index)
if (edited_preset.name != name)
return false;
int index = 0;
unsigned index = 0;
while (index < n)
{
if (index == filament_index) {
@@ -3725,6 +3730,8 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_vendor_configs_
model.bed_model = it.value();
} else if (boost::iequals(it.key(), BBL_JSON_KEY_BOTTOM_TEXTURE_END_NAME)) {
model.bottom_texture_end_name = it.value();
} else if (boost::iequals(it.key(), BBL_JSON_KEY_USE_DOUBLE_EXTRUDER_DEFAULT_TEXTURE)) {
model.use_double_extruder_default_texture = it.value();
} else if (boost::iequals(it.key(), BBL_JSON_KEY_BOTTOM_TEXTURE_RECT)) {
model.bottom_texture_rect = it.value();
} else if (boost::iequals(it.key(), BBL_JSON_KEY_MIDDLE_TEXTURE_RECT)) {
+9 -5
View File
@@ -2252,6 +2252,8 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
m_skirt.clear();
m_skirt_convex_hull.clear();
m_first_layer_convex_hull.points.clear();
for (PrintObject *object : m_objects) object->m_skirt.clear();
const bool draft_shield = config().draft_shield != dsDisabled;
if (this->has_skirt() && draft_shield) {
@@ -4121,7 +4123,7 @@ static void convert_layer_region_from_json(const json& j, LayerRegion& layer_reg
if (!ret) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":error parsing thin_fills found at layer %1%, print_z %2%") %layer_region.layer()->id() %layer_region.layer()->print_z;
char error_buf[1024];
::sprintf(error_buf, "Error while parsing thin_fills at layer %zd, print_z %f", layer_region.layer()->id(), layer_region.layer()->print_z);
::sprintf(error_buf, "Error while parsing thin_fills at layer %zu, print_z %f", layer_region.layer()->id(), layer_region.layer()->print_z);
throw Slic3r::FileIOError(error_buf);
}
}
@@ -4176,7 +4178,7 @@ static void convert_layer_region_from_json(const json& j, LayerRegion& layer_reg
if (!ret) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": error parsing perimeters found at layer %1%, print_z %2%") %layer_region.layer()->id() %layer_region.layer()->print_z;
char error_buf[1024];
::sprintf(error_buf, "Error while parsing perimeters at layer %zd, print_z %f", layer_region.layer()->id(), layer_region.layer()->print_z);
::sprintf(error_buf, "Error while parsing perimeters at layer %zu, print_z %f", layer_region.layer()->id(), layer_region.layer()->print_z);
throw Slic3r::FileIOError(error_buf);
}
}
@@ -4191,7 +4193,7 @@ static void convert_layer_region_from_json(const json& j, LayerRegion& layer_reg
if (!ret) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": error parsing fills found at layer %1%, print_z %2%") %layer_region.layer()->id() %layer_region.layer()->print_z;
char error_buf[1024];
::sprintf(error_buf, "Error while parsing fills at layer %zd, print_z %f", layer_region.layer()->id(), layer_region.layer()->print_z);
::sprintf(error_buf, "Error while parsing fills at layer %zu, print_z %f", layer_region.layer()->id(), layer_region.layer()->print_z);
throw Slic3r::FileIOError(error_buf);
}
}
@@ -4272,7 +4274,7 @@ void extract_support_layer(const json& support_layer_json, SupportLayer& support
if (!ret) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": error parsing fills found at support_layer %1%, print_z %2%")%support_layer.id() %support_layer.print_z;
char error_buf[1024];
::sprintf(error_buf, "Error while parsing fills at support_layer %zd, print_z %f", support_layer.id(), support_layer.print_z);
::sprintf(error_buf, "Error while parsing fills at support_layer %zu, print_z %f", support_layer.id(), support_layer.print_z);
throw Slic3r::FileIOError(error_buf);
}
}
@@ -4861,7 +4863,7 @@ void WipeTowerData::construct_mesh(float width, float depth, float height, float
wipe_tower_mesh_data = WipeTowerMeshData{};
float first_layer_height=0.08; //brim height
if (width < EPSILON || depth < EPSILON || height < EPSILON) return;
if (!is_rib_wipe_tower) {
if (!is_rib_wipe_tower || rib_length < EPSILON) {
wipe_tower_mesh_data->real_wipe_tower_mesh = make_cube(width, depth, height);
wipe_tower_mesh_data->real_brim_mesh = make_cube(width + 2 * brim_width, depth + 2 * brim_width, first_layer_height);
wipe_tower_mesh_data->real_brim_mesh.translate({-brim_width, -brim_width, 0});
@@ -4878,6 +4880,8 @@ void WipeTowerData::construct_mesh(float width, float depth, float height, float
wipe_tower_mesh_data->real_brim_mesh.translate(Vec3f(rib_offset[0], rib_offset[1], 0));
wipe_tower_mesh_data->bottom.translate(scaled(Vec2f(rib_offset[0], rib_offset[1])));
}
//wipe_tower_mesh_data->real_wipe_tower_mesh.write_ascii("../wipe_tower_mesh.obj");
//wipe_tower_mesh_data->real_brim_mesh.write_ascii("../wipe_tower_brim_mesh.obj");
}
} // namespace Slic3r
+8 -2
View File
@@ -2370,6 +2370,9 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloat { 0. });
def = this->add("support_object_skip_flush", coBool);
def->set_default_value(new ConfigOptionBool(false));
def = this->add("bed_temperature_formula", coEnum);
def->label = L("Bed temperature type");
def->tooltip = L("This option determines how the bed temperature is set during slicing: based on the temperature of the first filament or the highest temperature of the printed filaments.");
@@ -6275,10 +6278,11 @@ void PrintConfigDef::init_fff_params()
def = this->add("wipe_tower_rib_width", coFloat);
def->label = L("Rib width");
def->tooltip = L("Rib width.");
def->tooltip = L("Rib width is always less than half the prime tower side length.");
def->sidetext = L("mm"); // milimeters, CIS languages need translation
def->mode = comAdvanced;
def->min = 0;
def->max = 300;
def->set_default_value(new ConfigOptionFloat(8));
def = this->add("wipe_tower_fillet_wall", coBool);
@@ -7505,6 +7509,8 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
opt_key = "wipe_tower_fillet_wall";
} else if (opt_key == "extruder_clearance_max_radius") {
opt_key = "extruder_clearance_radius";
} else if (opt_key == "machine_switch_extruder_time") {
opt_key = "machine_tool_change_time";
}
// Ignore the following obsolete configuration keys:
@@ -8779,7 +8785,7 @@ void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig&
auto opt_nozzle_volume_type = dynamic_cast<const ConfigOptionEnumsGeneric*>(printer_config.option("nozzle_volume_type"));
std::vector<int> variant_index;
if (extruder_id > 0 && extruder_id <= extruder_count) {
if (extruder_id > 0 && extruder_id <= static_cast<unsigned> (extruder_count)) {
variant_index.resize(1);
ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(extruder_id - 1));
NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(extruder_id - 1));
+6 -3
View File
@@ -221,7 +221,7 @@ enum GapFillTarget {
enum LiftType {
NormalLift,
SpiralLift,
LazyLift
SlopeLift
};
enum SLAMaterial {
@@ -315,7 +315,8 @@ static std::unordered_map<NozzleType, std::string>NozzleTypeEumnToStr = {
{NozzleType::ntHardenedSteel, "hardened_steel"},
{NozzleType::ntStainlessSteel, "stainless_steel"},
{NozzleType::ntTungstenCarbide, "tungsten_carbide"},
{NozzleType::ntBrass, "brass"}
{NozzleType::ntBrass, "brass"},
{NozzleType::ntE3D, "E3D"}
};
static std::unordered_map<std::string, NozzleType>NozzleTypeStrToEumn = {
@@ -323,7 +324,8 @@ static std::unordered_map<std::string, NozzleType>NozzleTypeStrToEumn = {
{"hardened_steel", NozzleType::ntHardenedSteel},
{"stainless_steel", NozzleType::ntStainlessSteel},
{"tungsten_carbide", NozzleType::ntTungstenCarbide},
{"brass", NozzleType::ntBrass}
{"brass", NozzleType::ntBrass},
{"E3D", NozzleType::ntE3D}
};
// BBS
@@ -1262,6 +1264,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionInts, filament_map))
//((ConfigOptionInts, filament_extruder_id))
((ConfigOptionStrings, filament_extruder_variant))
((ConfigOptionBool, support_object_skip_flush))
((ConfigOptionEnum<BedTempFormula>, bed_temperature_formula))
((ConfigOptionInts, physical_extruder_map))
((ConfigOptionIntsNullable, nozzle_flush_dataset))
+1 -1
View File
@@ -80,7 +80,7 @@ public:
};
/*copied from AmsTray::get_display_filament_type()*/
std::string get_display_filament_type()
std::string get_display_filament_type() const
{
if (type == "PLA-S")
return "Sup.PLA";
+1
View File
@@ -81,6 +81,7 @@ public:
int tray_id;
int extruder_id;
NozzleVolumeType nozzle_volume_type;
BedType bed_type;
float nozzle_diameter;
std::string filament_id;
std::string setting_id;
+2 -1
View File
@@ -354,7 +354,8 @@ void set_log_path_and_level(const std::string& file, unsigned int level)
<< expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
<<"[Thread " << expr::attr<attrs::current_thread_id::value_type>("ThreadID") << "]"
<< ":" << expr::smessage
)
),
keywords::auto_flush = true
);
logging::add_common_attributes();
+6
View File
@@ -220,6 +220,8 @@ set(SLIC3R_GUI_SOURCES
GUI/GUI_Utils.hpp
GUI/HintNotification.cpp
GUI/HintNotification.hpp
GUI/ThermalPreconditioningDialog.cpp
GUI/ThermalPreconditioningDialog.hpp
GUI/HMS.cpp
GUI/HMS.hpp
GUI/HMSPanel.cpp
@@ -474,6 +476,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Widgets/AMSItem.hpp
GUI/Widgets/AxisCtrlButton.cpp
GUI/Widgets/AxisCtrlButton.hpp
GUI/SafetyOptionsDialog.hpp
GUI/SafetyOptionsDialog.cpp
GUI/Widgets/Button.cpp
GUI/Widgets/Button.hpp
GUI/Widgets/CheckBox.cpp
@@ -617,6 +621,8 @@ set(SLIC3R_GUI_SOURCES
Utils/WebSocketClient.hpp
Utils/WxFontUtils.cpp
Utils/WxFontUtils.hpp
Utils/FileTransferUtils.cpp
Utils/FileTransferUtils.hpp
)
add_subdirectory(GUI/DeviceCore)
+21 -24
View File
@@ -318,22 +318,14 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig
m_type = type;
//m_texture_filename = texture_filename;
m_model_filename = model_filename;
//BBS: add part plate logic
m_extended_bounding_box = this->calc_extended_bounding_box(false);
//BBS: add part plate logic
//BBS add default bed
m_triangles.reset();
if (with_reset) {
//m_texture.reset();
m_model.reset();
}
//BBS: add part plate logic, always update model offset
//else {
update_model_offset();
//}
update_model_offset();//include m_extended_bounding_box = this->calc_extended_bounding_box();
// Set the origin and size for rendering the coordinate system axes.
m_axes.set_origin({ 0.0, 0.0, static_cast<double>(GROUND_Z) });
@@ -407,9 +399,9 @@ void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix,
//BBS: add partplate related logic
// Calculate an extended bounding box from axes and current model for visualization purposes.
BoundingBoxf3 Bed3D::calc_extended_bounding_box(bool consider_model_offset) const
BoundingBoxf3 Bed3D::calc_printable_bounding_box() const
{
BoundingBoxf3 out { m_build_volume.bounding_volume() };
BoundingBoxf3 out{m_build_volume.bounding_volume()};
const Vec3d size = out.size();
// ensures that the bounding box is set as defined or the following calls to merge() will not work as intented
@@ -419,19 +411,22 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box(bool consider_model_offset) cons
out.min.z() = 0.0;
out.max.z() = 0.0;
// extend to contain axes
//BBS: add part plate related logic.
Vec3d offset{ m_position.x(), m_position.y(), 0.f };
//out.merge(m_axes.get_origin() + offset + m_axes.get_total_length() * Vec3d::Ones());
// BBS: add part plate related logic.
Vec3d offset{m_position.x(), m_position.y(), 0.f};
// out.merge(m_axes.get_origin() + offset + m_axes.get_total_length() * Vec3d::Ones());
out.merge(Vec3d(0.f, 0.f, GROUND_Z) + offset + m_axes.get_total_length() * Vec3d::Ones());
out.merge(out.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, out.max.z()));
//BBS: add part plate related logic.
if (consider_model_offset) {
// extend to contain model, if any
BoundingBoxf3 model_bb = m_model.get_bounding_box();
if (model_bb.defined) {
model_bb.translate(m_model_offset);
out.merge(model_bb);
}
return out;
}
BoundingBoxf3 Bed3D::calc_extended_bounding_box() const
{
BoundingBoxf3 out;
out.merge(m_printable_bounding_box);
BoundingBoxf3 model_bb = m_model.get_bounding_box();
if (model_bb.defined) {
model_bb.translate(m_model_offset);
out.merge(model_bb);
}
return out;
}
@@ -633,7 +628,8 @@ void Bed3D::update_model_offset()
(*model_offset_ptr)(2) = -0.41 + GROUND_Z;
// update extended bounding box
const_cast<BoundingBoxf3&>(m_extended_bounding_box) = calc_extended_bounding_box();
const_cast<BoundingBoxf3 &>(m_printable_bounding_box) = calc_printable_bounding_box();
const_cast<BoundingBoxf3 &>(m_extended_bounding_box) = calc_extended_bounding_box();
m_triangles.reset();
}
@@ -670,7 +666,8 @@ void Bed3D::update_bed_triangles()
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to update plate triangles\n";
}
// update extended bounding box
const_cast<BoundingBoxf3&>(m_extended_bounding_box) = calc_extended_bounding_box();
const_cast<BoundingBoxf3 &>(m_printable_bounding_box) = calc_printable_bounding_box();
const_cast<BoundingBoxf3 &>(m_extended_bounding_box) = calc_extended_bounding_box();
}
void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix)
+4 -1
View File
@@ -100,6 +100,7 @@ private:
std::string m_model_filename;
// Print volume bounding box exteded with axes and model.
BoundingBoxf3 m_extended_bounding_box;
BoundingBoxf3 m_printable_bounding_box;
// Slightly expanded print bed polygon, for collision detection.
//Polygon m_polygon;
GLModel m_triangles;
@@ -148,6 +149,7 @@ public:
// Bounding box around the print bed, axes and model, for rendering.
const BoundingBoxf3& extended_bounding_box() const { return m_extended_bounding_box; }
const BoundingBoxf3 &printable_bounding_box() const { return m_printable_bounding_box; }
// Check against an expanded 2d bounding box.
//FIXME shall one check against the real build volume?
@@ -161,7 +163,8 @@ public:
private:
//BBS: add partplate related logic
// Calculate an extended bounding box from axes and current model for visualization purposes.
BoundingBoxf3 calc_extended_bounding_box(bool consider_model_offset = true) const;
BoundingBoxf3 calc_printable_bounding_box() const;
BoundingBoxf3 calc_extended_bounding_box() const;
void update_model_offset();
//BBS: with offset
void update_bed_triangles();
+7 -7
View File
@@ -1188,7 +1188,7 @@ void AMSMaterialsSetting::on_select_filament(wxCommandEvent &evt)
m_filament_selection = evt.GetSelection();
//reset cali
int cali_select_idx;
int cali_select_idx = -1;
if ( !this->obj || m_filament_selection < 0) {
m_input_k_val->Enable(false);
@@ -1378,6 +1378,7 @@ ColorPicker::ColorPicker(wxWindow* parent, wxWindowID id, const wxPoint& pos /*=
m_bitmap_border = create_scaled_bitmap("color_picker_border", nullptr, 25);
m_bitmap_border_dark = create_scaled_bitmap("color_picker_border_dark", nullptr, 25);
m_bitmap_transparent_def = ScalableBitmap(this, "transparent_color_picker", 25);
m_bitmap_transparent = create_scaled_bitmap("transparent_color_picker", nullptr, 25);
}
@@ -1387,7 +1388,7 @@ void ColorPicker::msw_rescale()
{
m_bitmap_border = create_scaled_bitmap("color_picker_border", nullptr, 25);
m_bitmap_border_dark = create_scaled_bitmap("color_picker_border_dark", nullptr, 25);
m_bitmap_transparent = create_scaled_bitmap("transparent_color_picker", nullptr, 25);
m_bitmap_transparent_def.msw_rescale();
Refresh();
}
@@ -1442,15 +1443,15 @@ void ColorPicker::doRender(wxDC& dc)
if (m_selected) radius -= FromDIP(1);
if (alpha == 0) {
wxSize bmp_size = m_bitmap_transparent.GetSize();
wxSize bmp_size = m_bitmap_transparent_def.GetBmpSize();
int center_x = (size.x - bmp_size.x) / 2;
int center_y = (size.y - bmp_size.y) / 2;
dc.DrawBitmap(m_bitmap_transparent, center_x, center_y);
dc.DrawBitmap(m_bitmap_transparent_def.bmp(), center_x, center_y);
}
else if (alpha != 254 && alpha != 255) {
if (transparent_changed) {
std::string rgb = (m_colour.GetAsString(wxC2S_HTML_SYNTAX)).ToStdString();
if (rgb.size() == 8) {
if (rgb.size() == 9) {
//delete alpha value
rgb = rgb.substr(0, rgb.size() - 2);
}
@@ -1461,12 +1462,11 @@ void ColorPicker::doRender(wxDC& dc)
replace.push_back(fill_replace);
m_bitmap_transparent = ScalableBitmap(this, "transparent_color_picker", 25, false, false, true, replace).bmp();
transparent_changed = false;
}
wxSize bmp_size = m_bitmap_transparent.GetSize();
int center_x = (size.x - bmp_size.x) / 2;
int center_y = (size.y - bmp_size.y) / 2;
dc.DrawBitmap(m_bitmap_transparent, center_x, center_y);
}
}
else {
dc.SetPen(wxPen(m_colour));
+1
View File
@@ -37,6 +37,7 @@ public:
wxBitmap m_bitmap_border;
wxBitmap m_bitmap_border_dark;
wxBitmap m_bitmap_transparent;
ScalableBitmap m_bitmap_transparent_def; //default transparent material
wxColour m_colour;
std::vector<wxColour> m_cols;
+371 -83
View File
@@ -2,6 +2,16 @@
#include "GUI_App.hpp"
#include "I18N.hpp"
#include "slic3r/GUI/DeviceCore/DevExtruderSystem.h"
#include "slic3r/GUI/DeviceCore/DevFilaSystem.h"
#include "slic3r/GUI/DeviceCore/DevManager.h"
#include "slic3r/GUI/MsgDialog.hpp"
#include "slic3r/GUI/Widgets/AnimaController.hpp"
#include "slic3r/GUI/Widgets/Label.hpp"
#include "slic3r/GUI/Widgets/ComboBox.hpp"
namespace Slic3r { namespace GUI {
AMSSetting::AMSSetting(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
@@ -18,7 +28,7 @@ void AMSSetting::create()
m_sizer_main = new wxBoxSizer(wxVERTICAL);
SetBackgroundColour(*wxWHITE);
auto m_static_ams_settings = new wxStaticText(this, wxID_ANY, _L("AMS Settings"), wxDefaultPosition, wxDefaultSize, 0);
m_static_ams_settings = new wxStaticText(this, wxID_ANY, _L("AMS Settings"), wxDefaultPosition, wxDefaultSize, 0);
m_static_ams_settings->SetFont(::Label::Head_14);
m_static_ams_settings->SetForegroundColour(AMS_SETTING_GREY800);
@@ -27,6 +37,12 @@ void AMSSetting::create()
m_panel_body->SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizerl_body = new wxBoxSizer(wxVERTICAL);
m_ams_type = new AMSSettingTypePanel(m_panel_body, this);
m_ams_type->Show(false);
//m_ams_arrange_order = new AMSSettingArrangeAMSOrder(m_panel_body);
//m_ams_arrange_order->Show(false);
m_panel_Insert_material = new wxPanel(m_panel_body, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxTAB_TRAVERSAL);
m_panel_Insert_material->SetBackgroundColour(*wxWHITE);
wxBoxSizer* m_sizer_main_Insert_material = new wxBoxSizer(wxVERTICAL);
@@ -35,7 +51,7 @@ void AMSSetting::create()
wxBoxSizer *m_sizer_Insert_material = new wxBoxSizer(wxHORIZONTAL);
m_checkbox_Insert_material_auto_read = new ::CheckBox(m_panel_Insert_material);
m_checkbox_Insert_material_auto_read->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_insert_material_read, this);
m_sizer_Insert_material->Add(m_checkbox_Insert_material_auto_read, 0, wxTOP, 1);
m_sizer_Insert_material->Add(m_checkbox_Insert_material_auto_read, 0, wxALIGN_CENTER_VERTICAL);
m_sizer_Insert_material->Add(0, 0, 0, wxLEFT, 12);
@@ -45,13 +61,10 @@ void AMSSetting::create()
m_title_Insert_material_auto_read->SetFont(::Label::Head_13);
m_title_Insert_material_auto_read->SetForegroundColour(AMS_SETTING_GREY800);
m_title_Insert_material_auto_read->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_Insert_material->Add(m_title_Insert_material_auto_read, 0, wxALL | wxEXPAND, 0);
m_sizer_Insert_material->Add(m_title_Insert_material_auto_read, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT, 0);
wxBoxSizer *m_sizer_Insert_material_tip = new wxBoxSizer(wxHORIZONTAL);
m_sizer_Insert_material_tip_inline = new wxBoxSizer(wxVERTICAL);
m_sizer_Insert_material_tip->Add(0, 0, 0, wxLEFT, 10);
// tip line1
@@ -90,22 +103,20 @@ void AMSSetting::create()
m_sizer_Insert_material_tip->Add(m_sizer_Insert_material_tip_inline, 1, wxALIGN_CENTER, 0);
m_sizer_main_Insert_material->Add(m_sizer_Insert_material, 0, wxEXPAND | wxTOP, FromDIP(4));
m_sizer_main_Insert_material->Add(m_sizer_Insert_material_tip, 0, wxEXPAND | wxLEFT | wxTOP, 18);
m_sizer_main_Insert_material->Add(m_sizer_Insert_material_tip, 0, wxEXPAND | wxLEFT | wxTOP, FromDIP(10));
m_panel_Insert_material->SetSizer(m_sizer_main_Insert_material);
// checkbox area 2
wxBoxSizer *m_sizer_starting = new wxBoxSizer(wxHORIZONTAL);
m_checkbox_starting_auto_read = new ::CheckBox(m_panel_body);
m_checkbox_starting_auto_read->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_starting_read, this);
m_sizer_starting->Add(m_checkbox_starting_auto_read, 0, wxTOP, 1);
m_sizer_starting->Add(m_checkbox_starting_auto_read, 0, wxALIGN_CENTER_VERTICAL);
m_sizer_starting->Add(0, 0, 0, wxLEFT, 12);
m_title_starting_auto_read = new wxStaticText(m_panel_body, wxID_ANY, _L("Power on update"), wxDefaultPosition,wxDefaultSize, 0);
m_title_starting_auto_read->SetFont(::Label::Head_13);
m_title_starting_auto_read->SetForegroundColour(AMS_SETTING_GREY800);
m_title_starting_auto_read->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_starting->Add(m_title_starting_auto_read, 1, wxEXPAND, 0);
m_sizer_starting->Add(m_title_starting_auto_read, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT, 0);
wxBoxSizer *m_sizer_starting_tip = new wxBoxSizer(wxHORIZONTAL);
m_sizer_starting_tip->Add(0, 0, 0, wxLEFT, 10);
@@ -136,13 +147,13 @@ void AMSSetting::create()
wxBoxSizer* m_sizer_remain = new wxBoxSizer(wxHORIZONTAL);
m_checkbox_remain = new ::CheckBox(m_panel_body);
m_checkbox_remain->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_remain, this);
m_sizer_remain->Add(m_checkbox_remain, 0, wxTOP, 1);
m_sizer_remain->Add(m_checkbox_remain, 0, wxALIGN_CENTER_VERTICAL);
m_sizer_remain->Add(0, 0, 0, wxLEFT, 12);
m_title_remain = new wxStaticText(m_panel_body, wxID_ANY, _L("Update remaining capacity"), wxDefaultPosition, wxDefaultSize, 0);
m_title_remain->SetFont(::Label::Head_13);
m_title_remain->SetForegroundColour(AMS_SETTING_GREY800);
m_title_remain->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_remain->Add(m_title_remain, 1, wxEXPAND, 0);
m_sizer_remain->Add(m_title_remain, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT, 0);
@@ -164,13 +175,13 @@ void AMSSetting::create()
wxBoxSizer* m_sizer_switch_filament = new wxBoxSizer(wxHORIZONTAL);
m_checkbox_switch_filament = new ::CheckBox(m_panel_body);
m_checkbox_switch_filament->Bind(wxEVT_TOGGLEBUTTON, &AMSSetting::on_switch_filament, this);
m_sizer_switch_filament->Add(m_checkbox_switch_filament, 0, wxTOP, 1);
m_sizer_switch_filament->Add(m_checkbox_switch_filament, 0, wxALIGN_CENTER_VERTICAL);
m_sizer_switch_filament->Add(0, 0, 0, wxLEFT, 12);
m_title_switch_filament = new wxStaticText(m_panel_body, wxID_ANY, _L("AMS filament backup"), wxDefaultPosition, wxDefaultSize, 0);
m_title_switch_filament->SetFont(::Label::Head_13);
m_title_switch_filament->SetForegroundColour(AMS_SETTING_GREY800);
m_title_switch_filament->Wrap(AMS_SETTING_BODY_WIDTH);
m_sizer_switch_filament->Add(m_title_switch_filament, 1, wxEXPAND, 0);
m_sizer_switch_filament->Add(m_title_switch_filament, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT, 0);
@@ -242,22 +253,17 @@ void AMSSetting::create()
m_sizer_remain_block->Add(m_sizer_remain_tip, 0, wxLEFT, 18);
m_sizer_remain_block->Add(0, 0, 0, wxTOP, 15);
m_sizerl_body->Add(m_panel_Insert_material, 0, 0, 0);
m_sizerl_body->Add(m_sizer_starting, 0, wxEXPAND | wxTOP, FromDIP(8));
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
m_sizerl_body->Add(m_sizer_starting_tip, 0, wxLEFT, 18);
m_sizerl_body->Add(0, 0, 0, wxTOP, 15);
m_sizerl_body->Add(m_sizer_remain_block, 0, wxEXPAND, 0);
m_sizerl_body->Add(m_sizer_switch_filament, 0, wxEXPAND | wxTOP, FromDIP(8));
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
m_sizerl_body->Add(m_sizer_switch_filament_tip, 0, wxLEFT, 18);
m_sizerl_body->Add(0, 0, 0, wxTOP, 6);
m_sizerl_body->Add(0, 0, 0, wxTOP, FromDIP(5));
m_sizerl_body->Add(m_sizer_air_print, 0, wxEXPAND | wxTOP, FromDIP(8));
m_sizerl_body->Add(0, 0, 0, wxTOP, 8);
m_sizerl_body->Add(m_sizer_air_print_tip, 0, wxLEFT, 18);
m_sizerl_body->Add(0, 0, 0, wxTOP, 6);
m_sizerl_body->Add(0, 0, 0, wxTOP, FromDIP(5));
m_sizerl_body->AddSpacer(FromDIP(12));
m_sizerl_body->Add(m_ams_type, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(12));
//m_sizerl_body->Add(m_ams_arrange_order, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(12));
m_sizerl_body->Add(m_panel_Insert_material, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_sizer_starting, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_sizer_starting_tip, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_sizer_remain_block, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_sizer_switch_filament, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_sizer_switch_filament_tip, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_sizer_air_print, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_sizer_air_print_tip, 0, wxEXPAND | wxTOP, FromDIP(12));
m_sizerl_body->Add(m_panel_img, 1, wxEXPAND | wxALL, FromDIP(5));
m_panel_body->SetSizer(m_sizerl_body);
@@ -274,17 +280,96 @@ void AMSSetting::create()
this->Centre(wxBOTH);
wxGetApp().UpdateDlgDarkUI(this);
}
Bind(wxEVT_SHOW, [this](auto& e) {
if (this->IsShown()) {
if (ams_support_remain) {
m_sizer_remain_block->Show(true);
}
else {
m_sizer_remain_block->Show(false);
}
void AMSSetting::UpdateByObj(MachineObject* obj)
{
this->m_obj = obj;
if (!obj) {
this->Show(false);
return;
}
update_ams_img(obj);
m_ams_type->Update(obj);
//m_ams_arrange_order->Update(obj);
update_insert_material_read_mode(obj);
m_sizer_remain_block->Show(obj->is_support_update_remain);
update_starting_read_mode(obj->GetFilaSystem()->IsDetectOnPowerupEnabled());
update_remain_mode(obj->GetFilaSystem()->IsDetectRemainEnabled());
update_switch_filament(obj->GetFilaSystem()->IsAutoRefillEnabled());
update_air_printing_detection(obj);
update_firmware_switching_status();// on fila_firmware_switch
}
void AMSSetting::update_firmware_switching_status()
{
if (!m_obj) {
return;
}
auto fila_firmware_switch = m_obj->GetFilaSystem()->GetAmsFirmwareSwitch().lock();
if (fila_firmware_switch->GetSuppotedFirmwares().empty()) {
return;
}
if (m_switching == fila_firmware_switch->IsSwitching()) {
return;
}
m_switching = fila_firmware_switch->IsSwitching();
// BFS: Update all children
auto children = GetChildren();
while (!children.IsEmpty()) {
auto win = children.front();
children.pop_front();
// do something with win
if (win == m_static_ams_settings || win == m_ams_type) {
continue;
}
});
if (dynamic_cast<wxStaticText*>(win) != nullptr ||
dynamic_cast<CheckBox*>(win) != nullptr) {
win->Enable(!m_switching);
}
for (auto child : win->GetChildren()) {
children.push_back(child);
}
}
}
void AMSSetting::update_insert_material_read_mode(MachineObject* obj)
{
if (obj) {
auto setting = obj->GetFilaSystem()->GetAmsSystemSetting().IsDetectOnInsertEnabled();
if (!setting.has_value()) {
m_panel_Insert_material->Show(false);
return;
}
// special case for A series
if (auto ptr = obj->GetFilaSystem()->GetAmsFirmwareSwitch().lock(); ptr->SupportSwitchFirmware()) {
if (ptr->GetCurrentFirmwareIdxSel() == DevAmsSystemFirmwareSwitch::IDX_LITE) {
m_panel_Insert_material->Show(false);
return;
}
} else if (DevPrinterConfigUtil::get_printer_use_ams_type(obj->printer_type) == "f1") {
m_panel_Insert_material->Show(false);
return;
}
std::string extra_ams_str = (boost::format("ams_f1/%1%") % 0).str();
auto extra_ams_it = obj->module_vers.find(extra_ams_str);
if (extra_ams_it != obj->module_vers.end()) {
update_insert_material_read_mode(setting.value(), extra_ams_it->second.sw_ver);
} else {
update_insert_material_read_mode(setting.value(), "");
}
}
}
void AMSSetting::update_insert_material_read_mode(bool selected, std::string version)
@@ -320,12 +405,27 @@ void AMSSetting::update_insert_material_read_mode(bool selected, std::string ver
Fit();
}
void AMSSetting::update_ams_img(std::string ams_icon_str)
void AMSSetting::update_ams_img(MachineObject* obj_)
{
if (!obj_) {
return;
}
std::string ams_icon_str = DevPrinterConfigUtil::get_printer_ams_img(obj_->printer_type);
if (auto ams_switch = obj_->GetFilaSystem()->GetAmsFirmwareSwitch().lock();
ams_switch->GetCurrentFirmwareIdxSel() == 1) {
ams_icon_str = "ams_icon";// A series support AMS
}
// transfer to dark mode icon
if (wxGetApp().dark_mode()&& ams_icon_str=="extra_icon") {
ams_icon_str += "_dark";
}
m_am_img->SetBitmap(create_scaled_bitmap(ams_icon_str, nullptr, 126));
if (ams_icon_str != m_ams_img_name) {
m_am_img->SetBitmap(create_scaled_bitmap(ams_icon_str, nullptr, 126));
m_am_img->Refresh();
}
}
void AMSSetting::update_starting_read_mode(bool selected)
@@ -345,7 +445,7 @@ void AMSSetting::update_starting_read_mode(bool selected)
void AMSSetting::update_remain_mode(bool selected)
{
if (obj->is_support_update_remain) {
if (m_obj->is_support_update_remain) {
m_checkbox_remain->Show();
m_title_remain->Show();
m_tip_remain_line1->Show();
@@ -362,7 +462,7 @@ void AMSSetting::update_remain_mode(bool selected)
void AMSSetting::update_switch_filament(bool selected)
{
if (obj->is_support_filament_backup) {
if (m_obj->is_support_filament_backup) {
m_checkbox_switch_filament->Show();
m_title_switch_filament->Show();
m_tip_switch_filament_line1->Show();
@@ -376,28 +476,24 @@ void AMSSetting::update_switch_filament(bool selected)
m_checkbox_switch_filament->SetValue(selected);
}
void AMSSetting::update_air_printing_detection(bool selected)
void AMSSetting::update_air_printing_detection(MachineObject* obj)
{
if (false/*obj->is_support_air_print_detection*/) {
if(!obj) {
return;
}
if (obj->is_support_air_print_detection) {
m_checkbox_air_print->Show();
m_title_air_print->Show();
m_tip_air_print_line->Show();
}
else {
} else {
m_checkbox_air_print->Hide();
m_title_air_print->Hide();
m_tip_air_print_line->Hide();
}
Layout();
m_checkbox_air_print->SetValue(selected);
}
void AMSSetting::on_select_ok(wxMouseEvent &event)
{
if (obj) {
obj->command_ams_calibrate(ams_id);
}
m_checkbox_air_print->SetValue(obj->ams_air_print_status);
}
void AMSSetting::on_insert_material_read(wxCommandEvent &event)
@@ -420,7 +516,7 @@ void AMSSetting::on_insert_material_read(wxCommandEvent &event)
bool tray_read_opt = m_checkbox_Insert_material_auto_read->GetValue();
bool remain_opt = m_checkbox_remain->GetValue();
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt, remain_opt);
m_obj->command_ams_user_settings(start_read_opt, tray_read_opt, remain_opt);
m_sizer_Insert_material_tip_inline->Layout();
Layout();
@@ -446,7 +542,7 @@ void AMSSetting::on_starting_read(wxCommandEvent &event)
bool tray_read_opt = m_checkbox_Insert_material_auto_read->GetValue();
bool remain_opt = m_checkbox_remain->GetValue();
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt, remain_opt);
m_obj->command_ams_user_settings(start_read_opt, tray_read_opt, remain_opt);
m_sizer_starting_tip_inline->Layout();
Layout();
@@ -460,47 +556,239 @@ void AMSSetting::on_remain(wxCommandEvent& event)
bool start_read_opt = m_checkbox_starting_auto_read->GetValue();
bool tray_read_opt = m_checkbox_Insert_material_auto_read->GetValue();
bool remain_opt = m_checkbox_remain->GetValue();
obj->command_ams_user_settings(ams_id, start_read_opt, tray_read_opt, remain_opt);
m_obj->command_ams_user_settings(start_read_opt, tray_read_opt, remain_opt);
event.Skip();
}
void AMSSetting::on_switch_filament(wxCommandEvent& event)
{
bool switch_filament = m_checkbox_switch_filament->GetValue();
obj->command_ams_switch_filament(switch_filament);
m_obj->command_ams_switch_filament(switch_filament);
event.Skip();
}
void AMSSetting::on_air_print_detect(wxCommandEvent& event)
{
bool air_print_detect = m_checkbox_air_print->GetValue();
obj->command_ams_air_print_detect(air_print_detect);
m_obj->command_ams_air_print_detect(air_print_detect);
event.Skip();
}
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();
widget->Destroy();
return lab;
}
wxStaticText *AMSSetting::append_text(wxString text)
{
auto *widget = new wxStaticText(m_panel_body, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
widget->Wrap(250);
widget->SetMinSize(wxSize(250, -1));
return widget;
}
void AMSSetting::on_dpi_changed(const wxRect &suggested_rect)
{
//m_button_auto_demarcate->SetMinSize(AMS_SETTING_BUTTON_SIZE);
if (!m_ams_img_name.empty()) {
m_am_img->SetBitmap(create_scaled_bitmap(m_ams_img_name, nullptr, 126));
m_am_img->Refresh();
}
}
AMSSettingTypePanel::AMSSettingTypePanel(wxWindow* parent, AMSSetting* setting_dlg)
: wxPanel(parent), m_setting_dlg(setting_dlg)
{
CreateGui();
}
AMSSettingTypePanel::~AMSSettingTypePanel()
{
if (m_switching_icon->IsPlaying()) {
m_switching_icon->Stop();
}
}
void AMSSettingTypePanel::CreateGui()
{
wxBoxSizer* h_sizer = new wxBoxSizer(wxHORIZONTAL);
Label* title = new Label(this, ::Label::Head_13, _L("AMS Type"));
title->SetBackgroundColour(*wxWHITE);
m_type_combobox = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(240, -1), 0, nullptr, wxCB_READONLY);
m_type_combobox->SetMinSize(wxSize(240, -1));
m_type_combobox->Bind(wxEVT_COMBOBOX, &AMSSettingTypePanel::OnAmsTypeChanged, this);
m_switching_tips = new Label(this, ::Label::Body_14);
m_switching_tips->SetBackgroundColour(*wxWHITE);
m_switching_tips->Show(false);
std::vector<std::string> list{ "ams_rfid_1", "ams_rfid_2", "ams_rfid_3", "ams_rfid_4" };
m_switching_icon = new AnimaIcon(this, wxID_ANY, list, "refresh_printer", 100);
m_switching_icon->SetMinSize(wxSize(FromDIP(20), FromDIP(20)));
h_sizer->Add(title, 0);
h_sizer->AddStretchSpacer();
h_sizer->Add(m_type_combobox, 0, wxEXPAND);
h_sizer->Add(m_switching_icon, 0, wxALIGN_CENTER);
h_sizer->Add(m_switching_tips, 0, wxEXPAND | wxLEFT | wxALIGN_CENTER, FromDIP(8));
SetSizer(h_sizer);
Layout();
Fit();
}
void AMSSettingTypePanel::Update(const MachineObject* obj)
{
if (!obj) {
Show(false);
return;
}
m_ams_firmware_switch = obj->GetFilaSystem()->GetAmsFirmwareSwitch();
auto ptr = m_ams_firmware_switch.lock();
if (!ptr) {
Show(false);
return;
}
if (!ptr->SupportSwitchFirmware()) {
Show(false);
return;
}
if (ptr->IsSwitching()) {
int display_percent = obj->get_upgrade_percent();
if (display_percent == 100 || display_percent == 0) {
display_percent = 1;// special case, sometimes it's switching but percent is 0 or 100
}
const auto& tips = _L("Switching") + " " + wxString::Format("%d%%", display_percent);
m_switching_tips->SetLabel(tips);
m_switching_icon->Play();
m_switching_tips->Show(true);
m_switching_icon->Show(true);
m_type_combobox->Show(false);
} else {
int current_idx = ptr->GetCurrentFirmwareIdxSel();
auto ams_firmwares = ptr->GetSuppotedFirmwares();
if (m_ams_firmwares != ams_firmwares || m_ams_firmware_current_idx != current_idx) {
m_ams_firmware_current_idx = current_idx;
m_ams_firmwares = ams_firmwares;
m_type_combobox->Clear();
for (auto ams_firmware : m_ams_firmwares) {
if (m_ams_firmware_current_idx == ams_firmware.first) {
m_type_combobox->Append(_L(ams_firmware.second.m_name));
} else {
m_type_combobox->Append(_L(ams_firmware.second.m_name));
}
}
m_type_combobox->SetSelection(m_ams_firmware_current_idx);
}
if(m_switching_icon->IsPlaying()) {
m_switching_icon->Stop();
}
m_switching_tips->Show(false);
m_switching_icon->Show(false);
m_type_combobox->Show(true);
}
Show(true);
Layout();
}
void AMSSettingTypePanel::OnAmsTypeChanged(wxCommandEvent& event)
{
auto part = m_ams_firmware_switch.lock();
if (!part) {
event.Skip();
return;
}
int new_selection_idx = m_type_combobox->GetSelection();
if (new_selection_idx == part->GetCurrentFirmwareIdxSel()) {
event.Skip();
return;
}
auto obj_ = part->GetFilaSystem()->GetOwner();
if (obj_) {
if (obj_->is_in_printing() || obj_->is_in_upgrading()) {
MessageDialog dlg(this, _L("The printer is busy and cannot switch AMS type."), SLIC3R_APP_NAME + _L("Info"), wxOK | wxICON_INFORMATION);
dlg.ShowModal();
m_type_combobox->SetSelection(part->GetCurrentFirmwareIdxSel());
return;
}
auto ext = obj_->GetExtderSystem()->GetCurrentExtder();
if (ext && ext->HasFilamentInExt()) {
MessageDialog dlg(this, _L("Please unload all filament before switching."), SLIC3R_APP_NAME + _L("Info"), wxOK | wxICON_INFORMATION);
dlg.SetButtonLabel(wxID_OK, _L("Confirm"));
dlg.ShowModal();
m_type_combobox->SetSelection(part->GetCurrentFirmwareIdxSel());
if (m_setting_dlg) {
m_setting_dlg->EndModal(wxID_OK);
}
return;
}
MessageDialog dlg(this, _L("AMS type switching needs firmware update, taking about 30s. Switch now ?"), SLIC3R_APP_NAME + _L("Info"), wxOK | wxCANCEL | wxICON_INFORMATION);
dlg.SetButtonLabel(wxID_OK, _L("Confirm"));
int rtn = dlg.ShowModal();
if (rtn != wxID_OK) {
m_type_combobox->SetSelection(part->GetCurrentFirmwareIdxSel());
return;
}
part->CrtlSwitchFirmware(new_selection_idx);
}
event.Skip();
}
#if 0 /*used option*/
AMSSettingArrangeAMSOrder::AMSSettingArrangeAMSOrder(wxWindow* parent)
: wxPanel(parent)
{
CreateGui();
}
void AMSSettingArrangeAMSOrder::CreateGui()
{
wxBoxSizer* h_sizer = new wxBoxSizer(wxHORIZONTAL);
Label* title = new Label(this, ::Label::Head_13, _L("Arrange AMS Order"));
title->SetBackgroundColour(*wxWHITE);
m_btn_rearrange = new ScalableButton(this, wxID_ANY, "dev_ams_rearrange");
m_btn_rearrange->SetBackgroundColour(*wxWHITE);
m_btn_rearrange->SetMinSize(wxSize(FromDIP(13), FromDIP(13)));
m_btn_rearrange->Bind(wxEVT_BUTTON, &AMSSettingArrangeAMSOrder::OnBtnRearrangeClicked, this);
h_sizer->Add(title, 0);
h_sizer->AddStretchSpacer();
h_sizer->Add(m_btn_rearrange, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL);
SetSizer(h_sizer);
Layout();
Fit();
}
void AMSSettingArrangeAMSOrder::Update(const MachineObject* obj)
{
if (obj) {
m_ams_firmware_switch = obj->GetFilaSystem()->GetAmsFirmwareSwitch();
if (auto ptr = m_ams_firmware_switch.lock(); ptr->SupportSwitchFirmware()) {
Show(true);
return;
}
}
Show(false);
}
void AMSSettingArrangeAMSOrder::OnBtnRearrangeClicked(wxCommandEvent& event)
{
auto part = m_ams_firmware_switch.lock();
if (part) {
MessageDialog dlg(this, _L("AMS ID will be reset. If you want a specific ID sequence, "
"disconnect all AMS before resetting and connect them "
"in the desired order after resetting."),
SLIC3R_APP_NAME + _L("Info"), wxOK | wxCANCEL | wxICON_INFORMATION);
int rtn = dlg.ShowModal();
if (rtn == wxID_OK) {
part->GetFilaSystem()->CtrlAmsReset();
}
}
event.Skip();
}
#endif
}} // namespace Slic3r::GUI
+82 -19
View File
@@ -11,6 +11,8 @@
#include "Widgets/Label.hpp"
#include "Widgets/CheckBox.hpp"
#include "slic3r/GUI/DeviceCore/DevFilaAmsSetting.h"
#define AMS_SETTING_DEF_COLOUR wxColour(255, 255, 255)
#define AMS_SETTING_GREY800 wxColour(50, 58, 61)
#define AMS_SETTING_GREY700 wxColour(107, 107, 107)
@@ -19,38 +21,53 @@
#define AMS_SETTING_BUTTON_SIZE wxSize(FromDIP(150), FromDIP(24))
#define AMS_F1_SUPPORT_INSERTION_UPDATE_DEFAULT std::string("00.00.07.89")
class AnimaIcon;
class ComboBox;
namespace Slic3r { namespace GUI {
class AMSSettingTypePanel;
class AMSSetting : public DPIDialog
{
public:
AMSSetting(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE);
~AMSSetting();
void create();
void update_insert_material_read_mode(bool selected, std::string version);
void update_ams_img(std::string ams_icon_str);
void update_starting_read_mode(bool selected);
void update_remain_mode(bool selected);
void update_switch_filament(bool selected);
void update_air_printing_detection(bool selected);
void on_select_ok(wxMouseEvent& event);
void on_insert_material_read(wxCommandEvent &event);
void on_starting_read(wxCommandEvent &event);
void on_remain(wxCommandEvent& event);
void on_switch_filament(wxCommandEvent& event);
void on_air_print_detect(wxCommandEvent& event);
wxString append_title(wxString text);
wxStaticText *append_text(wxString text);
MachineObject *obj{nullptr};
bool ams_support_remain{false};
wxStaticBitmap* m_am_img;
int ams_id { 0 };
public:
void UpdateByObj(MachineObject* obj);
protected:
void create();
void update_ams_img(MachineObject* obj);
void update_starting_read_mode(bool selected);
void update_remain_mode(bool selected);
void update_switch_filament(bool selected);
void update_insert_material_read_mode(MachineObject* obj);
void update_insert_material_read_mode(bool selected, std::string version);
void update_air_printing_detection(MachineObject* obj);
void update_firmware_switching_status();
// event handlers
void on_insert_material_read(wxCommandEvent& event);
void on_starting_read(wxCommandEvent& event);
void on_remain(wxCommandEvent& event);
void on_switch_filament(wxCommandEvent& event);
void on_air_print_detect(wxCommandEvent& event);
void on_dpi_changed(const wxRect &suggested_rect) override;
protected:
MachineObject *m_obj{nullptr};
wxStaticText* m_static_ams_settings = nullptr;
bool m_switching = false;
AMSSettingTypePanel* m_ams_type;
//AMSSettingArrangeAMSOrder* m_ams_arrange_order;
wxStaticBitmap* m_am_img;
std::string m_ams_img_name;
wxPanel * m_panel_body;
wxPanel* m_panel_Insert_material;
CheckBox * m_checkbox_Insert_material_auto_read;
@@ -86,6 +103,52 @@ protected:
wxBoxSizer *m_sizer_remain_block;
};
class AMSSettingTypePanel : public wxPanel
{
public:
AMSSettingTypePanel(wxWindow* parent, AMSSetting* setting_dlg);
~AMSSettingTypePanel();
public:
void Update(const MachineObject* obj);
private:
void CreateGui();
void OnAmsTypeChanged(wxCommandEvent& event);
private:
std::weak_ptr<DevAmsSystemFirmwareSwitch> m_ams_firmware_switch;
int m_ams_firmware_current_idx{ -1 };
std::unordered_map<int, DevAmsSystemFirmwareSwitch::DevAmsSystemFirmware> m_ams_firmwares;
// widgets
AMSSetting* m_setting_dlg;
ComboBox* m_type_combobox;
Label* m_switching_tips;
AnimaIcon* m_switching_icon;
};
#if 0
class AMSSettingArrangeAMSOrder : public wxPanel
{
public:
AMSSettingArrangeAMSOrder(wxWindow* parent);
public:
void Update(const MachineObject* obj);
void Rescale() { m_btn_rearrange->msw_rescale(); Layout(); };
private:
void CreateGui();
void OnBtnRearrangeClicked(wxCommandEvent& event);
private:
std::weak_ptr<DevAmsSystemFirmwareSwitch> m_ams_firmware_switch;
ScalableButton* m_btn_rearrange;
};
#endif
}} // namespace Slic3r::GUI
#endif
+3 -5
View File
@@ -231,7 +231,7 @@ void MaterialItem::render(wxDC &dc)
dc.SetTextForeground(wxColour(0x26, 0x2E, 0x30));
dc.SetTextForeground(StateColor::darkModeColorFor(wxColour(0x26, 0x2E, 0x30)));
dc.SetFont(::Label::Head_12);
auto mapping_txt_size = wxSize(0, 0);
@@ -1257,12 +1257,10 @@ void AmsMapingPopup::update(MachineObject* obj, const std::vector<FilamentInfo>&
Refresh();
}
std::vector<TrayData> AmsMapingPopup::parse_ams_mapping(std::map<std::string, DevAms*> amsList)
std::vector<TrayData> AmsMapingPopup::parse_ams_mapping(const std::map<std::string, DevAms*, NumericStrCompare>& amsList)
{
std::vector<TrayData> m_tray_data;
std::map<std::string, DevAms *>::iterator ams_iter;
for (ams_iter = amsList.begin(); ams_iter != amsList.end(); ams_iter++) {
for (auto ams_iter = amsList.begin(); ams_iter != amsList.end(); ams_iter++) {
BOOST_LOG_TRIVIAL(trace) << "ams_mapping ams id " << ams_iter->first.c_str();
+3 -2
View File
@@ -39,6 +39,8 @@
#include <wx/simplebook.h>
#include <wx/hashmap.h>
#include "slic3r/GUI/DeviceCore/DevUtil.h"
#define MAPPING_ITEM_INVALID_REMAIN -1
namespace Slic3r { namespace GUI {
@@ -225,7 +227,6 @@ public:
std::vector<MappingItem*> m_mapping_item_list;
bool m_has_unmatch_filament {false};
bool m_supporting_mix_print {false}; //For single extruder, can ams and ext print together?
int m_current_filament_id;
ShowType m_show_type{ShowType::RIGHT};
std::string m_tag_material;
@@ -278,7 +279,7 @@ public:
void paintEvent(wxPaintEvent &evt);
void set_parent_item(MaterialItem* item) {m_parent_item = item;};
void set_show_type(ShowType type) { m_show_type = type; };
std::vector<TrayData> parse_ams_mapping(std::map<std::string, DevAms*> amsList);
std::vector<TrayData> parse_ams_mapping(const std::map<std::string, DevAms*, NumericStrCompare>& amsList);
using ResetCallback = std::function<void(const std::string&)>;
void reset_ams_info();
+1 -1
View File
@@ -157,7 +157,7 @@ void TrayListModel::update(MachineObject* obj)
m_titleColValues.push_back(title_text);
wxString color_text = wxString::Format("%s", tray->wx_color.GetAsString());
m_colorColValues.push_back(color_text);
wxString meterial_text = wxString::Format("%s", tray->type);
wxString meterial_text = wxString::Format("%s", tray->m_fila_type);
m_meterialColValues.push_back(meterial_text);
wxString weight_text = wxString::Format("%sg", tray->weight);
m_weightColValues.push_back(weight_text);
+5 -1
View File
@@ -17,6 +17,7 @@
namespace Slic3r {
wxDEFINE_EVENT(EVT_SHOW_ERROR_INFO_SEND, wxCommandEvent);
wxDEFINE_EVENT(EVT_SHOW_ERROR_FAIL_SEND, wxCommandEvent);
BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
: m_self{new wxPanel(parent, id == -1 ? wxID_ANY : id)}
@@ -69,7 +70,7 @@ BBLStatusBarSend::BBLStatusBarSend(wxWindow *parent, int id)
m_sizer_status_text = new wxBoxSizer(wxHORIZONTAL);
m_link_show_error = new Label(m_self, _L("Check the reason"));
m_link_show_error->SetForegroundColour(wxColour(0x6b6b6b));
m_link_show_error->SetForegroundColour(wxColour("#6b6b6b"));
m_link_show_error->SetFont(::Label::Head_13);
m_bitmap_show_error_close = create_scaled_bitmap("link_more_error_close", nullptr, 7);
@@ -174,6 +175,9 @@ void BBLStatusBarSend::show_error_info(wxString msg, int code, wxString descript
m_cancelbutton->Show();
m_self->Layout();
m_sizer->Layout();
wxCommandEvent* evt = new wxCommandEvent(EVT_SHOW_ERROR_FAIL_SEND);
wxQueueEvent(this->m_self->GetParent(), evt);
}
void BBLStatusBarSend::show_progress(bool show)
+1 -1
View File
@@ -102,7 +102,7 @@ using Slic3r::BBLStatusBarSend;
}
wxDECLARE_EVENT(EVT_SHOW_ERROR_INFO_SEND, wxCommandEvent);
wxDECLARE_EVENT(EVT_SHOW_ERROR_FAIL_SEND, wxCommandEvent);
} // namespace Slic3r
#endif // BBLSTATUSBAR_HPP
+28 -21
View File
@@ -44,8 +44,8 @@ wxString get_fail_reason(int code)
return _L("Failed to post ticket to server");
else if (code == BAMBU_NETWORK_ERR_BIND_PARSE_LOGIN_REPORT_FAILED)
return _L("Failed to parse login report reason");
return _L("Failed to parse login report reason");
else if (code == BAMBU_NETWORK_ERR_BIND_ECODE_LOGIN_REPORT_FAILED)
return _L("Failed to parse login report reason");
@@ -68,7 +68,7 @@ PingCodeBindDialog::PingCodeBindDialog(Plater* plater /*= nullptr*/)
wxBoxSizer* m_sizer_main = new wxBoxSizer(wxVERTICAL);
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_simplebook = new wxSimplebook(this);
m_simplebook->SetSize(wxSize(FromDIP(460), FromDIP(240)));
@@ -121,7 +121,7 @@ PingCodeBindDialog::PingCodeBindDialog(Plater* plater /*= nullptr*/)
for (int i = 0; i < PING_CODE_LENGTH; i++) {
m_text_input_single_code[i] = new TextInput(request_bind_panel, wxEmptyString, "", "", wxDefaultPosition, wxSize(FromDIP(38), FromDIP(38)), wxTE_PROCESS_ENTER | wxTE_CENTER);
wxTextAttr textAttr;
textAttr.SetAlignment(wxTEXT_ALIGNMENT_CENTER);
textAttr.SetAlignment(wxTEXT_ALIGNMENT_CENTER);
textAttr.SetTextColour(wxColour(34, 139, 34));
m_text_input_single_code[i]->GetTextCtrl()->SetDefaultStyle(textAttr);
m_text_input_single_code[i]->SetFont(Label::Body_16);
@@ -242,11 +242,11 @@ void PingCodeBindDialog::on_key_input(wxKeyEvent& evt)
if (keyCode == WXK_BACK || (keyCode >= '0' && keyCode <= '9') || (keyCode >= 'a' && keyCode <= 'z') || (keyCode >= 'A' && keyCode <= 'Z'))
{
evt.Skip();
evt.Skip();
}
else
{
wxBell();
wxBell();
return;
}
}
@@ -264,7 +264,7 @@ void PingCodeBindDialog::on_text_changed(wxCommandEvent& event) {
if (idx != -1 && text_input->GetValue().Length() == 1) {
if (idx < PING_CODE_LENGTH-1) {
m_text_input_single_code[idx + 1]->SetFocus();
m_text_input_single_code[idx + 1]->SetFocus();
}
auto has_empty = false;
@@ -298,7 +298,7 @@ void PingCodeBindDialog::on_key_backspace(wxKeyEvent& event)
break;
}
}
if (event.GetKeyCode() == WXK_BACK && idx >= 0) {
CallAfter([this, idx]() {
m_text_input_single_code[idx - 1]->SetFocus();
@@ -308,7 +308,7 @@ void PingCodeBindDialog::on_key_backspace(wxKeyEvent& event)
event.Skip();
}
void PingCodeBindDialog::on_bind_printer(wxCommandEvent& event)
void PingCodeBindDialog::on_bind_printer(wxCommandEvent& event)
{
wxString ping_code;
@@ -329,7 +329,7 @@ void PingCodeBindDialog::on_bind_printer(wxCommandEvent& event)
}
}
void PingCodeBindDialog::on_cancel(wxCommandEvent& event)
void PingCodeBindDialog::on_cancel(wxCommandEvent& event)
{
EndModal(wxCLOSE);
}
@@ -427,7 +427,7 @@ PingCodeBindDialog::~PingCodeBindDialog() {
m_link_show_error = new wxStaticText(this, wxID_ANY, _L("Check the reason"));
m_link_show_error->SetForegroundColour(wxColour(0x6b6b6b));
m_link_show_error->SetForegroundColour(wxColour("#6b6b6b"));
m_link_show_error->SetFont(::Label::Head_13);
m_bitmap_show_error_close = create_scaled_bitmap("link_more_error_close",nullptr, 7);
@@ -463,8 +463,8 @@ PingCodeBindDialog::~PingCodeBindDialog() {
m_panel_agreement->SetBackgroundColour(*wxWHITE);
m_panel_agreement->SetMinSize(wxSize(FromDIP(450), -1));
m_panel_agreement->SetMaxSize(wxSize(FromDIP(450), -1));
wxWrapSizer* sizer_privacy_agreement = new wxWrapSizer( wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS );
wxWrapSizer* sizere_notice_agreement= new wxWrapSizer( wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS );
wxBoxSizer* sizer_privacy_body = new wxBoxSizer(wxHORIZONTAL);
@@ -577,7 +577,7 @@ PingCodeBindDialog::~PingCodeBindDialog() {
wxBoxSizer* sizer_agreement = new wxBoxSizer(wxVERTICAL);
sizer_agreement->Add(sizer_privacy_body, 1, wxEXPAND, 0);
sizer_agreement->Add(sizere_notice_body, 1, wxEXPAND, 0);
m_checkbox_privacy->Bind(wxEVT_TOGGLEBUTTON, [this, m_checkbox_privacy](auto& e) {
m_allow_privacy = m_checkbox_privacy->GetValue();
@@ -608,7 +608,7 @@ PingCodeBindDialog::~PingCodeBindDialog() {
m_link_network_state->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_HAND); });
m_link_network_state->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {m_link_network_state->SetCursor(wxCURSOR_ARROW); });
wxBoxSizer* sizer_error_code = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_error_desc = new wxBoxSizer(wxHORIZONTAL);
@@ -921,8 +921,12 @@ void BindMachineDialog::on_show(wxShowEvent &event)
if (event.IsShown()) {
auto img = m_machine_info->get_printer_thumbnail_img_str();
if (wxGetApp().dark_mode()) { img += "_dark"; }
auto bitmap = create_scaled_bitmap(img, this, FromDIP(80));
m_printer_img->SetBitmap(bitmap);
try {
auto bitmap = create_scaled_bitmap(img, this, FromDIP(80));
m_printer_img->SetBitmap(bitmap);
}
catch (...){}
m_printer_img->Refresh();
m_printer_img->Show();
@@ -969,7 +973,7 @@ UnBindMachineDialog::UnBindMachineDialog(Plater *plater /*= nullptr*/)
SetBackgroundColour(*wxWHITE);
wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL);
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
m_line_top->SetBackgroundColour(wxColour("#A6A9AA"));
m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(38));
@@ -1138,8 +1142,11 @@ void UnBindMachineDialog::on_show(wxShowEvent &event)
if (event.IsShown()) {
auto img = m_machine_info->get_printer_thumbnail_img_str();
if (wxGetApp().dark_mode()) { img += "_dark"; }
auto bitmap = create_scaled_bitmap(img, this, FromDIP(80));
m_printer_img->SetBitmap(bitmap);
try {
auto bitmap = create_scaled_bitmap(img, this, FromDIP(80));
m_printer_img->SetBitmap(bitmap);
} catch (...) {}
m_printer_img->Refresh();
m_printer_img->Show();
@@ -1149,7 +1156,7 @@ void UnBindMachineDialog::on_show(wxShowEvent &event)
if (wxGetApp().is_user_login()) {
wxString username_text = from_u8(wxGetApp().getAgent()->get_user_name());
m_user_name->SetLabelText(username_text);
std::string avatar_url = wxGetApp().getAgent()->get_user_avatar();
Slic3r::Http http = Slic3r::Http::get(avatar_url);
std::string suffix = avatar_url.substr(avatar_url.find_last_of(".") + 1);
+49 -14
View File
@@ -9,6 +9,7 @@
#include "slic3r/Utils/CalibUtils.hpp"
#include <wx/gbsizer.h>
#include "Plater.hpp"
#include "DeviceCore/DevExtruderSystem.h"
#include "DeviceCore/DevManager.h"
@@ -31,9 +32,25 @@ enum CaliColumnType : int {
Cali_Type_Count
};
bool support_nozzle_volume(const MachineObject* obj)
{
if (!obj)
return false;
Preset * machine_preset = get_printer_preset(obj);
if (machine_preset) {
int extruder_nums = machine_preset->config.option<ConfigOptionFloatsNullable>("nozzle_diameter")->values.size();
auto nozzle_volume_opt = machine_preset->config.option<ConfigOptionFloatsNullable>("nozzle_volume");
if (nozzle_volume_opt) {
int printer_variant_size = nozzle_volume_opt->values.size();
return (printer_variant_size / extruder_nums) > 1;
}
}
return false;
}
int get_colume_idx(CaliColumnType type, MachineObject* obj)
{
if ((!obj || !obj->is_multi_extruders())
if (!support_nozzle_volume(obj)
&& (type > CaliColumnType::Cali_Nozzle)) {
return type - 1;
}
@@ -330,7 +347,7 @@ void HistoryWindow::sync_history_data() {
title_preset_name->SetFont(Label::Head_14);
gbSizer->Add(title_preset_name, { 0, get_colume_idx(CaliColumnType::Cali_Filament, curr_obj) }, { 1, 1 }, wxBOTTOM, FromDIP(15));
if (curr_obj && curr_obj->is_multi_extruders()) {
if (support_nozzle_volume(curr_obj)) {
auto nozzle_name = new Label(m_history_data_panel, _L("Nozzle Flow"));
nozzle_name->SetFont(Label::Head_14);
gbSizer->Add(nozzle_name, {0, get_colume_idx(CaliColumnType::Cali_Nozzle, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15));
@@ -366,9 +383,14 @@ void HistoryWindow::sync_history_data() {
delete_button->SetMinSize(wxSize(-1, FromDIP(24)));
delete_button->SetCornerRadius(FromDIP(12));
delete_button->Bind(wxEVT_BUTTON, [this, gbSizer, i, &result](auto& e) {
if (m_ui_op_lock) {
return;
} else {
m_ui_op_lock = true;
}
for (int j = 0; j < HISTORY_WINDOW_ITEMS_COUNT; j++) {
auto item = gbSizer->FindItemAtPosition({ i, j });
if (item)
if (item && item->GetWindow())
item->GetWindow()->Hide();
}
gbSizer->SetEmptyCellSize({ 0,0 });
@@ -393,6 +415,8 @@ void HistoryWindow::sync_history_data() {
edit_button->SetMinSize(wxSize(-1, FromDIP(24)));
edit_button->SetCornerRadius(FromDIP(12));
edit_button->Bind(wxEVT_BUTTON, [this, result, k_value, name_value, edit_button](auto& e) {
if (m_ui_op_lock) return;
PACalibResult result_buffer = result;
result_buffer.k_value = stof(k_value->GetLabel().ToStdString());
result_buffer.name = name_value->GetLabel().ToUTF8().data();
@@ -413,7 +437,7 @@ void HistoryWindow::sync_history_data() {
gbSizer->Add(name_value, {i, get_colume_idx(CaliColumnType::Cali_Name, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15));
gbSizer->Add(preset_name_value, {i, get_colume_idx(CaliColumnType::Cali_Filament, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15));
if (curr_obj && curr_obj->is_multi_extruders()) {
if (support_nozzle_volume(curr_obj)) {
wxString nozzle_name = get_nozzle_volume_type_name(result.nozzle_volume_type);
auto nozzle_name_label = new Label(m_history_data_panel, nozzle_name);
gbSizer->Add(nozzle_name_label, {i, get_colume_idx(CaliColumnType::Cali_Nozzle, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15));
@@ -423,6 +447,7 @@ void HistoryWindow::sync_history_data() {
gbSizer->Add(delete_button, {i, get_colume_idx(CaliColumnType::Cali_Delete, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15));
gbSizer->Add(edit_button, {i, get_colume_idx(CaliColumnType::Cali_Edit, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15));
i++;
m_ui_op_lock = false;
}
wxGetApp().UpdateDlgDarkUI(this);
@@ -520,9 +545,11 @@ EditCalibrationHistoryDialog::EditCalibrationHistoryDialog(wxWindow
Label *extruder_name_value = new Label(top_panel, extruder_name);
flex_sizer->Add(extruder_name_title);
flex_sizer->Add(extruder_name_value);
}
Label *nozzle_name_title = new Label(top_panel, _L("Nozzle"));
wxString nozzle_name;
if (support_nozzle_volume(curr_obj)) {
Label *nozzle_name_title = new Label(top_panel, _L("Nozzle"));
wxString nozzle_name;
const ConfigOptionDef *nozzle_volume_type_def = print_config_def.get("nozzle_volume_type");
if (nozzle_volume_type_def && nozzle_volume_type_def->enum_keys_map) {
for (auto iter = nozzle_volume_type_def->enum_keys_map->begin(); iter != nozzle_volume_type_def->enum_keys_map->end(); ++iter) {
@@ -615,7 +642,10 @@ void EditCalibrationHistoryDialog::on_save(wxCommandEvent& event) {
auto iter = std::find_if(m_history_results.begin(), m_history_results.end(), [this](const PACalibResult &item) {
bool has_same_name = item.name == m_new_result.name && item.filament_id == m_new_result.filament_id;
if (curr_obj && curr_obj->is_multi_extruders()) {
has_same_name &= (item.extruder_id == m_new_result.extruder_id && item.nozzle_volume_type == m_new_result.nozzle_volume_type);
has_same_name &= (item.extruder_id == m_new_result.extruder_id);
}
if (support_nozzle_volume(curr_obj)) {
has_same_name &= (item.nozzle_volume_type == m_new_result.nozzle_volume_type);
}
return has_same_name;
});
@@ -772,15 +802,15 @@ NewCalibrationHistoryDialog::NewCalibrationHistoryDialog(wxWindow *parent, const
m_comboBox_extruder->SetSelection(-1);
flex_sizer->Add(extruder_name_title);
flex_sizer->Add(m_comboBox_extruder);
}
if (support_nozzle_volume(curr_obj)) {
Label *nozzle_name_title = new Label(top_panel, _L("Nozzle"));
m_comboBox_nozzle_type = new ::ComboBox(top_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, NEW_HISTORY_DIALOG_INPUT_SIZE, 0, nullptr, wxCB_READONLY);
wxArrayString nozzle_items;
wxArrayString nozzle_items;
const ConfigOptionDef *nozzle_volume_type_def = print_config_def.get("nozzle_volume_type");
if (nozzle_volume_type_def && nozzle_volume_type_def->enum_keys_map) {
for (auto item : nozzle_volume_type_def->enum_labels) {
nozzle_items.push_back(_L(item));
}
for (auto item : nozzle_volume_type_def->enum_labels) { nozzle_items.push_back(_L(item)); }
}
m_comboBox_nozzle_type->Set(nozzle_items);
m_comboBox_nozzle_type->SetSelection(-1);
@@ -887,14 +917,16 @@ void NewCalibrationHistoryDialog::on_ok(wxCommandEvent &event)
msg_dlg.ShowModal();
return;
}
m_new_result.extruder_id = get_extruder_id(m_comboBox_extruder->GetSelection());
}
if (support_nozzle_volume(curr_obj)) {
std::string nozzle_name = m_comboBox_nozzle_type->GetValue().ToStdString();
if (nozzle_name.empty()) {
MessageDialog msg_dlg(nullptr, _L("The nozzle must be selected."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
m_new_result.extruder_id = get_extruder_id(m_comboBox_extruder->GetSelection());
m_new_result.nozzle_volume_type = NozzleVolumeType(m_comboBox_nozzle_type->GetSelection());
}
@@ -916,7 +948,10 @@ void NewCalibrationHistoryDialog::on_ok(wxCommandEvent &event)
auto iter = std::find_if(m_history_results.begin(), m_history_results.end(), [this](const PACalibResult &item) {
bool has_same_name = item.name == m_new_result.name && item.filament_id == m_new_result.filament_id;
if (curr_obj && curr_obj->is_multi_extruders()) {
has_same_name &= (item.extruder_id == m_new_result.extruder_id && item.nozzle_volume_type == m_new_result.nozzle_volume_type);
has_same_name &= (item.extruder_id == m_new_result.extruder_id);
}
if (support_nozzle_volume(curr_obj)) {
has_same_name &= (item.nozzle_volume_type == m_new_result.nozzle_volume_type);
}
return has_same_name;
});
+2
View File
@@ -40,6 +40,8 @@ protected:
bool& m_show_history_dialog;
std::vector<PACalibResult> m_calib_results_history;
MachineObject* curr_obj { nullptr };
bool m_ui_op_lock{ false };
};
class EditCalibrationHistoryDialog : public DPIDialog
+14 -2
View File
@@ -55,7 +55,8 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
select_vibration = create_check_option(_L("Vibration compensation"), cali_left_panel, _L("Vibration compensation"), "vibration");
select_motor_noise = create_check_option(_L("Motor noise cancellation"), cali_left_panel, _L("Motor noise cancellation"), "motor_noise");
select_nozzle_cali = create_check_option(_L("Nozzle offset calibration"), cali_left_panel, _L("Nozzle offset calibration"), "nozzle_cali");
select_heatbed_cali = create_check_option(_L("High-temperature Heatbed Calibration"), cali_left_panel, _L("High-temperature Heatbed Calibration"), "bed_cali");
select_heatbed_cali = create_check_option(_L("High-temperature Heatbed Calibration"), cali_left_panel, _L("High-temperature Heatbed Calibration"), "bed_cali");
select_clumppos_cali = create_check_option(_L("Nozzle clumping detection Calibration"), cali_left_panel, _L("Nozzle clumping detection Calibration"), "clump_pos_cali");
// STUDIO-10091 the default not checked option
if(m_checkbox_list.count("bed_cali") != 0)
@@ -70,6 +71,7 @@ CalibrationDialog::CalibrationDialog(Plater *plater)
cali_left_sizer->Add(select_motor_noise, 0, wxLEFT, FromDIP(15));
cali_left_sizer->Add(select_nozzle_cali, 0, wxLEFT, FromDIP(15));
cali_left_sizer->Add(select_heatbed_cali, 0, wxLEFT, FromDIP(15));
cali_left_sizer->Add(select_clumppos_cali, 0, wxLEFT, FromDIP(15));
cali_left_sizer->Add(0, FromDIP(30), 0, wxEXPAND, 0);
auto cali_left_text_top = new wxStaticText(cali_left_panel, wxID_ANY, _L("Calibration program"), wxDefaultPosition, wxDefaultSize, 0);
@@ -252,6 +254,13 @@ void CalibrationDialog::update_cali(MachineObject *obj)
m_checkbox_list["bed_cali"]->SetValue(false);
}
if (obj->GetConfig()->SupportCaliClumpPos()) {
select_clumppos_cali->Show();
} else {
select_clumppos_cali->Hide();
m_checkbox_list["clump_pos_cali"]->SetValue(false);
}
if (obj->is_calibration_running() || obj->is_calibration_done()) {
if (obj->is_calibration_done()) {
m_calibration_btn->Enable();
@@ -279,6 +288,8 @@ void CalibrationDialog::update_cali(MachineObject *obj)
for (int i = 0; i < obj->stage_list_info.size(); i++) {
m_calibration_flow->AppendItem(Slic3r::get_stage_string(obj->stage_list_info[i]));
}
last_stage_list_info = obj->stage_list_info;
}
int index = obj->get_curr_stage_idx();
m_calibration_flow->SelectItem(index);
@@ -333,7 +344,8 @@ void CalibrationDialog::on_start_calibration(wxMouseEvent &event)
m_checkbox_list["xcam_cali"]->GetValue(),
m_checkbox_list["motor_noise"]->GetValue(),
m_checkbox_list["nozzle_cali"]->GetValue(),
m_checkbox_list["bed_cali"]->GetValue()
m_checkbox_list["bed_cali"]->GetValue(),
m_checkbox_list["clump_pos_cali"]->GetValue()
);
}
}
+1
View File
@@ -45,6 +45,7 @@ private:
wxWindow* select_motor_noise { nullptr };
wxWindow* select_nozzle_cali{ nullptr };
wxWindow* select_heatbed_cali{ nullptr };
wxWindow* select_clumppos_cali{ nullptr };
wxWindow* create_check_option(wxString title, wxWindow *parent, wxString tooltip, std::string param);
public:
-4
View File
@@ -642,9 +642,6 @@ bool CalibrationPanel::Show(bool show) {
obj = dev->get_selected_machine();
if (obj == nullptr) {
dev->load_last_machine();
obj = dev->get_selected_machine();
if (obj)
GUI::wxGetApp().sidebar().load_ams_list(obj->get_dev_id(), obj);
}
else {
obj->reset_update_time();
@@ -682,7 +679,6 @@ void CalibrationPanel::set_default()
{
obj = nullptr;
last_conn_type = "undefined";
wxGetApp().sidebar().load_ams_list({}, {});
}
void CalibrationPanel::msw_rescale()
+10 -6
View File
@@ -375,7 +375,7 @@ bool CalibrationWizard::save_preset_with_index(const std::string &old_preset_nam
return true;
}
void CalibrationWizard::cache_preset_info(MachineObject* obj, float nozzle_dia)
void CalibrationWizard::cache_preset_info(MachineObject *obj, float nozzle_dia, BedType bed_type)
{
if (!obj) return;
@@ -388,6 +388,7 @@ void CalibrationWizard::cache_preset_info(MachineObject* obj, float nozzle_dia)
CaliPresetInfo result;
result.tray_id = item.first;
result.nozzle_diameter = nozzle_dia;
result.bed_type = bed_type;
result.filament_id = item.second->filament_id;
result.setting_id = item.second->setting_id;
result.name = item.second->name;
@@ -396,13 +397,12 @@ void CalibrationWizard::cache_preset_info(MachineObject* obj, float nozzle_dia)
int ams_id, slot_id, tray_id;
get_tray_ams_and_slot_id(curr_obj, result.tray_id, ams_id, slot_id, tray_id);
result.extruder_id = preset_page->get_extruder_id(ams_id);
result.nozzle_volume_type = preset_page->get_nozzle_volume_type(result.extruder_id);
result.nozzle_diameter = preset_page->get_nozzle_diameter(result.extruder_id);
}
else {
result.extruder_id = 0;
result.nozzle_volume_type = NozzleVolumeType::nvtStandard;
}
result.nozzle_volume_type = preset_page->get_nozzle_volume_type(result.extruder_id);
obj->selected_cali_preset.push_back(result);
}
@@ -697,7 +697,7 @@ void PressureAdvanceWizard::on_cali_start()
float nozzle_dia = -1;
preset_page->get_preset_info(nozzle_dia, plate_type);
CalibrationWizard::cache_preset_info(curr_obj, nozzle_dia);
CalibrationWizard::cache_preset_info(curr_obj, nozzle_dia, plate_type);
if (/*nozzle_dia < 0 || */ plate_type == BedType::btDefault) {
BOOST_LOG_TRIVIAL(error) << "CaliPreset: get preset info, nozzle and plate type error";
return;
@@ -970,6 +970,7 @@ void PressureAdvanceWizard::on_cali_save()
if (save_page->is_all_failed()) {
MessageDialog msg_dlg(nullptr, _L("The failed test result has been dropped."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
back_preset_info(curr_obj, true);
show_step(start_step);
return;
}
@@ -1207,7 +1208,7 @@ void FlowRateWizard::on_cali_start(CaliPresetStage stage, float cali_value, Flow
msg_dlg.ShowModal();
return;
}
CalibrationWizard::cache_preset_info(curr_obj, nozzle_dia);
CalibrationWizard::cache_preset_info(curr_obj, nozzle_dia, plate_type);
}
else if (from_page == FlowRatioCaliSource::FROM_COARSE_PAGE) {
selected_filaments = get_cached_selected_filament(curr_obj);
@@ -1278,6 +1279,7 @@ void FlowRateWizard::on_cali_start(CaliPresetStage stage, float cali_value, Flow
int selected_tray_id = curr_obj->selected_cali_preset.front().tray_id;
PresetCollection *filament_presets = &wxGetApp().preset_bundle->filaments;
Preset* preset = filament_presets->find_preset(curr_obj->selected_cali_preset.front().name);
plate_type = curr_obj->selected_cali_preset.front().bed_type;
if (preset) {
selected_filaments.insert(std::make_pair(selected_tray_id, preset));
}
@@ -1383,6 +1385,7 @@ void FlowRateWizard::on_cali_save()
if (save_page->is_all_failed()) {
MessageDialog msg_dlg(nullptr, _L("The failed test result has been dropped."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
back_preset_info(curr_obj, true);
show_step(start_step);
return;
}
@@ -1672,7 +1675,7 @@ void MaxVolumetricSpeedWizard::on_cali_start()
preset_page->get_preset_info(nozzle_dia, plate_type);
CalibrationWizard::cache_preset_info(curr_obj, nozzle_dia);
CalibrationWizard::cache_preset_info(curr_obj, nozzle_dia, plate_type);
wxArrayString values = preset_page->get_custom_range_values();
Calib_Params params;
@@ -1762,6 +1765,7 @@ void MaxVolumetricSpeedWizard::on_cali_save()
MessageDialog msg_dlg(nullptr, _L("Max volumetric speed calibration result has been saved to preset."), wxEmptyString, wxOK);
msg_dlg.ShowModal();
back_preset_info(curr_obj, true);
show_step(start_step);
}
+1 -1
View File
@@ -69,7 +69,7 @@ public:
bool save_preset(const std::string &old_preset_name, const std::string &new_preset_name, const std::map<std::string, ConfigOption *> &key_values, wxString& message);
bool save_preset_with_index(const std::string &old_preset_name, const std::string &new_preset_name, const std::map<std::string, ConfigIndexValue> &key_values, wxString &message);
virtual void cache_preset_info(MachineObject* obj, float nozzle_dia);
virtual void cache_preset_info(MachineObject *obj, float nozzle_dia, BedType bed_type);
virtual void recover_preset_info(MachineObject *obj);
virtual void back_preset_info(MachineObject *obj, bool cali_finish, bool back_cali_flag = true);
+5 -12
View File
@@ -109,22 +109,15 @@ void CalibrationCaliPage::set_cali_img()
}
else if (m_cali_method == CalibrationMethod::CALI_METHOD_AUTO || m_cali_method == CalibrationMethod::CALI_METHOD_NEW_AUTO) {
if (curr_obj) {
std::string image_name = curr_obj->get_auto_pa_cali_thumbnail_img_str();
if (curr_obj->is_multi_extruders()) {
if (m_cur_extruder_id == 0) {
m_picture_panel->set_bmp(ScalableBitmap(this, "fd_calibration_auto_multi_extruders_right", 400));
image_name += "_right";
} else {
assert(m_cur_extruder_id == 1);
m_picture_panel->set_bmp(ScalableBitmap(this, "fd_calibration_auto_multi_extruders_left", 400));
image_name += "_left";
}
}
else if (curr_obj->get_printer_arch() == PrinterArch::ARCH_I3) {
m_picture_panel->set_bmp(ScalableBitmap(this, "fd_calibration_auto_i3", 400));
} else if (curr_obj->is_series_o()) {
m_picture_panel->set_bmp(ScalableBitmap(this, "fd_calibration_auto_single_o", 400));
}
else {
m_picture_panel->set_bmp(ScalableBitmap(this, "fd_calibration_auto", 400));
}
m_picture_panel->set_bmp(ScalableBitmap(this, image_name, 400));
}
else {
m_picture_panel->set_bmp(ScalableBitmap(this, "fd_calibration_auto", 400));
@@ -277,7 +270,7 @@ void CalibrationCaliPage::update(MachineObject* obj)
enable_cali = false;
}
} else {
assert(false);
//assert(false);
}
m_action_panel->enable_button(CaliPageActionType::CALI_ACTION_CALI_NEXT, enable_cali);
}
@@ -1206,6 +1206,7 @@ void CalibrationPresetPage::create_page(wxWindow* parent)
m_sending_panel->get_sending_progress_bar()->set_cancel_callback_fina([this]() {
on_cali_cancel_job();
});
m_sending_panel->Bind(EVT_SHOW_ERROR_FAIL_SEND, [this](auto &event){on_cali_cancel_job();});
m_sending_panel->Hide();
m_custom_range_panel = new CaliPresetCustomRangePanel(parent);
+13 -2
View File
@@ -260,7 +260,12 @@ void CaliPASaveAutoPanel::sync_cali_result(const std::vector<PACalibResult>& cal
}
preset_names = default_naming(preset_names);
for (auto& item : cali_result) {
std::vector<PACalibResult> sorted_cali_result = cali_result;
std::sort(sorted_cali_result.begin(), sorted_cali_result.end(), [this](const PACalibResult &left, const PACalibResult& right) {
return left.tray_id < right.tray_id;
});
for (auto &item : sorted_cali_result) {
bool result_failed = false;
if (item.confidence != 0) {
result_failed = true;
@@ -339,7 +344,13 @@ void CaliPASaveAutoPanel::sync_cali_result(const std::vector<PACalibResult>& cal
n_value->GetTextCtrl()->SetValue(n_str);
for (auto& name : preset_names) {
if (item.tray_id == name.first) {
int tray_id = item.tray_id;
/* upgrade single extruder printer tray_id from 254 to 255 */
if (!m_obj->is_multi_extruders() && tray_id == VIRTUAL_TRAY_DEPUTY_ID) {
tray_id = VIRTUAL_TRAY_MAIN_ID;
}
if (tray_id == name.first) {
comboBox_tray_name->SetValue(from_u8(name.second));
}
}
+11 -3
View File
@@ -305,6 +305,15 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
is_msg_dlg_already_exist = false;
}
if (config->option<ConfigOptionBool>("enable_wrapping_detection")->value) {
std::string printer_type = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle);
if (!DevPrinterConfigUtil::support_wrapping_detection(printer_type)) {
DynamicPrintConfig new_conf = *config;
new_conf.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
apply(config, &new_conf);
}
}
double sparse_infill_density = config->option<ConfigOptionPercent>("sparse_infill_density")->value;
int fill_multiline = config->option<ConfigOptionInt>("fill_multiline")->value;
auto timelapse_type = config->opt_enum<TimelapseType>("timelapse_type");
@@ -933,9 +942,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
toggle_line("infill_overhang_angle", config->opt_enum<InfillPattern>("sparse_infill_pattern") == InfillPattern::ipLateralHoneycomb);
ConfigOptionPoints *wrapping_exclude_area_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionPoints>("wrapping_exclude_area");
bool support_wrapping_detect = wrapping_exclude_area_opt &&wrapping_exclude_area_opt->values.size() > 3;
toggle_line("enable_wrapping_detection", support_wrapping_detect);
std::string printer_type = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle);
toggle_line("enable_wrapping_detection", DevPrinterConfigUtil::support_wrapping_detection(printer_type));
}
void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)
+63 -13
View File
@@ -195,6 +195,23 @@ static bool caseInsensitiveCompare(const std::string& a, const std::string& b) {
return lowerA < lowerB;
}
static float my_stof(std::string str) {
const char dec_sep = is_decimal_separator_point() ? '.' : ',';
const char dec_sep_alt = dec_sep == '.' ? ',' : '.';
size_t alt_pos = str.find(dec_sep_alt);
if (alt_pos != std::string::npos) { str.replace(alt_pos, 1, 1, dec_sep); }
if (str == std::string(1, dec_sep)) { return 0.0f; }
try {
return static_cast<float>(std::stod(str));
} catch (...) {
return 0.f;
}
}
static bool delete_filament_preset_by_name(std::string delete_preset_name, std::string &selected_preset_name)
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select preset, name %1%") % delete_preset_name;
@@ -692,6 +709,11 @@ CreateFilamentPresetDialog::CreateFilamentPresetDialog(wxWindow *parent)
Layout();
Fit();
this->Bind(wxEVT_SIZE, [this](wxSizeEvent &event) {
this->Refresh();
event.Skip();
});
wxGetApp().UpdateDlgDarkUI(this);
}
@@ -816,6 +838,8 @@ wxBoxSizer *CreateFilamentPresetDialog::create_vendor_item()
Refresh();
Layout();
Fit();
e.Skip();
});
comboBoxSizer->Add(vendor_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
@@ -1465,12 +1489,25 @@ void CreateFilamentPresetDialog::get_all_visible_printer_name()
void CreateFilamentPresetDialog::update_dialog_size()
{
this->Freeze();
int height_before = m_filament_preset_panel->GetSize().GetHeight();
m_filament_preset_panel->SetSizerAndFit(m_filament_presets_sizer);
int width = m_filament_preset_panel->GetSize().GetWidth();
int height = m_filament_preset_panel->GetSize().GetHeight();
m_scrolled_preset_panel->SetMinSize(wxSize(std::min(1400, width + FromDIP(26)), std::min(600, height + FromDIP(18))));
m_scrolled_preset_panel->SetMaxSize(wxSize(std::min(1400, width + FromDIP(26)), std::min(600, height + FromDIP(18))));
m_scrolled_preset_panel->SetSize(wxSize(std::min(1500, width + FromDIP(26)), std::min(600, height + FromDIP(18))));
int width = m_filament_preset_panel->GetSize().GetWidth();
int height = m_filament_preset_panel->GetSize().GetHeight();
int screen_height = wxGetDisplaySize().GetHeight();
wxSize dialog_size = this->GetSize();
int max_available_height = screen_height - FromDIP(100);
int ideal_scroll_height = height + FromDIP(26);
int other_parts_height = dialog_size.GetHeight() - m_scrolled_preset_panel->GetSize().GetHeight() + FromDIP(12);
int max_safe_scroll_height = max_available_height - other_parts_height;
int final_scroll_height = std::min(ideal_scroll_height, max_safe_scroll_height);
m_scrolled_preset_panel->SetMinSize(wxSize(std::min(1400, width + FromDIP(26)), final_scroll_height));
m_scrolled_preset_panel->SetMaxSize(wxSize(std::min(1400, width + FromDIP(26)), final_scroll_height));
m_scrolled_preset_panel->SetSize(wxSize(std::min(1500, width + FromDIP(26)), final_scroll_height));
Layout();
Fit();
Refresh();
@@ -1807,6 +1844,8 @@ wxBoxSizer *CreatePrinterPresetDialog::create_printer_item(wxWindow *parent)
Layout();
m_page1->SetSizerAndFit(m_page1_sizer);
Fit();
e.Skip();
});
vertical_sizer->Add(checkbox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
@@ -1831,8 +1870,12 @@ wxBoxSizer *CreatePrinterPresetDialog::create_nozzle_diameter_item(wxWindow *par
wxBoxSizer *comboBoxSizer = new wxBoxSizer(wxHORIZONTAL);
m_nozzle_diameter = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, OPTION_SIZE, 0, nullptr, wxCB_READONLY);
wxArrayString nozzle_diameters;
const char dec_sep = is_decimal_separator_point() ? '.' : ',';
for (const std::string& nozzle : nozzle_diameter_vec) {
nozzle_diameters.Add(nozzle + " mm");
std::string display_nozzle = nozzle;
size_t pos = display_nozzle.find('.');
if (pos != std::string::npos) { display_nozzle.replace(pos, 1, 1, dec_sep); }
nozzle_diameters.Add(display_nozzle + " mm");
}
m_nozzle_diameter->Set(nozzle_diameters);
m_nozzle_diameter->SetSelection(0);
@@ -1842,7 +1885,7 @@ wxBoxSizer *CreatePrinterPresetDialog::create_nozzle_diameter_item(wxWindow *par
m_custom_nozzle_diameter_ctrl->SetHint(_L("Input Custom Nozzle Diameter"));
m_custom_nozzle_diameter_ctrl->Bind(wxEVT_CHAR, [this](wxKeyEvent &event) {
int key = event.GetKeyCode();
if (key != 46 && cannot_input_key.find(key) != cannot_input_key.end()) { // "@" can not be inputed
if (key != 44 && key != 46 && cannot_input_key.find(key) != cannot_input_key.end()) { // "@" can not be inputed
event.Skip(false);
return;
}
@@ -1881,6 +1924,8 @@ wxBoxSizer *CreatePrinterPresetDialog::create_nozzle_diameter_item(wxWindow *par
Layout();
m_page1->SetSizerAndFit(m_page1_sizer);
Fit();
e.Skip();
});
vertical_sizer->Add(checkbox_sizer, 0, wxEXPAND | wxTOP, FromDIP(5));
@@ -2250,7 +2295,7 @@ void CreatePrinterPresetDialog::generate_process_presets_data(std::vector<Preset
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " entry, and nozzle is: " << nozzle;
std::unordered_map<std::string, float> nozzle_diameter_map_ = nozzle_diameter_map;
float nozzle_dia = std::stof(get_nozzle_diameter());
float nozzle_dia = my_stof(get_nozzle_diameter());
for (const Preset *preset : presets) {
auto layer_height = dynamic_cast<ConfigOptionFloat *>(const_cast<Preset *>(preset)->config.option("layer_height", true));
if (layer_height)
@@ -2391,7 +2436,7 @@ std::string CreatePrinterPresetDialog::get_nozzle_diameter() const
}
float nozzle = 0;
try {
nozzle = std::stof(diameter);
nozzle = my_stof(diameter);
}
catch (...) { }
if (nozzle == 0) diameter = "0.4";
@@ -2723,6 +2768,11 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren
// create preset name
std::string printer_model_name = get_custom_printer_model();
std::string printer_nozzle_name = get_nozzle_diameter();
// Replace comma with period in nozzle diameter for consistency
size_t comma_pos = printer_nozzle_name.find(',');
if (comma_pos != std::string::npos) {
printer_nozzle_name.replace(comma_pos, 1, ".");
}
std::string nozzle_diameter = printer_nozzle_name + " nozzle";
std::string printer_preset_name = printer_model_name + " " + nozzle_diameter;
@@ -2884,7 +2934,7 @@ wxWindow *CreatePrinterPresetDialog::create_page2_dialog_buttons(wxWindow *paren
if (nozzle_diameter_map.end() != iter) {
std::fill(nozzle_diameter->values.begin(), nozzle_diameter->values.end(), iter->second);
} else {
std::fill(nozzle_diameter->values.begin(), nozzle_diameter->values.end(), std::stof(get_nozzle_diameter()));
std::fill(nozzle_diameter->values.begin(), nozzle_diameter->values.end(), my_stof(get_nozzle_diameter()));
}
}
}
@@ -3064,7 +3114,7 @@ wxArrayString CreatePrinterPresetDialog::printer_preset_sort_with_nozzle_diamete
for (const Slic3r::VendorProfile::PrinterVariant &variant : model.variants) {
try {
float variant_diameter = std::stof(variant.name);
float variant_diameter = my_stof(variant.name);
preset_sort.push_back(std::make_pair(variant_diameter, model_name + " @ " + variant.name + " nozzle"));
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "nozzle: " << variant_diameter << "model: " << preset_sort.back().second;
}
@@ -3307,11 +3357,11 @@ bool CreatePrinterPresetDialog::validate_input_valid()
} else {
nozzle_diameter = into_u8(m_nozzle_diameter->GetStringSelection());
size_t index_mm = nozzle_diameter.find(" mm");
if (std::string::npos != index_mm) { nozzle_diameter.substr(0, index_mm); }
if (std::string::npos != index_mm) { nozzle_diameter = nozzle_diameter.substr(0, index_mm); }
}
float nozzle_dia = 0;
try {
nozzle_dia = std::stof(nozzle_diameter);
nozzle_dia = my_stof(nozzle_diameter);
} catch (...) { }
if (nozzle_dia == 0) {
MessageDialog dlg(this, _L("The entered nozzle diameter is invalid, please re-enter:\n"), wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Info"),
+4
View File
@@ -13,6 +13,8 @@ list(APPEND SLIC3R_GUI_SOURCES
GUI/DeviceCore/DevCtrl.h
GUI/DeviceCore/DevCtrl.cpp
GUI/DeviceCore/DevDefs.h
GUI/DeviceCore/DevExtensionTool.h
GUI/DeviceCore/DevExtensionTool.cpp
GUI/DeviceCore/DevExtruderSystem.h
GUI/DeviceCore/DevExtruderSystem.cpp
GUI/DeviceCore/DevExtruderSystemCtrl.cpp
@@ -20,10 +22,12 @@ list(APPEND SLIC3R_GUI_SOURCES
GUI/DeviceCore/DevFan.h
GUI/DeviceCore/DevFilaAmsSetting.h
GUI/DeviceCore/DevFilaAmsSetting.cpp
GUI/DeviceCore/DevFilaAmsSettingCtrl.cpp
GUI/DeviceCore/DevFilaBlackList.h
GUI/DeviceCore/DevFilaBlackList.cpp
GUI/DeviceCore/DevFilaSystem.h
GUI/DeviceCore/DevFilaSystem.cpp
GUI/DeviceCore/DevFilaSystemCtrl.cpp
GUI/DeviceCore/DevFirmware.h
GUI/DeviceCore/DevFirmware.cpp
GUI/DeviceCore/DevPrintOptions.h
+2
View File
@@ -18,6 +18,7 @@ void DevConfig::ParseConfig(const json& print_json)
void DevConfig::ParseChamberConfig(const json& print_json)
{
DevJsonValParser::ParseVal(print_json, "support_chamber", m_has_chamber);
DevJsonValParser::ParseVal(print_json, "support_chamber_temp_edit", m_support_chamber_edit);
if (m_support_chamber_edit)
{
@@ -49,6 +50,7 @@ void DevConfig::ParseCalibrationConfig(const json& print_json)
DevJsonValParser::ParseVal(print_json, "support_nozzle_offset_calibration", m_support_calibration_nozzle_offset);
DevJsonValParser::ParseVal(print_json, "support_high_tempbed_calibration", m_support_calibration_high_temp_bed);
DevJsonValParser::ParseVal(print_json, "support_auto_flow_calibration", m_support_calibration_pa_flow_auto);
DevJsonValParser::ParseVal(print_json, "support_clump_position_calibration", m_support_calibration_clump_pos);
}
}
+4
View File
@@ -21,6 +21,7 @@ public:
public:
// chamber
bool HasChamber() const { return m_has_chamber; }
bool SupportChamberEdit() const { return m_support_chamber_edit; }
int GetChamberTempEditMin() const { return m_chamber_temp_edit_min; }
int GetChamberTempEditMax() const { return m_chamber_temp_edit_max; }
@@ -38,6 +39,7 @@ public:
bool SupportCalibrationLidar() const { return m_support_calibration_lidar; }
bool SupportCalibrationNozzleOffset() const { return m_support_calibration_nozzle_offset; }
bool SupportCalibrationHighTempBed() const { return m_support_calibration_high_temp_bed; }
bool SupportCaliClumpPos() const { return m_support_calibration_clump_pos; }
bool SupportCalibrationPA_FlowAuto() const { return m_support_calibration_pa_flow_auto; }
@@ -54,6 +56,7 @@ private:
/*configure vals*/
// chamber
bool m_has_chamber = false; // whether the machine has a chamber
bool m_support_chamber_edit = false;
int m_chamber_temp_edit_min = 0;
int m_chamber_temp_edit_max = 60;
@@ -71,6 +74,7 @@ private:
bool m_support_calibration_lidar = false;
bool m_support_calibration_nozzle_offset = false;
bool m_support_calibration_high_temp_bed = false; // High-temperature Heatbed Calibration
bool m_support_calibration_clump_pos = false; // clump position calibration
bool m_support_calibration_pa_flow_auto = false;// PA flow calibration. used in SendPrint
};
+29 -1
View File
@@ -71,11 +71,20 @@ public:
/*extruder*/
static bool get_printer_can_set_nozzle(std::string type_str) { return get_value_from_config<bool>(type_str, "enable_set_nozzle_info"); }// can set nozzle from studio
/*print job*/
static bool support_ams_ext_mix_print(std::string type_str) { return get_value_from_config<bool>(type_str, "print", "support_ams_ext_mix_print"); }
/*calibration*/
static std::vector<std::string> get_unsupport_auto_cali_filaments(std::string type_str) { return get_value_from_config<std::vector<std::string>>(type_str, "auto_cali_not_support_filaments"); }
/*detection*/
static bool support_wrapping_detection(const std::string& type_str) { return get_value_from_config<bool>(type_str, "support_wrapping_detection"); }
static bool support_wrapping_detection(const std::string& type_str) { return get_value_from_config<bool>(type_str, "support_wrapping_detection"); }
/*safety options*/
static bool support_safety_options(const std::string &type_str) { return get_value_from_config<bool>(type_str, "support_safety_options"); }
/*print check*/
static bool support_print_check_extension_fan_f000_mounted(const std::string& type_str) { return get_value_from_config<bool>(type_str, "print", "support_print_check_extension_fan_f000_mounted"); }
public:
template<typename T>
@@ -103,6 +112,25 @@ public:
return T();
};
template<typename T>
static T get_value_from_config(const std::string& type_str, const std::string& item1, const std::string& item2)
{
try
{
const auto& json_item1 = get_value_from_config<nlohmann::json>(type_str, item1);
if (json_item1.contains(item2))
{
return json_item1[item2].get<T>();
}
}
catch (...)
{
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " failed to get " << item1 << ", " << item2;
}
return T();
}
static nlohmann::json get_json_from_config(const std::string& type_str, const std::string& key1, const std::string& key2 = std::string())
{
std::string config_file = m_resource_file_path + "/printers/" + type_str + ".json";
+47
View File
@@ -9,6 +9,53 @@ using namespace nlohmann;
namespace Slic3r
{
DevCtrlInfo::DevCtrlInfo(MachineObject* obj, int sequence_id, const json& req_json,
int interval_max, int interval_min)
{
m_request_dev_id = obj->get_dev_id();
m_request_seq = sequence_id;
m_request_time = time(nullptr);
m_request_json = req_json;
m_request_interval_max = interval_max;
m_request_interval_min = interval_min;
}
bool DevCtrlInfo::CheckCanUpdateData(const nlohmann::json& jj)
{
if (m_request_json.empty()) {
return true;
}
if (m_time_out) {
return true;
}
if (time(nullptr) - m_request_time > m_request_interval_max) {
OnTimeOut();
return true;
}
if (time(nullptr) - m_request_time < m_request_interval_min) {
return false;
}
if (m_received) {
return true;
}
try {
if (jj.contains("sequence_id") && jj["sequence_id"].is_string()) {
int sequence_id = stoi(jj["sequence_id"].get<std::string>());
if (sequence_id >= m_request_seq) {
OnReceived();
return true;
}
}
} catch (...) {
;
}
return false;
}
int DevCtrl::command_select_extruder(int id)
{
json j;
+27
View File
@@ -10,6 +10,33 @@ namespace Slic3r
//Previous definitions
class MachineObject;
class DevCtrlInfo
{
public:
DevCtrlInfo() {};
DevCtrlInfo(MachineObject* obj, int sequence_id, const json& req_json, int interval_max = 3, int interval_min = 0);
public:
bool CheckCanUpdateData(const nlohmann::json& jj);
private:
void OnTimeOut() { m_time_out = true;}
void OnReceived() { m_received = true;} ;
private:
bool m_time_out = false;
bool m_received = false;
std::string m_request_dev_id = "";
time_t m_request_time = 0;
int m_request_seq = 0;
json m_request_json = json();
// check
int m_request_interval_max = 3;
int m_request_interval_min = 0;
};
class DevCtrl
{
@@ -0,0 +1,39 @@
#include "DevExtensionTool.h"
#include "DevUtil.h"
#include <nlohmann/json.hpp>
using namespace nlohmann;
namespace Slic3r
{
DevExtensionTool::DevExtensionTool(MachineObject* obj) : m_owner(obj)
{
m_mount_3dp = MOUNT_NOT_MOUNTED;
m_calib = CALIB_NONE;
m_tool_type = TOOL_TYPE_EMPTY;
}
void DevExtensionToolParser::ParseV2_0(const nlohmann::json& extension_tool_json, std::weak_ptr<DevExtensionTool> extension_tool)
{
if (auto ext_tool = extension_tool.lock())
{
DevJsonValParser::ParseVal(extension_tool_json, "mount_3d", ext_tool->m_mount_3dp, ext_tool->m_mount_3dp);
DevJsonValParser::ParseVal(extension_tool_json, "calib", ext_tool->m_calib, ext_tool->m_calib);
{
const std::string& type_str = DevJsonValParser::GetVal<std::string>(extension_tool_json, "type", "");
static std::map<std::string, DevExtensionTool::ToolType> s_type_map = {
{"CP00", DevExtensionTool::TOOL_TYPE_CUT_CP00},
{"LB00", DevExtensionTool::TOOL_TYPE_LASER_LB00},
{"F000", DevExtensionTool::TOOL_TYPE_FAN_F000}
};
auto iter = s_type_map.find(type_str);
iter != s_type_map.end() ? ext_tool->m_tool_type = iter->second : DevExtensionTool::TOOL_TYPE_EMPTY;
}
}
}
}
@@ -0,0 +1,67 @@
#pragma once
#include <optional>
#include "libslic3r/CommonDefs.hpp"
#include "slic3r/Utils/json_diff.hpp"
#include <wx/string.h>
#include "DevDefs.h"
namespace Slic3r
{
//Previous definitions
class MachineObject;
// some extension tools for toolheads
class DevExtensionTool
{
friend class DevExtensionToolParser;
public:
static std::shared_ptr<DevExtensionTool> Create(MachineObject* obj) { return std::shared_ptr<DevExtensionTool>(new DevExtensionTool(obj)); }
public:
// tool type
bool IsToolTypeFanF000() const { return m_tool_type == TOOL_TYPE_FAN_F000; }
// mount state
bool IsMounted() const { return m_mount_3dp == MOUNT_MOUNTED; }
protected:
DevExtensionTool(MachineObject* obj);
private:
MachineObject* m_owner = nullptr;
enum MountState
{
MOUNT_NOT_MOUNTED = 0,
MOUNT_MOUNTED = 1,
MOUNT_NO_MODULE = 2,
MOUNT_NO_CABLE = 3
} m_mount_3dp;
enum CalibState
{
CALIB_NONE = 0,
CALIB_FIRST = 1,
CALIB_MOUNT = 2
} m_calib;
enum ToolType
{
TOOL_TYPE_EMPTY = 0,
TOOL_TYPE_CUT_CP00 = 1,
TOOL_TYPE_LASER_LB00 = 2,
TOOL_TYPE_FAN_F000 = 3,
} m_tool_type;
};
class DevExtensionToolParser
{
public:
static void ParseV2_0(const nlohmann::json& extension_tool_json, std::weak_ptr<DevExtensionTool> extension_tool);
};
};
@@ -166,8 +166,11 @@ namespace Slic3r
if (!tray_tar.empty())
{
int tray_tar_int = atoi(tray_tar.c_str());
if (tray_tar_int == VIRTUAL_TRAY_MAIN_ID || tray_tar_int == VIRTUAL_TRAY_DEPUTY_ID)
{
if (tray_tar_int == VIRTUAL_TRAY_MAIN_ID) /*255 means unloading*/ {
system->m_extders[MAIN_EXTRUDER_ID].m_star.ams_id = "";
system->m_extders[MAIN_EXTRUDER_ID].m_star.slot_id = std::to_string(VIRTUAL_TRAY_MAIN_ID);
}
else if (tray_tar_int == VIRTUAL_TRAY_DEPUTY_ID) /*254 means loading ext spool*/ {
system->m_extders[MAIN_EXTRUDER_ID].m_star.ams_id = std::to_string(VIRTUAL_TRAY_MAIN_ID);
system->m_extders[MAIN_EXTRUDER_ID].m_star.slot_id = "0";
}
+47 -47
View File
@@ -1,5 +1,5 @@
#include <nlohmann/json.hpp>
#include "DevFan.h"
#include "DevFan.h"
#include <wx/app.h>
#include "slic3r/GUI/DeviceManager.hpp"
#include "slic3r/GUI/GUI.hpp"
@@ -158,62 +158,62 @@ void Slic3r::DevFan::ParseV2_0(const json &print_json) {
void Slic3r::DevFan::ParseV3_0(const json &device)
void Slic3r::DevFan::ParseV3_0(const json &device)
{
if (device.contains("airduct")) {
m_air_duct_data.curren_mode = -1;
m_air_duct_data.modes.clear();
m_air_duct_data.parts.clear();
if (device.contains("airduct")) {
is_support_airduct = true;
m_air_duct_data.curren_mode = -1;
m_air_duct_data.modes.clear();
m_air_duct_data.parts.clear();
m_air_duct_data.curren_mode = device["airduct"]["modeCur"].get<int>();
m_air_duct_data.curren_mode = device["airduct"]["modeCur"].get<int>();
const json &airduct = device["airduct"];
if (airduct.contains("modeCur")) { m_air_duct_data.curren_mode = airduct["modeCur"].get<int>(); }
if (airduct.contains("subMode")) { m_air_duct_data.m_sub_mode = airduct["subMode"].get<int>(); }
if (airduct.contains("modeList") && airduct["modeList"].is_array()) {
auto list = airduct["modeList"].get<std::vector<json>>();
const json &airduct = device["airduct"];
if (airduct.contains("modeCur")) { m_air_duct_data.curren_mode = airduct["modeCur"].get<int>(); }
if (airduct.contains("subMode")) { m_air_duct_data.m_sub_mode = airduct["subMode"].get<int>(); }
if (airduct.contains("modeList") && airduct["modeList"].is_array()) {
auto list = airduct["modeList"].get<std::vector<json>>();
for (int i = 0; i < list.size(); ++i) {
// only show 2 mode for o
if (m_owner->is_series_o() && i >= 2) { break; }
for (int i = 0; i < list.size(); ++i) {
// only show 2 mode for o
if (m_owner->is_series_o() && i >= 2) { break; }
json mode_json = list[i];
AirMode mode;
if (mode_json.contains("modeId")) mode.id = mode_json["modeId"].get<int>();
if (mode_json.contains("ctrl")) {
for (auto it_mode_ctrl = mode_json["ctrl"].begin(); it_mode_ctrl != mode_json["ctrl"].end(); it_mode_ctrl++) {
mode.ctrl.push_back((*it_mode_ctrl).get<int>() >> 4);
}
}
if (mode_json.contains("off")) {
for (auto it_mode_off = mode_json["off"].begin(); it_mode_off != mode_json["off"].end(); *it_mode_off++) {
mode.off.push_back((*it_mode_off).get<int>() >> 4);
}
}
if (AIR_DUCT(mode.id) == AIR_DUCT::AIR_DUCT_EXHAUST) { continue; } /*STUDIO-12796*/
m_air_duct_data.modes[mode.id] = mode;
json mode_json = list[i];
AirMode mode;
if (mode_json.contains("modeId")) mode.id = mode_json["modeId"].get<int>();
if (mode_json.contains("ctrl")) {
for (auto it_mode_ctrl = mode_json["ctrl"].begin(); it_mode_ctrl != mode_json["ctrl"].end(); it_mode_ctrl++) {
mode.ctrl.push_back((*it_mode_ctrl).get<int>() >> 4);
}
}
if (airduct.contains("parts") && airduct["parts"].is_array()) {
for (auto it_part = airduct["parts"].begin(); it_part != airduct["parts"].end(); it_part++) {
int state = (*it_part)["state"].get<int>();
int range = (*it_part)["range"].get<int>();
AirParts part;
part.type = m_owner->get_flag_bits((*it_part)["id"].get<int>(), 0, 4);
part.id = m_owner->get_flag_bits((*it_part)["id"].get<int>(), 4, 8);
part.func = (*it_part)["func"].get<int>();
part.state = m_owner->get_flag_bits(state, 0, 8);
part.range_start = m_owner->get_flag_bits(range, 0, 16);
part.range_end = m_owner->get_flag_bits(range, 16, 16);
m_air_duct_data.parts.push_back(part);
if (mode_json.contains("off")) {
for (auto it_mode_off = mode_json["off"].begin(); it_mode_off != mode_json["off"].end(); *it_mode_off++) {
mode.off.push_back((*it_mode_off).get<int>() >> 4);
}
}
if (AIR_DUCT(mode.id) == AIR_DUCT::AIR_DUCT_EXHAUST) { continue; } /*STUDIO-12796*/
m_air_duct_data.modes[mode.id] = mode;
}
}
if (airduct.contains("parts") && airduct["parts"].is_array()) {
for (auto it_part = airduct["parts"].begin(); it_part != airduct["parts"].end(); it_part++) {
int state = (*it_part)["state"].get<int>();
int range = (*it_part)["range"].get<int>();
AirParts part;
part.type = m_owner->get_flag_bits((*it_part)["id"].get<int>(), 0, 4);
part.id = m_owner->get_flag_bits((*it_part)["id"].get<int>(), 4, 8);
part.func = (*it_part)["func"].get<int>();
part.state = m_owner->get_flag_bits(state, 0, 8);
part.range_start = m_owner->get_flag_bits(range, 0, 16);
part.range_end = m_owner->get_flag_bits(range, 16, 16);
m_air_duct_data.parts.push_back(part);
}
}
}
}
+6 -1
View File
@@ -2,6 +2,8 @@
#include <nlohmann/json.hpp>
#include "slic3r/Utils/json_diff.hpp"
#include <map>
namespace Slic3r {
class MachineObject;
@@ -69,7 +71,7 @@ public:
struct AirDuctData
{
int curren_mode{0};
std::unordered_map<int, AirMode> modes;
std::map<int, AirMode> modes;
std::vector<AirParts> parts;
int m_sub_mode = -1;// the submode of airduct, for cooling: 0-filter, 1-cooling
@@ -106,6 +108,7 @@ public:
};
bool is_at_heating_mode() const { return m_air_duct_data.curren_mode == AIR_DUCT_HEATING_INTERNAL_FILT; };
bool is_at_cooling_mode() const { return m_air_duct_data.curren_mode == AIR_DUCT_COOLING_FILT; };
void SetSupportCoolingFilter(bool enable) { m_air_duct_data.m_support_cooling_filter = enable; }
AirDuctData GetAirDuctData() { return m_air_duct_data; };
@@ -121,6 +124,7 @@ public:
void ParseV3_0(const json &print_json);
public:
bool GetSupportAirduct() { return is_support_airduct; };
bool GetSupportAuxFanData() { return is_support_aux_fan; };
bool GetSupportChamberFan() { return is_support_aux_fan; };
int GetHeatBreakFanSpeed() { return heatbreak_fan_speed; }
@@ -135,6 +139,7 @@ private:
bool is_support_aux_fan{false};
bool is_support_chamber_fan{false};
bool is_support_airduct{false};
int heatbreak_fan_speed = 0;
int cooling_fan_speed = 0;
@@ -1,13 +1,70 @@
#include "DevFilaAmsSetting.h"
#include "DevUtil.h"
namespace Slic3r {
void DevAmsSystemSetting::Reset()
{
SetDetectOnInsertEnabled(false);
m_enable_detect_on_insert.reset();
SetDetectOnPowerupEnabled(false);
SetDetectRemainEnabled(false);
SetAutoRefillEnabled(false);
}
void DevAmsSystemFirmwareSwitch::Reset()
{
m_status.clear();
m_current_firmware_run = DevAmsSystemFirmware();
m_current_firmware_sel = DevAmsSystemFirmware();
m_firmwares.clear();
}
void DevAmsSystemFirmwareSwitch::ParseFirmwareSwitch(const nlohmann::json& j)
{
if (!m_ctrl_switching.CheckCanUpdateData(j.contains("upgrade") ? j["upgrade"] :j)) {
return;
}
if (j.contains("print")) {
const auto& print_jj = j["print"];
if (print_jj.contains("upgrade_state")) {
const auto& upgrade_jj = print_jj["upgrade_state"];
if (upgrade_jj.contains("mc_for_ams_firmware")) {
const auto& mc_for_ams_firmware_jj = upgrade_jj["mc_for_ams_firmware"];
if (mc_for_ams_firmware_jj.contains("firmware")) {
m_firmwares.clear();
const auto& firmwares = mc_for_ams_firmware_jj["firmware"];
for (auto item : firmwares) {
DevAmsSystemFirmware firmware;
DevJsonValParser::ParseVal(item, "id", firmware.m_firmare_idx);
DevJsonValParser::ParseVal(item, "name", firmware.m_name);
DevJsonValParser::ParseVal(item, "version", firmware.m_version);
m_firmwares[firmware.m_firmare_idx] = firmware;
}
}
if (mc_for_ams_firmware_jj.contains("current_firmware_id")) {
int idx = DevJsonValParser::GetVal(mc_for_ams_firmware_jj, "current_firmware_id", -1);
if (m_firmwares.count(idx) != 0) {
m_current_firmware_sel = m_firmwares[idx];
} else {
m_current_firmware_sel = DevAmsSystemFirmware();
}
}
if (mc_for_ams_firmware_jj.contains("current_run_firmware_id")) {
auto idx = DevJsonValParser::GetVal(mc_for_ams_firmware_jj, "current_run_firmware_id", IDX_DC);
if (m_firmwares.count(idx) != 0) {
m_current_firmware_run = m_firmwares[idx];
} else {
m_current_firmware_run = DevAmsSystemFirmware();
}
}
DevJsonValParser::ParseVal(mc_for_ams_firmware_jj, "status", m_status);
}
}
}
}
}
+69 -2
View File
@@ -1,4 +1,7 @@
#pragma once
#include <optional>
#include <nlohmann/json.hpp>
#include "DevCtrl.h"
namespace Slic3r
{
@@ -11,7 +14,7 @@ public:
public:
// getters
bool IsDetectOnInsertEnabled() const { return m_enable_detect_on_insert; };
std::optional<bool> IsDetectOnInsertEnabled() const { return m_enable_detect_on_insert; };
bool IsDetectOnPowerupEnabled() const { return m_enable_detect_on_powerup; }
bool IsDetectRemainEnabled() const { return m_enable_detect_remain; }
bool IsAutoRefillEnabled() const { return m_enable_auto_refill; }
@@ -26,10 +29,74 @@ public:
private:
DevFilaSystem* m_owner = nullptr;
bool m_enable_detect_on_insert = false;
std::optional<bool> m_enable_detect_on_insert = false;
bool m_enable_detect_on_powerup = false;
bool m_enable_detect_remain = false;
bool m_enable_auto_refill = false;
};
class DevAmsSystemFirmwareSwitch
{
public:
enum DevAmsSystemIdx : int
{
IDX_DC = -1,
IDX_LITE = 0,
IDX_AMS_AMS2_AMSHT = 1,
};
struct DevAmsSystemFirmware
{
DevAmsSystemIdx m_firmare_idx = IDX_DC;
std::string m_name;
std::string m_version;
public:
bool operator==(const DevAmsSystemFirmware& o) const
{
return (m_firmare_idx == o.m_firmare_idx) &&
(m_name == o.m_name) &&
(m_version == o.m_version);
};
};
public:
static std::shared_ptr<DevAmsSystemFirmwareSwitch> Create(DevFilaSystem* owner)
{
return std::shared_ptr<DevAmsSystemFirmwareSwitch>(new DevAmsSystemFirmwareSwitch(owner));
};
protected:
DevAmsSystemFirmwareSwitch(DevFilaSystem* owner) : m_owner(owner) {};
public:
DevFilaSystem* GetFilaSystem() const { return m_owner; };
bool SupportSwitchFirmware() const { return !m_firmwares.empty();};
DevAmsSystemIdx GetCurrentFirmwareIdxSel() const { return m_current_firmware_sel.m_firmare_idx; };
DevAmsSystemIdx GetCurrentFirmwareIdxRun() const { return m_current_firmware_run.m_firmare_idx; };
std::unordered_map<int, DevAmsSystemFirmware> GetSuppotedFirmwares() const { return m_firmwares;};
bool IsSwitching() const { return m_status == "SWITCHING";};
bool IsIdle() const { return m_status == "IDLE";};
// commands
int CrtlSwitchFirmware(int firmware_idx);
// setters
void Reset();
void ParseFirmwareSwitch(const nlohmann::json& j);
private:
DevFilaSystem* m_owner = nullptr;
std::string m_status;
DevAmsSystemFirmware m_current_firmware_run;
DevAmsSystemFirmware m_current_firmware_sel;
std::unordered_map<int, DevAmsSystemFirmware> m_firmwares;
DevCtrlInfo m_ctrl_switching;
};
}// namespace Slic3r
@@ -0,0 +1,29 @@
#include "DevFilaAmsSetting.h"
#include "DevFilaSystem.h"
#include "slic3r/GUI/DeviceManager.hpp"
namespace Slic3r {
int DevAmsSystemFirmwareSwitch::CrtlSwitchFirmware(int firmware_idx)
{
if (!m_owner) {
return -1;
}
MachineObject* obj_ = m_owner->GetOwner();
json command_json;
command_json["upgrade"]["command"] = "mc_for_ams_firmware_upgrade";
command_json["upgrade"]["sequence_id"] = std::to_string(obj_->m_sequence_id++);
command_json["upgrade"]["src_id"] = 1;// 1-Studio
command_json["upgrade"]["id"] = firmware_idx;
int rtn = obj_->publish_json(command_json);
if (rtn == 0) {
m_status = "SWITCHING";
m_ctrl_switching = DevCtrlInfo(obj_, obj_->m_sequence_id - 1, command_json, 3, 1);
}
return rtn;
};
}
@@ -169,8 +169,12 @@ void check_filaments(std::string model_id,
wiki_url = filament_item.contains("wiki") ? filament_item["wiki"].get<std::string>() : "";
return;
// Using in description
// Error in description
L("TPU is not supported by AMS.");
L("AMS does not support 'Bambu Lab PET-CF'.");
// Warning in description
L("Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer.");
L("Damp PVA will become flexible and get stuck inside AMS, please take care to dry it before use.");
L("Damp PVA is flexible and may get stuck in extruder. Dry it before use.");
L("The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite.");
+23 -20
View File
@@ -43,7 +43,7 @@ void DevAmsTray::reset()
tag_uid = "";
setting_id = "";
filament_setting_id = "";
type = "";
m_fila_type = "";
sub_brands = "";
color = "";
weight = "";
@@ -67,7 +67,7 @@ void DevAmsTray::reset()
bool DevAmsTray::is_tray_info_ready() const
{
if (color.empty()) return false;
if (type.empty()) return false;
if (m_fila_type.empty()) return false;
//if (setting_id.empty()) return false;
return true;
}
@@ -75,27 +75,27 @@ bool DevAmsTray::is_tray_info_ready() const
bool DevAmsTray::is_unset_third_filament() const
{
if (this->is_bbl) return false;
return (color.empty() || type.empty());
return (color.empty() || m_fila_type.empty());
}
std::string DevAmsTray::get_display_filament_type() const
{
if (type == "PLA-S") return "Sup.PLA";
if (type == "PA-S") return "Sup.PA";
if (type == "ABS-S") return "Sup.ABS";
return type;
if (m_fila_type == "PLA-S") return "Sup.PLA";
if (m_fila_type == "PA-S") return "Sup.PA";
if (m_fila_type == "ABS-S") return "Sup.ABS";
return m_fila_type;
}
std::string DevAmsTray::get_filament_type()
{
if (type == "Sup.PLA") { return "PLA-S"; }
if (type == "Sup.PA") { return "PA-S"; }
if (type == "Sup.ABS") { return "ABS-S"; }
if (type == "Support W") { return "PLA-S"; }
if (type == "Support G") { return "PA-S"; }
if (type == "Support") { if (setting_id == "GFS00") { type = "PLA-S"; } else if (setting_id == "GFS01") { type = "PA-S"; } else { return "PLA-S"; } }
if (m_fila_type == "Sup.PLA") { return "PLA-S"; }
if (m_fila_type == "Sup.PA") { return "PA-S"; }
if (m_fila_type == "Sup.ABS") { return "ABS-S"; }
if (m_fila_type == "Support W") { return "PLA-S"; }
if (m_fila_type == "Support G") { return "PA-S"; }
if (m_fila_type == "Support") { if (setting_id == "GFS00") { m_fila_type = "PLA-S"; } else if (setting_id == "GFS01") { m_fila_type = "PA-S"; } else { return "PLA-S"; } }
return type;
return m_fila_type;
}
@@ -361,11 +361,14 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS
int type_id = 1; // 0:dummy 1:ams 2:ams-lite 3:n3f 4:n3s
/*ams info*/
if (it->contains("info"))
{
if (it->contains("info")) {
const std::string& info = (*it)["info"].get<std::string>();
type_id = DevUtil::get_flag_bits(info, 0, 4);
extuder_id = DevUtil::get_flag_bits(info, 8, 4);
} else {
if (!obj->is_enable_ams_np && obj->get_printer_ams_type() == "f1") {
type_id = DevAms::AMS_LITE;
}
}
/*AMS without initialization*/
@@ -513,21 +516,21 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS
std::string type = MachineObject::setting_id_to_type(curr_tray->setting_id, (*tray_it)["tray_type"].get<std::string>());
if (curr_tray->setting_id == "GFS00")
{
curr_tray->type = "PLA-S";
curr_tray->m_fila_type = "PLA-S";
}
else if (curr_tray->setting_id == "GFS01")
{
curr_tray->type = "PA-S";
curr_tray->m_fila_type = "PA-S";
}
else
{
curr_tray->type = type;
curr_tray->m_fila_type = type;
}
}
else
{
curr_tray->setting_id = "";
curr_tray->type = "";
curr_tray->m_fila_type = "";
}
if (tray_it->contains("tray_sub_brands"))
curr_tray->sub_brands = (*tray_it)["tray_sub_brands"].get<std::string>();
+17 -5
View File
@@ -4,8 +4,11 @@
#include "DevDefs.h"
#include "DevFilaAmsSetting.h"
#include "DevUtil.h"
#include <map>
#include <optional>
#include <memory>
#include <wx/string.h>
#include <wx/colour.h>
@@ -28,7 +31,7 @@ public:
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 m_fila_type;
std::string sub_brands;
std::string color;
std::vector<std::string> cols;
@@ -57,7 +60,7 @@ public:
// operators
bool operator==(DevAmsTray const& o) const
{
return id == o.id && type == o.type && filament_setting_id == o.filament_setting_id && color == o.color;
return id == o.id && m_fila_type == o.m_fila_type && filament_setting_id == o.filament_setting_id && color == o.color;
}
bool operator!=(DevAmsTray const& o) const { return !operator==(o); }
@@ -150,12 +153,14 @@ public:
~DevFilaSystem();
public:
MachineObject* GetOwner() const { return m_owner; }
bool HasAms() const { return !amsList.empty(); }
bool IsAmsSettingUp() const;
/* ams */
DevAms* GetAmsById(const std::string& ams_id) const;
std::map<std::string, DevAms*>& GetAmsList() { return amsList; }
std::map<std::string, DevAms*, NumericStrCompare>& GetAmsList() { return amsList; }
int GetAmsCount() const { return amsList.size(); }
/* tray*/
@@ -167,10 +172,16 @@ public:
/* AMS settings*/
DevAmsSystemSetting& GetAmsSystemSetting() { return m_ams_system_setting; }
bool IsDetectOnInsertEnabled() const { return m_ams_system_setting.IsDetectOnInsertEnabled(); };
std::optional<bool> IsDetectOnInsertEnabled() const { return m_ams_system_setting.IsDetectOnInsertEnabled(); };
bool IsDetectOnPowerupEnabled() const { return m_ams_system_setting.IsDetectOnPowerupEnabled(); }
bool IsDetectRemainEnabled() const { return m_ams_system_setting.IsDetectRemainEnabled(); }
bool IsAutoRefillEnabled() const { return m_ams_system_setting.IsAutoRefillEnabled(); }
std::weak_ptr<DevAmsSystemFirmwareSwitch> GetAmsFirmwareSwitch() const { return m_ams_firmware_switch;}
public:
// ctrls
int CtrlAmsReset() const;
public:
static bool IsBBL_Filament(std::string tag_uid);
@@ -181,9 +192,10 @@ private:
/* ams properties */
int m_ams_cali_stat = 0;
std::map<std::string, DevAms*> amsList; // key: ams[id], start with 0
std::map<std::string, DevAms*, NumericStrCompare> amsList;// key: ams[id], start with 0
DevAmsSystemSetting m_ams_system_setting{ this };
std::shared_ptr<DevAmsSystemFirmwareSwitch> m_ams_firmware_switch = DevAmsSystemFirmwareSwitch::Create(this);
};// class DevFilaSystem
@@ -0,0 +1,19 @@
#include <nlohmann/json.hpp>
#include "DevFilaSystem.h"
#include "slic3r/GUI/DeviceManager.hpp"// TODO: remove this include
#include "DevUtil.h"
using namespace nlohmann;
namespace Slic3r
{
int DevFilaSystem::CtrlAmsReset() const
{
json jj_command;
jj_command["print"]["command"] = "ams_reset";
jj_command["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
return m_owner->publish_json(jj_command);
}
}
+38 -17
View File
@@ -273,7 +273,7 @@ namespace Slic3r
obj->last_alive = Slic3r::Utils::get_current_time_utc();
obj->m_is_online = true;
obj->set_dev_name(dev_name);
/* 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();
@@ -430,6 +430,8 @@ namespace Slic3r
selected_machine = "";
local_selected_machine = "";
OnSelectedMachineChanged(selected_machine, "");
// clean user list
for (auto it = userMachineList.begin(); it != userMachineList.end(); it++)
{
@@ -445,18 +447,22 @@ namespace Slic3r
bool DeviceManager::set_selected_machine(std::string dev_id)
{
BOOST_LOG_TRIVIAL(info) << "set_selected_machine=" << dev_id;
BOOST_LOG_TRIVIAL(info) << "set_selected_machine=" << dev_id
<< " cur_selected=" << selected_machine;
auto my_machine_list = get_my_machine_list();
auto it = my_machine_list.find(dev_id);
// disconnect last
// disconnect last if dev_id difference from previous one
auto last_selected = my_machine_list.find(selected_machine);
if (last_selected != my_machine_list.end())
if (last_selected != my_machine_list.end() && selected_machine != dev_id)
{
if (last_selected->second->connection_type() == "lan")
{
m_agent->disconnect_printer();
}
else if (last_selected->second->connection_type() == "cloud") {
m_agent->set_user_selected_machine("");
}
}
// connect curr
@@ -464,8 +470,12 @@ namespace Slic3r
{
if (selected_machine == dev_id)
{
// same dev_id, cloud => reset update time
if (it->second->connection_type() != "lan")
{
BOOST_LOG_TRIVIAL(info) << "set_selected_machine: same cloud machine, dev_id =" << dev_id
<< ", just reset update time";
// only reset update time
it->second->reset_update_time();
@@ -474,8 +484,12 @@ namespace Slic3r
return true;
}
// same dev_id, lan => disconnect and reconnect
else
{
BOOST_LOG_TRIVIAL(info) << "set_selected_machine: same lan machine, dev_id =" << dev_id
<< ", disconnect and reconnect";
// lan mode printer reconnect printer
if (m_agent)
{
@@ -497,27 +511,20 @@ namespace Slic3r
{
if (it->second->connection_type() != "lan" || it->second->connection_type().empty())
{
if (m_agent->get_user_selected_machine() == dev_id)
{
it->second->reset_update_time();
}
else
{
BOOST_LOG_TRIVIAL(info) << "static: set_selected_machine: same dev_id = " << dev_id;
m_agent->set_user_selected_machine(dev_id);
it->second->reset();
}
// diff dev_id, cloud => set_user_selected_machine(new)
BOOST_LOG_TRIVIAL(info) << "set_selected_machine: select new cloud machine, dev_id =" << dev_id;
m_agent->set_user_selected_machine(dev_id);
it->second->reset();
}
else
{
BOOST_LOG_TRIVIAL(info) << "static: set_selected_machine: same dev_id = empty";
BOOST_LOG_TRIVIAL(info) << "set_selected_machine: select new lan machine, dev_id =" << dev_id;
it->second->reset();
#if !BBL_RELEASE_TO_PUBLIC
it->second->connect(Slic3r::GUI::wxGetApp().app_config->get("enable_ssl_for_mqtt") == "true" ? true : false);
#else
it->second->connect(it->second->local_use_ssl_for_mqtt);
#endif
m_agent->set_user_selected_machine(dev_id);
it->second->set_lan_mode_connection_state(true);
}
}
@@ -527,6 +534,11 @@ namespace Slic3r
data.second.checked_filament.clear();
}
}
if (selected_machine != dev_id) {
OnSelectedMachineChanged(selected_machine, dev_id);
}
selected_machine = dev_id;
return true;
}
@@ -819,7 +831,16 @@ namespace Slic3r
void DeviceManager::OnSelectedMachineLost()
{
GUI::wxGetApp().sidebar().update_sync_status(nullptr);
GUI::wxGetApp().sidebar().load_ams_list(string(), nullptr);
GUI::wxGetApp().sidebar().load_ams_list(nullptr);
}
void DeviceManager::OnSelectedMachineChanged(const std::string& /*pre_dev_id*/,
const std::string& /*new_dev_id*/)
{
if (MachineObject* obj_ = get_selected_machine()) {
GUI::wxGetApp().sidebar().update_sync_status(obj_);
GUI::wxGetApp().sidebar().load_ams_list(obj_);
};
}
void DeviceManager::reload_printer_settings()
+1
View File
@@ -101,6 +101,7 @@ private:
void OnMachineBindStateChanged(MachineObject* obj, const std::string& new_state);
void OnSelectedMachineLost();
void OnSelectedMachineChanged(const std::string& pre_dev_id, const std::string& new_dev_id);
/*TODO*/
@@ -62,8 +62,8 @@ static void s_parse_nozzle_type(const std::string& nozzle_type_str, DevNozzle& n
void DevNozzleSystemParser::ParseV1_0(const nlohmann::json& nozzletype_json,
const nlohmann::json& diameter_json,
const int& nozzle_flow_type,
DevNozzleSystem* system)
DevNozzleSystem* system,
std::optional<int> flag_e3d)
{
//Since both the old and new protocols push data.
// assert(system->m_nozzles.size() < 2);
@@ -100,10 +100,12 @@ void DevNozzleSystemParser::ParseV1_0(const nlohmann::json& nozzletype_json,
}
{
if (nozzle_flow_type != -1) {
if (flag_e3d.has_value()) {
// 0: BBL S_FLOW; 1:E3D H_FLOW (only P)
if (nozzle_flow_type == 1) {
if (flag_e3d.value() == 1) {
// note: E3D = E3D nozzle type + High Flow
nozzle.m_nozzle_flow = NozzleFlowType::H_FLOW;
nozzle.m_nozzle_type = NozzleType::ntE3D;
} else {
nozzle.m_nozzle_flow = NozzleFlowType::S_FLOW;
}
+8 -1
View File
@@ -23,11 +23,18 @@ namespace Slic3r
friend class DevNozzleSystemParser;
public:
DevNozzleSystem(MachineObject* owner) : m_owner(owner) {}
private:
enum Status : int
{
NOZZLE_SYSTEM_IDLE = 0,
NOZZLE_SYSTEM_REFRESHING = 1,
};
public:
bool ContainsNozzle(int id) const { return m_nozzles.find(id) != m_nozzles.end(); }
DevNozzle GetNozzle(int id) const;
const std::map<int, DevNozzle>& GetNozzles() const { return m_nozzles;}
bool IsRefreshing() const { return m_state == 1; }
private:
void Reset();
@@ -44,7 +51,7 @@ namespace Slic3r
class DevNozzleSystemParser
{
public:
static void ParseV1_0(const nlohmann::json& nozzletype_json, const nlohmann::json& diameter_json, const int& nozzle_flow_type, DevNozzleSystem* system);
static void ParseV1_0(const nlohmann::json& nozzletype_json, const nlohmann::json& diameter_json, DevNozzleSystem* system, std::optional<int> flag_e3d);
static void ParseV2_0(const json& nozzle_json, DevNozzleSystem* system);
};
};
+21 -2
View File
@@ -107,7 +107,6 @@ void DevPrintOptionsParser::ParseDetectionV1_2(DevPrintOptions *opts, MachineObj
}
}
if (time(nullptr) - opts->xcam_auto_recovery_hold_start > HOLD_TIME_3SEC) {
if (print_json.contains("auto_recovery")) { opts->xcam_auto_recovery_step_loss = print_json["auto_recovery"].get<bool>(); }
}
@@ -145,7 +144,11 @@ void DevPrintOptionsParser::ParseDetectionV2_0(DevPrintOptions *opts, std::strin
if (time(nullptr) - opts->xcam_filament_tangle_detect_hold_start > HOLD_TIME_3SEC) {
opts->xcam_filament_tangle_detect = DevUtil::get_flag_bits(print_json, 23);
}
}
void DevPrintOptionsParser::ParseDetectionV2_1(DevPrintOptions *opts, std::string cfg) {
if (time(nullptr) - opts->idel_heating_protect_hold_strat > HOLD_TIME_3SEC)
opts->idel_heating_protect_enabled = DevUtil::get_flag_bits(cfg, 32, 2);
}
void DevPrintOptions::SetPrintingSpeedLevel(DevPrintingSpeedLevel speed_level)
@@ -168,8 +171,15 @@ int DevPrintOptions::command_xcam_control_ai_monitoring(bool on_off, std::string
xcam_ai_monitoring_hold_start = time(nullptr);
xcam_ai_monitoring_sensitivity = lvl;
return command_xcam_control("printing_monitor", on_off, m_obj, lvl);
}
int DevPrintOptions::command_xcam_control_idelheatingprotect_detector(bool on_off)
{
idel_heating_protect_enabled = on_off;
idel_heating_protect_hold_strat = time(nullptr);
return command_set_against_continued_heating_mode(on_off);
}
int DevPrintOptions::command_xcam_control_buildplate_marker_detector(bool on_off)
{
xcam_buildplate_marker_detector = on_off;
@@ -239,6 +249,15 @@ int DevPrintOptions::command_xcam_control(std::string module_name, bool on_off ,
return obj->publish_json(j);
}
int DevPrintOptions::command_set_against_continued_heating_mode(bool on_off)
{
json j;
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["command"] = "set_against_continued_heating_mode";
j["print"]["enable"] = on_off;
return m_obj->publish_json(j);
}
int DevPrintOptions::command_set_printing_option(bool auto_recovery, MachineObject *obj)
{
json j;
+14 -9
View File
@@ -27,6 +27,7 @@ public:
int command_xcam_control_auto_recovery_step_loss(bool on_off);
int command_xcam_control_allow_prompt_sound(bool on_off);
int command_xcam_control_filament_tangle_detect(bool on_off);
int command_xcam_control_idelheatingprotect_detector(bool on_off);
int command_xcam_control(std::string module_name, bool on_off, MachineObject *obj ,std::string lvl = "");
@@ -37,19 +38,20 @@ public:
// set fliament tangle detect
int command_set_filament_tangle_detect(bool fliament_tangle_detect, MachineObject *obj);
int command_set_against_continued_heating_mode(bool on_off);
void parse_auto_recovery_step_loss_status(int flag);
void parse_allow_prompt_sound_status(int flag);
void parse_filament_tangle_detect_status(int flag);
bool GetAiMonitoring() const { return xcam_ai_monitoring; };
bool GetFirstLayerInspector() const{ return xcam_first_layer_inspector; };
bool GetBuildplateMarkerDetector() const { return xcam_buildplate_marker_detector; };
bool GetAutoRecoveryStepLoss() const { return xcam_auto_recovery_step_loss; };
bool GetAllowPromptSound() const { return xcam_allow_prompt_sound; };
bool GetFilamentTangleDetect() const { return xcam_filament_tangle_detect; };
string GetAiMonitoringSensitivity() const { return xcam_ai_monitoring_sensitivity; };
bool GetAiMonitoring() const { return xcam_ai_monitoring; }
bool GetFirstLayerInspector() const{ return xcam_first_layer_inspector; }
bool GetBuildplateMarkerDetector() const { return xcam_buildplate_marker_detector; }
bool GetAutoRecoveryStepLoss() const { return xcam_auto_recovery_step_loss; }
bool GetAllowPromptSound() const { return xcam_allow_prompt_sound; }
bool GetFilamentTangleDetect() const { return xcam_filament_tangle_detect; }
int GetIdelHeatingProtectEenabled() const { return idel_heating_protect_enabled; }
string GetAiMonitoringSensitivity() const { return xcam_ai_monitoring_sensitivity; }
private:
@@ -65,12 +67,14 @@ private:
bool xcam_auto_recovery_step_loss{false};
bool xcam_allow_prompt_sound{false};
bool xcam_filament_tangle_detect{false};
int idel_heating_protect_enabled = -1;
time_t xcam_ai_monitoring_hold_start = 0;
time_t xcam_buildplate_marker_hold_start = 0;
time_t xcam_first_layer_hold_start = 0;
time_t xcam_auto_recovery_hold_start = 0;
time_t xcam_prompt_sound_hold_start = 0;
time_t xcam_filament_tangle_detect_hold_start = 0;
time_t idel_heating_protect_hold_strat = 0;
MachineObject* m_obj;/*owner*/
};
@@ -85,7 +89,8 @@ public:
static void ParseDetectionV1_1(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json, bool enable);
static void ParseDetectionV1_2(DevPrintOptions *opts, MachineObject *obj, const nlohmann::json &print_json);
static void ParseDetectionV2_0(DevPrintOptions *opts, std::string print_json);
static void ParseDetectionV2_0(DevPrintOptions *opts, std::string cfg);
static void ParseDetectionV2_1(DevPrintOptions *opts, std::string cfg);
};
} // namespace Slic3r
+35
View File
@@ -37,6 +37,22 @@ public:
class DevJsonValParser
{
public:
template<typename T>
static T GetVal(const nlohmann::json& j, const std::string& key, const T& default_val = T())
{
try
{
if (j.contains(key)) { return j[key].get<T>(); }
}
catch (const nlohmann::json::exception& e)
{
assert(0 && __FUNCTION__);
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": " << e.what();
}
return default_val;
}
template<typename T>
static void ParseVal(const nlohmann::json& j, const std::string& key, T& val)
{
@@ -69,4 +85,23 @@ public:
static std::string get_longlong_val(const nlohmann::json& j);
};
struct NumericStrCompare
{
bool operator()(const std::string& a, const std::string& b) const noexcept
{
int ai = -1;
try {
ai = std::stoi(a);
} catch (...) { };
int bi = -1;
try {
bi = std::stoi(b);
} catch (...) { };
return ai < bi;
}
};
}; // namespace Slic3r
+39 -39
View File
@@ -13,34 +13,14 @@ namespace GUI
static std::unordered_set<std::string> message_containing_retry{
"0701-8004",
"0701-8005",
"0701-8006",
"0701-8006",
"0701-8007",
"0700-8012",
"0701-8012",
"0702-8012",
"0703-8012",
"07FF-8003",
"07FF-8004",
"07FF-8005",
"07FF-8006",
"07FF-8007",
"07FF-8010",
"07FF-8011",
"07FF-8012",
"07FF-8013",
"12FF-8007",
"1200-8006"
};
static std::unordered_set<std::string> message_containing_done{
"07FF-8007",
"12FF-8007"
};
static std::unordered_set<std::string> message_containing_resume{
"0300-8013"
};
DeviceErrorDialog::DeviceErrorDialog(MachineObject* obj, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
:DPIDialog(parent, id, title, pos, size, style), m_obj(obj)
@@ -104,6 +84,10 @@ DeviceErrorDialog::DeviceErrorDialog(MachineObject* obj, wxWindow* parent, wxWin
wxGetApp().UpdateDlgDarkUI(this);
Bind(wxEVT_WEBREQUEST_STATE, &DeviceErrorDialog::on_webrequest_state, this);
Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &e){
if (m_obj) { m_obj->command_clean_print_error_uiop(m_obj->print_error); }
e.Skip();
});
}
DeviceErrorDialog::~DeviceErrorDialog()
@@ -191,7 +175,9 @@ void DeviceErrorDialog::init_button_list()
init_button(PROBLEM_SOLVED_RESUME, _L("Problem Solved and Resume"));
init_button(TURN_OFF_FIRE_ALARM, _L("Got it, Turn off the Fire Alarm."));
init_button(RETRY_PROBLEM_SOLVED, _L("Retry (problem solved)"));
init_button(CANCLE, _L("Cancel"));
init_button(STOP_DRYING, _L("Stop Drying"));
init_button(PROCEED, _L("Proceed"));
init_button(DBL_CHECK_CANCEL, _L("Cancel"));
init_button(DBL_CHECK_DONE, _L("Done"));
init_button(DBL_CHECK_RETRY, _L("Retry"));
@@ -206,6 +192,17 @@ void DeviceErrorDialog::on_dpi_changed(const wxRect& suggested_rect)
Refresh();
}
wxString DeviceErrorDialog::parse_error_level(int error_code)
{
int level = (error_code & 0x0000F000) >> 12;
switch (level) {
case 0x4: return _L("Error");
case 0x8: return _L("Warning");
case 0xC: return _L("Info");
default: return _L("Unknown");
}
}
static const std::unordered_set<string> s_jump_liveview_error_codes = { "0300-8003", "0300-8002", "0300-800A"};
wxString DeviceErrorDialog::show_error_code(int error_code)
{
@@ -219,13 +216,16 @@ wxString DeviceErrorDialog::show_error_code(int error_code)
wxString error_msg = wxGetApp().get_hms_query()->query_print_error_msg(m_obj, error_code);
if (error_msg.IsEmpty()) { error_msg = _L("Unknown error.");}
/* parse error level */
wxString error_level = parse_error_level(error_code);
/* error_str is old error code*/
if (message_containing_retry.count(error_str) || message_containing_done.count(error_str) || message_containing_resume.count(error_str)) {
if (message_containing_retry.count(error_str)) {
/* convert old error code to pseudo buttons*/
std::vector<int> pseudo_button = convert_to_pseudo_buttons(error_str);
/* do update*/
update_contents(_L("Warning"), error_msg, error_str, wxEmptyString, pseudo_button);
update_contents(error_level, error_msg, error_str, wxEmptyString, pseudo_button);
} else {
/* action buttons*/
std::vector<int> used_button;
@@ -233,7 +233,7 @@ wxString DeviceErrorDialog::show_error_code(int error_code)
if (s_jump_liveview_error_codes.count(error_str)) { used_button.emplace_back(DeviceErrorDialog::JUMP_TO_LIVEVIEW); } // special case
/* do update*/
update_contents(_L("Error"), error_msg, error_str, error_image_url, used_button);
update_contents(error_level, error_msg, error_str, error_image_url, used_button);
}
wxGetApp().UpdateDlgDarkUI(this);
@@ -248,22 +248,9 @@ wxString DeviceErrorDialog::show_error_code(int error_code)
std::vector<int> DeviceErrorDialog::convert_to_pseudo_buttons(std::string error_str)
{
std::vector<int> pseudo_button;
if (message_containing_done.count(error_str) && message_containing_retry.count(error_str)) {
pseudo_button.emplace_back(DBL_CHECK_RETRY);
pseudo_button.emplace_back(DBL_CHECK_DONE);
pseudo_button.emplace_back(DBL_CHECK_OK);
} else if (message_containing_done.count(error_str)) {
pseudo_button.emplace_back(DBL_CHECK_DONE);
pseudo_button.emplace_back(DBL_CHECK_OK);
} else if (message_containing_retry.count(error_str)) {
pseudo_button.emplace_back(DBL_CHECK_RETRY);
pseudo_button.emplace_back(DBL_CHECK_OK);
} else if (message_containing_resume.count(error_str)) {
pseudo_button.emplace_back(DBL_CHECK_RESUME);
pseudo_button.emplace_back(DBL_CHECK_OK);
} else {
pseudo_button.emplace_back(DBL_CHECK_OK);
}
pseudo_button.emplace_back(DBL_CHECK_RETRY);
pseudo_button.emplace_back(DBL_CHECK_OK);
return pseudo_button;
}
@@ -451,10 +438,23 @@ void DeviceErrorDialog::on_button_click(ActionButton btn_id)
m_obj->command_ams_control("resume");
break;
}
case DeviceErrorDialog::CANCLE: {
break;
}
case DeviceErrorDialog::STOP_DRYING: {
m_obj->command_ams_drying_stop();
break;
}
case DeviceErrorDialog::PROCEED: {
if(!m_action_json.is_null()){
try{
m_obj->command_ack_proceed(m_action_json);
} catch(...){
BOOST_LOG_TRIVIAL(error) << "DeviceErrorDialog: Action Proceed missing params.";
}
}
break;
}
case DeviceErrorDialog::ERROR_BUTTON_COUNT: break;
case DeviceErrorDialog::DBL_CHECK_CANCEL: {
+7
View File
@@ -6,6 +6,7 @@
#include "GUI_Utils.hpp"
#include "Widgets/StateColor.hpp"
#include <nlohmann/json.hpp>
class Label;
class Button;
@@ -42,7 +43,9 @@ public:
RETRY_PROBLEM_SOLVED = 34,
STOP_DRYING = 35,
CANCLE = 37,
REMOVE_CLOSE_BTN = 39, // special case, do not show close button
PROCEED = 41,
ERROR_BUTTON_COUNT,
@@ -53,6 +56,8 @@ public:
DBL_CHECK_RESUME = 10003,
DBL_CHECK_OK = 10004,
};
/* action params json */
nlohmann::json m_action_json;
public:
DeviceErrorDialog(MachineObject* obj,
@@ -66,11 +71,13 @@ public:
public:
wxString show_error_code(int error_code);
void set_action_json(const nlohmann::json &action_json) { m_action_json = action_json; }
protected:
void init_button_list();
void init_button(ActionButton style, wxString buton_text);
wxString parse_error_level(int error_code);
std::vector<int> convert_to_pseudo_buttons(std::string error_str);
void update_contents(const wxString& title, const wxString& text, const wxString& error_code,const wxString& image_url, const std::vector<int>& btns);
+220 -49
View File
@@ -23,6 +23,7 @@
#include "fast_float/fast_float.h"
#include "DeviceCore/DevFilaSystem.h"
#include "DeviceCore/DevExtensionTool.h"
#include "DeviceCore/DevExtruderSystem.h"
#include "DeviceCore/DevNozzleSystem.h"
#include "DeviceCore/DevBed.h"
@@ -186,6 +187,8 @@ wxString Slic3r::get_stage_string(int stage)
return _L("Measuring Surface");
case 58:
return _L("Thermal Preconditioning for first layer optimization");
case 65:
return _L("Calibrating the detection position of nozzle clumping"); // N7
default:
BOOST_LOG_TRIVIAL(info) << "stage = " << stage;
}
@@ -530,6 +533,7 @@ MachineObject::MachineObject(DeviceManager* manager, NetworkAgent* agent, std::s
m_bed = new DevBed(this);
m_storage = new DevStorage(this);
m_extder_system = new DevExtderSystem(this);
m_extension_tool = DevExtensionTool::Create(this);
m_nozzle_system = new DevNozzleSystem(this);
m_fila_system = new DevFilaSystem(this);
m_hms_system = new DevHMS(this);
@@ -650,7 +654,11 @@ std::string MachineObject::get_filament_id(std::string ams_id, std::string tray_
}
std::string MachineObject::get_filament_type(const std::string& ams_id, const std::string& tray_id) const {
return this->get_tray(ams_id, tray_id).type;
return this->get_tray(ams_id, tray_id).get_filament_type();
}
std::string MachineObject::get_filament_display_type(const std::string& ams_id, const std::string& tray_id) const {
return this->get_tray(ams_id, tray_id).get_display_filament_type();
}
void MachineObject::_parse_ams_status(int ams_status)
@@ -718,7 +726,7 @@ std::string MachineObject::get_lifecycle_type_str()
return "product";
}
bool MachineObject::is_in_upgrading()
bool MachineObject::is_in_upgrading() const
{
return upgrade_display_state == DevFirmwareUpgradingState::UpgradingInProgress;
}
@@ -728,7 +736,7 @@ bool MachineObject::is_upgrading_avalable()
return upgrade_display_state == DevFirmwareUpgradingState::UpgradingAvaliable;
}
int MachineObject::get_upgrade_percent()
int MachineObject::get_upgrade_percent() const
{
if (upgrade_progress.empty())
return 0;
@@ -1000,6 +1008,10 @@ void MachineObject::parse_home_flag(int flag)
}
is_support_air_print_detection = ((flag >> 29) & 0x1) != 0;
if (auto ptr = m_fila_system->GetAmsFirmwareSwitch().lock();
ptr->GetCurrentFirmwareIdxRun() == DevAmsSystemFirmwareSwitch::IDX_AMS_AMS2_AMSHT) {
is_support_air_print_detection = false;// special case, for the firmware, air print is not supported
}
ams_air_print_status = ((flag >> 28) & 0x1) != 0;
/*if (!is_support_p1s_plus) {
@@ -1487,6 +1499,14 @@ int MachineObject::command_set_nozzle_new(int nozzle_id, int temp)
return this->publish_json(j, 1);
}
int MachineObject::command_refresh_nozzle(){
json j;
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["command"] = "refresh_nozzle";
return this->publish_json(j, 1);
}
int MachineObject::command_set_chamber(int temp)
{
json j;
@@ -1541,12 +1561,12 @@ int MachineObject::command_ams_change_filament(bool load, std::string ams_id, st
return this->publish_json(j);
}
int MachineObject::command_ams_user_settings(int ams_id, bool start_read_opt, bool tray_read_opt, bool remain_flag)
int MachineObject::command_ams_user_settings(bool start_read_opt, bool tray_read_opt, bool remain_flag)
{
json j;
j["print"]["command"] = "ams_user_setting";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["ams_id"] = ams_id;
j["print"]["ams_id"] = -1; // all ams
j["print"]["startup_read_option"] = start_read_opt;
j["print"]["tray_read_option"] = tray_read_opt;
j["print"]["calibrate_remain_flag"] = remain_flag;
@@ -1838,7 +1858,7 @@ bool MachineObject::is_support_command_calibration()
return true;
}
int MachineObject::command_start_calibration(bool vibration, bool bed_leveling, bool xcam_cali, bool motor_noise, bool nozzle_cali, bool bed_cali)
int MachineObject::command_start_calibration(bool vibration, bool bed_leveling, bool xcam_cali, bool motor_noise, bool nozzle_cali, bool bed_cali, bool clumppos_cali)
{
if (!is_support_command_calibration()) {
// fixed gcode file
@@ -1851,7 +1871,8 @@ int MachineObject::command_start_calibration(bool vibration, bool bed_leveling,
json j;
j["print"]["command"] = "calibration";
j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
j["print"]["option"]= (bed_cali ? 1 << 5 : 0)
j["print"]["option"] = + (clumppos_cali ? 1 << 6 : 0)
+ (bed_cali ? 1 << 5 : 0)
+ (nozzle_cali ? 1 << 4 : 0)
+ (motor_noise ? 1 << 3 : 0)
+ (vibration ? 1 << 2 : 0)
@@ -2097,6 +2118,22 @@ int MachineObject::command_xcam_control(std::string module_name, bool on_off, st
return this->publish_json(j);
}
int MachineObject::command_ack_proceed(json& proceed) {
if (proceed["command"].empty()) return -1;
proceed["err_code"] = 0;
if (proceed.contains("err_ignored")) {
proceed["err_ignored"].push_back(proceed["err_index"]);
} else {
proceed["err_ignored"] = std::vector<int>{proceed["err_index"]};
}
proceed["sequence_id"] = std::to_string(MachineObject::m_sequence_id++);
json j;
j["print"] = proceed;
return this->publish_json(j);
}
int MachineObject::command_xcam_control_ai_monitoring(bool on_off, std::string lvl)
{
bool print_halt = (lvl == "never_halt") ? false:true;
@@ -2324,6 +2361,7 @@ void MachineObject::reset()
}
}
subtask_ = nullptr;
has_extra_flow_type = false;
m_partskip_ids.clear();
}
@@ -2750,6 +2788,13 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
}
} catch (...) {}
try {
if (auto ptr = m_fila_system->GetAmsFirmwareSwitch().lock()) {
ptr->ParseFirmwareSwitch(j);
}
} catch (...) {
BOOST_LOG_TRIVIAL(error) << "parse_json: failed to parse firmware switch info";
}
if (j.contains("print")) {
json jj = j["print"];
@@ -2830,6 +2875,10 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
if (jj.contains("support_update_remain")) {
if (jj["support_update_remain"].is_boolean()) {
is_support_update_remain = jj["support_update_remain"].get<bool>();
if (auto ptr = m_fila_system->GetAmsFirmwareSwitch().lock();
ptr->GetCurrentFirmwareIdxRun() == DevAmsSystemFirmwareSwitch::IDX_AMS_AMS2_AMSHT) {
is_support_update_remain = true;// special case, for the firmware, remain is supported
}
}
}
@@ -2910,6 +2959,12 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
bed_temperature_limit = jj["bed_temperature_limit"].get<int>();
}
}
if (jj.contains("support_refresh_nozzle")) {
if (jj["support_refresh_nozzle"].is_boolean()) {
is_support_refresh_nozzle = jj["support_refresh_nozzle"].get<bool>();
}
}
}
@@ -2960,9 +3015,15 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
if (!key_field_only)
{
if (is_studio_cmd(sequence_id) && jj.contains("command") && jj.contains("err_code") && jj.contains("result"))
if (is_studio_cmd(sequence_id) && jj.contains("command") && jj.contains("err_code"))
{
if (jj["err_code"].is_number()) { add_command_error_code_dlg(jj["err_code"].get<int>());}
if (jj["err_code"].is_number())
{
/* proceed action*/
json action_json = jj.contains("err_index") ? jj : json();
add_command_error_code_dlg(jj["err_code"].get<int>(), action_json);
}
}
}
@@ -3247,7 +3308,11 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
}
}
if (jj.contains("stg_cur")) {
stage_curr = jj["stg_cur"].get<int>();
stage_curr = jj["stg_cur"].get<int>();
}
if (jj.contains("stg_cd")) {
stage_remaining_seconds = jj["stg_cd"].get<int>();
}
}
catch (...) {
@@ -3317,14 +3382,14 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
if (jj.contains("nozzle_diameter") && jj.contains("nozzle_type"))
{
int nozzle_flow_type = -1;
if(jj.contains("flag3")){
int flag3 = jj["flag3"].get<int>();
nozzle_flow_type = get_flag_bits(flag3, 10, 3);
std::optional<int> flag_e3d;
if (jj.contains("flag3")) {
int flag3 = jj["flag3"].get<int>();
flag_e3d = std::make_optional(get_flag_bits(flag3, 10, 3));
has_extra_flow_type = true;
}
DevNozzleSystemParser::ParseV1_0(jj["nozzle_type"], jj["nozzle_diameter"], nozzle_flow_type, m_nozzle_system);
DevNozzleSystemParser::ParseV1_0(jj["nozzle_type"], jj["nozzle_diameter"], m_nozzle_system, flag_e3d);
}
}
@@ -3726,7 +3791,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
vt_slot[0].color = jj["tray_color"].get<std::string>();
vt_slot[0].setting_id = jj["tray_info_idx"].get<std::string>();
//vt_tray.type = jj["tray_type"].get<std::string>();
vt_slot[0].type = setting_id_to_type(vt_slot[0].setting_id, jj["tray_type"].get<std::string>());
vt_slot[0].m_fila_type = setting_id_to_type(vt_slot[0].setting_id, jj["tray_type"].get<std::string>());
// delay update
vt_slot[0].set_hold_count();
} else {
@@ -3751,7 +3816,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
}*/
tray_it->second->setting_id = jj["tray_info_idx"].get<std::string>();
tray_it->second->type = setting_id_to_type(tray_it->second->setting_id, jj["tray_type"].get<std::string>());
tray_it->second->m_fila_type = setting_id_to_type(tray_it->second->setting_id, jj["tray_type"].get<std::string>());
// delay update
tray_it->second->set_hold_count();
} else {
@@ -3959,7 +4024,6 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
if (jj["result"].get<std::string>() == "fail") {
is_succeed = false;
}
is_succeed = false;
}
if (is_succeed) {
@@ -4044,12 +4108,22 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_
pa_calib_result.setting_id = (*it)["setting_id"].get<std::string>();
}
// old
if (jj["nozzle_diameter"].is_number_float()) {
pa_calib_result.nozzle_diameter = jj["nozzle_diameter"].get<float>();
} else if (jj["nozzle_diameter"].is_string()) {
pa_calib_result.nozzle_diameter = string_to_float(jj["nozzle_diameter"].get<std::string>());
}
// new: should get nozzle diameter from filament item
if ((*it).contains("setting_id")) {
if ((*it)["nozzle_diameter"].is_number_float()) {
pa_calib_result.nozzle_diameter = (*it)["nozzle_diameter"].get<float>();
} else if ((*it)["nozzle_diameter"].is_string()) {
pa_calib_result.nozzle_diameter = string_to_float((*it)["nozzle_diameter"].get<std::string>());
}
}
if (it->contains("ams_id")) {
pa_calib_result.ams_id = (*it)["ams_id"].get<int>();
} else {
@@ -4632,18 +4706,18 @@ DevAmsTray MachineObject::parse_vt_tray(json vtray)
//std::string type = vtray["tray_type"].get<std::string>();
std::string type = setting_id_to_type(vt_tray.setting_id, vtray["tray_type"].get<std::string>());
if (vt_tray.setting_id == "GFS00") {
vt_tray.type = "PLA-S";
vt_tray.m_fila_type = "PLA-S";
}
else if (vt_tray.setting_id == "GFS01") {
vt_tray.type = "PA-S";
vt_tray.m_fila_type = "PA-S";
}
else {
vt_tray.type = type;
vt_tray.m_fila_type = type;
}
}
else {
vt_tray.setting_id = "";
vt_tray.type = "";
vt_tray.m_fila_type = "";
}
if (vtray.contains("tray_sub_brands"))
vt_tray.sub_brands = vtray["tray_sub_brands"].get<std::string>();
@@ -4828,22 +4902,17 @@ void MachineObject::parse_new_info(json print)
tutk_state = get_flag_bits(cfg, 6) == 1 ? "disable" : "";
m_lamp->SetChamberLight(get_flag_bits(cfg, 7) == 1 ? DevLamp::LIGHT_EFFECT_ON : DevLamp::LIGHT_EFFECT_OFF);
//is_support_build_plate_marker_detect = get_flag_bits(cfg, 12); todo yangcong
if (time(nullptr) - xcam_first_layer_hold_start > HOLD_TIME_3SEC) { xcam_first_layer_inspector = get_flag_bits(cfg, 12); }
if (time(nullptr) - xcam_first_layer_hold_start > HOLD_TIME_3SEC) {
xcam_first_layer_inspector = get_flag_bits(cfg, 12);
}
if (time(nullptr) - xcam_ai_monitoring_hold_start > HOLD_COUNT_MAX)
{
if (time(nullptr) - xcam_ai_monitoring_hold_start > HOLD_COUNT_MAX) {
xcam_ai_monitoring = get_flag_bits(cfg, 15);
switch (get_flag_bits(cfg, 13, 2))
{
case 0: xcam_ai_monitoring_sensitivity = "never_halt"; break;
case 1: xcam_ai_monitoring_sensitivity = "low"; break;
case 2: xcam_ai_monitoring_sensitivity = "medium"; break;
case 3: xcam_ai_monitoring_sensitivity = "high"; break;
default: break;
switch (get_flag_bits(cfg, 13, 2)) {
case 0: xcam_ai_monitoring_sensitivity = "never_halt"; break;
case 1: xcam_ai_monitoring_sensitivity = "low"; break;
case 2: xcam_ai_monitoring_sensitivity = "medium"; break;
case 3: xcam_ai_monitoring_sensitivity = "high"; break;
default: break;
}
}
@@ -4880,6 +4949,8 @@ void MachineObject::parse_new_info(json print)
}
installed_upgrade_kit = get_flag_bits(cfg, 25);
DevPrintOptionsParser::ParseDetectionV2_1(m_print_options, cfg);
}
/*fun*/
@@ -4916,6 +4987,19 @@ void MachineObject::parse_new_info(json print)
m_fan->SetSupportCoolingFilter(get_flag_bits(fun, 46));
is_support_ext_change_assist = get_flag_bits(fun, 48);
is_support_partskip = get_flag_bits(fun, 49);
is_support_idelheadingprotect_detection = get_flag_bits(fun, 62);
}
/*fun2*/
std::string fun2;
if (print.contains("fun2") && print["fun2"].is_string()) {
fun2 = print["fun2"].get<std::string>();
BOOST_LOG_TRIVIAL(info) << "new print data fun2 = " << fun2;
}
// fun2 may have infinite length, use get_flag_bits_no_border
if (!fun2.empty()) {
is_support_print_with_emmc = get_flag_bits_no_border(fun2, 0) == 1;
}
/*aux*/
@@ -4925,7 +5009,6 @@ void MachineObject::parse_new_info(json print)
if (!aux.empty()) {
m_storage->set_sdcard_state(get_flag_bits(aux, 12, 2));
//sdcard_state = MachineObject::SdcardState(get_flag_bits(aux, 12, 2));
}
/*stat*/
@@ -4954,6 +5037,7 @@ void MachineObject::parse_new_info(json print)
if (device.contains("nozzle")) { DevNozzleSystemParser::ParseV2_0(device["nozzle"], m_nozzle_system); }
if (device.contains("extruder")) { ExtderSystemParser::ParseV2_0(device["extruder"], m_extder_system);}
if (device.contains("ext_tool")) { DevExtensionToolParser::ParseV2_0(device["ext_tool"], m_extension_tool); }
if (device.contains("ctc")) {
json const& ctc = device["ctc"];
@@ -4967,6 +5051,10 @@ void MachineObject::parse_new_info(json print)
}
}
static bool is_hex_digit(char c) {
return std::isxdigit(static_cast<unsigned char>(c)) != 0;
}
int MachineObject::get_flag_bits(std::string str, int start, int count) const
{
try {
@@ -4974,7 +5062,94 @@ int MachineObject::get_flag_bits(std::string str, int start, int count) const
unsigned long long mask = (1ULL << count) - 1;
int flag = (decimal_value >> start) & mask;
return flag;
} catch (...) {
}
catch (...) {
return 0;
}
}
uint32_t MachineObject::get_flag_bits_no_border(std::string str, int start_idx, int count) const
{
if (start_idx < 0 || count <= 0) return 0;
try {
// --- 1) trim ---
auto ltrim = [](std::string& s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
[](unsigned char ch) { return !std::isspace(ch); }));
};
auto rtrim = [](std::string& s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
[](unsigned char ch) { return !std::isspace(ch); }).base(), s.end());
};
ltrim(str); rtrim(str);
// --- 2) remove 0x/0X prefix ---
if (str.size() >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
str.erase(0, 2);
}
// --- 3) keep only hex digits ---
std::string hex;
hex.reserve(str.size());
for (char c : str) {
if (std::isxdigit(static_cast<unsigned char>(c))) hex.push_back(c);
}
if (hex.empty()) return 0;
// --- 4) use size_t for all index/bit math ---
const size_t total_bits = hex.size() * 4ULL;
const size_t ustart = static_cast<size_t>(start_idx);
if (ustart >= total_bits) return 0;
const int int_bits = std::numeric_limits<uint32_t>::digits; // typically 32
const size_t need_bits = static_cast<size_t>(std::min(count, int_bits));
// [first_bit, last_bit]
const size_t first_bit = ustart;
const size_t last_bit = std::min(ustart + need_bits, total_bits) - 1ULL;
if (last_bit < first_bit) return 0;
const size_t right_index = hex.size() - 1ULL;
const size_t first_nibble = first_bit / 4ULL;
const size_t last_nibble = last_bit / 4ULL;
const size_t start_idx = right_index - last_nibble;
const size_t end_idx = right_index - first_nibble;
if (end_idx < start_idx) return 0;
const size_t sub_len = end_idx - start_idx + 1ULL;
if (end_idx >= hex.size()) return 0;
const std::string sub_hex = hex.substr(start_idx, sub_len);
unsigned long long chunk = std::stoull(sub_hex, nullptr, 16);
const unsigned nibble_offset = static_cast<unsigned>(first_bit % 4ULL);
const unsigned long long shifted =
(nibble_offset == 0U) ? chunk : (chunk >> nibble_offset);
uint32_t mask;
if (need_bits >= static_cast<size_t>(std::numeric_limits<uint32_t>::digits)) {
mask = std::numeric_limits<uint32_t>::max();
}
else {
mask = static_cast<uint32_t>((1ULL << need_bits) - 1ULL);
}
const uint32_t val = static_cast<uint32_t>(shifted & mask);
return val;
}
catch (const std::invalid_argument&) {
return 0;
}
catch (const std::out_of_range&) {
return 0;
}
catch (...) {
return 0;
}
}
@@ -5157,7 +5332,7 @@ void MachineObject::check_ams_filament_valid()
<< slot_id << "filament_id: " << curr_tray->setting_id;
command_ams_filament_settings(std::stoi(ams_id), std::stoi(slot_id), curr_tray->setting_id, preset_setting_id, curr_tray->color, curr_tray->type,
command_ams_filament_settings(std::stoi(ams_id), std::stoi(slot_id), curr_tray->setting_id, preset_setting_id, curr_tray->color, curr_tray->m_fila_type,
std::stoi(curr_tray->nozzle_temp_min), std::stoi(curr_tray->nozzle_temp_max));
}
continue;
@@ -5218,7 +5393,7 @@ void MachineObject::check_ams_filament_valid()
if (!is_equation) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << __LINE__
<< " vt_tray filament is not match min max temp and reset, filament_id: " << vt_tray.setting_id;
command_ams_filament_settings(vt_id, 0, vt_tray.setting_id, preset_setting_id, vt_tray.color, vt_tray.type, std::stoi(vt_tray.nozzle_temp_min),
command_ams_filament_settings(vt_id, 0, vt_tray.setting_id, preset_setting_id, vt_tray.color, vt_tray.m_fila_type, std::stoi(vt_tray.nozzle_temp_min),
std::stoi(vt_tray.nozzle_temp_max));
}
@@ -5305,11 +5480,11 @@ std::string MachineObject::get_error_code_str(int error_code)
return print_error_str;
}
void MachineObject::add_command_error_code_dlg(int command_err)
void MachineObject::add_command_error_code_dlg(int command_err, json action_json)
{
if (command_err > 0 && !Slic3r::GUI::wxGetApp().get_hms_query()->is_internal_error(this, command_err))
{
GUI::wxGetApp().CallAfter([this, command_err, token = std::weak_ptr<int>(m_token)]
GUI::wxGetApp().CallAfter([this, command_err, action_json, token = std::weak_ptr<int>(m_token)]
{
if (token.expired()) { return;}
GUI::DeviceErrorDialog* device_error_dialog = new GUI::DeviceErrorDialog(this, (wxWindow*)GUI::wxGetApp().mainframe);
@@ -5319,6 +5494,7 @@ void MachineObject::add_command_error_code_dlg(int command_err)
event.Skip();
});
if(!action_json.is_null()) device_error_dialog->set_action_json(action_json);
device_error_dialog->show_error_code(command_err);
m_command_error_code_dlgs.insert(device_error_dialog);
});
@@ -5340,9 +5516,9 @@ Slic3r::DevPrintingSpeedLevel MachineObject::GetPrintingSpeedLevel() const
return m_print_options->GetPrintingSpeedLevel();
}
bool MachineObject::is_ams_unload()
bool MachineObject::is_target_slot_unload() const
{
return m_extder_system->GetTargetAmsId().compare("255") == 0;
return m_extder_system->GetTargetSlotId().compare("255") == 0;
}
Slic3r::DevAms* MachineObject::get_curr_Ams()
@@ -5360,11 +5536,6 @@ bool MachineObject::HasAms() const
return m_fila_system->HasAms();
}
bool MachineObject::IsDetectOnInsertEnabled() const
{
return m_fila_system->GetAmsSystemSetting().IsDetectOnInsertEnabled();
}
void change_the_opacity(wxColour& colour)
{
if (colour.Alpha() == 255) {
+25 -13
View File
@@ -20,7 +20,7 @@
#include "DeviceCore/DevDefs.h"
#include "DeviceCore/DevConfigUtil.h"
#include "DeviceCore/DevFirmware.h"
#include "DeviceErrorDialog.hpp"
#include <wx/object.h>
#include <wx/timer.h>
@@ -79,6 +79,7 @@ class DevAmsTray;
class DevBed;
class DevConfig;
class DevCtrl;
class DevExtensionTool;
class DevExtderSystem;
class DevFan;
class DevFilaSystem;
@@ -110,6 +111,7 @@ private:
/*parts*/
DevLamp* m_lamp;
std::shared_ptr<DevExtensionTool> m_extension_tool;
DevExtderSystem* m_extder_system;
DevNozzleSystem* m_nozzle_system;
DevFilaSystem* m_fila_system;
@@ -274,11 +276,12 @@ public:
std::string get_filament_id(std::string ams_id, std::string tray_id) const;
std::string get_filament_type(const std::string& ams_id, const std::string& tray_id) const;
std::string get_filament_display_type(const std::string& ams_id, const std::string& tray_id) const;
// parse amsStatusMain and ams_status_sub
void _parse_ams_status(int ams_status);
bool is_ams_unload();
bool is_target_slot_unload() const;
bool can_unload_filament();
bool is_support_amx_ext_mix_mapping() const { return true;}
@@ -289,13 +292,10 @@ public:
bool is_multi_extruders() const;
int get_extruder_id_by_ams_id(const std::string& ams_id);
/* ams settings*/
bool IsDetectOnInsertEnabled() const;;
//bool IsDetectOnPowerupEnabled() const { return m_enable_detect_on_powerup; }
//bool IsDetectRemainEnabled() const { return m_enable_detect_remain; }
//bool IsAutoRefillEnabled() const { return m_enable_auto_refill; }
/* E3D has extra nozzle flow type info */
bool has_extra_flow_type{false};
[[nodiscard]] bool is_nozzle_flow_type_supported() const { return is_enable_np; };
[[nodiscard]] bool is_nozzle_flow_type_supported() const { return is_enable_np | has_extra_flow_type; };
[[nodiscard]] wxString get_nozzle_replace_url() const;
/*online*/
@@ -317,6 +317,8 @@ public:
/* parts */
DevExtderSystem* GetExtderSystem() const { return m_extder_system; }
std::weak_ptr<DevExtensionTool> GetExtensionTool() const { return m_extension_tool; }
DevNozzleSystem* GetNozzleSystem() const { return m_nozzle_system;}
DevFilaSystem* GetFilaSystem() const { return m_fila_system;}
@@ -363,9 +365,9 @@ public:
std::string get_firmware_type_str();
std::string get_lifecycle_type_str();
bool is_in_upgrading();
bool is_in_upgrading() const;
bool is_upgrading_avalable();
int get_upgrade_percent();
int get_upgrade_percent() const;
std::string get_ota_version();
bool check_version_valid();
wxString get_upgrade_result_str(int upgrade_err_code);
@@ -396,7 +398,7 @@ public:
std::string get_print_error_str() const { return MachineObject::get_error_code_str(this->print_error); }
std::unordered_set<GUI::DeviceErrorDialog*> m_command_error_code_dlgs;
void add_command_error_code_dlg(int command_err);
void add_command_error_code_dlg(int command_err, json action_json=json{});
int curr_layer = 0;
int total_layers = 0;
@@ -444,6 +446,7 @@ public:
std::vector<int> stage_list_info;
int stage_curr = 0;
int stage_remaining_seconds = 0;
int m_push_count = 0;
int m_full_msg_count = 0; /*the full message count, there are full or diff messages from network*/
bool calibration_done { false };
@@ -454,6 +457,7 @@ public:
wxString get_curr_stage();
int get_curr_stage_idx();
int get_stage_remaining_seconds() const { return stage_remaining_seconds; }
bool is_in_calibration();
bool is_calibration_running();
@@ -597,12 +601,17 @@ public:
bool is_support_brtc{false}; // fun[31], support tcp and upload protocol
bool is_support_ext_change_assist{false};
bool is_support_partskip{false};
bool is_support_refresh_nozzle{false};
// refine printer function options
bool is_support_spaghetti_detection{false};
bool is_support_purgechutepileup_detection{false};
bool is_support_nozzleclumping_detection{false};
bool is_support_airprinting_detection{false};
bool is_support_idelheadingprotect_detection{false};
// fun2
bool is_support_print_with_emmc{false};
bool installed_upgrade_kit{false};
int bed_temperature_limit = -1;
@@ -679,6 +688,7 @@ public:
int command_set_printer_nozzle(std::string nozzle_type, float diameter);
int command_set_printer_nozzle2(int id, std::string nozzle_type, float diameter);
int command_get_access_code();
int command_ack_proceed(json& proceed);
/* command upgrade */
int command_upgrade_confirm();
@@ -710,12 +720,13 @@ public:
int command_set_nozzle(int temp);
int command_set_nozzle_new(int nozzle_id, int temp);
int command_refresh_nozzle();
int command_set_chamber(int temp);
int check_resume_condition();
// ams controls
//int command_ams_switch(int tray_index, int old_temp = 210, int new_temp = 210);
int command_ams_change_filament(bool load, std::string ams_id, std::string slot_id, int old_temp = 210, int new_temp = 210);
int command_ams_user_settings(int ams_id, bool start_read_opt, bool tray_read_opt, bool remain_flag = false);
int command_ams_user_settings(bool start_read_opt, bool tray_read_opt, bool remain_flag = false);
int command_ams_switch_filament(bool switch_filament);
int command_ams_air_print_detect(bool air_print_detect);
int command_ams_calibrate(int ams_id);
@@ -751,7 +762,7 @@ public:
int command_extruder_control(int nozzle_id, double val);
// calibration printer
bool is_support_command_calibration();
int command_start_calibration(bool vibration, bool bed_leveling, bool xcam_cali, bool motor_noise, bool nozzle_cali, bool bed_cali);
int command_start_calibration(bool vibration, bool bed_leveling, bool xcam_cali, bool motor_noise, bool nozzle_cali, bool bed_cali, bool clumppos_cali);
// PA calibration
int command_start_pa_calibration(const X1CCalibInfos& pa_data, int mode = 0); // 0: automatic mode; 1: manual mode. default: automatic mode
@@ -855,6 +866,7 @@ public:
bool check_enable_np(const json& print) const;
void parse_new_info(json print);
int get_flag_bits(std::string str, int start, int count = 1) const;
uint32_t get_flag_bits_no_border(std::string str, int start_idx, int count = 1) const;
int get_flag_bits(int num, int start, int count = 1, int base = 10) const;
/* Device Filament Check */
@@ -9,9 +9,11 @@
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/wxExtensions.hpp"
#include "slic3r/GUI/Widgets/Label.hpp"
#include <wx/stattext.h>
#define MODEL_STR L("Model:")
#define SERIAL_STR L("Serial:")
#define VERSION_STR L("Version:")
@@ -64,45 +66,47 @@ void uiDeviceUpdateVersion::SetVersion(const wxString& cur_version, const wxStri
void uiDeviceUpdateVersion::CreateWidgets()
{
m_dev_name = new wxStaticText(this, wxID_ANY, "_");
m_dev_snl = new wxStaticText(this, wxID_ANY, "_");
m_dev_version = new wxStaticText(this, wxID_ANY, "_");
m_dev_name = new wxStaticText(this, wxID_ANY, "-");
m_dev_snl = new wxStaticText(this, wxID_ANY, "-");
m_dev_version = new wxStaticText(this, wxID_ANY, "-");
wxStaticText* serial_text = new wxStaticText(this, wxID_ANY, _L(SERIAL_STR));
wxStaticText* version_text = new wxStaticText(this, wxID_ANY, _L(VERSION_STR));
wxStaticText *model_text = new wxStaticText(this, wxID_ANY, _L(MODEL_STR));
// Use bold font
wxFont font = this->GetFont();
wxFont font = Label::Head_14;
font.SetWeight(wxFONTWEIGHT_BOLD);
m_dev_name->SetFont(font);
serial_text->SetFont(font);
version_text->SetFont(font);
model_text->SetFont(font);
// The grid sizer
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(2, 3, 0, 0);
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(0, 2, 0, 0);
//grid_sizer->AddGrowableCol(1);
grid_sizer->SetFlexibleDirection(wxHORIZONTAL);
grid_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
grid_sizer->Add(model_text, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
grid_sizer->Add(m_dev_name, 0, wxALL | wxEXPAND, FromDIP(5));
grid_sizer->Add(serial_text, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
grid_sizer->Add(m_dev_snl, 0, wxALIGN_LEFT | wxALL, FromDIP(5));
grid_sizer->Add(0, 0, wxALL, wxEXPAND);
grid_sizer->Add(m_dev_snl, 0, wxALL | wxEXPAND, FromDIP(5));
m_dev_upgrade_indicator = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(5), FromDIP(5)));
m_dev_upgrade_indicator->SetBitmap(ScalableBitmap(this, "monitor_upgrade_online", 5).bmp());
wxBoxSizer* version_hsizer = new wxBoxSizer(wxHORIZONTAL);
version_hsizer->Add(m_dev_upgrade_indicator, 0, wxALL, FromDIP(5));
version_hsizer->Add(version_text, 0, wxLEFT | wxBOTTOM|wxALIGN_RIGHT, FromDIP(5));
grid_sizer->Add(version_hsizer, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
grid_sizer->Add(m_dev_version, 0, wxALIGN_LEFT | wxALL, FromDIP(5));
grid_sizer->Add(0, 0, wxALL, wxEXPAND);
version_hsizer->Add(0, 0, 1, wxEXPAND, 0);
version_hsizer->Add(m_dev_upgrade_indicator, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
version_hsizer->Add(version_text, 0, wxALL, FromDIP(5));
grid_sizer->Add(version_hsizer, 0, wxEXPAND, 0);
grid_sizer->Add(m_dev_version, 0, wxEXPAND | wxALL, FromDIP(5));
// Updating
wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->AddSpacer(FromDIP(20));
main_sizer->Add(m_dev_name, 0, wxALIGN_LEFT | wxALL, FromDIP(5));
main_sizer->AddSpacer(FromDIP(40));
main_sizer->Add(grid_sizer, 0, wxALIGN_LEFT, FromDIP(5));
SetSizer(main_sizer);
+2
View File
@@ -244,6 +244,8 @@ void FilamentMapDialog::on_checkbox(wxCommandEvent &event)
dialog.ShowModal();
this->Close();
}
event.Skip();
}
void FilamentMapDialog::on_ok(wxCommandEvent &event)
+43
View File
@@ -23,6 +23,7 @@
#include "OpenGLManager.hpp"
#include "Plater.hpp"
#include "MainFrame.hpp"
#include "WipeTowerDialog.hpp"
#include "GUI_App.hpp"
#include "GUI_ObjectList.hpp"
#include "GUI_Colors.hpp"
@@ -3048,6 +3049,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
auto clash_flag = construct_error_string(object_results, get_object_clashed_text());
auto unprintable_flag= construct_extruder_unprintable_error(object_results, get_left_extruder_unprintable_text(), get_right_extruder_unprintable_text());
bool is_flushing_volume_valid = is_flushing_matrix_error();
_set_warning_notification(EWarning::FlushingVolumeZero, is_flushing_volume_valid);
_set_warning_notification(EWarning::ObjectClashed, clash_flag);
_set_warning_notification(EWarning::LeftExtruderPrintableError, unprintable_flag.first);
_set_warning_notification(EWarning::RightExtruderPrintableError, unprintable_flag.second);
@@ -3079,6 +3082,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
}
else {
_set_warning_notification(EWarning::ObjectOutside, false);
_set_warning_notification(EWarning::FlushingVolumeZero, false);
_set_warning_notification(EWarning::ObjectClashed, false);
_set_warning_notification(EWarning::LeftExtruderPrintableError, false);
_set_warning_notification(EWarning::RightExtruderPrintableError, false);
@@ -10228,6 +10232,10 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
text = _u8L(get_filament_mixture_warning_text());
break;
}
case EWarning::FlushingVolumeZero:
text = _u8L("Partial flushing volume set to 0. Multi-color printing may cause color mixing in models. Please redjust flushing settings.");
error = ErrorType::SLICING_ERROR;
break;
}
//BBS: this may happened when exit the app, plater is null
if (!wxGetApp().plater())
@@ -10331,6 +10339,19 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
else
notification_manager.close_slicing_customize_error_notification(NotificationType::BBLFilamentPrintableError, NotificationLevel::ErrorNotificationLevel);
}
else if (warning == EWarning::FlushingVolumeZero) {
if (state) {
auto callback = [](wxEvtHandler *) {
auto plater = wxGetApp().plater();
const wxEventTypeTag<SimpleEvent> EVT_SCHEDULE_BACKGROUND_PROCESS(wxNewEventType());
open_flushing_dialog(plater, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, plater));
plater->get_view3D_canvas3D()->reload_scene(true);
return false;
};
notification_manager.push_flushing_volume_error_notification(NotificationType::BBLFlushingVolumeZero, NotificationLevel::WarningNotificationLevel, text, _u8L("Flushing Volume"), callback);
} else
notification_manager.close_flushing_volume_error_notification(NotificationType::BBLFlushingVolumeZero, NotificationLevel::WarningNotificationLevel);
}
else {
if (state)
notification_manager.push_slicing_error_notification(text, conflictObj ? std::vector<ModelObject const*>{conflictObj} : std::vector<ModelObject const*>{});
@@ -10355,6 +10376,28 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
}
}
bool GLCanvas3D::is_flushing_matrix_error() {
const auto &project_config = wxGetApp().preset_bundle->project_config;
const std::vector<double> &config_matrix = (project_config.option<ConfigOptionFloats>("flush_volumes_matrix"))->values;
const std::vector<double> &config_multiplier = (project_config.option<ConfigOptionFloats>("flush_multiplier"))->values;
for (auto multiplier : config_multiplier) {
if (multiplier == 0) return true;
}
int matrix_len = config_matrix.size() / config_multiplier.size();
int row_len = std::sqrt(matrix_len);
for (int i = 0; i < config_matrix.size(); i++)
{
int relative_id = i % matrix_len;
int row_id = relative_id / row_len;
int col_id = relative_id % row_len;
if (row_id != col_id && config_matrix[i] == 0) return true;
}
return false;
}
bool GLCanvas3D::_is_any_volume_outside() const
{
for (const GLVolume* volume : m_volumes.volumes) {
+2
View File
@@ -395,6 +395,7 @@ class GLCanvas3D
PrimeTowerOutside,
NozzleFilamentIncompatible,
MixtureFilamentIncompatible,
FlushingVolumeZero
};
class RenderStats
@@ -1295,6 +1296,7 @@ private:
// generates a warning notification containing the given message
void _set_warning_notification(EWarning warning, bool state);
bool is_flushing_matrix_error();
bool _is_any_volume_outside() const;
// updates the selection from the content of m_hover_volume_idxs
+53 -47
View File
@@ -902,10 +902,10 @@ void GUI_App::post_init()
if (app_config->get("default_page") == "1")
mainframe->select_tab(size_t(1));
mainframe->Thaw();
plater_->trigger_restore_project(1);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", end load_gl_resources";
}
//#endif
plater_->trigger_restore_project(1);
//#endif
//BBS: remove GCodeViewer as seperate APP logic
/*if (this->init_params->start_as_gcodeviewer) {
@@ -1004,9 +1004,6 @@ void GUI_App::post_init()
});
}
if (is_user_login())
request_user_handle(0);
if(!m_networking_need_update && m_agent) {
m_agent->set_on_ssdp_msg_fn(
[this](std::string json_str) {
@@ -1725,7 +1722,6 @@ void GUI_App::init_networking_callbacks()
obj->command_get_access_code();
if (m_agent)
m_agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
GUI::wxGetApp().sidebar().load_ams_list(obj->get_dev_id(), obj);
}
});
});
@@ -1764,7 +1760,6 @@ void GUI_App::init_networking_callbacks()
obj->command_get_version();
event.SetInt(0);
event.SetString(obj->get_dev_id());
GUI::wxGetApp().sidebar().load_ams_list(obj->get_dev_id(), obj);
} else if (state == ConnectStatus::ConnectStatusFailed) {
// Orca: only update status if same device id
if (m_device_manager->selected_machine != dev_id) return;
@@ -1821,24 +1816,19 @@ void GUI_App::init_networking_callbacks()
CallAfter([this, dev_id, msg] {
if (is_closing())
return;
this->process_network_msg(dev_id, msg);
MachineObject* obj = this->m_device_manager->get_user_machine(dev_id);
if (obj) {
if (process_network_msg(dev_id, msg)) {
return;
}
if (MachineObject* obj = this->m_device_manager->get_user_machine(dev_id)) {
auto sel = this->m_device_manager->get_selected_machine();
if (sel && sel->get_dev_id() == dev_id)
{
if (sel && sel->get_dev_id() == dev_id) {
obj->parse_json("cloud", msg);
}
else {
GUI::wxGetApp().sidebar().load_ams_list(obj);
} else {
obj->parse_json("cloud", msg, true);
}
if (sel == obj || sel == nullptr) {
GUI::wxGetApp().sidebar().load_ams_list(obj->get_dev_id(), obj);
}
}
if (GUI::wxGetApp().plater())
@@ -1875,13 +1865,14 @@ void GUI_App::init_networking_callbacks()
if (is_closing())
return;
this->process_network_msg(dev_id, msg);
MachineObject* obj = m_device_manager->get_my_machine(dev_id);
if (this->process_network_msg(dev_id, msg)) {
return;
}
if (obj) {
if (MachineObject* obj = m_device_manager->get_my_machine(dev_id)) {
obj->parse_json("lan", msg);
if (this->m_device_manager->get_selected_machine() == obj) {
GUI::wxGetApp().sidebar().load_ams_list(obj->get_dev_id(), obj);
GUI::wxGetApp().sidebar().load_ams_list(obj);
}
}
@@ -2096,6 +2087,8 @@ void GUI_App::init_app_config()
set_log_path_and_level(log_filename, 3);
#endif
BOOST_LOG_TRIVIAL(info) << boost::format("gui mode, Current OrcaSlicer Version %1% build %2%") % SoftFever_VERSION % GIT_COMMIT_HASH;
//BBS: remove GCodeViewer as seperate APP logic
if (!app_config)
app_config = new AppConfig();
@@ -2389,7 +2382,6 @@ bool GUI_App::on_init_inner()
}
#endif
BOOST_LOG_TRIVIAL(info) << boost::format("gui mode, Current OrcaSlicer Version %1%")%SoftFever_VERSION;
BOOST_LOG_TRIVIAL(info) << get_system_info();
// initialize label colors and fonts
@@ -2662,7 +2654,6 @@ bool GUI_App::on_init_inner()
preset_bundle->backup_user_folder();
Bind(EVT_SET_SELECTED_MACHINE, &GUI_App::on_set_selected_machine, this);
Bind(EVT_UPDATE_MACHINE_LIST, &GUI_App::on_update_machine_list, this);
Bind(EVT_USER_LOGIN, &GUI_App::on_user_login, this);
Bind(EVT_USER_LOGIN_HANDLE, &GUI_App::on_user_login_handle, this);
@@ -3943,7 +3934,6 @@ void GUI_App::request_user_logout()
wxGetApp().check_and_keep_current_preset_changes(_L("User logged out"), header, ActionButtons::KEEP | ActionButtons::SAVE, &transfer_preset_changes);
m_device_manager->clean_user_info();
GUI::wxGetApp().sidebar().load_ams_list({}, {});
remove_user_presets();
enable_user_preset_folder(false);
preset_bundle->load_user_presets(DEFAULT_USER_FOLDER_NAME, ForwardCompatibilitySubstitutionRule::Enable);
@@ -4305,18 +4295,6 @@ void GUI_App::enable_user_preset_folder(bool enable)
}
}
void GUI_App::on_set_selected_machine(wxCommandEvent &evt)
{
// Orca: do not connect to default device during app startup, because some of the lan machines might not online yet
// and user will be prompted by several "Connect XXX failed" error message.
return;
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (dev) {
dev->set_selected_machine(m_agent->get_user_selected_machine());
}
}
void GUI_App::on_update_machine_list(wxCommandEvent &evt)
{
/* DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
@@ -4337,8 +4315,6 @@ void GUI_App::on_user_login_handle(wxCommandEvent &evt)
boost::thread update_thread = boost::thread([this, dev] {
dev->update_user_machine_list_info();
auto evt = new wxCommandEvent(EVT_SET_SELECTED_MACHINE);
wxQueueEvent(this, evt);
});
if (online_login) {
@@ -4897,20 +4873,34 @@ void GUI_App::check_new_version_sf(bool show_tips, int by_user)
http.perform();
}
void GUI_App::process_network_msg(std::string dev_id, std::string msg)
// return true if handled
bool GUI_App::process_network_msg(std::string dev_id, std::string msg)
{
if (dev_id.empty()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << msg;
}
else if (msg == "device_cert_installed") {
BOOST_LOG_TRIVIAL(info) << "process_network_msg, device_cert_installed";
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
MachineObject* obj = dev->get_my_machine(dev_id);
if (obj) {
obj->update_device_cert_state(true);
if (Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager()) {
if (MachineObject* obj = dev->get_my_machine(dev_id)) {
obj->update_device_cert_state(true);
}
}
return true;
}
else if (msg == "device_cert_uninstalled") {
BOOST_LOG_TRIVIAL(info) << "process_network_msg, device_cert_uninstalled";
if (Slic3r::DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager()) {
if (MachineObject* obj = dev->get_my_machine(dev_id)){
obj->update_device_cert_state(false);
}
}
return true;
}
return false;
}
//BBS pop up a dialog and download files
@@ -6817,6 +6807,21 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage
{
wxCHECK_MSG(mainframe != nullptr, false, "Internal error: Main frame not created / null");
#ifdef __APPLE__
if (is_adding_script_handler()) {
BOOST_LOG_TRIVIAL(info) << "run_wizard: Script handler is being added, delaying wizard creation";
auto timer = new wxTimer();
timer->Bind(wxEVT_TIMER, [this, reason, start_page, timer](wxTimerEvent &) {
timer->Stop();
run_wizard(reason, start_page);
delete timer;
});
timer->StartOnce(200);
return true;
}
#endif
//if (reason == ConfigWizard::RR_USER) {
// //TODO: turn off it currently, maybe need to turn on in the future
// if (preset_updater->config_update(app_config->orig_version(), PresetUpdater::UpdateParams::FORCED_BEFORE_WIZARD) == PresetUpdater::R_ALL_CANCELED)
@@ -7291,6 +7296,7 @@ bool is_soluble_filament(int extruder_id)
bool has_filaments(const std::vector<string>& model_filaments) {
auto &filament_presets = Slic3r::GUI::wxGetApp().preset_bundle->filament_presets;
if (!Slic3r::GUI::wxGetApp().plater()) return false;
auto model_objects = Slic3r::GUI::wxGetApp().plater()->model().objects;
const Slic3r::DynamicPrintConfig &config = wxGetApp().preset_bundle->full_config();
Model::setExtruderParams(config, filament_presets.size());
+1 -2
View File
@@ -468,7 +468,6 @@ public:
void handle_http_error(unsigned int status, std::string body);
void on_http_error(wxCommandEvent &evt);
void on_set_selected_machine(wxCommandEvent& evt);
void on_update_machine_list(wxCommandEvent& evt);
void on_user_login(wxCommandEvent &evt);
void on_user_login_handle(wxCommandEvent& evt);
@@ -483,7 +482,7 @@ public:
void check_update(bool show_tips, int by_user);
void check_new_version(bool show_tips = false, int by_user = 0);
void check_new_version_sf(bool show_tips = false, int by_user = 0);
void process_network_msg(std::string dev_id, std::string msg);
bool process_network_msg(std::string dev_id, std::string msg);
void request_new_version(int by_user);
void enter_force_upgrade();
void set_skip_version(bool skip = true);
+1 -1
View File
@@ -10,7 +10,7 @@ static const char* HMS_PATH = "hms";
static const char* HMS_LOCAL_IMG_PATH = "hms/local_image";
// the local HMS info
static unordered_set<string> package_dev_id_types {"094", "239", "093"};
static unordered_set<string> package_dev_id_types {"094", "239", "093", "22E"};
namespace Slic3r {
namespace GUI {
+3 -1
View File
@@ -66,7 +66,9 @@ bool ImageDPIFrame::Show(bool show)
}
void ImageDPIFrame::set_bitmap(const wxBitmap &bit_map) {
m_bitmap->SetBitmap(bit_map);
if (&bit_map && bit_map.IsOk()) {
m_bitmap->SetBitmap(bit_map);
}
}
void ImageDPIFrame::set_title(const wxString& title) {
+2 -2
View File
@@ -58,7 +58,7 @@ void BindJob::process(Ctl &ctl)
wxDateTime::TimeZone tz(wxDateTime::Local);
long offset = tz.GetOffset();
std::string timezone = get_timezone_utc_hm(offset);
m_agent->track_update_property("ssdp_version", m_ssdp_version, "string");
int result = m_agent->bind(m_dev_ip, m_dev_id, m_sec_link, timezone, m_improved,
[this, &ctl, &curr_percent, &msg, &result_code, &result_info](int stage, int code, std::string info) {
@@ -114,7 +114,7 @@ void BindJob::process(Ctl &ctl)
;
}
}
post_fail_event(result_code, result_info);
return;
}
+38 -16
View File
@@ -12,6 +12,8 @@
#include "slic3r/GUI/DeviceCore/DevManager.h"
#include "slic3r/GUI/DeviceCore/DevUtil.h"
#include "slic3r/Utils/FileTransferUtils.hpp"
namespace Slic3r {
namespace GUI {
@@ -206,13 +208,26 @@ void PrintJob::process(Ctl &ctl)
// check access code and ip address
if (this->connection_type == "lan" && m_print_type == "from_normal") {
params.dev_id = m_dev_id;
params.project_name = "verify_job";
params.filename = job_data._temp_path.string();
params.connection_type = this->connection_type;
bool emmc_ok = false;
bool ftp_ok = false;
if (could_emmc_print) {
std::string devIP = m_dev_ip;
std::string accessCode = m_access_code;
std::string url = "bambu:///local/" + devIP + "?port=6000&user=" + "bblp" + "&passwd=" + accessCode;
std::unique_ptr<FileTransferTunnel> tunnel = std::make_unique<FileTransferTunnel>(module(), url);
emmc_ok = tunnel->sync_start_connect();
}
{
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, nullptr);
if (result != 0) {
result = m_agent->start_send_gcode_to_sdcard(params, nullptr, nullptr, nullptr);
ftp_ok = result == 0;
}
if (!emmc_ok && !ftp_ok) {
BOOST_LOG_TRIVIAL(error) << "access code is invalid";
m_enter_ip_address_fun_fail();
m_job_finished = true;
@@ -233,6 +248,7 @@ void PrintJob::process(Ctl &ctl)
params.task_vibration_cali = this->task_vibration_cali;
params.task_layer_inspect = this->task_layer_inspect;
params.task_record_timelapse= this->task_record_timelapse;
params.nozzle_mapping = this->task_nozzle_mapping;
params.ams_mapping = this->task_ams_mapping;
params.ams_mapping2 = this->task_ams_mapping2;
params.ams_mapping_info = this->task_ams_mapping_info;
@@ -245,6 +261,7 @@ void PrintJob::process(Ctl &ctl)
params.auto_flow_cali = this->auto_flow_cali;
params.auto_offset_cali = this->auto_offset_cali;
params.task_ext_change_assist = this->task_ext_change_assist;
params.try_emmc_print = this->could_emmc_print;
if (m_print_type == "from_sdcard_view") {
params.dst_file = m_dst_path;
@@ -560,32 +577,37 @@ void PrintJob::process(Ctl &ctl)
ctl.update_status(curr_percent, _u8L("Sending print job through cloud service"));
result = m_agent->start_print(params, update_fn, cancel_fn, wait_fn);
}
}
} else {
switch(this->sdcard_state) {
}
} else {
if (this->could_emmc_print) {
ctl.update_status(curr_percent, _u8L("Sending print job over LAN"));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
} else {
switch(this->sdcard_state) {
case DevStorage::SdcardState::NO_SDCARD:
ctl.update_status(curr_percent, _u8L("A Storage needs to be inserted before printing via LAN."));
return;
case DevStorage::SdcardState::HAS_SDCARD_ABNORMAL:
if(this->has_sdcard) {
// means the storage is abnormal but can be used option is enabled
ctl.update_status(curr_percent, _u8L("Sending print job over LAN, but the Storage in the printer is abnormal and print-issues may be caused by this."));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
ctl.update_status(curr_percent, _u8L("Sending print job over LAN, but the Storage in the printer is abnormal and print-issues may be caused by this."));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
break;
}
ctl.update_status(curr_percent, _u8L("The Storage in the printer is abnormal. Please replace it with a normal Storage before sending print job to printer."));
return;
return;
case DevStorage::SdcardState::HAS_SDCARD_READONLY:
ctl.update_status(curr_percent, _u8L("The Storage in the printer is read-only. Please replace it with a normal Storage before sending print job to printer."));
return;
return;
case DevStorage::SdcardState::HAS_SDCARD_NORMAL:
ctl.update_status(curr_percent, _u8L("Sending print job over LAN"));
result = m_agent->start_local_print(params, update_fn, cancel_fn);
break;
default:
default:
ctl.update_status(curr_percent, _u8L("Encountered an unknown error with the Storage status. Please try again."));
return;
}
return;
}
}
}
if (result < 0) {
+3 -1
View File
@@ -61,6 +61,7 @@ public:
std::string m_ftp_folder;
std::string m_access_code;
std::string task_bed_type;
std::string task_nozzle_mapping;
std::string task_ams_mapping;
std::string task_ams_mapping2;
std::string task_ams_mapping_info;
@@ -82,8 +83,9 @@ public:
bool task_layer_inspect;
bool cloud_print_only { false };
bool has_sdcard { false };
bool could_emmc_print { false };
bool task_use_ams { true };
DevStorage::SdcardState sdcard_state = DevStorage::SdcardState::NO_SDCARD;
bool task_ext_change_assist { false };
+7 -7
View File
@@ -304,23 +304,23 @@ void SendJob::process(Ctl &ctl)
case DevStorage::SdcardState::HAS_SDCARD_ABNORMAL:
if(this->has_sdcard) {
// means the sdcard is abnormal but can be used option is enabled
ctl.update_status(curr_percent, _u8L("Sending G-code file over LAN, but the Storage in the printer is abnormal and print-issues may be caused by this."));
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn, nullptr);
ctl.update_status(curr_percent, _u8L("Sending G-code file over LAN, but the Storage in the printer is abnormal and print-issues may be caused by this."));
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn, nullptr);
break;
}
ctl.update_status(curr_percent, _u8L("The Storage in the printer is abnormal. Please replace it with a normal Storage before sending to printer."));
return;
return;
case DevStorage::SdcardState::HAS_SDCARD_READONLY:
ctl.update_status(curr_percent, _u8L("The Storage in the printer is read-only. Please replace it with a normal Storage before sending to printer."));
return;
return;
case DevStorage::SdcardState::HAS_SDCARD_NORMAL:
ctl.update_status(curr_percent, _u8L("Sending G-code file over LAN"));
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn, nullptr);
result = m_agent->start_send_gcode_to_sdcard(params, update_fn, cancel_fn, nullptr);
break;
default:
ctl.update_status(curr_percent, _u8L("Encountered an unknown error with the Storage status. Please try again."));
return;
}
return;
}
}
if (ctl.was_canceled()) {
+1 -1
View File
@@ -46,7 +46,7 @@ public:
bool cloud_print_only { false };
bool has_sdcard { false };
bool task_use_ams { true };
DevStorage::SdcardState sdcard_state = DevStorage::SdcardState::NO_SDCARD;
wxWindow* m_parent{nullptr};

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