Fix filament syncing by fixing nozzle diameter guards (#13330)

* Remove unused `get_printer_preset` calls.

* `Plater::check_printer_initialized` should skip nozzle flow type checks if nozzle is unknown.

Also remove unnecessary `is_multi_extruders` check.

* Remove unused `CalibUtils::is_same_nozzle_diameters()` fn.

* Simplify `CalibUtils::check_printable_status_before_cali`.

The single-arity can delegate to the vectorized arity.

* Add `DevExtruderSystem::NozzleDiameterMatchesOrUnknown` to simply checks.

* Update `CalibrationPresetPage::update_sync_button_status()` to use `NozzleDiameterMatchesOrUnknown`.

Simplify logic by iterating over each extruder and checking for diameter and volume type match.

The previous code had several mistakes (from what I could tell):

- `curr_obj->is_multi_extruders()` doesn't imply exactly 2 extruders
- the single/multi branch served no purpose
- the single branch failed to check the volume type

* Specify `std::fabs` and add explicit import.

Ref: https://github.com/OrcaSlicer/OrcaSlicer/pull/13330#discussion_r3133613736

Not sure how idiomatic this is in C++ / OrcaSlicer codebase, but CoPilot suggested it and it seems reasonable.

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
Kevin J. Lynagh
2026-05-16 13:13:40 +02:00
committed by GitHub
parent 427d0f7a9f
commit 8dd1dd8921
5 changed files with 50 additions and 157 deletions

View File

@@ -1648,6 +1648,29 @@ bool CalibrationPresetPage::is_blocking_printing()
return false;
}
bool CalibrationPresetPage::is_nozzle_info_synced() const
{
if (!curr_obj || !curr_obj->is_info_ready())
return false;
for (const DevExtder& extruder : curr_obj->GetExtderSystem()->GetExtruders()) {
const int extruder_id = extruder.GetExtId();
if (!curr_obj->GetExtderSystem()->NozzleDiameterMatchesOrUnknown(extruder_id, get_nozzle_diameter(extruder_id)))
return false;
if (curr_obj->is_nozzle_flow_type_supported()) {
if (extruder.GetNozzleFlowType() == NozzleFlowType::NONE_FLOWTYPE)
return false;
if (int(extruder.GetNozzleFlowType()) - 1 != int(get_nozzle_volume_type(extruder_id)))
return false;
}
}
return true;
}
void CalibrationPresetPage::update_sync_button_status()
{
auto set_status = [this](bool synced) {
@@ -1664,53 +1687,7 @@ void CalibrationPresetPage::update_sync_button_status()
}
};
if (!curr_obj || !curr_obj->is_info_ready()) {
set_status(false);
return;
}
struct CaliNozzleInfo
{
float nozzle_diameter{0.4f};
int nozzle_volume_type{0};
bool operator==(const CaliNozzleInfo &other) const
{
return abs(nozzle_diameter - other.nozzle_diameter) < EPSILON
&& nozzle_volume_type == other.nozzle_volume_type;
}
};
if (curr_obj->is_multi_extruders()) {
std::vector<CaliNozzleInfo> machine_obj_nozzle_infos;
machine_obj_nozzle_infos.resize(2);
for (const DevExtder& extruder : curr_obj->GetExtderSystem()->GetExtruders()) {
machine_obj_nozzle_infos[extruder.GetExtId()].nozzle_diameter = extruder.GetNozzleDiameter();
machine_obj_nozzle_infos[extruder.GetExtId()].nozzle_volume_type = int(extruder.GetNozzleFlowType()) - 1;
}
std::vector<CaliNozzleInfo> cali_nozzle_infos;
cali_nozzle_infos.resize(2);
for (size_t extruder_id = 0; extruder_id < 2; ++extruder_id) {
cali_nozzle_infos[extruder_id].nozzle_diameter = get_nozzle_diameter(extruder_id);
cali_nozzle_infos[extruder_id].nozzle_volume_type = int(get_nozzle_volume_type(extruder_id));
}
if (machine_obj_nozzle_infos == cali_nozzle_infos) {
set_status(true);
}
else {
set_status(false);
}
}
else {
if (abs(curr_obj->GetExtderSystem()->GetNozzleDiameter(0) - get_nozzle_diameter(0)) < EPSILON) {
set_status(true);
}
else {
set_status(false);
}
}
set_status(is_nozzle_info_synced());
}
void CalibrationPresetPage::update_show_status()

View File

@@ -265,6 +265,7 @@ protected:
void update_combobox_filaments(MachineObject* obj);
void update_show_status();
void update_sync_button_status();
bool is_nozzle_info_synced() const;
void show_status(CaliPresetPageStatus status);
void Enable_Send_Button(bool enable);
bool is_blocking_printing();

View File

@@ -6,6 +6,7 @@
#include <wx/string.h>
#include "DevDefs.h"
#include <cmath>
namespace Slic3r
{
@@ -145,6 +146,15 @@ public:
float GetNozzleDiameter(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetNozzleDiameter() : 0.0; }
int GetNozzleTempCurrent(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetCurrentTemp() : 0; }
int GetNozzleTempTarget(int extder_id) const { return GetExtderById(extder_id) ? GetExtderById(extder_id)->GetTargetTemp() : 0; }
bool NozzleDiameterMatchesOrUnknown(int extder_id, float target_diameter) const
{
float diameter = GetNozzleDiameter(extder_id);
if (diameter == 0.0f) {
return true;
} else {
return std::fabs(diameter - target_diameter) < 1e-3;
}
}
// get slot info which is connected to the extruder
std::string GetCurrentAmsId() const;

View File

@@ -14992,7 +14992,7 @@ Preset *get_printer_preset(const MachineObject *obj)
return nullptr;
Preset *printer_preset = nullptr;
float machine_nozzle_diameter = obj->GetExtderSystem()->GetNozzleDiameter(0);
PresetBundle *preset_bundle = wxGetApp().preset_bundle;
for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) {
// only use system printer preset
@@ -15005,7 +15005,8 @@ Preset *get_printer_preset(const MachineObject *obj)
std::string model_id = printer_it->get_current_printer_type(preset_bundle);
std::string printer_type = obj->get_show_printer_type();
if (model_id.compare(printer_type) == 0 && printer_nozzle_vals && abs(printer_nozzle_vals->get_at(0) - machine_nozzle_diameter) < 1e-3) {
bool nozzle_diameter_matches_or_unknown = printer_nozzle_vals && obj->GetExtderSystem()->NozzleDiameterMatchesOrUnknown(0, printer_nozzle_vals->get_at(0));
if (model_id.compare(printer_type) == 0 && nozzle_diameter_matches_or_unknown) {
printer_preset = &(*printer_it);
}
}
@@ -15021,12 +15022,12 @@ bool Plater::check_printer_initialized(MachineObject *obj, bool only_warning, bo
const auto& extruders = obj->GetExtderSystem()->GetExtruders();
for (const DevExtder& extruder : extruders) {
if (obj->is_multi_extruders()) {
if (extruder.GetNozzleFlowType() == NozzleFlowType::NONE_FLOWTYPE) {
has_been_initialized = false;
break;
}
// Skip check if nozzle type is unknown
if (extruder.GetNozzleType() == NozzleType::ntUndefine) {
continue;
}
if (extruder.GetNozzleFlowType() == NozzleFlowType::NONE_FLOWTYPE) {
has_been_initialized = false;
break;

View File

@@ -169,52 +169,6 @@ static wxString to_wstring_name(std::string name)
return wxEmptyString;
}
static bool is_same_nozzle_diameters(const DynamicPrintConfig &full_config, const MachineObject *obj, wxString& error_msg)
{
if (obj == nullptr)
return true;
try {
std::string nozzle_type;
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<ConfigOptionFloats>("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->GetExtderSystem()->GetTotalExtderCount());
for (size_t idx = 0; idx < obj->GetExtderSystem()->GetTotalExtderCount(); ++idx)
machine_nozzle_diameters[idx] = obj->GetExtderSystem()->GetNozzleDiameter(idx);
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;
}
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 (...) {}
return true;
}
static bool is_same_nozzle_type(const DynamicPrintConfig &full_config, const MachineObject *obj, wxString& error_msg)
{
if (obj == nullptr)
@@ -267,9 +221,6 @@ static bool check_nozzle_diameter_and_type(const DynamicPrintConfig &full_config
if (obj->GetExtderSystem()->GetNozzleType(0) == NozzleType::ntUndefine)
return true;
// if (!is_same_nozzle_diameters(full_config, obj, error_msg))
// return false;
if (!is_same_nozzle_type(full_config, obj, error_msg))
return false;
@@ -1374,7 +1325,6 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
}
bool is_multi_extruder = obj->is_multi_extruders();
Preset *printer_preset = get_printer_preset(obj);
for (const auto &cali_info : cali_infos.calib_datas) {
wxString name = "";
@@ -1393,9 +1343,9 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
return false;
}
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(extruder_id);
NozzleFlowType nozzle_volume_type = obj->GetExtderSystem()->GetNozzleFlowType(extruder_id);
if (!is_approx(cali_info.nozzle_diameter, diameter)) {
if (!obj->GetExtderSystem()->NozzleDiameterMatchesOrUnknown(extruder_id, cali_info.nozzle_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);
@@ -1436,7 +1386,6 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
return true;
bool is_multi_extruder = obj->is_multi_extruders();
Preset *printer_preset = get_printer_preset(obj);
for (const auto &cali_info : cali_infos) {
wxString name = "";
@@ -1460,10 +1409,7 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
return false;
}
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(extruder_id);
NozzleFlowType nozzle_volume_type = obj->GetExtderSystem()->GetNozzleFlowType(cali_info.extruder_id);
if (!is_approx(cali_info.nozzle_diameter, diameter)) {
if (!obj->GetExtderSystem()->NozzleDiameterMatchesOrUnknown(extruder_id, cali_info.nozzle_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);
@@ -1473,6 +1419,9 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
return false;
}
NozzleFlowType nozzle_volume_type = obj->GetExtderSystem()->GetNozzleFlowType(extruder_id);
if (nozzle_volume_type == NozzleFlowType::NONE_FLOWTYPE) {
if (is_multi_extruder)
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
@@ -1496,52 +1445,7 @@ bool CalibUtils::check_printable_status_before_cali(const MachineObject *obj, co
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 ConfigOptionFloats *nozzle_diameter_config = cali_info.printer_prest->config.option<ConfigOptionFloats>("nozzle_diameter");
float nozzle_diameter = nozzle_diameter_config->values[0];
bool is_multi_extruder = obj->is_multi_extruders();
wxString name = _L("left");
if (cali_info.extruder_id == 0) {
name = _L("right");
}
float diameter = obj->GetExtderSystem()->GetNozzleDiameter(cali_info.extruder_id);
NozzleFlowType nozzle_volume_type = obj->GetExtderSystem()->GetNozzleFlowType(cali_info.extruder_id);
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 (nozzle_volume_type == NozzleFlowType::NONE_FLOWTYPE) {
if (is_multi_extruder)
error_message = wxString::Format(_L("Printer %s nozzle information has not been set. Please configure it before proceeding with the calibration."), name);
else
error_message = nozzle_not_set_text;
return false;
}
if (NozzleVolumeType(nozzle_volume_type - 1) != cali_info.nozzle_volume_type) {
if (is_multi_extruder)
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);
else
error_message = nozzle_volume_type_not_match_text;
return false;
}
return true;
return check_printable_status_before_cali(obj, std::vector<CalibInfo>{cali_info}, error_message);
}
bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &full_config, const Calib_Params &params, wxString &error_message)