mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-29 22:02:10 +00:00
fix: port BBS NozzleStatusRecorder pattern for per-carousel-slot purge tracking
The upstream _make_wipe_tower() tracked purge volumes per-extruder (2 slots), which collapsed all H2C carousel filaments into one slot and caused massive redundant AMS flushing (~40g instead of ~0.4g). Changes: - Print.cpp: Replace per-extruder nozzle_cur_filament_ids with BBS NozzleStatusRecorder that tracks per group_id (carousel slot 0..6). Use get_nozzle_for_filament() to resolve physical slot per layer. Select filament_prime_volume_nc for nozzle changes, filament_prime_volume for filament changes (BBS pattern). - PrintConfig.hpp/cpp: Register filament_prime_volume (per-filament EC prime volume, default 45mm³) matching BBS PrintConfig. - Preset.cpp: Add filament_prime_volume to preset keys list. Safe for non-carousel printers: group_id == extruder_id when each extruder has one nozzle, so NozzleStatusRecorder behaves identically to the original per-extruder tracking. Reference to BBS: BambuStudio/src/libslic3r/Print.cpp _make_wipe_tower() L3341-3392
This commit is contained in:
@@ -1372,7 +1372,7 @@ static std::vector<std::string> s_Preset_filament_options {/*"filament_colour",
|
|||||||
"filament_ramming_travel_time", "filament_ramming_travel_time_nc",
|
"filament_ramming_travel_time", "filament_ramming_travel_time_nc",
|
||||||
"filament_pre_cooling_temperature", "filament_pre_cooling_temperature_nc",
|
"filament_pre_cooling_temperature", "filament_pre_cooling_temperature_nc",
|
||||||
"filament_preheat_temperature_delta", "filament_retract_length_nc",
|
"filament_preheat_temperature_delta", "filament_retract_length_nc",
|
||||||
"filament_change_length_nc", "filament_prime_volume_nc",
|
"filament_change_length_nc", "filament_prime_volume", "filament_prime_volume_nc",
|
||||||
"long_retractions_when_ec", "retraction_distances_when_ec",
|
"long_retractions_when_ec", "retraction_distances_when_ec",
|
||||||
//ams chamber
|
//ams chamber
|
||||||
"filament_dev_ams_drying_ams_limitations", "filament_dev_ams_drying_temperature", "filament_dev_ams_drying_time", "filament_dev_ams_drying_heat_distortion_temperature",
|
"filament_dev_ams_drying_ams_limitations", "filament_dev_ams_drying_temperature", "filament_dev_ams_drying_time", "filament_dev_ams_drying_heat_distortion_temperature",
|
||||||
|
|||||||
@@ -3975,14 +3975,27 @@ void Print::_make_wipe_tower()
|
|||||||
multi_extruder_flush.emplace_back(wipe_volumes);
|
multi_extruder_flush.emplace_back(wipe_volumes);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int>filament_maps = get_filament_maps();
|
// Reference to BBS: BambuStudio/src/libslic3r/Print.cpp _make_wipe_tower()
|
||||||
|
// Use NozzleStatusRecorder for per-carousel-slot tracking (BBS pattern).
|
||||||
|
// The original Orca code tracked per-extruder (2 slots), which collapsed all
|
||||||
|
// carousel filaments into one slot and caused massive redundant AMS flushing.
|
||||||
|
auto group_result = get_layered_nozzle_group_result();
|
||||||
|
MultiNozzleUtils::NozzleStatusRecorder nozzle_recorder;
|
||||||
|
|
||||||
|
std::vector<int>filament_maps = get_filament_maps();
|
||||||
|
int layer_idx = -1;
|
||||||
|
|
||||||
std::vector<unsigned int> nozzle_cur_filament_ids(nozzle_nums, -1);
|
|
||||||
unsigned int current_filament_id = m_wipe_tower_data.tool_ordering.first_extruder();
|
unsigned int current_filament_id = m_wipe_tower_data.tool_ordering.first_extruder();
|
||||||
size_t cur_nozzle_id = filament_maps[current_filament_id] - 1;
|
// Initialize NozzleStatusRecorder with the first filament's carousel slot
|
||||||
nozzle_cur_filament_ids[cur_nozzle_id] = current_filament_id;
|
if (group_result) {
|
||||||
|
auto nozzle = group_result->get_nozzle_for_filament(current_filament_id, layer_idx);
|
||||||
|
if (nozzle)
|
||||||
|
nozzle_recorder.set_nozzle_status(nozzle->group_id, current_filament_id, nozzle->extruder_id);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
|
for (auto& layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
|
||||||
|
++layer_idx;
|
||||||
|
|
||||||
if (!layer_tools.has_wipe_tower) continue;
|
if (!layer_tools.has_wipe_tower) continue;
|
||||||
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
|
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
|
||||||
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, current_filament_id);
|
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, current_filament_id);
|
||||||
@@ -3993,30 +4006,73 @@ void Print::_make_wipe_tower()
|
|||||||
if (filament_id == current_filament_id)
|
if (filament_id == current_filament_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int nozzle_id = filament_maps[filament_id] - 1;
|
|
||||||
unsigned int pre_filament_id = nozzle_cur_filament_ids[nozzle_id];
|
|
||||||
|
|
||||||
float volume_to_purge = 0;
|
float volume_to_purge = 0;
|
||||||
if (pre_filament_id != (unsigned int)(-1) && pre_filament_id != filament_id) {
|
|
||||||
volume_to_purge = multi_extruder_flush[nozzle_id][pre_filament_id][filament_id];
|
// Reference to BBS: BambuStudio/src/libslic3r/Print.cpp L3361-3392
|
||||||
// Fast purge mode uses flush_multiplier_fast; Default is inert.
|
// Per-carousel-slot purge tracking via NozzleStatusRecorder
|
||||||
float flush_multiplier = (m_config.prime_volume_mode == PrimeVolumeMode::pvmFast) ? m_config.flush_multiplier_fast.get_at(nozzle_id)
|
if (group_result) {
|
||||||
: m_config.flush_multiplier.get_at(nozzle_id);
|
auto nozzle_info = group_result->get_nozzle_for_filament(filament_id, layer_idx);
|
||||||
|
if (nozzle_info) {
|
||||||
|
int extruder_id = nozzle_info->extruder_id;
|
||||||
|
int nozzle_id = nozzle_info->group_id;
|
||||||
|
int prev_nozzle_filament = nozzle_recorder.get_filament_in_nozzle(nozzle_id);
|
||||||
|
|
||||||
|
if (!nozzle_recorder.is_nozzle_empty(nozzle_id) &&
|
||||||
|
static_cast<int>(filament_id) != prev_nozzle_filament) {
|
||||||
|
volume_to_purge = multi_extruder_flush[extruder_id][prev_nozzle_filament][filament_id];
|
||||||
|
// Fast purge mode uses flush_multiplier_fast; Default is inert.
|
||||||
|
float flush_multiplier = (m_config.prime_volume_mode == PrimeVolumeMode::pvmFast)
|
||||||
|
? m_config.flush_multiplier_fast.get_at(extruder_id)
|
||||||
|
: m_config.flush_multiplier.get_at(extruder_id);
|
||||||
|
volume_to_purge *= flush_multiplier;
|
||||||
|
volume_to_purge = layer_tools.wiping_extrusions().mark_wiping_extrusions(
|
||||||
|
*this, current_filament_id, filament_id, volume_to_purge);
|
||||||
|
}
|
||||||
|
nozzle_recorder.set_nozzle_status(nozzle_id, filament_id, extruder_id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback: original Orca per-extruder path (non-carousel printers)
|
||||||
|
int nozzle_id = filament_maps[filament_id] - 1;
|
||||||
|
volume_to_purge = multi_extruder_flush[nozzle_id][current_filament_id][filament_id];
|
||||||
|
float flush_multiplier = (m_config.prime_volume_mode == PrimeVolumeMode::pvmFast)
|
||||||
|
? m_config.flush_multiplier_fast.get_at(nozzle_id)
|
||||||
|
: m_config.flush_multiplier.get_at(nozzle_id);
|
||||||
volume_to_purge *= flush_multiplier;
|
volume_to_purge *= flush_multiplier;
|
||||||
volume_to_purge = pre_filament_id == -1 ? 0 :
|
volume_to_purge = layer_tools.wiping_extrusions().mark_wiping_extrusions(
|
||||||
layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_filament_id, filament_id, volume_to_purge);
|
*this, current_filament_id, filament_id, volume_to_purge);
|
||||||
}
|
}
|
||||||
|
|
||||||
//During the filament change, the extruder will extrude an extra length of grab_length for the corresponding detection, so the purge can reduce this length.
|
//During the filament change, the extruder will extrude an extra length of grab_length for the corresponding detection, so the purge can reduce this length.
|
||||||
float grab_purge_volume = m_config.grab_length.get_at(nozzle_id) * 2.4; //(diameter/2)^2*PI=2.4
|
int grab_extruder_id = filament_maps[filament_id] - 1;
|
||||||
|
float grab_purge_volume = m_config.grab_length.get_at(grab_extruder_id) * 2.4; //(diameter/2)^2*PI=2.4
|
||||||
volume_to_purge = std::max(0.f, volume_to_purge - grab_purge_volume);
|
volume_to_purge = std::max(0.f, volume_to_purge - grab_purge_volume);
|
||||||
|
|
||||||
// Saving mode reduces the prime volume to 15 mm3; Default is inert.
|
// Reference to BBS: BambuStudio/src/libslic3r/Print.cpp L3381-3387
|
||||||
float prime_volume = (m_config.prime_volume_mode == PrimeVolumeMode::pvmSaving) ? 15.f : (float) m_config.prime_volume;
|
// Select prime volume per-filament: nozzle change (carousel rotation) uses
|
||||||
|
// filament_prime_volume_nc, filament change (same nozzle slot) uses filament_prime_volume.
|
||||||
|
// BBS passes both to plan_toolchange (7 args), we select the right one here (6 args).
|
||||||
|
float wipe_volume_ec = filament_id < m_config.filament_prime_volume.values.size()
|
||||||
|
? m_config.filament_prime_volume.values[filament_id]
|
||||||
|
: (float) m_config.prime_volume;
|
||||||
|
float wipe_volume_nc = filament_id < m_config.filament_prime_volume_nc.values.size()
|
||||||
|
? m_config.filament_prime_volume_nc.values[filament_id]
|
||||||
|
: (float) m_config.prime_volume;
|
||||||
|
|
||||||
|
float prime_volume = wipe_volume_ec;
|
||||||
|
if (group_result) {
|
||||||
|
bool is_nozzle_change = group_result->are_filaments_same_extruder(current_filament_id, filament_id, layer_idx) &&
|
||||||
|
!group_result->are_filaments_same_nozzle(current_filament_id, filament_id, layer_idx);
|
||||||
|
if (is_nozzle_change) {
|
||||||
|
prime_volume = wipe_volume_nc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_config.prime_volume_mode == PrimeVolumeMode::pvmSaving) {
|
||||||
|
prime_volume = 15.f;
|
||||||
|
}
|
||||||
|
|
||||||
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, filament_id,
|
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, filament_id,
|
||||||
prime_volume, volume_to_purge);
|
prime_volume, volume_to_purge);
|
||||||
current_filament_id = filament_id;
|
current_filament_id = filament_id;
|
||||||
nozzle_cur_filament_ids[nozzle_id] = filament_id;
|
|
||||||
}
|
}
|
||||||
layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this);
|
layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this);
|
||||||
|
|
||||||
|
|||||||
@@ -7995,6 +7995,15 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comDevelop;
|
def->mode = comDevelop;
|
||||||
def->set_default_value(new ConfigOptionBool(false));
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
|
// Reference to BBS: BambuStudio/src/libslic3r/PrintConfig.cpp L2617-2624
|
||||||
|
def = this->add("filament_prime_volume", coFloats);
|
||||||
|
def->label = L("Filament change");
|
||||||
|
def->tooltip = L("The volume of material required to prime the extruder on the tower, excluding a hotend change.");
|
||||||
|
def->sidetext = L("mm³");
|
||||||
|
def->min = 1.0;
|
||||||
|
def->mode = comSimple;
|
||||||
|
def->set_default_value(new ConfigOptionFloats{45.});
|
||||||
|
|
||||||
def = this->add("filament_prime_volume_nc", coFloats);
|
def = this->add("filament_prime_volume_nc", coFloats);
|
||||||
def->label = L("Hotend change");
|
def->label = L("Hotend change");
|
||||||
def->tooltip = L("The volume of material required to prime the extruder for a hotend change on the tower.");
|
def->tooltip = L("The volume of material required to prime the extruder for a hotend change on the tower.");
|
||||||
|
|||||||
@@ -1837,6 +1837,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||||||
// BBS: wipe tower is only used for priming
|
// BBS: wipe tower is only used for priming
|
||||||
((ConfigOptionFloat, prime_volume))
|
((ConfigOptionFloat, prime_volume))
|
||||||
// Nozzle-change (nc) prime volume + pre-heat delta
|
// Nozzle-change (nc) prime volume + pre-heat delta
|
||||||
|
// Reference to BBS: BambuStudio/src/libslic3r/PrintConfig.hpp L1524-1525
|
||||||
|
((ConfigOptionFloats, filament_prime_volume))
|
||||||
((ConfigOptionFloats, filament_prime_volume_nc))
|
((ConfigOptionFloats, filament_prime_volume_nc))
|
||||||
((ConfigOptionFloatsNullable, filament_preheat_temperature_delta))
|
((ConfigOptionFloatsNullable, filament_preheat_temperature_delta))
|
||||||
((ConfigOptionFloats, flush_multiplier))
|
((ConfigOptionFloats, flush_multiplier))
|
||||||
|
|||||||
1
tests/_orca-test-repo
Submodule
1
tests/_orca-test-repo
Submodule
Submodule tests/_orca-test-repo added at 0dfd8df467
Reference in New Issue
Block a user