mirror of
https://github.com/QIDITECH/QIDIStudio.git
synced 2026-02-01 17:38:42 +03:00
update slic3r
This commit is contained in:
@@ -24,6 +24,8 @@ public:
|
||||
virtual std::string get_status(wxString& curl_msg) const override { return "1"; };
|
||||
virtual float get_progress(wxString& curl_msg) const override { return 1; };
|
||||
virtual std::pair<std::string, float> get_status_progress(wxString& curl_msg) const override { return std::make_pair("1", 1); };
|
||||
virtual bool send_command_to_printer(wxString& curl_msg, wxString commond) const override {return false;};
|
||||
virtual bool send_timelapse_status(wxString& msg, std::string ip, bool status) const {return false;};
|
||||
wxString get_test_ok_msg () const override;
|
||||
wxString get_test_failed_msg (wxString &msg) const override;
|
||||
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../GUI/DeviceManager.hpp"
|
||||
#include "../GUI/Jobs/ProgressIndicator.hpp"
|
||||
#include "../GUI/PartPlate.hpp"
|
||||
#include "../GUI/OpenGLManager.hpp"
|
||||
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "../GUI/MsgDialog.hpp"
|
||||
@@ -12,7 +13,7 @@
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
const float MIN_PA_K_VALUE = 0.0;
|
||||
const float MAX_PA_K_VALUE = 1.0;
|
||||
const float MAX_PA_K_VALUE = 2.0;
|
||||
|
||||
std::shared_ptr<PrintJob> CalibUtils::print_job;
|
||||
wxString wxstr_temp_dir = fs::path(fs::temp_directory_path() / "calib").wstring();
|
||||
@@ -30,6 +31,11 @@ static std::string MachineBedTypeString[6] = {
|
||||
"suprtack"
|
||||
};
|
||||
|
||||
std::vector<std::string> not_support_auto_pa_cali_filaments = {
|
||||
"GFU03", // TPU 90A
|
||||
"GFU04" // TPU 85A
|
||||
};
|
||||
|
||||
void get_default_k_n_value(const std::string &filament_id, float &k, float &n)
|
||||
{
|
||||
if (filament_id.compare("GFG00") == 0) {
|
||||
@@ -55,6 +61,35 @@ void get_default_k_n_value(const std::string &filament_id, float &k, float &n)
|
||||
}
|
||||
}
|
||||
|
||||
wxString get_nozzle_volume_type_name(NozzleVolumeType type)
|
||||
{
|
||||
if (NozzleVolumeType::nvtStandard == type) {
|
||||
return _L("Standard");
|
||||
} else if (NozzleVolumeType::nvtHighFlow == type) {
|
||||
return _L("High Flow");
|
||||
}
|
||||
return wxString();
|
||||
}
|
||||
|
||||
void get_tray_ams_and_slot_id(MachineObject* obj, int in_tray_id, int &ams_id, int &slot_id, int &tray_id)
|
||||
{
|
||||
assert(obj);
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
if (in_tray_id == VIRTUAL_TRAY_MAIN_ID || in_tray_id == VIRTUAL_TRAY_DEPUTY_ID) {
|
||||
ams_id = in_tray_id;
|
||||
slot_id = 0;
|
||||
tray_id = ams_id;
|
||||
if (!obj->is_enable_np)
|
||||
tray_id = VIRTUAL_TRAY_DEPUTY_ID;
|
||||
} else {
|
||||
ams_id = in_tray_id / 4;
|
||||
slot_id = in_tray_id % 4;
|
||||
tray_id = in_tray_id;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_calib_mode_name(CalibMode cali_mode, int stage)
|
||||
{
|
||||
switch(cali_mode) {
|
||||
@@ -101,24 +136,38 @@ static bool is_same_nozzle_diameters(const DynamicPrintConfig &full_config, cons
|
||||
|
||||
try {
|
||||
std::string nozzle_type;
|
||||
const ConfigOptionEnum<NozzleType> * config_nozzle_type = full_config.option<ConfigOptionEnum<NozzleType>>("nozzle_type");
|
||||
if (config_nozzle_type->value == NozzleType::ntHardenedSteel) {
|
||||
nozzle_type = "hardened_steel";
|
||||
} else if (config_nozzle_type->value == NozzleType::ntStainlessSteel) {
|
||||
nozzle_type = "stainless_steel";
|
||||
|
||||
const ConfigOptionEnumsGenericNullable * config_nozzle_type = full_config.option<ConfigOptionEnumsGenericNullable>("nozzle_type");
|
||||
std::vector<std::string> config_nozzle_types_str(config_nozzle_type->size());
|
||||
for (size_t idx = 0; idx < config_nozzle_type->size(); ++idx)
|
||||
config_nozzle_types_str[idx] = NozzleTypeEumnToStr[NozzleType(config_nozzle_type->values[idx])];
|
||||
|
||||
auto opt_nozzle_diameters = full_config.option<ConfigOptionFloatsNullable>("nozzle_diameter");
|
||||
|
||||
std::vector<float> config_nozzle_diameters(opt_nozzle_diameters->size());
|
||||
for (size_t idx = 0; idx < opt_nozzle_diameters->size(); ++idx)
|
||||
config_nozzle_diameters[idx] = opt_nozzle_diameters->values[idx];
|
||||
|
||||
std::vector<float> machine_nozzle_diameters(obj->m_extder_data.extders.size());
|
||||
for (size_t idx = 0; idx < obj->m_extder_data.extders.size(); ++idx)
|
||||
machine_nozzle_diameters[idx] = obj->m_extder_data.extders[idx].current_nozzle_diameter;
|
||||
|
||||
if (config_nozzle_diameters.size() != machine_nozzle_diameters.size()) {
|
||||
wxString nozzle_in_preset = wxString::Format(_L("nozzle size in preset: %d"), config_nozzle_diameters.size());
|
||||
wxString nozzle_in_printer = wxString::Format(_L("nozzle size memorized: %d"), machine_nozzle_diameters.size());
|
||||
error_msg = _L("The size of nozzle type in preset is not consistent with memorized nozzle.Did you change your nozzle lately ? ") + "\n " + nozzle_in_preset +
|
||||
"\n " + nozzle_in_printer + "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto opt_nozzle_diameters = full_config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
if (opt_nozzle_diameters != nullptr) {
|
||||
float preset_nozzle_diameter = opt_nozzle_diameters->get_at(0);
|
||||
if (preset_nozzle_diameter != obj->nozzle_diameter) {
|
||||
wxString nozzle_in_preset = wxString::Format(_L("nozzle in preset: %s %s"), wxString::Format("%.1f", preset_nozzle_diameter).ToStdString(), to_wstring_name(nozzle_type));
|
||||
wxString nozzle_in_printer = wxString::Format(_L("nozzle memorized: %.1f %s"), obj->nozzle_diameter, to_wstring_name(obj->nozzle_type));
|
||||
|
||||
error_msg = _L("Your nozzle diameter in preset is not consistent with memorized nozzle diameter. Did you change your nozzle lately?") + "\n " + nozzle_in_preset +
|
||||
"\n " + nozzle_in_printer + "\n";
|
||||
for (size_t idx = 0; idx < config_nozzle_diameters.size(); ++idx) {
|
||||
if (config_nozzle_diameters[idx] != machine_nozzle_diameters[idx]) {
|
||||
wxString nozzle_in_preset = wxString::Format(_L("nozzle[%d] in preset: %.1f"), idx, config_nozzle_diameters[idx]);
|
||||
wxString nozzle_in_printer = wxString::Format(_L("nozzle[%d] memorized: %.1f"), idx, machine_nozzle_diameters[idx]);
|
||||
error_msg = _L("Your nozzle type in preset is not consistent with memorized nozzle.Did you change your nozzle lately ? ") + "\n " + nozzle_in_preset +
|
||||
"\n " + nozzle_in_printer + "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (...) {}
|
||||
@@ -131,21 +180,15 @@ static bool is_same_nozzle_type(const DynamicPrintConfig &full_config, const Mac
|
||||
if (obj == nullptr)
|
||||
return true;
|
||||
|
||||
NozzleType nozzle_type = NozzleType::ntUndefine;
|
||||
|
||||
if (obj->nozzle_type == "stainless_steel") {
|
||||
nozzle_type = NozzleType::ntStainlessSteel;
|
||||
} else if (obj->nozzle_type == "hardened_steel") {
|
||||
nozzle_type = NozzleType::ntHardenedSteel;
|
||||
}
|
||||
|
||||
NozzleType nozzle_type = obj->m_extder_data.extders[0].current_nozzle_type;
|
||||
int printer_nozzle_hrc = Print::get_hrc_by_nozzle_type(nozzle_type);
|
||||
|
||||
if (full_config.has("required_nozzle_HRC")) {
|
||||
int filament_nozzle_hrc = full_config.opt_int("required_nozzle_HRC", 0);
|
||||
if (abs(filament_nozzle_hrc) > abs(printer_nozzle_hrc)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "filaments hardness mismatch: printer_nozzle_hrc = " << printer_nozzle_hrc << ", filament_nozzle_hrc = " << filament_nozzle_hrc;
|
||||
std::string filament_type = full_config.opt_string("filament_type", 0);
|
||||
error_msg = wxString::Format(_L("*Printing %s material with %s may cause nozzle damage"), filament_type, to_wstring_name(obj->nozzle_type));
|
||||
error_msg = wxString::Format(_L("Printing %1s material with %2s nozzle may cause nozzle damage."), filament_type, to_wstring_name(NozzleTypeEumnToStr[obj->m_extder_data.extders[0].current_nozzle_type]));
|
||||
error_msg += "\n";
|
||||
|
||||
MessageDialog msg_dlg(nullptr, error_msg, wxEmptyString, wxICON_WARNING | wxOK | wxCANCEL);
|
||||
@@ -177,12 +220,15 @@ static bool check_nozzle_diameter_and_type(const DynamicPrintConfig &full_config
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Slic3r::GUI::wxGetApp().plater()->check_printer_initialized(obj))
|
||||
return false;
|
||||
|
||||
// P1P/S
|
||||
if (obj->nozzle_type.empty())
|
||||
if (obj->m_extder_data.extders[0].current_nozzle_type == NozzleType::ntUndefine)
|
||||
return true;
|
||||
|
||||
if (!is_same_nozzle_diameters(full_config, obj, error_msg))
|
||||
return false;
|
||||
// if (!is_same_nozzle_diameters(full_config, obj, error_msg))
|
||||
// return false;
|
||||
|
||||
if (!is_same_nozzle_type(full_config, obj, error_msg))
|
||||
return false;
|
||||
@@ -190,6 +236,40 @@ static bool check_nozzle_diameter_and_type(const DynamicPrintConfig &full_config
|
||||
return true;
|
||||
}
|
||||
|
||||
static void init_multi_extruder_params_for_cali(DynamicPrintConfig& config, const CalibInfo& calib_info)
|
||||
{
|
||||
int extruder_count = 1;
|
||||
auto nozzle_diameters_opt = dynamic_cast<const ConfigOptionFloatsNullable*>(config.option("nozzle_diameter"));
|
||||
if (nozzle_diameters_opt != nullptr) {
|
||||
extruder_count = (int)(nozzle_diameters_opt->size());
|
||||
}
|
||||
std::vector<int>& nozzle_volume_types = dynamic_cast<ConfigOptionEnumsGeneric*>(config.option("nozzle_volume_type", true))->values;
|
||||
nozzle_volume_types.clear();
|
||||
nozzle_volume_types.resize(extruder_count, (int)calib_info.nozzle_volume_type);
|
||||
|
||||
std::vector<int> physical_extruder_maps = dynamic_cast<ConfigOptionInts*>(config.option("physical_extruder_map", true))->values;
|
||||
int extruder_id = calib_info.extruder_id;
|
||||
for (size_t index = 0; index < extruder_count; ++index) {
|
||||
if (physical_extruder_maps[index] == extruder_id)
|
||||
{
|
||||
extruder_id = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int num_filaments = 1;
|
||||
auto filament_colour_opt = dynamic_cast<const ConfigOptionStrings*>(config.option("filament_colour"));
|
||||
if (filament_colour_opt != nullptr) {
|
||||
num_filaments = (int)(filament_colour_opt->size());
|
||||
}
|
||||
std::vector<int>& filament_maps = config.option<ConfigOptionInts>("filament_map", true)->values;
|
||||
filament_maps.clear();
|
||||
filament_maps.resize(num_filaments, extruder_id);
|
||||
|
||||
config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode", true)->value = FilamentMapMode::fmmManual;
|
||||
|
||||
}
|
||||
|
||||
|
||||
CalibMode CalibUtils::get_calib_mode_by_name(const std::string name, int& cali_stage)
|
||||
{
|
||||
if (name == "pa_line_calib_mode") {
|
||||
@@ -254,7 +334,7 @@ bool CalibUtils::validate_input_k_value(wxString k_text, float* output_value)
|
||||
;
|
||||
}
|
||||
|
||||
if (k_value < MIN_PA_K_VALUE || k_value > MAX_PA_K_VALUE) {
|
||||
if (k_value <= MIN_PA_K_VALUE || k_value >= MAX_PA_K_VALUE) {
|
||||
*output_value = default_k;
|
||||
return false;
|
||||
}
|
||||
@@ -348,8 +428,11 @@ void CalibUtils::calib_PA(const X1CCalibInfos& calib_infos, int mode, wxString&
|
||||
if (obj_ == nullptr)
|
||||
return;
|
||||
|
||||
if (calib_infos.calib_datas.size() > 0)
|
||||
if (calib_infos.calib_datas.size() > 0) {
|
||||
if (!check_printable_status_before_cali(obj_, calib_infos, error_message))
|
||||
return;
|
||||
obj_->command_start_pa_calibration(calib_infos, mode);
|
||||
}
|
||||
}
|
||||
|
||||
void CalibUtils::emit_get_PA_calib_results(float nozzle_diameter)
|
||||
@@ -379,7 +462,7 @@ bool CalibUtils::get_PA_calib_results(std::vector<PACalibResult>& pa_calib_resul
|
||||
return pa_calib_results.size() > 0;
|
||||
}
|
||||
|
||||
void CalibUtils::emit_get_PA_calib_infos(float nozzle_diameter)
|
||||
void CalibUtils::emit_get_PA_calib_infos(const PACalibExtruderInfo &cali_info)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev)
|
||||
@@ -389,7 +472,7 @@ void CalibUtils::emit_get_PA_calib_infos(float nozzle_diameter)
|
||||
if (obj_ == nullptr)
|
||||
return;
|
||||
|
||||
obj_->command_get_pa_calibration_tab(nozzle_diameter);
|
||||
obj_->command_get_pa_calibration_tab(cali_info);
|
||||
}
|
||||
|
||||
bool CalibUtils::get_PA_calib_tab(std::vector<PACalibResult> &pa_calib_infos)
|
||||
@@ -408,6 +491,7 @@ bool CalibUtils::get_PA_calib_tab(std::vector<PACalibResult> &pa_calib_infos)
|
||||
return obj_->has_get_pa_calib_tab;
|
||||
}
|
||||
|
||||
//w
|
||||
void CalibUtils::emit_get_PA_calib_info(float nozzle_diameter, const std::string &filament_id)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
@@ -419,20 +503,6 @@ void CalibUtils::emit_get_PA_calib_info(float nozzle_diameter, const std::string
|
||||
obj_->command_get_pa_calibration_tab(nozzle_diameter, filament_id);
|
||||
}
|
||||
|
||||
bool CalibUtils::get_PA_calib_info(PACalibResult & pa_calib_info) {
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) return false;
|
||||
|
||||
MachineObject *obj_ = dev->get_selected_machine();
|
||||
if (obj_ == nullptr) return false;
|
||||
|
||||
if (!obj_->pa_calib_tab.empty()) {
|
||||
pa_calib_info = obj_->pa_calib_tab.front();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CalibUtils::set_PA_calib_result(const std::vector<PACalibResult> &pa_calib_values, bool is_auto_cali)
|
||||
{
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
@@ -472,7 +542,7 @@ void CalibUtils::delete_PA_calib_result(const PACalibIndexInfo& pa_calib_info)
|
||||
obj_->command_delete_pa_calibration(pa_calib_info);
|
||||
}
|
||||
|
||||
void CalibUtils::calib_flowrate_X1C(const X1CCalibInfos& calib_infos, std::string& error_message)
|
||||
void CalibUtils::calib_flowrate_X1C(const X1CCalibInfos& calib_infos, wxString& error_message)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev)
|
||||
@@ -482,8 +552,11 @@ void CalibUtils::calib_flowrate_X1C(const X1CCalibInfos& calib_infos, std::strin
|
||||
if (obj_ == nullptr)
|
||||
return;
|
||||
|
||||
if (calib_infos.calib_datas.size() > 0)
|
||||
if (calib_infos.calib_datas.size() > 0) {
|
||||
if (!check_printable_status_before_cali(obj_, calib_infos, error_message))
|
||||
return;
|
||||
obj_->command_start_flow_ratio_calibration(calib_infos);
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << "flow_rate_cali: auto | send info | cali_datas is empty.";
|
||||
}
|
||||
@@ -518,6 +591,21 @@ bool CalibUtils::get_flow_ratio_calib_results(std::vector<FlowRatioCalibResult>&
|
||||
|
||||
bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString &error_message)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
MachineObject *obj_ = dev->get_selected_machine();
|
||||
if (obj_ == nullptr) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_printable_status_before_cali(obj_, calib_info, error_message))
|
||||
return false;
|
||||
|
||||
if (pass != 1 && pass != 2)
|
||||
return false;
|
||||
|
||||
@@ -530,13 +618,13 @@ bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString
|
||||
|
||||
read_model_from_file(input_file, model);
|
||||
|
||||
DynamicConfig print_config = calib_info.print_prest->config;
|
||||
DynamicConfig filament_config = calib_info.filament_prest->config;
|
||||
DynamicConfig printer_config = calib_info.printer_prest->config;
|
||||
DynamicPrintConfig print_config = calib_info.print_prest->config;
|
||||
DynamicPrintConfig filament_config = calib_info.filament_prest->config;
|
||||
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
|
||||
|
||||
/// --- scale ---
|
||||
// model is created for a 0.4 nozzle, scale z with nozzle size.
|
||||
const ConfigOptionFloats *nozzle_diameter_config = printer_config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
const ConfigOptionFloatsNullable *nozzle_diameter_config = printer_config.option<ConfigOptionFloatsNullable>("nozzle_diameter");
|
||||
assert(nozzle_diameter_config->values.size() > 0);
|
||||
float nozzle_diameter = nozzle_diameter_config->values[0];
|
||||
float xyScale = nozzle_diameter / 0.6;
|
||||
@@ -555,10 +643,20 @@ bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString
|
||||
//}
|
||||
|
||||
Flow infill_flow = Flow(nozzle_diameter * 1.2f, layer_height, nozzle_diameter);
|
||||
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
|
||||
|
||||
int index = get_index_for_extruder_parameter(filament_config, "filament_max_volumetric_speed", calib_info.extruder_id, calib_info.extruder_type, calib_info.nozzle_volume_type);
|
||||
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloatsNullable>("filament_max_volumetric_speed")->get_at(index);
|
||||
double max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1));
|
||||
double internal_solid_speed = std::floor(std::min(print_config.opt_float("internal_solid_infill_speed"), max_infill_speed));
|
||||
double top_surface_speed = std::floor(std::min(print_config.opt_float("top_surface_speed"), max_infill_speed));
|
||||
|
||||
index = get_index_for_extruder_parameter(print_config, "internal_solid_infill_speed", calib_info.extruder_id, calib_info.extruder_type, calib_info.nozzle_volume_type);
|
||||
double internal_solid_speed = std::floor(std::min(print_config.opt_float_nullable("internal_solid_infill_speed", index), max_infill_speed));
|
||||
ConfigOptionFloatsNullable* internal_solid_speed_opt = print_config.option<ConfigOptionFloatsNullable>("internal_solid_infill_speed");
|
||||
internal_solid_speed_opt->values[index] = internal_solid_speed;
|
||||
|
||||
index = get_index_for_extruder_parameter(print_config, "top_surface_speed", calib_info.extruder_id, calib_info.extruder_type, calib_info.nozzle_volume_type);
|
||||
double top_surface_speed = std::floor(std::min(print_config.opt_float_nullable("top_surface_speed", index), max_infill_speed));
|
||||
ConfigOptionFloatsNullable *top_surface_speed_opt = print_config.option<ConfigOptionFloatsNullable>("top_surface_speed");
|
||||
top_surface_speed_opt->values[index] = top_surface_speed;
|
||||
|
||||
// adjust parameters
|
||||
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
|
||||
@@ -580,8 +678,8 @@ bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString
|
||||
_obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f));
|
||||
_obj->config.set_key_value("infill_direction", new ConfigOptionFloat(45));
|
||||
_obj->config.set_key_value("ironing_type", new ConfigOptionEnum<IroningType>(IroningType::NoIroning));
|
||||
_obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(internal_solid_speed));
|
||||
_obj->config.set_key_value("top_surface_speed", new ConfigOptionFloat(top_surface_speed));
|
||||
_obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloatsNullable(internal_solid_speed_opt->values));
|
||||
_obj->config.set_key_value("top_surface_speed", new ConfigOptionFloatsNullable(top_surface_speed_opt->values));
|
||||
|
||||
// extract flowrate from name, filename format: flowrate_xxx
|
||||
std::string obj_name = _obj->name;
|
||||
@@ -603,23 +701,15 @@ bool CalibUtils::calib_flowrate(int pass, const CalibInfo &calib_info, wxString
|
||||
full_config.apply(filament_config);
|
||||
full_config.apply(printer_config);
|
||||
|
||||
full_config.set_key_value("filament_ids", new ConfigOptionStrings({calib_info.filament_prest->filament_id}));
|
||||
|
||||
init_multi_extruder_params_for_cali(full_config, calib_info);
|
||||
|
||||
Calib_Params params;
|
||||
params.mode = CalibMode::Calib_Flow_Rate;
|
||||
if (!process_and_store_3mf(&model, full_config, params, error_message))
|
||||
return false;
|
||||
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
MachineObject *obj_ = dev->get_selected_machine();
|
||||
if (obj_ == nullptr) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
json js;
|
||||
if (pass == 1)
|
||||
@@ -650,17 +740,20 @@ void CalibUtils::calib_pa_pattern(const CalibInfo &calib_info, Model& model)
|
||||
full_config.apply(filament_config);
|
||||
full_config.apply(printer_config);
|
||||
|
||||
float nozzle_diameter = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
|
||||
float nozzle_diameter = printer_config.option<ConfigOptionFloatsNullable>("nozzle_diameter")->get_at(0);
|
||||
|
||||
for (const auto opt : SuggestedConfigCalibPAPattern().float_pairs) {
|
||||
print_config.set_key_value(opt.first, new ConfigOptionFloat(opt.second));
|
||||
}
|
||||
for (const auto opt : SuggestedConfigCalibPAPattern().floats_pairs) {
|
||||
print_config.set_key_value(opt.first, new ConfigOptionFloatsNullable(opt.second));
|
||||
}
|
||||
|
||||
int index = get_index_for_extruder_parameter(print_config, "outer_wall_speed", calib_info.extruder_id, calib_info.extruder_type, calib_info.nozzle_volume_type);
|
||||
float wall_speed = CalibPressureAdvance::find_optimal_PA_speed(full_config, print_config.get_abs_value("line_width"), print_config.get_abs_value("layer_height"), calib_info.extruder_id, 0);
|
||||
ConfigOptionFloatsNullable *wall_speed_speed_opt = print_config.option<ConfigOptionFloatsNullable>("outer_wall_speed");
|
||||
wall_speed_speed_opt->values[index] = wall_speed;
|
||||
|
||||
print_config.set_key_value("outer_wall_speed",
|
||||
new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed(
|
||||
full_config, print_config.get_abs_value("line_width"),
|
||||
print_config.get_abs_value("layer_height"), 0)));
|
||||
|
||||
for (const auto opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) {
|
||||
print_config.set_key_value(opt.first, new ConfigOptionFloat(nozzle_diameter * opt.second / 100));
|
||||
}
|
||||
@@ -694,6 +787,21 @@ void CalibUtils::calib_pa_pattern(const CalibInfo &calib_info, Model& model)
|
||||
|
||||
bool CalibUtils::calib_generic_PA(const CalibInfo &calib_info, wxString &error_message)
|
||||
{
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
MachineObject *obj_ = dev->get_selected_machine();
|
||||
if (obj_ == nullptr) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_printable_status_before_cali(obj_, calib_info, error_message))
|
||||
return false;
|
||||
|
||||
const Calib_Params ¶ms = calib_info.params;
|
||||
if (params.mode != CalibMode::Calib_PA_Line && params.mode != CalibMode::Calib_PA_Pattern)
|
||||
return false;
|
||||
@@ -722,21 +830,11 @@ bool CalibUtils::calib_generic_PA(const CalibInfo &calib_info, wxString &error_m
|
||||
full_config.apply(filament_config);
|
||||
full_config.apply(printer_config);
|
||||
|
||||
init_multi_extruder_params_for_cali(full_config, calib_info);
|
||||
|
||||
if (!process_and_store_3mf(&model, full_config, params, error_message))
|
||||
return false;
|
||||
|
||||
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
if (!dev) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
MachineObject *obj_ = dev->get_selected_machine();
|
||||
if (obj_ == nullptr) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
json js;
|
||||
if (params.mode == CalibMode::Calib_PA_Line)
|
||||
@@ -744,7 +842,7 @@ bool CalibUtils::calib_generic_PA(const CalibInfo &calib_info, wxString &error_m
|
||||
else if (params.mode == CalibMode::Calib_PA_Pattern)
|
||||
js["cali_type"] = "cali_pa_pattern";
|
||||
|
||||
const ConfigOptionFloats *nozzle_diameter_config = printer_config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
const ConfigOptionFloatsNullable *nozzle_diameter_config = printer_config.option<ConfigOptionFloatsNullable>("nozzle_diameter");
|
||||
assert(nozzle_diameter_config->values.size() > 0);
|
||||
float nozzle_diameter = nozzle_diameter_config->values[0];
|
||||
|
||||
@@ -807,8 +905,8 @@ void CalibUtils::calib_temptue(const CalibInfo &calib_info, wxString &error_mess
|
||||
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
|
||||
|
||||
auto start_temp = lround(params.start);
|
||||
filament_config.set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1, (int) start_temp));
|
||||
filament_config.set_key_value("nozzle_temperature", new ConfigOptionInts(1, (int) start_temp));
|
||||
filament_config.set_key_value("nozzle_temperature_initial_layer", new ConfigOptionIntsNullable(1, (int) start_temp));
|
||||
filament_config.set_key_value("nozzle_temperature", new ConfigOptionIntsNullable(1, (int) start_temp));
|
||||
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
|
||||
|
||||
model.objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
|
||||
@@ -823,6 +921,8 @@ void CalibUtils::calib_temptue(const CalibInfo &calib_info, wxString &error_mess
|
||||
full_config.apply(filament_config);
|
||||
full_config.apply(printer_config);
|
||||
|
||||
init_multi_extruder_params_for_cali(full_config, calib_info);
|
||||
|
||||
process_and_store_3mf(&model, full_config, params, error_message);
|
||||
if (!error_message.empty())
|
||||
return;
|
||||
@@ -851,20 +951,20 @@ void CalibUtils::calib_max_vol_speed(const CalibInfo &calib_info, wxString &erro
|
||||
if (scale_obj < 1.0)
|
||||
obj->scale(scale_obj, 1, 1);
|
||||
|
||||
const ConfigOptionFloats *nozzle_diameter_config = printer_config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
const ConfigOptionFloatsNullable *nozzle_diameter_config = printer_config.option<ConfigOptionFloatsNullable>("nozzle_diameter");
|
||||
assert(nozzle_diameter_config->values.size() > 0);
|
||||
double nozzle_diameter = nozzle_diameter_config->values[0];
|
||||
double line_width = nozzle_diameter * 1.75;
|
||||
double layer_height = nozzle_diameter * 0.8;
|
||||
|
||||
auto max_lh = printer_config.option<ConfigOptionFloats>("max_layer_height");
|
||||
auto max_lh = printer_config.option<ConfigOptionFloatsNullable>("max_layer_height");
|
||||
if (max_lh->values[0] < layer_height) max_lh->values[0] = {layer_height};
|
||||
|
||||
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{50});
|
||||
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloatsNullable{50});
|
||||
filament_config.set_key_value("slow_down_layer_time", new ConfigOptionInts{0});
|
||||
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
|
||||
|
||||
print_config.set_key_value("enable_overhang_speed", new ConfigOptionBool{false});
|
||||
print_config.set_key_value("enable_overhang_speed", new ConfigOptionBoolsNullable{false});
|
||||
print_config.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
print_config.set_key_value("wall_loops", new ConfigOptionInt(1));
|
||||
print_config.set_key_value("top_shell_layers", new ConfigOptionInt(0));
|
||||
@@ -891,7 +991,7 @@ void CalibUtils::calib_max_vol_speed(const CalibInfo &calib_info, wxString &erro
|
||||
}
|
||||
|
||||
auto new_params = params;
|
||||
auto mm3_per_mm = Flow(line_width, layer_height, nozzle_diameter).mm3_per_mm() * filament_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0);
|
||||
auto mm3_per_mm = Flow(line_width, layer_height, nozzle_diameter).mm3_per_mm() * filament_config.option<ConfigOptionFloatsNullable>("filament_flow_ratio")->get_at(0);
|
||||
new_params.end = params.end / mm3_per_mm;
|
||||
new_params.start = params.start / mm3_per_mm;
|
||||
new_params.step = params.step / mm3_per_mm;
|
||||
@@ -902,6 +1002,8 @@ void CalibUtils::calib_max_vol_speed(const CalibInfo &calib_info, wxString &erro
|
||||
full_config.apply(filament_config);
|
||||
full_config.apply(printer_config);
|
||||
|
||||
init_multi_extruder_params_for_cali(full_config, calib_info);
|
||||
|
||||
process_and_store_3mf(&model, full_config, new_params, error_message);
|
||||
if (!error_message.empty())
|
||||
return;
|
||||
@@ -924,10 +1026,10 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
|
||||
DynamicPrintConfig printer_config = calib_info.printer_prest->config;
|
||||
|
||||
filament_config.set_key_value("slow_down_layer_time", new ConfigOptionInts{0});
|
||||
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200});
|
||||
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloatsNullable{200});
|
||||
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
|
||||
|
||||
print_config.set_key_value("enable_overhang_speed", new ConfigOptionBool{false});
|
||||
print_config.set_key_value("enable_overhang_speed", new ConfigOptionBoolsNullable{false});
|
||||
print_config.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
print_config.set_key_value("wall_loops", new ConfigOptionInt(1));
|
||||
print_config.set_key_value("top_shell_layers", new ConfigOptionInt(0));
|
||||
@@ -960,6 +1062,8 @@ void CalibUtils::calib_VFA(const CalibInfo &calib_info, wxString &error_message)
|
||||
full_config.apply(filament_config);
|
||||
full_config.apply(printer_config);
|
||||
|
||||
init_multi_extruder_params_for_cali(full_config, calib_info);
|
||||
|
||||
process_and_store_3mf(&model, full_config, params, error_message);
|
||||
if (!error_message.empty())
|
||||
return;
|
||||
@@ -985,7 +1089,7 @@ void CalibUtils::calib_retraction(const CalibInfo &calib_info, wxString &error_m
|
||||
|
||||
double layer_height = 0.2;
|
||||
|
||||
auto max_lh = printer_config.option<ConfigOptionFloats>("max_layer_height");
|
||||
auto max_lh = printer_config.option<ConfigOptionFloatsNullable>("max_layer_height");
|
||||
if (max_lh->values[0] < layer_height) max_lh->values[0] = {layer_height};
|
||||
|
||||
filament_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(calib_info.bed_type));
|
||||
@@ -1011,6 +1115,8 @@ void CalibUtils::calib_retraction(const CalibInfo &calib_info, wxString &error_m
|
||||
full_config.apply(filament_config);
|
||||
full_config.apply(printer_config);
|
||||
|
||||
init_multi_extruder_params_for_cali(full_config, calib_info);
|
||||
|
||||
process_and_store_3mf(&model, full_config, params, error_message);
|
||||
if (!error_message.empty())
|
||||
return;
|
||||
@@ -1018,6 +1124,15 @@ void CalibUtils::calib_retraction(const CalibInfo &calib_info, wxString &error_m
|
||||
send_to_print(calib_info, error_message);
|
||||
}
|
||||
|
||||
bool CalibUtils::is_support_auto_pa_cali(std::string filament_id)
|
||||
{
|
||||
auto iter = std::find(not_support_auto_pa_cali_filaments.begin(), not_support_auto_pa_cali_filaments.end(), filament_id);
|
||||
if (iter != not_support_auto_pa_cali_filaments.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int CalibUtils::get_selected_calib_idx(const std::vector<PACalibResult> &pa_calib_values, int cali_idx) {
|
||||
for (int i = 0; i < pa_calib_values.size(); ++i) {
|
||||
if(pa_calib_values[i].cali_idx == cali_idx)
|
||||
@@ -1040,9 +1155,129 @@ bool CalibUtils::get_pa_k_n_value_by_cali_idx(const MachineObject *obj, int cali
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, const X1CCalibInfos &cali_infos, wxString &error_message)
|
||||
{
|
||||
if (!obj) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
float cali_diameter = cali_infos.calib_datas[0].nozzle_diameter;
|
||||
int extruder_id = cali_infos.calib_datas[0].extruder_id;
|
||||
for (const auto& cali_info : cali_infos.calib_datas) {
|
||||
if (cali_infos.cali_mode == CalibMode::Calib_PA_Line && !is_support_auto_pa_cali(cali_info.filament_id)) {
|
||||
error_message = _L("TPU 90A/TPU 85A is too soft and does not support automatic Flow Dynamics calibration.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_approx(cali_diameter, cali_info.nozzle_diameter)) {
|
||||
error_message = _L("Automatic calibration only supports cases where the left and right nozzle diameters are identical.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (extruder_id >= obj->m_extder_data.extders.size()) {
|
||||
error_message = _L("The number of printer extruders and the printer selected for calibration does not match.");
|
||||
return false;
|
||||
}
|
||||
|
||||
float diameter = obj->m_extder_data.extders[extruder_id].current_nozzle_diameter;
|
||||
bool is_multi_extruder = obj->is_multi_extruders();
|
||||
std::vector<NozzleFlowType> nozzle_volume_types;
|
||||
if (is_multi_extruder) {
|
||||
for (const Extder& extruder : obj->m_extder_data.extders) {
|
||||
nozzle_volume_types.emplace_back(extruder.current_nozzle_flow_type);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &cali_info : cali_infos.calib_datas) {
|
||||
wxString name = _L("left");
|
||||
if (cali_info.extruder_id == 0) {
|
||||
name = _L("right");
|
||||
}
|
||||
|
||||
if (!is_approx(cali_info.nozzle_diameter, diameter)) {
|
||||
if (is_multi_extruder)
|
||||
error_message = wxString::Format(_L("The currently selected nozzle diameter of %s extruder does not match the actual nozzle diameter.\n"
|
||||
"Please click the Sync button above and restart the calibration."), name);
|
||||
else
|
||||
error_message = _L("The nozzle diameter does not match the actual printer nozzle diameter.\n"
|
||||
"Please click the Sync button above and restart the calibration.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_multi_extruder) {
|
||||
if (nozzle_volume_types[cali_info.extruder_id] == NozzleFlowType::NONE_FLOWTYPE) {
|
||||
|
||||
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NozzleVolumeType(nozzle_volume_types[cali_info.extruder_id] - 1) != cali_info.nozzle_volume_type) {
|
||||
error_message = wxString::Format(_L("The currently selected nozzle type of %s extruder does not match the actual printer nozzle type.\n"
|
||||
"Please click the Sync button above and restart the calibration."), name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CalibUtils::check_printable_status_before_cali(const MachineObject* obj, const CalibInfo& cali_info, wxString& error_message)
|
||||
{
|
||||
if (!obj) {
|
||||
error_message = _L("Need select printer");
|
||||
return false;
|
||||
}
|
||||
|
||||
const ConfigOptionFloatsNullable *nozzle_diameter_config = cali_info.printer_prest->config.option<ConfigOptionFloatsNullable>("nozzle_diameter");
|
||||
float nozzle_diameter = nozzle_diameter_config->values[0];
|
||||
|
||||
float diameter = obj->m_extder_data.extders[cali_info.extruder_id].current_nozzle_diameter;
|
||||
bool is_multi_extruder = obj->is_multi_extruders();
|
||||
std::vector<NozzleFlowType> nozzle_volume_types;
|
||||
if (is_multi_extruder) {
|
||||
for (const Extder& extruder : obj->m_extder_data.extders) {
|
||||
nozzle_volume_types.emplace_back(extruder.current_nozzle_flow_type);
|
||||
}
|
||||
}
|
||||
|
||||
wxString name = _L("left");
|
||||
if (cali_info.extruder_id == 0) {
|
||||
name = _L("right");
|
||||
}
|
||||
|
||||
if (!is_approx(nozzle_diameter, diameter)) {
|
||||
if (is_multi_extruder)
|
||||
error_message = wxString::Format(_L("The currently selected nozzle diameter of %s extruder does not match the actual nozzle diameter.\n"
|
||||
"Please click the Sync button above and restart the calibration."), name);
|
||||
else
|
||||
error_message = _L("The nozzle diameter does not match the actual printer nozzle diameter.\n"
|
||||
"Please click the Sync button above and restart the calibration.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_multi_extruder) {
|
||||
if (nozzle_volume_types[cali_info.extruder_id] == NozzleFlowType::NONE_FLOWTYPE) {
|
||||
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NozzleVolumeType(nozzle_volume_types[cali_info.extruder_id] - 1) != cali_info.nozzle_volume_type) {
|
||||
error_message = wxString::Format(_L("The currently selected nozzle type of %s extruder does not match the actual printer nozzle type.\n"
|
||||
"Please click the Sync button above and restart the calibration."), name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &full_config, const Calib_Params ¶ms, wxString &error_message)
|
||||
{
|
||||
Pointfs bedfs = full_config.opt<ConfigOptionPoints>("printable_area")->values;
|
||||
std::vector<Pointfs> extruder_areas = full_config.option<ConfigOptionPointsGroups>("extruder_printable_area")->values;
|
||||
std::vector<double> extruder_heights = full_config.option<ConfigOptionFloatsNullable>("extruder_printable_height")->values;
|
||||
double print_height = full_config.opt_float("printable_height");
|
||||
double current_width = bedfs[2].x() - bedfs[0].x();
|
||||
double current_depth = bedfs[2].y() - bedfs[0].y();
|
||||
@@ -1089,7 +1324,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
|
||||
int print_index;
|
||||
part_plate->get_print(&print, &gcode_result, &print_index);
|
||||
|
||||
BuildVolume build_volume(bedfs, print_height);
|
||||
BuildVolume build_volume(bedfs, print_height, extruder_areas, extruder_heights);
|
||||
unsigned int count = model->update_print_volume_state(build_volume);
|
||||
if (count == 0) {
|
||||
error_message = _L("Unable to calibrate: maybe because the set calibration value range is too large, or the step is too small");
|
||||
@@ -1141,7 +1376,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
|
||||
ThumbnailData* thumbnail_data = &plate_data_list[0]->plate_thumbnail;
|
||||
unsigned int thumbnail_width = 512, thumbnail_height = 512;
|
||||
const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, 0};
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("thumbnail");
|
||||
const auto& shader = wxGetApp().get_shader("thumbnail");
|
||||
|
||||
for (unsigned int obj_idx = 0; obj_idx < (unsigned int)model->objects.size(); ++ obj_idx) {
|
||||
const ModelObject &model_object = *model->objects[obj_idx];
|
||||
@@ -1158,28 +1393,14 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
|
||||
}
|
||||
}
|
||||
|
||||
switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type())
|
||||
{
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": framebuffer_type: ARB");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*thumbnail_data,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model->objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
break;
|
||||
}
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": framebuffer_type: EXT");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*thumbnail_data,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model->objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown");
|
||||
break;
|
||||
}
|
||||
const auto& p_ogl_manager = Slic3r::GUI::wxGetApp().get_opengl_manager();
|
||||
p_ogl_manager->bind_vao();
|
||||
p_ogl_manager->bind_shader(shader);
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(p_ogl_manager, *thumbnail_data,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model->objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
p_ogl_manager->unbind_shader();
|
||||
p_ogl_manager->unbind_vao();
|
||||
thumbnails.push_back(thumbnail_data);
|
||||
}
|
||||
|
||||
@@ -1255,12 +1476,12 @@ void CalibUtils::send_to_print(const CalibInfo &calib_info, wxString &error_mess
|
||||
}
|
||||
|
||||
else if (!obj_->is_support_print_without_sd && (obj_->get_sdcard_state() == MachineObject::SdcardState::NO_SDCARD)) {
|
||||
error_message = _L("An SD card needs to be inserted before printing.");
|
||||
error_message = _L("Storage needs to be inserted before printing.");
|
||||
return;
|
||||
}
|
||||
if (obj_->is_lan_mode_printer()) {
|
||||
if (obj_->get_sdcard_state() == MachineObject::SdcardState::NO_SDCARD) {
|
||||
error_message = _L("An SD card needs to be inserted before printing via LAN.");
|
||||
error_message = _L("Storage needs to be inserted before printing via LAN.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1303,12 +1524,15 @@ void CalibUtils::send_to_print(const CalibInfo &calib_info, wxString &error_mess
|
||||
print_job->task_ams_mapping_info = "";
|
||||
print_job->task_use_ams = select_ams == "[254]" ? false : true;
|
||||
|
||||
std::string new_ams_mapping = "[{\"ams_id\":" + std::to_string(calib_info.ams_id) + ", \"slot_id\":" + std::to_string(calib_info.slot_id) + "}]";
|
||||
print_job->task_ams_mapping2 = new_ams_mapping;
|
||||
|
||||
CalibMode cali_mode = calib_info.params.mode;
|
||||
print_job->m_project_name = get_calib_mode_name(cali_mode, flow_ratio_mode);
|
||||
print_job->set_calibration_task(true);
|
||||
|
||||
print_job->has_sdcard = obj_->has_sdcard();
|
||||
print_job->set_print_config(MachineBedTypeString[bed_type], true, false, false, false, true);
|
||||
print_job->has_sdcard = obj_->get_sdcard_state() == MachineObject::SdcardState::HAS_SDCARD_NORMAL;
|
||||
print_job->set_print_config(MachineBedTypeString[bed_type], true, false, false, false, true, 0, 0, 0);
|
||||
print_job->set_print_job_finished_event(wxGetApp().plater()->get_send_calibration_finished_event(), print_job->m_project_name);
|
||||
|
||||
{ // after send: record the print job
|
||||
|
||||
@@ -15,6 +15,11 @@ extern const float MAX_PA_K_VALUE;
|
||||
class CalibInfo
|
||||
{
|
||||
public:
|
||||
int extruder_id = 0;
|
||||
int ams_id = 0;
|
||||
int slot_id = 0;
|
||||
ExtruderType extruder_type{ExtruderType::etDirectDrive};
|
||||
NozzleVolumeType nozzle_volume_type;
|
||||
Calib_Params params;
|
||||
Preset* printer_prest;
|
||||
Preset* filament_prest;
|
||||
@@ -34,21 +39,21 @@ public:
|
||||
static CalibMode get_calib_mode_by_name(const std::string name, int &cali_stage);
|
||||
|
||||
static void calib_PA(const X1CCalibInfos& calib_infos, int mode, wxString& error_message);
|
||||
|
||||
|
||||
static void emit_get_PA_calib_results(float nozzle_diameter);
|
||||
static bool get_PA_calib_results(std::vector<PACalibResult> &pa_calib_results);
|
||||
|
||||
static void emit_get_PA_calib_infos(float nozzle_diameter);
|
||||
|
||||
static void emit_get_PA_calib_infos(const PACalibExtruderInfo &cali_info);
|
||||
static bool get_PA_calib_tab(std::vector<PACalibResult> &pa_calib_infos);
|
||||
|
||||
//w
|
||||
static void emit_get_PA_calib_info(float nozzle_diameter, const std::string &filament_id);
|
||||
static bool get_PA_calib_info(PACalibResult &pa_calib_info);
|
||||
|
||||
|
||||
static void set_PA_calib_result(const std::vector<PACalibResult>& pa_calib_values, bool is_auto_cali);
|
||||
static void select_PA_calib_result(const PACalibIndexInfo &pa_calib_info);
|
||||
static void delete_PA_calib_result(const PACalibIndexInfo &pa_calib_info);
|
||||
|
||||
static void calib_flowrate_X1C(const X1CCalibInfos& calib_infos, std::string& error_message);
|
||||
static void calib_flowrate_X1C(const X1CCalibInfos& calib_infos, wxString& error_message);
|
||||
static void emit_get_flow_ratio_calib_results(float nozzle_diameter);
|
||||
static bool get_flow_ratio_calib_results(std::vector<FlowRatioCalibResult> &flow_ratio_calib_results);
|
||||
static bool calib_flowrate(int pass, const CalibInfo &calib_info, wxString &error_message);
|
||||
@@ -62,6 +67,8 @@ public:
|
||||
static void calib_retraction(const CalibInfo &calib_info, wxString &error_message);
|
||||
|
||||
//help function
|
||||
static bool is_support_auto_pa_cali(std::string filament_id);
|
||||
|
||||
static int get_selected_calib_idx(const std::vector<PACalibResult> &pa_calib_values, int cali_idx);
|
||||
static bool get_pa_k_n_value_by_cali_idx(const MachineObject* obj, int cali_idx, float& out_k, float& out_n);
|
||||
|
||||
@@ -69,12 +76,18 @@ public:
|
||||
static bool validate_input_k_value(wxString k_text, float* output_value);
|
||||
static bool validate_input_flow_ratio(wxString flow_ratio, float* output_value);
|
||||
|
||||
static bool check_printable_status_before_cali(const MachineObject *obj, const X1CCalibInfos &cali_infos, wxString &error_message);
|
||||
static bool check_printable_status_before_cali(const MachineObject *obj, const CalibInfo &cali_info, wxString &error_message);
|
||||
|
||||
private:
|
||||
static bool process_and_store_3mf(Model* model, const DynamicPrintConfig& full_config, const Calib_Params& params, wxString& error_message);
|
||||
static void send_to_print(const CalibInfo &calib_info, wxString& error_message, int flow_ratio_mode = 0); // 0: none 1: coarse 2: fine
|
||||
};
|
||||
|
||||
extern void get_tray_ams_and_slot_id(MachineObject* obj, int in_tray_id, int &ams_id, int &slot_id, int &tray_id);
|
||||
|
||||
extern void get_default_k_n_value(const std::string &filament_id, float &k, float &n);
|
||||
extern wxString get_nozzle_volume_type_name(NozzleVolumeType type);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ public:
|
||||
virtual std::string get_status(wxString& curl_msg) const override { return "1"; };
|
||||
virtual float get_progress(wxString& curl_msg) const override { return 1; };
|
||||
virtual std::pair<std::string, float> get_status_progress(wxString& curl_msg) const override { return std::make_pair("1", 1); };
|
||||
virtual bool send_command_to_printer(wxString& curl_msg, wxString commond) const override {return false;};
|
||||
virtual bool send_timelapse_status(wxString& msg, std::string ip, bool status) const {return false;};
|
||||
wxString get_test_ok_msg() const override;
|
||||
wxString get_test_failed_msg(wxString &msg) const override;
|
||||
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
|
||||
|
||||
@@ -24,6 +24,8 @@ public:
|
||||
virtual std::string get_status(wxString& curl_msg) const override { return "1"; };
|
||||
virtual float get_progress(wxString& curl_msg) const override { return 1; };
|
||||
virtual std::pair<std::string, float> get_status_progress(wxString& curl_msg) const override { return std::make_pair("1", 1); };
|
||||
virtual bool send_command_to_printer(wxString& curl_msg, wxString commond) const override {return false;};
|
||||
virtual bool send_timelapse_status(wxString& msg, std::string ip, bool status) const {return false;};
|
||||
wxString get_test_ok_msg() const override;
|
||||
wxString get_test_failed_msg(wxString &msg) const override;
|
||||
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
|
||||
|
||||
@@ -751,6 +751,12 @@ void Http::set_extra_headers(std::map<std::string, std::string> headers)
|
||||
extra_headers.swap(headers);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> Http::get_extra_headers()
|
||||
{
|
||||
std::lock_guard<std::mutex> l(g_mutex);
|
||||
return extra_headers;
|
||||
}
|
||||
|
||||
bool Http::ca_file_supported()
|
||||
{
|
||||
::CURL *curl = ::curl_easy_init();
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
|
||||
//QDS set global header for each http request
|
||||
static void set_extra_headers(std::map<std::string, std::string> headers);
|
||||
static std::map<std::string, std::string> get_extra_headers();
|
||||
|
||||
~Http();
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ public:
|
||||
virtual std::string get_status(wxString& curl_msg) const override { return "1"; };
|
||||
virtual float get_progress(wxString& curl_msg) const override { return 1; };
|
||||
virtual std::pair<std::string, float> get_status_progress(wxString& curl_msg) const override { return std::make_pair("1", 1); };
|
||||
virtual bool send_command_to_printer(wxString& curl_msg, wxString commond) const override {return false;};
|
||||
virtual bool send_timelapse_status(wxString& msg, std::string ip, bool status) const {return false;};
|
||||
wxString get_test_ok_msg() const override;
|
||||
wxString get_test_failed_msg(wxString& msg) const override;
|
||||
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
|
||||
|
||||
@@ -16,6 +16,7 @@ void set_tag_when_enter_full_screen(bool isfullscreen);
|
||||
void set_title_colour_after_set_title(void * window);
|
||||
void initGestures(void * view, wxEvtHandler * handler);
|
||||
void openFolderForFile(wxString const & file);
|
||||
void StaticGroup_layoutBadge(void * group, void * badge);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -416,3 +416,12 @@ void initGestures(void * view, wxEvtHandler * handler)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void StaticGroup_layoutBadge(void * group, void * badge)
|
||||
{
|
||||
NSView * vg = (NSView *)group;
|
||||
NSView * vb = (NSView *)badge;
|
||||
vb.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[vg addConstraint: [NSLayoutConstraint constraintWithItem:vb attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:vg attribute:NSLayoutAttributeTop multiplier:1.0 constant:15]];
|
||||
[vg addConstraint: [NSLayoutConstraint constraintWithItem:vb attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:vg attribute:NSLayoutAttributeRight multiplier:1.0 constant:-1]];
|
||||
}
|
||||
@@ -75,7 +75,6 @@ func_get_user_nickanme NetworkAgent::get_user_nickanme_ptr = nullpt
|
||||
func_build_login_cmd NetworkAgent::build_login_cmd_ptr = nullptr;
|
||||
func_build_logout_cmd NetworkAgent::build_logout_cmd_ptr = nullptr;
|
||||
func_build_login_info NetworkAgent::build_login_info_ptr = nullptr;
|
||||
func_get_model_id_from_desgin_id NetworkAgent::get_model_id_from_desgin_id_ptr = nullptr;
|
||||
func_ping_bind NetworkAgent::ping_bind_ptr = nullptr;
|
||||
func_bind_detect NetworkAgent::bind_detect_ptr = nullptr;
|
||||
func_set_server_callback NetworkAgent::set_server_callback_ptr = nullptr;
|
||||
@@ -112,7 +111,6 @@ func_modify_printer_name NetworkAgent::modify_printer_name_ptr = null
|
||||
func_get_camera_url NetworkAgent::get_camera_url_ptr = nullptr;
|
||||
func_get_design_staffpick NetworkAgent::get_design_staffpick_ptr = nullptr;
|
||||
func_start_pubilsh NetworkAgent::start_publish_ptr = nullptr;
|
||||
func_get_profile_3mf NetworkAgent::get_profile_3mf_ptr = nullptr;
|
||||
func_get_model_publish_url NetworkAgent::get_model_publish_url_ptr = nullptr;
|
||||
func_get_model_mall_home_url NetworkAgent::get_model_mall_home_url_ptr = nullptr;
|
||||
func_get_model_mall_detail_url NetworkAgent::get_model_mall_detail_url_ptr = nullptr;
|
||||
@@ -292,7 +290,6 @@ int NetworkAgent::initialize_network_module(bool using_backup)
|
||||
ping_bind_ptr = reinterpret_cast<func_ping_bind>(get_network_function("qidi_network_ping_bind"));
|
||||
bind_detect_ptr = reinterpret_cast<func_bind_detect>(get_network_function("qidi_network_bind_detect"));
|
||||
set_server_callback_ptr = reinterpret_cast<func_set_server_callback>(get_network_function("qidi_network_set_server_callback"));
|
||||
get_model_id_from_desgin_id_ptr = reinterpret_cast<func_get_model_id_from_desgin_id>(get_network_function("qidi_network_get_model_id_from_desgin_id"));
|
||||
bind_ptr = reinterpret_cast<func_bind>(get_network_function("qidi_network_bind"));
|
||||
unbind_ptr = reinterpret_cast<func_unbind>(get_network_function("qidi_network_unbind"));
|
||||
get_qiditech_host_ptr = reinterpret_cast<func_get_qiditech_host>(get_network_function("qidi_network_get_qiditech_host"));
|
||||
@@ -326,7 +323,6 @@ int NetworkAgent::initialize_network_module(bool using_backup)
|
||||
get_camera_url_ptr = reinterpret_cast<func_get_camera_url>(get_network_function("qidi_network_get_camera_url"));
|
||||
get_design_staffpick_ptr = reinterpret_cast<func_get_design_staffpick>(get_network_function("qidi_network_get_design_staffpick"));
|
||||
start_publish_ptr = reinterpret_cast<func_start_pubilsh>(get_network_function("qidi_network_start_publish"));
|
||||
get_profile_3mf_ptr = reinterpret_cast<func_get_profile_3mf>(get_network_function("qidi_network_get_profile_3mf"));
|
||||
get_model_publish_url_ptr = reinterpret_cast<func_get_model_publish_url>(get_network_function("qidi_network_get_model_publish_url"));
|
||||
get_subtask_ptr = reinterpret_cast<func_get_subtask>(get_network_function("qidi_network_get_subtask"));
|
||||
get_model_mall_home_url_ptr = reinterpret_cast<func_get_model_mall_home_url>(get_network_function("qidi_network_get_model_mall_home_url"));
|
||||
@@ -414,7 +410,6 @@ int NetworkAgent::unload_network_module()
|
||||
build_login_cmd_ptr = nullptr;
|
||||
build_logout_cmd_ptr = nullptr;
|
||||
build_login_info_ptr = nullptr;
|
||||
get_model_id_from_desgin_id_ptr = nullptr;
|
||||
ping_bind_ptr = nullptr;
|
||||
bind_ptr = nullptr;
|
||||
unbind_ptr = nullptr;
|
||||
@@ -448,7 +443,6 @@ int NetworkAgent::unload_network_module()
|
||||
get_camera_url_ptr = nullptr;
|
||||
get_design_staffpick_ptr = nullptr;
|
||||
start_publish_ptr = nullptr;
|
||||
get_profile_3mf_ptr = nullptr;
|
||||
get_model_publish_url_ptr = nullptr;
|
||||
get_subtask_ptr = nullptr;
|
||||
get_model_mall_home_url_ptr = nullptr;
|
||||
@@ -1026,18 +1020,6 @@ std::string NetworkAgent::build_login_info()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int NetworkAgent::get_model_id_from_desgin_id(std::string& desgin_id, std::string& model_id)
|
||||
{
|
||||
int ret = 0;
|
||||
if (network_agent && get_model_id_from_desgin_id_ptr) {
|
||||
ret = get_model_id_from_desgin_id_ptr(network_agent, desgin_id, model_id);
|
||||
if (ret)
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" error: network_agent=%1%, ret=%2%, pin code=%3%")
|
||||
% network_agent % ret % desgin_id;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int NetworkAgent::ping_bind(std::string ping_code)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1449,16 +1431,6 @@ int NetworkAgent::start_publish(PublishParams params, OnUpdateStatusFn update_fn
|
||||
return ret;
|
||||
}
|
||||
|
||||
int NetworkAgent::get_profile_3mf(QDTProfile* profile)
|
||||
{
|
||||
int ret = -1;
|
||||
if (network_agent && get_profile_3mf_ptr) {
|
||||
ret = get_profile_3mf_ptr(network_agent, profile);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" : network_agent=%1%, ret=%2%") % network_agent % ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int NetworkAgent::get_model_publish_url(std::string* url)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1542,6 +1514,9 @@ int NetworkAgent::track_event(std::string evt_key, std::string content)
|
||||
if (!this->enable_track)
|
||||
return 0;
|
||||
|
||||
if (!this->is_user_login())
|
||||
return 0;
|
||||
|
||||
int ret = 0;
|
||||
if (network_agent && track_event_ptr) {
|
||||
ret = track_event_ptr(network_agent, evt_key, content);
|
||||
|
||||
@@ -55,7 +55,6 @@ typedef std::string (*func_get_user_nickanme)(void *agent);
|
||||
typedef std::string (*func_build_login_cmd)(void *agent);
|
||||
typedef std::string (*func_build_logout_cmd)(void *agent);
|
||||
typedef std::string (*func_build_login_info)(void *agent);
|
||||
typedef int (*func_get_model_id_from_desgin_id)(void *agent, std::string& desgin_id, std::string& model_id);
|
||||
typedef int (*func_ping_bind)(void *agent, std::string ping_code);
|
||||
typedef int (*func_bind_detect)(void *agent, std::string dev_ip, std::string sec_link, detectResult& detect);
|
||||
typedef int (*func_set_server_callback)(void *agent, OnServerErrFn fn);
|
||||
@@ -92,7 +91,6 @@ typedef int (*func_modify_printer_name)(void *agent, std::string dev_id, std::st
|
||||
typedef int (*func_get_camera_url)(void *agent, std::string dev_id, std::function<void(std::string)> callback);
|
||||
typedef int (*func_get_design_staffpick)(void *agent, int offset, int limit, std::function<void(std::string)> callback);
|
||||
typedef int (*func_start_pubilsh)(void *agent, PublishParams params, OnUpdateStatusFn update_fn, WasCancelledFn cancel_fn, std::string* out);
|
||||
typedef int (*func_get_profile_3mf)(void *agent, QDTProfile* profile);
|
||||
typedef int (*func_get_model_publish_url)(void *agent, std::string* url);
|
||||
typedef int (*func_get_subtask)(void *agent, QDTModelTask* task, OnGetSubTaskFn getsub_fn);
|
||||
typedef int (*func_get_model_mall_home_url)(void *agent, std::string* url);
|
||||
@@ -176,7 +174,6 @@ public:
|
||||
std::string build_login_cmd();
|
||||
std::string build_logout_cmd();
|
||||
std::string build_login_info();
|
||||
int get_model_id_from_desgin_id(std::string& desgin_id, std::string& model_id);
|
||||
int ping_bind(std::string ping_code);
|
||||
int bind_detect(std::string dev_ip, std::string sec_link, detectResult& detect);
|
||||
int set_server_callback(OnServerErrFn fn);
|
||||
@@ -213,7 +210,6 @@ public:
|
||||
int get_camera_url(std::string dev_id, std::function<void(std::string)> callback);
|
||||
int get_design_staffpick(int offset, int limit, std::function<void(std::string)> callback);
|
||||
int start_publish(PublishParams params, OnUpdateStatusFn update_fn, WasCancelledFn cancel_fn, std::string* out);
|
||||
int get_profile_3mf(QDTProfile* profile);
|
||||
int get_model_publish_url(std::string* url);
|
||||
int get_subtask(QDTModelTask* task, OnGetSubTaskFn getsub_fn);
|
||||
int get_model_mall_home_url(std::string* url);
|
||||
@@ -287,7 +283,6 @@ private:
|
||||
static func_build_login_cmd build_login_cmd_ptr;
|
||||
static func_build_logout_cmd build_logout_cmd_ptr;
|
||||
static func_build_login_info build_login_info_ptr;
|
||||
static func_get_model_id_from_desgin_id get_model_id_from_desgin_id_ptr;
|
||||
static func_ping_bind ping_bind_ptr;
|
||||
static func_bind_detect bind_detect_ptr;
|
||||
static func_set_server_callback set_server_callback_ptr;
|
||||
@@ -324,7 +319,6 @@ private:
|
||||
static func_get_camera_url get_camera_url_ptr;
|
||||
static func_get_design_staffpick get_design_staffpick_ptr;
|
||||
static func_start_pubilsh start_publish_ptr;
|
||||
static func_get_profile_3mf get_profile_3mf_ptr;
|
||||
static func_get_model_publish_url get_model_publish_url_ptr;
|
||||
static func_get_subtask get_subtask_ptr;
|
||||
static func_get_model_mall_home_url get_model_mall_home_url_ptr;
|
||||
|
||||
@@ -130,6 +130,7 @@ bool OctoPrint::test(wxString &msg) const
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Before uploading, %1%:Test at: %2%") % name % url;
|
||||
http.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
|
||||
res = false;
|
||||
@@ -158,6 +159,7 @@ bool OctoPrint::test(wxString &msg) const
|
||||
res = false;
|
||||
msg = "Could not parse server response";
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Get version success. The version msg is %1%") % msg;
|
||||
})
|
||||
#ifdef WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
@@ -243,16 +245,19 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro
|
||||
if (upload_data.post_action == PrintHostPostUploadAction::StartPrint)
|
||||
http.form_add("print", "true");
|
||||
|
||||
//y61
|
||||
// http.form_add("plateindex", std::to_string(partplate_list.get_curr_plate_index()));
|
||||
|
||||
//y53
|
||||
progress_percentage = 0;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Uploading the file to device %1%, url: %2%") % name % url;
|
||||
http.form_add_file("file", upload_data.source_path.string(), upload_filename.string())
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body;
|
||||
})
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
//y40 y53
|
||||
if (progress_percentage < 0.99){
|
||||
if (progress_percentage < 0.99) {
|
||||
if (status == 404)
|
||||
{
|
||||
body = ("Network connection fails.");
|
||||
@@ -265,6 +270,8 @@ bool OctoPrint::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Erro
|
||||
error_fn(format_error(body, error, status));
|
||||
res = false;
|
||||
}
|
||||
else
|
||||
res = true;
|
||||
})
|
||||
.on_progress([&](Http::Progress progress, bool &cancel) {
|
||||
prorgess_fn(std::move(progress), cancel);
|
||||
@@ -325,6 +332,7 @@ std::string OctoPrint::get_status(wxString& msg) const
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get status at: %2%") % name % url;
|
||||
//y36
|
||||
http.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
@@ -336,9 +344,9 @@ std::string OctoPrint::get_status(wxString& msg) const
|
||||
else
|
||||
body += ("Unable to get required resources from Aliyun server, please check your network settings.");
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
|
||||
print_state = "offline";
|
||||
msg = format_error(body, error, status);
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got print_stats: %2%") % name % body;
|
||||
@@ -397,6 +405,7 @@ float OctoPrint::get_progress(wxString& msg) const
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get progress at: %2%") % name % url;
|
||||
http.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
if (status == 404)
|
||||
@@ -407,14 +416,12 @@ float OctoPrint::get_progress(wxString& msg) const
|
||||
else
|
||||
body += ("Unable to get required resources from Aliyun server, please check your network settings.");
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status %
|
||||
body;
|
||||
res = false;
|
||||
msg = format_error(body, error, status);
|
||||
})
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status %
|
||||
body;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got display_status: %2%") % name % body;
|
||||
|
||||
try {
|
||||
// All successful HTTP requests will return a json encoded object in the form of :
|
||||
// {result: <response data>}
|
||||
@@ -438,6 +445,7 @@ float OctoPrint::get_progress(wxString& msg) const
|
||||
res = false;
|
||||
msg = "Could not parse server response";
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got display_status: %2%, msg is %3%") % name % body %msg;
|
||||
})
|
||||
#ifdef _WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
@@ -452,324 +460,64 @@ float OctoPrint::get_progress(wxString& msg) const
|
||||
return process;
|
||||
}
|
||||
|
||||
|
||||
//w42
|
||||
bool OctoPrint::get_printer_state(wxString& msg)
|
||||
bool OctoPrint::send_command_to_printer(wxString& msg, wxString commond) const
|
||||
{
|
||||
return true;
|
||||
const char* name = get_name();
|
||||
// printer_state: http://192.168.20.66/printer/objects/query?print_stats
|
||||
const char* name = get_name();
|
||||
std::string gcode = "G28";
|
||||
std::string commond_str = commond.ToStdString();
|
||||
std::string json_body = "{\"script\": \"" + commond_str + "\"}";
|
||||
|
||||
std::string print_state = "";
|
||||
float process = 0;
|
||||
auto url = make_url("printer/objects/query?print_stats=state&display_status=progress");
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get version at: %2%") % name % url;
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
http.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
if (status == 404) {
|
||||
body = ("Network connection fails.");
|
||||
if (body.find("AWS") != std::string::npos)
|
||||
body += ("Unable to get required resources from AWS server, please check your network settings.");
|
||||
else
|
||||
body += ("Unable to get required resources from Aliyun server, please check your network settings.");
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status %
|
||||
body;
|
||||
print_state = "offline";
|
||||
msg = format_error(body, error, status);
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got print_stats and process: %2%") % name % body;
|
||||
try {
|
||||
// All successful HTTP requests will return a json encoded object in the form of :
|
||||
// {result: <response data>}
|
||||
std::stringstream ss(body);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
if (ptree.front().first != "result") {
|
||||
msg = "Could not parse server response";
|
||||
print_state = "offline";
|
||||
process = 0;
|
||||
|
||||
}
|
||||
if (!ptree.front().second.get_optional<std::string>("status")) {
|
||||
msg = "Could not parse server response";
|
||||
print_state = "offline";
|
||||
|
||||
}
|
||||
print_state = ptree.get<std::string>("result.status.print_stats.state");
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Got state: %2%") % name % print_state;
|
||||
;
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
print_state = "offline";
|
||||
msg = "Could not parse server response";
|
||||
}
|
||||
})
|
||||
auto url = make_url("printer/gcode/script");
|
||||
bool successful = false;
|
||||
Http http = Http::post(std::move(url));
|
||||
http.header("Content-Type", "application/json")
|
||||
.set_post_body(json_body)
|
||||
.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error sending G-code: %2%, HTTP %3%, body: %4%")
|
||||
% name % error % status % body;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: G-code sent successfully: %2%") % name % gcode;
|
||||
successful = true;
|
||||
})
|
||||
#ifdef _WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
.on_ip_resolve([&](std::string address) {
|
||||
// Workaround for Windows 10/11 mDNS resolve issue, where two mDNS resolves in succession fail.
|
||||
// Remember resolved address to be reused at successive REST API call.
|
||||
msg = GUI::from_u8(address);
|
||||
})
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
#endif // _WIN32
|
||||
.perform_sync();
|
||||
|
||||
return print_state == "standby" ? true : false;
|
||||
.perform_sync();
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
bool OctoPrint::get_box_state(wxString& msg)
|
||||
//y60
|
||||
bool OctoPrint::send_timelapse_status(wxString& msg, std::string ip, bool status) const
|
||||
{
|
||||
const char* name = get_name();
|
||||
int box_count = 0;
|
||||
|
||||
auto url = make_url("server/files/config/saved_variables.cfg");
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Getting saved variables at: %2%") % name % url;
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
http.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting saved variables: %2%, HTTP %3%, body: `%4%`")
|
||||
% name % error % status % body;
|
||||
msg = format_error(body, error, status);
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
try {
|
||||
std::istringstream cfg_stream(body);
|
||||
std::string line;
|
||||
|
||||
while (std::getline(cfg_stream, line)) {
|
||||
if (line.find("box_count = ") != std::string::npos) {
|
||||
size_t value_start = line.find("=") + 1;
|
||||
std::string value_str = line.substr(value_start);
|
||||
|
||||
// Trim whitespace
|
||||
value_str.erase(0, value_str.find_first_not_of(" "));
|
||||
value_str.erase(value_str.find_last_not_of(" ") + 1);
|
||||
|
||||
box_count = std::stoi(value_str);
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got box_count value: %2%") % name % box_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
msg = wxString::Format("Error parsing box_count value: %s", e.what());
|
||||
}
|
||||
})
|
||||
const char* name = get_name();
|
||||
std::string status_str = status ? "true" : "false";
|
||||
std::string url = (boost::format("http://%1%:7125/machine/timelapse/settings?enabled=%2%") % ip % status_str).str();
|
||||
bool successful = false;
|
||||
std::string json_body = "{}";
|
||||
Http http = Http::post(std::move(url));
|
||||
http.header("Content-Type", "application/json")
|
||||
.set_post_body(json_body)
|
||||
.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error sending G-code: %2%, HTTP %3%, body: %4%")
|
||||
% name % error % status % body;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: G-code sent successfully: %2%") % name % status_str;
|
||||
successful = true;
|
||||
})
|
||||
#ifdef _WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
.on_ip_resolve([&](std::string address) {
|
||||
msg = GUI::from_u8(address);
|
||||
})
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
#endif // _WIN32
|
||||
.perform_sync();
|
||||
if (box_count > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
GUI::Box_info OctoPrint::get_box_info(wxString& msg)
|
||||
{
|
||||
const char* name = get_name();
|
||||
int box_count = 0;
|
||||
GUI::Box_info filament_info;
|
||||
|
||||
auto url = make_url("server/files/config/saved_variables.cfg");
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Getting saved variables at: %2%") % name % url;
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
http.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting saved variables: %2%, HTTP %3%, body: `%4%`")
|
||||
% name % error % status % body;
|
||||
msg = format_error(body, error, status);
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
try {
|
||||
std::istringstream cfg_stream(body);
|
||||
std::string line;
|
||||
filament_info = GUI::Box_info();
|
||||
|
||||
while (std::getline(cfg_stream, line)) {
|
||||
line.erase(0, line.find_first_not_of(" "));
|
||||
line.erase(line.find_last_not_of(" ") + 1);
|
||||
|
||||
if (line.find("box_count = ") != std::string::npos) {
|
||||
size_t value_start = line.find("=") + 1;
|
||||
std::string value_str = line.substr(value_start);
|
||||
|
||||
value_str.erase(0, value_str.find_first_not_of(" "));
|
||||
value_str.erase(value_str.find_last_not_of(" ") + 1);
|
||||
|
||||
box_count = std::stoi(value_str);
|
||||
filament_info.box_count = box_count;
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got box_count value: %2%") % name % box_count;
|
||||
}
|
||||
for (int i = 0; i < box_count * 4; ++i) {
|
||||
std::string color_key = "color_slot" + std::to_string(i);
|
||||
std::string filament_key = "filament_slot" + std::to_string(i);
|
||||
std::string vendor_key = "vendor_slot" + std::to_string(i);
|
||||
std::string slot_key = "slot" + std::to_string(i);
|
||||
|
||||
// Create regex patterns for exact variable name matches
|
||||
std::regex color_pattern("^\\s*" + color_key + "\\s*=");
|
||||
std::regex filament_pattern("^\\s*" + filament_key + "\\s*=");
|
||||
std::regex vendor_pattern("^\\s*" + vendor_key + "\\s*=");
|
||||
std::regex slot_pattern("^\\s*" + slot_key + "\\s*=");
|
||||
|
||||
if (std::regex_search(line, color_pattern)) {
|
||||
size_t value_start = line.find("=") + 1;
|
||||
std::string value_str = line.substr(value_start);
|
||||
value_str.erase(0, value_str.find_first_not_of(" "));
|
||||
value_str.erase(value_str.find_last_not_of(" ") + 1);
|
||||
filament_info.filament_color_index[i] = std::stoi(value_str);
|
||||
}
|
||||
else if (std::regex_search(line, filament_pattern)) {
|
||||
size_t value_start = line.find("=") + 1;
|
||||
std::string value_str = line.substr(value_start);
|
||||
value_str.erase(0, value_str.find_first_not_of(" "));
|
||||
value_str.erase(value_str.find_last_not_of(" ") + 1);
|
||||
filament_info.filament_index[i] = std::stoi(value_str);
|
||||
}
|
||||
else if (std::regex_search(line, vendor_pattern)) {
|
||||
size_t value_start = line.find("=") + 1;
|
||||
std::string value_str = line.substr(value_start);
|
||||
value_str.erase(0, value_str.find_first_not_of(" "));
|
||||
value_str.erase(value_str.find_last_not_of(" ") + 1);
|
||||
filament_info.filament_vendor[i] = std::stoi(value_str);
|
||||
}
|
||||
else if (std::regex_search(line, slot_pattern)) {
|
||||
size_t value_start = line.find("=") + 1;
|
||||
std::string value_str = line.substr(value_start);
|
||||
value_str.erase(0, value_str.find_first_not_of(" "));
|
||||
value_str.erase(value_str.find_last_not_of(" ") + 1);
|
||||
filament_info.slot_state[i] = std::stoi(value_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
msg = wxString::Format("Error parsing config values: %s", e.what());
|
||||
}
|
||||
})
|
||||
#ifdef _WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
.on_ip_resolve([&](std::string address) {
|
||||
msg = GUI::from_u8(address);
|
||||
})
|
||||
#endif // _WIN32
|
||||
.perform_sync();
|
||||
|
||||
return filament_info;
|
||||
}
|
||||
|
||||
void OctoPrint::get_color_filament_str(wxString& msg, GUI::Box_info& machine_filament_info)
|
||||
{
|
||||
const char* name = get_name();
|
||||
auto url = make_url("server/files/config/officiall_filas_list.cfg");
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Getting saved variables at: %2%") % name % url;
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
http.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting saved variables: %2%, HTTP %3%, body: `%4%`")
|
||||
% name % error % status % body;
|
||||
msg = format_error(body, error, status);
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
try {
|
||||
boost::property_tree::ptree pt;
|
||||
std::istringstream is(body);
|
||||
boost::property_tree::ini_parser::read_ini(is, pt);
|
||||
|
||||
int slots_to_process = machine_filament_info.box_count * 4;
|
||||
|
||||
for (int i = 0; i < slots_to_process && i < 16; i++) {
|
||||
int fila_index = machine_filament_info.filament_index[i];
|
||||
std::string section_name = "fila" + std::to_string(fila_index);
|
||||
|
||||
try {
|
||||
std::string fila_id = pt.get<std::string>(section_name + ".fila_id", "");
|
||||
machine_filament_info.filament_id[i] = fila_id;
|
||||
|
||||
std::string vendor = pt.get<std::string>(section_name + ".vendor", "");
|
||||
if (!vendor.empty()) {
|
||||
machine_filament_info.filament_vendor[i] =
|
||||
vendor == "QIDI" ? 1 : 2;
|
||||
}
|
||||
}
|
||||
catch (const boost::property_tree::ptree_error& e) {
|
||||
BOOST_LOG_TRIVIAL(warning) << boost::format("%1%: Could not find filament info for index %2%: %3%")
|
||||
% name % fila_index % e.what();
|
||||
}
|
||||
|
||||
int color_index = machine_filament_info.filament_color_index[i];
|
||||
std::string color_key = std::to_string(color_index);
|
||||
|
||||
try {
|
||||
std::string color_value = pt.get<std::string>("colordict." + color_key, "");
|
||||
machine_filament_info.filment_colors[i] = color_value;
|
||||
}
|
||||
catch (const boost::property_tree::ptree_error& e) {
|
||||
BOOST_LOG_TRIVIAL(warning) << boost::format("%1%: Could not find color for index %2%: %3%")
|
||||
% name % color_index % e.what();
|
||||
}
|
||||
}
|
||||
msg = wxString::Format("Successfully loaded filament and color information for %d boxes",
|
||||
machine_filament_info.box_count);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
msg = wxString::Format("Error parsing config values: %s", e.what());
|
||||
}
|
||||
})
|
||||
#ifdef _WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
.on_ip_resolve([&](std::string address) {
|
||||
msg = GUI::from_u8(address);
|
||||
})
|
||||
#endif // _WIN32
|
||||
.perform_sync();
|
||||
machine_filament_info.filament_index[0]=0;
|
||||
|
||||
}
|
||||
|
||||
std::pair<std::string, float> OctoPrint::send_command_to_printer(wxString& msg)
|
||||
{
|
||||
// printer_state: http://192.168.20.66/printer/objects/query?print_stats
|
||||
const char* name = get_name();
|
||||
std::string gcode = "G28";
|
||||
std::string json_body = "{\"script\": \"" + gcode + "\"}";
|
||||
|
||||
auto url = make_url("printer/gcode/script");
|
||||
|
||||
Http http = Http::post(std::move(url));
|
||||
http.header("Content-Type", "application/json")
|
||||
.set_post_body(json_body)
|
||||
.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error sending G-code: %2%, HTTP %3%, body: %4%")
|
||||
% name % error % status % body;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned status) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: G-code sent successfully: %2%") % name % gcode;
|
||||
})
|
||||
#ifdef _WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
#endif // _WIN32
|
||||
.perform_sync();
|
||||
|
||||
return std::make_pair("test", 0.01);
|
||||
.perform_sync();
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
std::pair<std::string, float> OctoPrint::get_status_progress(wxString& msg) const
|
||||
@@ -789,6 +537,7 @@ std::pair<std::string, float> OctoPrint::get_status_progress(wxString& msg) cons
|
||||
|
||||
auto http = Http::get(std::move(url));
|
||||
set_auth(http);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Get status progress, the url is %1%") % url;
|
||||
// B64 //y6
|
||||
http.timeout_connect(4)
|
||||
.on_error([&](std::string body, std::string error, unsigned status) {
|
||||
@@ -800,42 +549,41 @@ std::pair<std::string, float> OctoPrint::get_status_progress(wxString& msg) cons
|
||||
else
|
||||
body += ("Unable to get required resources from Aliyun server, please check your network settings.");
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status %
|
||||
body;
|
||||
print_state = "offline";
|
||||
msg = format_error(body, error, status);
|
||||
})
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting version: %2%, HTTP %3%, body: `%4%`") % name % error % status % body;
|
||||
})
|
||||
.on_complete([&](std::string body, unsigned) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got print_stats and process: %2%") % name % body;
|
||||
try {
|
||||
// All successful HTTP requests will return a json encoded object in the form of :
|
||||
// {result: <response data>}
|
||||
std::stringstream ss(body);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
if (ptree.front().first != "result") {
|
||||
msg = "Could not parse server response";
|
||||
print_state = "offline";
|
||||
process = 0;
|
||||
return;
|
||||
}
|
||||
if (!ptree.front().second.get_optional<std::string>("status")) {
|
||||
msg = "Could not parse server response";
|
||||
print_state = "offline";
|
||||
process = 0;
|
||||
return;
|
||||
}
|
||||
print_state = ptree.get<std::string>("result.status.print_stats.state");
|
||||
process = std::stof(ptree.get<std::string>("result.status.display_status.progress"));
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Got state: %2%") % name % print_state;
|
||||
;
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got print_stats and process: %2%") % name % body;
|
||||
try {
|
||||
// All successful HTTP requests will return a json encoded object in the form of :
|
||||
// {result: <response data>}
|
||||
std::stringstream ss(body);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
if (ptree.front().first != "result") {
|
||||
msg = "Could not parse server response";
|
||||
print_state = "offline";
|
||||
process = 0;
|
||||
msg = "Could not parse server response";
|
||||
return;
|
||||
}
|
||||
})
|
||||
if (!ptree.front().second.get_optional<std::string>("status")) {
|
||||
msg = "Could not parse server response";
|
||||
print_state = "offline";
|
||||
process = 0;
|
||||
return;
|
||||
}
|
||||
print_state = ptree.get<std::string>("result.status.print_stats.state");
|
||||
process = std::stof(ptree.get<std::string>("result.status.display_status.progress"));
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Got state: %2%") % name % print_state;
|
||||
;
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
print_state = "offline";
|
||||
process = 0;
|
||||
msg = "Could not parse server response";
|
||||
}
|
||||
})
|
||||
#ifdef _WIN32
|
||||
.ssl_revoke_best_effort(m_ssl_revoke_best_effort)
|
||||
.on_ip_resolve([&](std::string address) {
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
|
||||
#include "PrintHost.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
//w42
|
||||
#include "slic3r/GUI/SelectMachine.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -47,11 +44,8 @@ public:
|
||||
static double progress_percentage;
|
||||
|
||||
//w42
|
||||
bool get_box_state(wxString& curl_msg);
|
||||
bool get_printer_state(wxString& curl_msg);
|
||||
std::pair<std::string, float> send_command_to_printer(wxString& curl_msg);
|
||||
GUI::Box_info get_box_info(wxString& msg);
|
||||
void get_color_filament_str(wxString& msg, GUI::Box_info& machine_filament_info);
|
||||
bool send_command_to_printer(wxString& curl_msg, wxString commond) const;
|
||||
bool send_timelapse_status(wxString& msg, std::string ip, bool status) const;
|
||||
|
||||
protected:
|
||||
std::string m_show_ip;
|
||||
|
||||
@@ -54,55 +54,68 @@ static const char *TMP_EXTENSION = ".data";
|
||||
static const char *PRESET_SUBPATH = "presets";
|
||||
static const char *PLUGINS_SUBPATH = "plugins";
|
||||
|
||||
void copy_file_fix(const fs::path &source, const fs::path &target)
|
||||
int copy_file_fix(const fs::path &source, const fs::path &target, std::string& error_message)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << format("PresetUpdater: Copying %1% -> %2%", source, target);
|
||||
std::string error_message;
|
||||
|
||||
//CopyFileResult cfr = Slic3r::GUI::copy_file_gui(source.string(), target.string(), error_message, false);
|
||||
CopyFileResult cfr = copy_file(source.string(), target.string(), error_message, false);
|
||||
if (cfr != CopyFileResult::SUCCESS) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Copying failed(" << cfr << "): " << error_message;
|
||||
throw Slic3r::CriticalException(GUI::format(
|
||||
_L("Copying of file %1% to %2% failed: %3%"),
|
||||
source, target, error_message));
|
||||
return -1;
|
||||
}
|
||||
// Permissions should be copied from the source file by copy_file(). We are not sure about the source
|
||||
// permissions, let's rewrite them with 644.
|
||||
static constexpr const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read;
|
||||
fs::permissions(target, perms);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//QDS: add directory copy
|
||||
void copy_directory_fix(const fs::path &source, const fs::path &target)
|
||||
int copy_directory_fix(const fs::path &source, const fs::path &target, std::string& error_message)
|
||||
{
|
||||
int ret = 0;
|
||||
BOOST_LOG_TRIVIAL(debug) << format("PresetUpdater: Copying %1% -> %2%", source, target);
|
||||
std::string error_message;
|
||||
|
||||
if (fs::exists(target))
|
||||
fs::remove_all(target);
|
||||
fs::create_directories(target);
|
||||
if (fs::exists(target)) {
|
||||
boost::system::error_code ec;
|
||||
fs::remove_all(target, ec);
|
||||
if (ec) {
|
||||
error_message = ec.message();
|
||||
BOOST_LOG_TRIVIAL(error) << "copy_directory_fix: Failed to remove existing target directory: " + error_message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
boost::system::error_code ec;
|
||||
fs::create_directories(target, ec);
|
||||
if (ec) {
|
||||
error_message = ec.message();
|
||||
BOOST_LOG_TRIVIAL(error) << "copy_directory_fix: Failed to create target directory: " + error_message;
|
||||
return -2;
|
||||
}
|
||||
for (auto &dir_entry : fs::directory_iterator(source))
|
||||
{
|
||||
std::string source_file = dir_entry.path().string();
|
||||
fs::path source_file = dir_entry.path();
|
||||
fs::path target_file = target / dir_entry.path().filename();
|
||||
|
||||
std::string name = dir_entry.path().filename().string();
|
||||
std::string target_file = target.string() + "/" + name;
|
||||
|
||||
if (fs::is_directory(dir_entry)) {
|
||||
const auto target_path = target / name;
|
||||
copy_directory_fix(dir_entry, target_path);
|
||||
ret = copy_directory_fix(source_file, target_file, error_message);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
//CopyFileResult cfr = Slic3r::GUI::copy_file_gui(source_file, target_file, error_message, false);
|
||||
CopyFileResult cfr = copy_file(source_file, target_file, error_message, false);
|
||||
CopyFileResult cfr = copy_file(source_file.string(), target_file.string(), error_message, false);
|
||||
if (cfr != CopyFileResult::SUCCESS) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Copying failed(" << cfr << "): " << error_message;
|
||||
throw Slic3r::CriticalException(GUI::format(
|
||||
_L("Copying directory %1% to %2% failed: %3%"),
|
||||
source, target, error_message));
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Update
|
||||
@@ -134,16 +147,27 @@ struct Update
|
||||
, is_directory(is_dir)
|
||||
{}
|
||||
|
||||
//QDS: add directory support
|
||||
void install() const
|
||||
{
|
||||
if (is_directory) {
|
||||
copy_directory_fix(source, target);
|
||||
//QDS: add directory support
|
||||
int install() const
|
||||
{
|
||||
int ret = 0;
|
||||
std::string error_message;
|
||||
|
||||
if (is_directory) {
|
||||
ret = copy_directory_fix(source, target, error_message);
|
||||
}
|
||||
else {
|
||||
copy_file_fix(source, target);
|
||||
ret = copy_file_fix(source, target, error_message);
|
||||
}
|
||||
}
|
||||
|
||||
/*if (ret) {
|
||||
throw Slic3r::CriticalException(GUI::format(
|
||||
_L("Copying of file %1% to %2% failed: %3%"),
|
||||
source, target, error_message));
|
||||
}*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Update &self)
|
||||
{
|
||||
@@ -1144,6 +1168,16 @@ void PresetUpdater::priv::sync_plugins(std::string http_url, std::string plugin_
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
if (GUI::wxGetApp().is_running_on_arm64()) {
|
||||
//set to arm64 for plugins
|
||||
std::map<std::string, std::string> current_headers = Slic3r::Http::get_extra_headers();
|
||||
current_headers["X-QDT-OS-Type"] = "windows_arm";
|
||||
|
||||
Slic3r::Http::set_extra_headers(current_headers);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("set X-QDT-OS-Type to windows_arm");
|
||||
}
|
||||
#endif
|
||||
try {
|
||||
std::map<std::string, Resource> resources
|
||||
{
|
||||
@@ -1154,6 +1188,16 @@ void PresetUpdater::priv::sync_plugins(std::string http_url, std::string plugin_
|
||||
catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(warning) << format("[QDT Updater] sync_plugins: %1%", e.what());
|
||||
}
|
||||
#if defined(__WINDOWS__)
|
||||
if (GUI::wxGetApp().is_running_on_arm64()) {
|
||||
//set back
|
||||
std::map<std::string, std::string> current_headers = Slic3r::Http::get_extra_headers();
|
||||
current_headers["X-QDT-OS-Type"] = "windows";
|
||||
|
||||
Slic3r::Http::set_extra_headers(current_headers);
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("set X-QDT-OS-Type back to windows");
|
||||
}
|
||||
#endif
|
||||
|
||||
bool result = get_cached_plugins_version(cached_version, force_upgrade);
|
||||
if (result) {
|
||||
@@ -1246,26 +1290,48 @@ void PresetUpdater::priv::sync_printer_config(std::string http_url)
|
||||
|
||||
bool PresetUpdater::priv::install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot) const
|
||||
{
|
||||
Updates updates;
|
||||
Updates updates;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << format("Installing %1% bundles from resources ...", bundles.size());
|
||||
|
||||
for (const auto &bundle : bundles) {
|
||||
auto path_in_rsrc = (this->rsrc_path / bundle).replace_extension(".json");
|
||||
auto path_in_vendors = (this->vendor_path / bundle).replace_extension(".json");
|
||||
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), bundle, "", "");
|
||||
BOOST_LOG_TRIVIAL(info) << format("Installing %1% bundles from resources ...", bundles.size());
|
||||
|
||||
for (const auto &bundle : bundles) {
|
||||
//QDS: add directory support
|
||||
auto print_in_rsrc = this->rsrc_path / bundle;
|
||||
auto print_in_vendors = this->vendor_path / bundle;
|
||||
auto print_in_vendors = this->vendor_path / bundle;
|
||||
fs::path print_folder(print_in_vendors);
|
||||
if (fs::exists(print_folder))
|
||||
fs::remove_all(print_folder);
|
||||
fs::create_directories(print_folder);
|
||||
updates.updates.emplace_back(std::move(print_in_rsrc), std::move(print_in_vendors), Version(), bundle, "", "", false, true);
|
||||
}
|
||||
|
||||
return perform_updates(std::move(updates), snapshot);
|
||||
auto path_in_rsrc = (this->rsrc_path / bundle).replace_extension(".json");
|
||||
auto path_in_vendors = (this->vendor_path / bundle).replace_extension(".json");
|
||||
|
||||
//delete the json at first
|
||||
boost::system::error_code ec;
|
||||
if (fs::exists(path_in_vendors)) {
|
||||
fs::remove(path_in_vendors, ec);
|
||||
if (ec) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("install_bundles_rsrc: Failed to remove file %1%, error %2% ") % path_in_vendors.string() % ec.message();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fs::exists(print_folder)) {
|
||||
fs::remove_all(print_folder, ec);
|
||||
if (ec) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("install_bundles_rsrc: Failed to remove directory %1%, error %2% ") % print_folder.string() % ec.message();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fs::create_directories(print_folder, ec);
|
||||
if (ec) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("install_bundles_rsrc: Failed to create directory %1%, error %2% ")% print_folder.string() %ec.message();
|
||||
return false;
|
||||
}
|
||||
updates.updates.emplace_back(std::move(print_in_rsrc), std::move(print_in_vendors), Version(), bundle, "", "", false, true);
|
||||
|
||||
//copy json at the last
|
||||
updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version(), bundle, "", "");
|
||||
}
|
||||
|
||||
return perform_updates(std::move(updates), snapshot);
|
||||
}
|
||||
|
||||
|
||||
@@ -1290,7 +1356,7 @@ void PresetUpdater::priv::check_installed_vendor_profiles() const
|
||||
vendor_name.erase(vendor_name.size() - 5);
|
||||
if (enabled_config_update) {
|
||||
if ( fs::exists(path_in_vendor)) {
|
||||
if (enabled_vendors.find(vendor_name) != enabled_vendors.end()) {
|
||||
if ((vendor_name == PresetBundle::QDT_BUNDLE) || (enabled_vendors.find(vendor_name) != enabled_vendors.end())) {
|
||||
Semver resource_ver = get_version_from_json(file_path);
|
||||
Semver vendor_ver = get_version_from_json(path_in_vendor.string());
|
||||
|
||||
@@ -1430,10 +1496,10 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version
|
||||
version.config_version = cached_semver;
|
||||
//version.comment = description;
|
||||
|
||||
updates.updates.emplace_back(std::move(file_path), std::move(path_in_vendor.string()), std::move(version), vendor_name, description, "", force_update, false);
|
||||
|
||||
//QDS: add directory support
|
||||
updates.updates.emplace_back(cache_folder / vendor_name, vendor_path / vendor_name, Version(), vendor_name, "", "", force_update, true);
|
||||
|
||||
updates.updates.emplace_back(std::move(file_path), std::move(path_in_vendor.string()), std::move(version), vendor_name, description, "", force_update, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1447,6 +1513,7 @@ Updates PresetUpdater::priv::get_config_updates(const Semver &old_slic3r_version
|
||||
//QDS: switch to new QDT.json configs
|
||||
bool PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) const
|
||||
{
|
||||
int ret = 0;
|
||||
//std::string vendor_path;
|
||||
//std::string vendor_name;
|
||||
if (updates.incompats.size() > 0) {
|
||||
@@ -1475,7 +1542,11 @@ bool PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons
|
||||
for (const auto &update : updates.updates) {
|
||||
BOOST_LOG_TRIVIAL(info) << '\t' << update;
|
||||
|
||||
update.install();
|
||||
ret = update.install();
|
||||
if (ret) {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("[QDT Updater]:perform_updates to %1% failed, ret=%2%")% update.target.string() % ret;
|
||||
break;
|
||||
}
|
||||
//if (!update.is_directory) {
|
||||
// vendor_path = update.source.parent_path().string();
|
||||
// vendor_name = update.vendor;
|
||||
@@ -1500,7 +1571,7 @@ bool PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons
|
||||
//}
|
||||
}
|
||||
|
||||
return true;
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
void PresetUpdater::priv::set_waiting_updates(Updates u)
|
||||
@@ -1660,7 +1731,7 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
|
||||
ret = reload_configs_update_gui();
|
||||
if (!ret) {
|
||||
BOOST_LOG_TRIVIAL(warning) << format("[QDT Updater]:reload_configs_update_gui failed");
|
||||
return R_INCOMPAT_EXIT;
|
||||
return R_ALL_CANCELED;
|
||||
}
|
||||
Semver cur_ver = GUI::wxGetApp().preset_bundle->get_vendor_profile_version(PresetBundle::QDT_BUNDLE);
|
||||
|
||||
@@ -1691,8 +1762,10 @@ PresetUpdater::UpdateResult PresetUpdater::config_update(const Semver& old_slic3
|
||||
const auto res = dlg.ShowModal();
|
||||
if (res == wxID_OK) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "[QDT Updater]:selected yes to update";
|
||||
if (! p->perform_updates(std::move(updates)) ||
|
||||
! reload_configs_update_gui())
|
||||
if (!p->perform_updates(std::move(updates)))
|
||||
return R_INCOMPAT_EXIT;
|
||||
|
||||
if (!reload_configs_update_gui())
|
||||
return R_ALL_CANCELED;
|
||||
return R_UPDATE_INSTALLED;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
virtual std::string get_status(wxString& curl_msg) const = 0;
|
||||
virtual float get_progress(wxString& curl_msg) const = 0;
|
||||
virtual std::pair<std::string, float> get_status_progress(wxString& curl_msg) const = 0;
|
||||
virtual bool send_command_to_printer(wxString& curl_msg, wxString commond) const = 0;
|
||||
virtual bool send_timelapse_status(wxString& msg, std::string ip, bool status) const = 0;
|
||||
virtual wxString get_test_ok_msg () const = 0;
|
||||
virtual wxString get_test_failed_msg (wxString &msg) const = 0;
|
||||
virtual bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const = 0;
|
||||
@@ -80,12 +82,13 @@ protected:
|
||||
|
||||
struct PrintHostJob
|
||||
{
|
||||
// y10
|
||||
std::chrono::system_clock::time_point create_time;
|
||||
int sendinginterval;
|
||||
// y10 //y58
|
||||
std::chrono::system_clock::time_point create_time = std::chrono::system_clock::now();
|
||||
int sendinginterval = 0;
|
||||
PrintHostUpload upload_data;
|
||||
std::unique_ptr<PrintHost> printhost;
|
||||
bool cancelled = false;
|
||||
bool is_3mf = false;
|
||||
|
||||
PrintHostJob() {}
|
||||
PrintHostJob(const PrintHostJob&) = delete;
|
||||
@@ -95,6 +98,7 @@ struct PrintHostJob
|
||||
, cancelled(other.cancelled)
|
||||
, create_time(std::move(other.create_time))
|
||||
, sendinginterval(other.sendinginterval)
|
||||
, is_3mf(other.is_3mf)
|
||||
{}
|
||||
|
||||
PrintHostJob(DynamicPrintConfig *config)
|
||||
@@ -111,6 +115,8 @@ struct PrintHostJob
|
||||
// y10
|
||||
create_time = std::move(other.create_time);
|
||||
sendinginterval = other.sendinginterval;
|
||||
//y58
|
||||
is_3mf = other.is_3mf;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ public:
|
||||
virtual std::string get_status(wxString& curl_msg) const override { return "1"; };
|
||||
virtual float get_progress(wxString& curl_msg) const override { return 1; };
|
||||
virtual std::pair<std::string, float> get_status_progress(wxString& curl_msg) const override { return std::make_pair("1", 1); };
|
||||
virtual bool send_command_to_printer(wxString& curl_msg, wxString commond) const override {return false;};
|
||||
virtual bool send_timelapse_status(wxString& msg, std::string ip, bool status) const {return false;};
|
||||
wxString get_test_ok_msg () const override;
|
||||
wxString get_test_failed_msg (wxString &msg) const override;
|
||||
bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const override;
|
||||
|
||||
386
src/slic3r/Utils/WxFontUtils.cpp
Normal file
386
src/slic3r/Utils/WxFontUtils.cpp
Normal file
@@ -0,0 +1,386 @@
|
||||
#include "WxFontUtils.hpp"
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <CoreText/CTFont.h>
|
||||
#include <wx/uri.h>
|
||||
#include <wx/fontutil.h> // wxNativeFontInfo
|
||||
#include <wx/osx/core/cfdictionary.h>
|
||||
#elif defined(__linux__)
|
||||
#include "slic3r/Utils/FontConfigHelp.hpp"
|
||||
#endif
|
||||
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
#ifdef __APPLE__
|
||||
namespace {
|
||||
bool is_valid_ttf(std::string_view file_path)
|
||||
{
|
||||
if (file_path.empty()) return false;
|
||||
auto const pos_point = file_path.find_last_of('.');
|
||||
if (pos_point == std::string_view::npos) return false;
|
||||
|
||||
// use point only after last directory delimiter
|
||||
auto const pos_directory_delimiter = file_path.find_last_of("/\\");
|
||||
if (pos_directory_delimiter != std::string_view::npos &&
|
||||
pos_point < pos_directory_delimiter)
|
||||
return false; // point is before directory delimiter
|
||||
|
||||
// check count of extension chars
|
||||
size_t extension_size = file_path.size() - pos_point;
|
||||
if (extension_size >= 5) return false; // a lot of symbols for extension
|
||||
if (extension_size <= 1) return false; // few letters for extension
|
||||
|
||||
std::string_view extension = file_path.substr(pos_point + 1, extension_size);
|
||||
|
||||
// Because of MacOs - Courier, Geneva, Monaco
|
||||
if (extension == std::string_view("dfont")) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// get filepath from wxFont on Mac OsX
|
||||
std::string get_file_path(const wxFont& font) {
|
||||
const wxNativeFontInfo *info = font.GetNativeFontInfo();
|
||||
if (info == nullptr) return {};
|
||||
CTFontDescriptorRef descriptor = info->GetCTFontDescriptor();
|
||||
CFURLRef typeref = (CFURLRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute);
|
||||
if (typeref == NULL) return {};
|
||||
ScopeGuard sg([&typeref]() { CFRelease(typeref); });
|
||||
CFStringRef url = CFURLGetString(typeref);
|
||||
if (url == NULL) return {};
|
||||
wxString file_uri(wxCFStringRef::AsString(url));
|
||||
wxURI uri(file_uri);
|
||||
const wxString &path = uri.GetPath();
|
||||
wxString path_unescaped = wxURI::Unescape(path);
|
||||
std::string path_str = path_unescaped.ToUTF8().data();
|
||||
BOOST_LOG_TRIVIAL(trace) << "input uri(" << file_uri.c_str() << ") convert to path(" << path.c_str() << ") string(" << path_str << ").";
|
||||
return path_str;
|
||||
}
|
||||
} // namespace
|
||||
#endif // __APPLE__
|
||||
|
||||
bool WxFontUtils::can_load(const wxFont &font)
|
||||
{
|
||||
|
||||
if (!font.IsOk()) return false;
|
||||
#ifdef _WIN32
|
||||
return Emboss::can_load(font.GetHFONT()) != nullptr;
|
||||
#elif defined(__APPLE__)
|
||||
return true;
|
||||
//return is_valid_ttf(get_file_path(font));
|
||||
#elif defined(__linux__)
|
||||
return true;
|
||||
// font config check file path take about 4000ms for chech them all
|
||||
//std::string font_path = Slic3r::GUI::get_font_path(font);
|
||||
//return !font_path.empty();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<Emboss::FontFile> WxFontUtils::create_font_file(const wxFont &font)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return Emboss::create_font_file(font.GetHFONT());
|
||||
#elif defined(__APPLE__)
|
||||
std::string file_path = get_file_path(font);
|
||||
if (!is_valid_ttf(file_path)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Can not process font('" << get_human_readable_name(font) << "'), "
|
||||
<< "file in path('" << file_path << "') is not valid TTF.";
|
||||
return nullptr;
|
||||
}
|
||||
return Emboss::create_font_file(file_path.c_str());
|
||||
#elif defined(__linux__)
|
||||
std::string font_path = Slic3r::GUI::get_font_path(font);
|
||||
if (font_path.empty()){
|
||||
BOOST_LOG_TRIVIAL(error) << "Can not read font('" << get_human_readable_name(font) << "'), "
|
||||
<< "file path is empty.";
|
||||
return nullptr;
|
||||
}
|
||||
return Emboss::create_font_file(font_path.c_str());
|
||||
#else
|
||||
// HERE is place to add implementation for another platform
|
||||
// to convert wxFont to font data as windows or font file path as linux
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
EmbossStyle::Type WxFontUtils::get_current_type()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return EmbossStyle::Type::wx_win_font_descr;
|
||||
#elif defined(__APPLE__)
|
||||
return EmbossStyle::Type::wx_mac_font_descr;
|
||||
#elif defined(__linux__)
|
||||
return EmbossStyle::Type::wx_lin_font_descr;
|
||||
#else
|
||||
return EmbossStyle::Type::undefined;
|
||||
#endif
|
||||
}
|
||||
|
||||
EmbossStyle WxFontUtils::create_emboss_style(const wxFont &font, const std::string& name)
|
||||
{
|
||||
std::string name_item = name.empty()? get_human_readable_name(font) : name;
|
||||
std::string fontDesc = store_wxFont(font);
|
||||
EmbossStyle::Type type = get_current_type();
|
||||
|
||||
// synchronize font property with actual font
|
||||
FontProp font_prop;
|
||||
|
||||
// The point size is defined as 1/72 of the Anglo-Saxon inch (25.4 mm): it
|
||||
// is approximately 0.0139 inch or 352.8 um. But it is too small, so I
|
||||
// decide use point size as mm for emboss
|
||||
font_prop.size_in_mm = font.GetPointSize(); // *0.3528f;
|
||||
|
||||
WxFontUtils::update_property(font_prop, font);
|
||||
return { name_item, fontDesc, type, font_prop };
|
||||
}
|
||||
|
||||
// NOT working on linux GTK2
|
||||
// load font used by Operating system as default GUI
|
||||
//EmbossStyle WxFontUtils::get_os_font()
|
||||
//{
|
||||
// wxSystemFont system_font = wxSYS_DEFAULT_GUI_FONT;
|
||||
// wxFont font = wxSystemSettings::GetFont(system_font);
|
||||
// EmbossStyle es = create_emboss_style(font);
|
||||
// es.name += std::string(" (OS default)");
|
||||
// return es;
|
||||
//}
|
||||
|
||||
std::string WxFontUtils::get_human_readable_name(const wxFont &font)
|
||||
{
|
||||
if (!font.IsOk()) return "Font is NOT ok.";
|
||||
// Face name is optional in wxFont
|
||||
if (!font.GetFaceName().empty()) {
|
||||
return std::string(font.GetFaceName().c_str());
|
||||
} else {
|
||||
return std::string((font.GetFamilyString() + " " +
|
||||
font.GetStyleString() + " " +
|
||||
font.GetWeightString())
|
||||
.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::string WxFontUtils::store_wxFont(const wxFont &font)
|
||||
{
|
||||
// wxString os = wxPlatformInfo::Get().GetOperatingSystemIdName();
|
||||
wxString font_descriptor = font.GetNativeFontInfoDesc();
|
||||
BOOST_LOG_TRIVIAL(trace) << "'" << font_descriptor << "' wx string get from GetNativeFontInfoDesc. wxFont " <<
|
||||
"IsOk(" << font.IsOk() << "), " <<
|
||||
"isNull(" << font.IsNull() << ")" <<
|
||||
// "IsFree(" << font.IsFree() << "), " << // on MacOs is no function is free
|
||||
"IsFixedWidth(" << font.IsFixedWidth() << "), " <<
|
||||
"IsUsingSizeInPixels(" << font.IsUsingSizeInPixels() << "), " <<
|
||||
"Encoding(" << (int)font.GetEncoding() << "), " ;
|
||||
return std::string(font_descriptor.ToUTF8().data());
|
||||
}
|
||||
|
||||
wxFont WxFontUtils::load_wxFont(const std::string &font_descriptor)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(trace) << "'" << font_descriptor << "'font descriptor string param of load_wxFont()";
|
||||
wxString font_descriptor_wx = wxString::FromUTF8(font_descriptor);
|
||||
BOOST_LOG_TRIVIAL(trace) << "'" << font_descriptor_wx.c_str() << "' wx string descriptor";
|
||||
wxFont wx_font(font_descriptor_wx);
|
||||
BOOST_LOG_TRIVIAL(trace) << "loaded font is '" << get_human_readable_name(wx_font) << "'.";
|
||||
return wx_font;
|
||||
}
|
||||
|
||||
using TypeToFamily = boost::bimap<wxFontFamily, std::string_view>;
|
||||
const TypeToFamily WxFontUtils::type_to_family =
|
||||
boost::assign::list_of<TypeToFamily::relation>
|
||||
(wxFONTFAMILY_DEFAULT, "default")
|
||||
(wxFONTFAMILY_DECORATIVE, "decorative")
|
||||
(wxFONTFAMILY_ROMAN, "roman")
|
||||
(wxFONTFAMILY_SCRIPT, "script")
|
||||
(wxFONTFAMILY_SWISS, "swiss")
|
||||
(wxFONTFAMILY_MODERN, "modern")
|
||||
(wxFONTFAMILY_TELETYPE, "teletype");
|
||||
|
||||
using TypeToStyle = boost::bimap<wxFontStyle, std::string_view>;
|
||||
const TypeToStyle WxFontUtils::type_to_style =
|
||||
boost::assign::list_of<TypeToStyle::relation>
|
||||
(wxFONTSTYLE_ITALIC, "italic")
|
||||
(wxFONTSTYLE_SLANT, "slant")
|
||||
(wxFONTSTYLE_NORMAL, "normal");
|
||||
|
||||
using TypeToWeight = boost::bimap<wxFontWeight, std::string_view>;
|
||||
const TypeToWeight WxFontUtils::type_to_weight =
|
||||
boost::assign::list_of<TypeToWeight::relation>
|
||||
(wxFONTWEIGHT_THIN, "thin")
|
||||
(wxFONTWEIGHT_EXTRALIGHT, "extraLight")
|
||||
(wxFONTWEIGHT_LIGHT, "light")
|
||||
(wxFONTWEIGHT_NORMAL, "normal")
|
||||
(wxFONTWEIGHT_MEDIUM, "medium")
|
||||
(wxFONTWEIGHT_SEMIBOLD, "semibold")
|
||||
(wxFONTWEIGHT_BOLD, "bold")
|
||||
(wxFONTWEIGHT_EXTRABOLD, "extraBold")
|
||||
(wxFONTWEIGHT_HEAVY, "heavy")
|
||||
(wxFONTWEIGHT_EXTRAHEAVY, "extraHeavy");
|
||||
|
||||
wxFont WxFontUtils::create_wxFont(const EmbossStyle &style)
|
||||
{
|
||||
const FontProp &fp = style.prop;
|
||||
double point_size = static_cast<double>(fp.size_in_mm);
|
||||
wxFontInfo info(point_size);
|
||||
if (fp.family.has_value()) {
|
||||
auto it = type_to_family.right.find(*fp.family);
|
||||
if (it != type_to_family.right.end()) info.Family(it->second);
|
||||
}
|
||||
// Face names are not portable, so prefer to use Family() in portable code.
|
||||
/* if (fp.face_name.has_value()) {
|
||||
wxString face_name(*fp.face_name);
|
||||
info.FaceName(face_name);
|
||||
}*/
|
||||
if (fp.style.has_value()) {
|
||||
auto it = type_to_style.right.find(*fp.style);
|
||||
if (it != type_to_style.right.end()) info.Style(it->second);
|
||||
}
|
||||
if (fp.weight.has_value()) {
|
||||
auto it = type_to_weight.right.find(*fp.weight);
|
||||
if (it != type_to_weight.right.end()) info.Weight(it->second);
|
||||
}
|
||||
|
||||
// Improve: load descriptor instead of store to font property to 3mf
|
||||
// switch (es.type) {
|
||||
// case EmbossStyle::Type::wx_lin_font_descr:
|
||||
// case EmbossStyle::Type::wx_win_font_descr:
|
||||
// case EmbossStyle::Type::wx_mac_font_descr:
|
||||
// case EmbossStyle::Type::file_path:
|
||||
// case EmbossStyle::Type::undefined:
|
||||
// default:
|
||||
//}
|
||||
|
||||
wxFont wx_font(info);
|
||||
// Check if exist font file
|
||||
std::unique_ptr<Emboss::FontFile> ff = create_font_file(wx_font);
|
||||
if (ff == nullptr) return {};
|
||||
|
||||
return wx_font;
|
||||
}
|
||||
|
||||
void WxFontUtils::update_property(FontProp &font_prop, const wxFont &font)
|
||||
{
|
||||
wxString wx_face_name = font.GetFaceName();
|
||||
std::string face_name((const char *) wx_face_name.ToUTF8());
|
||||
if (!face_name.empty()) font_prop.face_name = face_name;
|
||||
|
||||
wxFontFamily wx_family = font.GetFamily();
|
||||
if (wx_family != wxFONTFAMILY_DEFAULT) {
|
||||
auto it = type_to_family.left.find(wx_family);
|
||||
if (it != type_to_family.left.end()) font_prop.family = it->second;
|
||||
}
|
||||
|
||||
wxFontStyle wx_style = font.GetStyle();
|
||||
if (wx_style != wxFONTSTYLE_NORMAL) {
|
||||
auto it = type_to_style.left.find(wx_style);
|
||||
if (it != type_to_style.left.end()) font_prop.style = it->second;
|
||||
}
|
||||
|
||||
wxFontWeight wx_weight = font.GetWeight();
|
||||
if (wx_weight != wxFONTWEIGHT_NORMAL) {
|
||||
auto it = type_to_weight.left.find(wx_weight);
|
||||
if (it != type_to_weight.left.end()) font_prop.weight = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
bool WxFontUtils::is_italic(const wxFont &font) {
|
||||
wxFontStyle wx_style = font.GetStyle();
|
||||
return wx_style == wxFONTSTYLE_ITALIC ||
|
||||
wx_style == wxFONTSTYLE_SLANT;
|
||||
}
|
||||
|
||||
bool WxFontUtils::is_bold(const wxFont &font) {
|
||||
wxFontWeight wx_weight = font.GetWeight();
|
||||
return wx_weight != wxFONTWEIGHT_NORMAL;
|
||||
}
|
||||
|
||||
void Slic3r::GUI::WxFontUtils::get_suitable_font_size(int max_height, wxDC &dc)
|
||||
{
|
||||
wxFont font = dc.GetFont();
|
||||
if (!font.IsOk()) return;
|
||||
|
||||
int font_size = font.GetPointSize();
|
||||
int height = dc.GetFontMetrics().height;
|
||||
if (height < max_height) /*go smaller*/
|
||||
{
|
||||
while (height < max_height) {
|
||||
font_size++;
|
||||
font.SetPointSize(font_size);
|
||||
dc.SetFont(font);
|
||||
height = dc.GetFontMetrics().height;
|
||||
}
|
||||
|
||||
if (height > max_height)
|
||||
{
|
||||
font_size--;
|
||||
font.SetPointSize(font_size);
|
||||
dc.SetFont(font);
|
||||
}
|
||||
}
|
||||
else if (height > max_height) /*go bigger*/
|
||||
{
|
||||
while (height > max_height && font_size > 1) {
|
||||
font_size--;
|
||||
font.SetPointSize(font_size);
|
||||
dc.SetFont(font);
|
||||
height = dc.GetFontMetrics().height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Emboss::FontFile> WxFontUtils::set_italic(wxFont &font, const Emboss::FontFile &font_file)
|
||||
{
|
||||
static std::vector<wxFontStyle> italic_styles = {
|
||||
wxFontStyle::wxFONTSTYLE_ITALIC,
|
||||
wxFontStyle::wxFONTSTYLE_SLANT
|
||||
};
|
||||
wxFontStyle orig_style = font.GetStyle();
|
||||
for (wxFontStyle style : italic_styles) {
|
||||
font.SetStyle(style);
|
||||
std::unique_ptr<Emboss::FontFile> new_font_file =
|
||||
WxFontUtils::create_font_file(font);
|
||||
|
||||
// can create italic font?
|
||||
if (new_font_file == nullptr)
|
||||
continue;
|
||||
|
||||
// is still same font file pointer?
|
||||
if (font_file == *new_font_file)
|
||||
continue;
|
||||
|
||||
return new_font_file;
|
||||
}
|
||||
// There is NO italic font by wx
|
||||
font.SetStyle(orig_style);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Emboss::FontFile> WxFontUtils::set_bold(wxFont &font, const Emboss::FontFile& font_file)
|
||||
{
|
||||
static std::vector<wxFontWeight> bold_weight = {
|
||||
wxFontWeight::wxFONTWEIGHT_BOLD,
|
||||
wxFontWeight::wxFONTWEIGHT_HEAVY,
|
||||
wxFontWeight::wxFONTWEIGHT_EXTRABOLD,
|
||||
wxFontWeight::wxFONTWEIGHT_EXTRAHEAVY
|
||||
};
|
||||
wxFontWeight orig_weight = font.GetWeight();
|
||||
for (wxFontWeight weight : bold_weight) {
|
||||
font.SetWeight(weight);
|
||||
std::unique_ptr<Emboss::FontFile> new_font_file =
|
||||
WxFontUtils::create_font_file(font);
|
||||
|
||||
// can create bold font file?
|
||||
if (new_font_file == nullptr) continue;
|
||||
|
||||
// is still same font file pointer?
|
||||
if (font_file == *new_font_file) continue;
|
||||
|
||||
return new_font_file;
|
||||
}
|
||||
// There is NO bold font by wx
|
||||
font.SetWeight(orig_weight);
|
||||
return nullptr;
|
||||
}
|
||||
75
src/slic3r/Utils/WxFontUtils.hpp
Normal file
75
src/slic3r/Utils/WxFontUtils.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef slic3r_WxFontUtils_hpp_
|
||||
#define slic3r_WxFontUtils_hpp_
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <boost/bimap.hpp>
|
||||
#include <wx/dc.h>
|
||||
#include <wx/font.h>
|
||||
#include "libslic3r/Emboss.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
// Help class to work with wx widget font object( wxFont )
|
||||
class WxFontUtils
|
||||
{
|
||||
public:
|
||||
// only static functions
|
||||
WxFontUtils() = delete;
|
||||
|
||||
// check if exist file for wxFont
|
||||
// return pointer on data or nullptr when can't load
|
||||
static bool can_load(const wxFont &font);
|
||||
// os specific load of wxFont
|
||||
static std::unique_ptr<::Slic3r::Emboss::FontFile> create_font_file(const wxFont &font);
|
||||
|
||||
static EmbossStyle::Type get_current_type();
|
||||
static EmbossStyle create_emboss_style(const wxFont &font, const std::string &name = "");
|
||||
|
||||
static std::string get_human_readable_name(const wxFont &font);
|
||||
|
||||
// serialize / deserialize font
|
||||
static std::string store_wxFont(const wxFont &font);
|
||||
static wxFont load_wxFont(const std::string &font_descriptor);
|
||||
|
||||
// Try to create similar font, loaded from 3mf from different Computer
|
||||
static wxFont create_wxFont(const EmbossStyle &style);
|
||||
// update font property by wxFont - without emboss depth and font size
|
||||
static void update_property(FontProp &font_prop, const wxFont &font);
|
||||
|
||||
static bool is_italic(const wxFont &font);
|
||||
static bool is_bold(const wxFont &font);
|
||||
|
||||
static void get_suitable_font_size(int max_height, wxDC &dc);
|
||||
|
||||
/// <summary>
|
||||
/// Set italic into wx font
|
||||
/// When italic font is same as original return nullptr.
|
||||
/// To not load font file twice on success is font_file returned.
|
||||
/// </summary>
|
||||
/// <param name="font">wx descriptor of font</param>
|
||||
/// <param name="font_file">file described in wx font</param>
|
||||
/// <returns>New created font fileon success otherwise nullptr</returns>
|
||||
static std::unique_ptr<::Slic3r::Emboss::FontFile> set_italic(wxFont &font, const ::Slic3r::Emboss::FontFile &prev_font_file);
|
||||
|
||||
/// <summary>
|
||||
/// Set boldness into wx font
|
||||
/// When bolded font is same as original return nullptr.
|
||||
/// To not load font file twice on success is font_file returned.
|
||||
/// </summary>
|
||||
/// <param name="font">wx descriptor of font</param>
|
||||
/// <param name="font_file">file described in wx font</param>
|
||||
/// <returns>New created font fileon success otherwise nullptr</returns>
|
||||
static std::unique_ptr<::Slic3r::Emboss::FontFile> set_bold(wxFont &font, const ::Slic3r::Emboss::FontFile &font_file);
|
||||
|
||||
// convert wxFont types to string and vice versa
|
||||
static const boost::bimap<wxFontFamily, std::string_view> type_to_family;
|
||||
static const boost::bimap<wxFontStyle, std::string_view> type_to_style;
|
||||
static const boost::bimap<wxFontWeight, std::string_view> type_to_weight;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Slic3r::GUI
|
||||
#endif // slic3r_WxFontUtils_hpp_
|
||||
@@ -97,7 +97,7 @@ namespace QDT {
|
||||
#define QIDI_NETWORK_LIBRARY "qidi_networking"
|
||||
#define QIDI_NETWORK_AGENT_NAME "qidi_network_agent"
|
||||
|
||||
#define QIDI_NETWORK_AGENT_VERSION "01.10.02.28"
|
||||
#define QIDI_NETWORK_AGENT_VERSION "02.00.02.50"
|
||||
|
||||
//iot preset type strings
|
||||
#define IOT_PRINTER_TYPE_STRING "printer"
|
||||
@@ -202,7 +202,9 @@ struct PrintParams {
|
||||
std::string ftp_file;
|
||||
std::string ftp_file_md5;
|
||||
std::string ams_mapping;
|
||||
std::string ams_mapping2;
|
||||
std::string ams_mapping_info;
|
||||
std::string nozzles_info;
|
||||
std::string connection_type;
|
||||
std::string comments;
|
||||
int origin_profile_id = 0;
|
||||
@@ -228,6 +230,9 @@ struct PrintParams {
|
||||
bool task_use_ams;
|
||||
std::string task_bed_type;
|
||||
std::string extra_options;
|
||||
int auto_bed_leveling{ 0 };
|
||||
int auto_flow_cali{ 0 };
|
||||
int auto_offset_cali{ 0 };
|
||||
};
|
||||
|
||||
struct TaskQueryParams
|
||||
|
||||
Reference in New Issue
Block a user