Misc updates and clean up

- WipeTower: use filament_ramming_volumetric_speed(_nc) for ramming, falling back to
  max_vol_speed only when nil; gate precool temps on enable_pre_heating
- ToolOrderUtils: disable the inter-layer forecast in the per-nozzle base reorder so
  H2D/H2C ordering is unchanged
- PrintConfig: stop stripping filament_prime_volume in handle_legacy; document that
  prime_volume drives the Type2 wipe tower and filament_prime_volume the Type1 one
- GCodeProcessor: exclude post-print end-gcode M400 dwells from the M73 estimate and
  drop the dead air-filtration state
- Trim verbose BambuStudio source-location comments across the port
This commit is contained in:
SoftFever
2026-07-20 17:26:38 +08:00
parent 65ab9b61a8
commit 9b5eb76478
8 changed files with 53 additions and 100 deletions

View File

@@ -1529,15 +1529,7 @@ void GCodeProcessor::run_post_process()
tag.remove_suffix(1);
tag.remove_prefix(1); // strip leading ';'
if (tag == Machine_Start_GCode_End_Tag) { m_machine_start_gcode_end_line_id = line_id; return; }
if (tag == Machine_End_GCode_Start_Tag) {
m_machine_end_gcode_start_line_id = line_id;
// End gcode M400 delays (air purification, timelapse, sound) are post-print
// by definition. Skip them so M73 reports print completion time.
// Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp —
// BBS drops leftover in calculate_time(is_final=true), achieving the same.
m_skip_end_gcode_delays = true;
return;
}
if (tag == Machine_End_GCode_Start_Tag) { m_machine_end_gcode_start_line_id = line_id; return; }
}
// filament-change commands: T<fid>, ;VT<fid>, M1020 S<fid>, each optionally " H<nozzle_id>"
@@ -2932,8 +2924,6 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_preheat_steps = 1;
m_result.backtrace_enabled = config.ooze_prevention && m_preheat_time > 0 && (m_is_XL_printer || (!m_single_extruder_multi_material && filament_count > 1));
m_support_air_filtration = config.support_air_filtration.value;
assert(config.nozzle_volume.size() == config.nozzle_diameter.size());
m_nozzle_volume.resize(config.nozzle_volume.size());
for (size_t idx = 0; idx < config.nozzle_volume.size(); ++idx)
@@ -3087,10 +3077,6 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
const ConfigOptionInt *nozzle_HRC = config.option<ConfigOptionInt>("nozzle_hrc");
if (nozzle_HRC != nullptr) m_result.nozzle_hrc = nozzle_HRC->value;
const ConfigOptionBool *support_air_filt = config.option<ConfigOptionBool>("support_air_filtration");
if (support_air_filt != nullptr)
m_support_air_filtration = support_air_filt->value;
const ConfigOptionInts* physical_extruder_map = config.option<ConfigOptionInts>("physical_extruder_map");
if (physical_extruder_map != nullptr) {
m_physical_extruder_map = physical_extruder_map->values;
@@ -3508,7 +3494,6 @@ void GCodeProcessor::reset()
m_extruder_blocks.clear();
m_machine_start_gcode_end_line_id = (unsigned int) (-1);
m_machine_end_gcode_start_line_id = (unsigned int) (-1);
m_support_air_filtration = false;
m_skip_end_gcode_delays = false;
m_remaining_volume = std::vector<float>(MAXIMUM_EXTRUDER_NUMBER, 0.f);
@@ -4237,10 +4222,9 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
return;
}
// End gcode marker: skip M400 S/P delays after this point so M73 reports
// print completion time, not post-print filtration/cooldown time.
// Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp —
// BBS drops leftover in calculate_time(is_final=true), achieving the same.
// End gcode marker: skip post-print M400 S/P dwells after this point so the M73 estimate reports
// print-completion time, not post-print filtration/cooldown. BBS drops the same remainder in
// calculate_time(is_final).
if (comment == Machine_End_GCode_Start_Tag) {
m_skip_end_gcode_delays = true;
return;
@@ -6428,18 +6412,10 @@ void GCodeProcessor::process_M400(const GCodeReader::GCodeLine& line)
float value_p = 0.0;
if (line.has_value('S', value_s) || line.has_value('P', value_p)) {
value_s += value_p * 0.001;
// End gcode M400 delays (air purification M400 S180, timelapse M400 S5,
// sound M400 S1) are post-print by definition. Skip them so M73 reports
// print completion time, not post-print filtration/cooldown time.
// Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp —
// BBS drops leftover in calculate_time(is_final=true), achieving the same
// effect of excluding end gcode delays from M73 total. We skip at the
// source instead, leaving calculate_time unchanged for all printers.
// Skip post-print end-gcode dwells so they don't inflate the M73 estimate (see
// m_skip_end_gcode_delays). Only omits dwell time — no state is updated here.
if (m_skip_end_gcode_delays)
return;
simulate_st_synchronize(value_s);
}
}

View File

@@ -1109,14 +1109,9 @@ class Print;
std::vector<ExtruderPreHeating::ExtruderUsageBlcok> m_extruder_blocks;
unsigned int m_machine_start_gcode_end_line_id{ (unsigned int) (-1) };
unsigned int m_machine_end_gcode_start_line_id{ (unsigned int) (-1) };
// End gcode M400 delays (air purification, timelapse, sound) are post-print
// by definition. M73 should report print completion time, not post-print time.
// m_skip_end_gcode_delays is set when MACHINE_END_GCODE_START tag is encountered
// during the streaming parse (process_tags), telling process_M400 to skip timed
// delays in the end gcode scope.
// Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp —
// BBS drops leftover in calculate_time(is_final=true), achieving the same effect.
bool m_support_air_filtration{ false };
// Set when the MACHINE_END_GCODE_START tag is seen during the streaming parse; tells
// process_M400 to skip post-print end-gcode dwells (air purification, timelapse, sound)
// so they don't inflate the M73 estimate. BBS excludes them in calculate_time(is_final).
bool m_skip_end_gcode_delays{ false };
// Tracks, during the stream, which filament sits in each physical nozzle and which nozzle each
// extruder currently carries. Written by both branches of the two-arg process_filament_change

View File

@@ -1098,8 +1098,10 @@ namespace Slic3r
// This avoids expensive inter-layer transitions (e.g. ending layer with F2 when
// next layer starts with F3, costing flush[F2→F3], instead of ending with F3
// which gives flush[F3→F3]=0). Limited to ≤5 filaments due to O(N!×M!) complexity.
// Matches the multi-extruder path behavior (ToolOrderUtils.cpp:1227).
bool use_forcast = (filament_used.size() <= max_n_with_forcast && filament_used_next_layer.size() <= max_n_with_forcast);
// The per-nozzle base reorder does not use the inter-layer forecast. This function drives
// BBL multi-extruder grouping cost and H2C ordering, so keeping it false avoids perturbing
// existing H2D/H2C output.
bool use_forcast = false;
float tmp_cost = 0;
std::vector<unsigned int> sequence;
uint128_t hash_key = filament_list_to_hash_key(filament_used, filament_used_next_layer, curr_filament_id, use_forcast);

View File

@@ -1610,27 +1610,31 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
m_filpar[idx].max_e_speed = (max_vol_speed / filament_area());
// Vortek H2C: carousel-specific ramming, precool, and reverse travel parameters
// Matches BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp L1878-1932
{
// Ramming speed: .first = extruder change, .second = nozzle change (carousel)
float ramming_vol_speed = float(config.filament_max_volumetric_speed.get_at(idx));
if (config.filament_max_volumetric_speed.is_nil(idx) || ramming_vol_speed < EPSILON)
// Use the dedicated ramming volumetric speed, falling back to max_vol_speed only when
// the setting is nil/-1.
float ramming_vol_speed = float(config.filament_ramming_volumetric_speed.get_at(idx));
if (config.filament_ramming_volumetric_speed.is_nil(idx) || is_approx(config.filament_ramming_volumetric_speed.get_at(idx), -1.))
ramming_vol_speed = max_vol_speed;
m_filpar[idx].max_e_ramming_speed.first = (ramming_vol_speed / filament_area());
float ramming_vol_speed_nc = ramming_vol_speed; // default: same as extruder change
if (!config.filament_ramming_volumetric_speed_nc.is_nil(idx)
&& !is_approx(config.filament_ramming_volumetric_speed_nc.get_at(idx), -1.))
ramming_vol_speed_nc = float(config.filament_ramming_volumetric_speed_nc.get_at(idx));
float ramming_vol_speed_nc = float(config.filament_ramming_volumetric_speed_nc.get_at(idx));
if (config.filament_ramming_volumetric_speed_nc.is_nil(idx) || is_approx(config.filament_ramming_volumetric_speed_nc.get_at(idx), -1.))
ramming_vol_speed_nc = max_vol_speed;
m_filpar[idx].max_e_ramming_speed.second = (ramming_vol_speed_nc / filament_area());
}
{
// Precool target temp: .first = extruder change, .second = nozzle change (carousel)
// Precool is only active when enable_pre_heating is on; otherwise no precool temp/timing is
// applied and the downstream precool_t stays 0, matching printers with pre-heating disabled.
m_filpar[idx].precool_target_temp = {0, 0};
if (!config.filament_pre_cooling_temperature.is_nil(idx))
m_filpar[idx].precool_target_temp.first = config.filament_pre_cooling_temperature.get_at(idx);
if (!config.filament_pre_cooling_temperature_nc.is_nil(idx))
m_filpar[idx].precool_target_temp.second = config.filament_pre_cooling_temperature_nc.get_at(idx);
if (config.enable_pre_heating.value) {
if (!config.filament_pre_cooling_temperature.is_nil(idx) && config.filament_pre_cooling_temperature.get_at(idx) != 0)
m_filpar[idx].precool_target_temp.first = config.filament_pre_cooling_temperature.get_at(idx);
if (!config.filament_pre_cooling_temperature_nc.is_nil(idx) && config.filament_pre_cooling_temperature_nc.get_at(idx) != 0)
m_filpar[idx].precool_target_temp.second = config.filament_pre_cooling_temperature_nc.get_at(idx);
}
}
{
// Precool timing: (nozzle_temp - precool_temp) / hotend_cooling_rate
@@ -2600,8 +2604,6 @@ void WipeTower::plan_toolchange(float z_par, float layer_height_par, unsigned in
nozzle_change_depth = nozzle_change_line_count * m_nozzle_change_perimeter_width;
depth += nozzle_change_depth;
}
// Vortek H2C override: carousel rotation (same extruder, different nozzle) also needs ramming depth
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp plan_toolchange() L2862 is_need_ramming()
if (nozzle_change_depth == 0
&& !m_filament_nozzle_map.empty()
&& old_tool < m_filament_nozzle_map.size() && new_tool < m_filament_nozzle_map.size()
@@ -2764,7 +2766,6 @@ bool WipeTower::is_petg_filament(int filament_id) const
return m_filpar[filament_id].material == "PETG";
}
// Matches BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp L3080-3085
bool WipeTower::is_need_reverse_travel(int filament_id, bool extruder_change) const
{
if (extruder_change)
@@ -2896,11 +2897,6 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool, bool sol
&& is_valid_last_layer(m_current_tool, m_cur_layer_id, m_z_pos)) {
m_nozzle_change_result = nozzle_change_new(m_current_tool, new_tool, solid_nozzlechange);
}
// Vortek H2C override: also trigger nozzle_change for carousel rotations within same extruder.
// Original Orca code above only checks m_filament_map (extruder-level). For H2C carousel,
// filaments on the same extruder but different nozzles also need ramming.
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp tool_change_new() L3244
// BBS uses is_need_ramming() = !are_filaments_same_nozzle() for nozzle-level gating.
if (m_nozzle_change_result.gcode.empty()
&& !m_filament_nozzle_map.empty()
&& m_current_tool < m_filament_nozzle_map.size() && new_tool < m_filament_nozzle_map.size()
@@ -3072,11 +3068,7 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id,
}
float nz_extrusion_flow = nozzle_change_extrusion_flow(m_layer_height);
// Vortek H2C: carousel barrier inside nozzle change zone (emit M632/M633 ONLY for carousel = !extruder_change)
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp ramming() L3421-3429
bool extruder_change = !is_in_same_extruder(old_filament_id, new_filament_id);
// Vortek H2C: use carousel-specific ramming speed when available
// Matches BBS: ramming() L3435-3436 — max_e_ramming_speed.first (ext change) / .second (carousel)
float max_e_ramming = extruder_change
? m_filpar[m_current_tool].max_e_ramming_speed.first
: m_filpar[m_current_tool].max_e_ramming_speed.second;
@@ -3098,7 +3090,6 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id,
if (!extruder_change && m_is_multiple_nozzle) {
writer.append("M632 S" + std::to_string(new_filament_id) + " M N\n");
// BBS L3425-3428: precool departing hotend + fan on inside barrier
// Use m_physical_extruder_map for heater index (matches format_line_M104 in add_M104_by_requirement)
if (m_filpar[m_current_tool].precool_target_temp.second != 0) {
int logical_ext = m_filament_map.empty() ? 0 : m_filament_map[m_current_tool] - 1;
@@ -3136,10 +3127,6 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id,
nozzle_change_line_count = solid_infill ? std::numeric_limits<int>::max() : nozzle_change_line_count;
m_left_to_right = true;
// Vortek H2C: per_cooling_max_speed — clamp ramming speed by cooldown time
// so departing nozzle reaches precool_target_temp before carousel rotation.
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp ramming() L3449-3462
// BBS: "nozzle change does not require forcing a cooldown" — only extruder changes need this.
if (extruder_change) {
float ramming_length = nozzle_change_line_count * (xr - xl);
int extruder_id = m_filament_map.empty() ? 0 : m_filament_map[m_current_tool] - 1;
@@ -3188,16 +3175,14 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id,
block->last_nozzle_change_id = old_filament_id;
NozzleChangeResult result;
// Vortek H2C: re-arm carousel barrier + reverse travel (BBS ramming() L3493-3535)
if (!extruder_change && m_is_multiple_nozzle) {
writer.append("M632 S" + std::to_string(new_filament_id) + " M N\n");
}
if (is_need_reverse_travel(m_current_tool, extruder_change)) {
// BBS L3499-3526: reverse travel without extrusion back through ramming zone
bool left_to_right = !m_left_to_right;
int tpu_line_count = real_nozzle_change_line_count;
float reverse_speed = nozzle_change_speed * 2; // BBS L3502
float reverse_speed = nozzle_change_speed * 2; // reverse travel runs at double the nozzle-change speed
float rt_time = extruder_change ? m_filpar[m_current_tool].ramming_travel_time.first
: m_filpar[m_current_tool].ramming_travel_time.second;
float need_reverse_travel_dis = rt_time * reverse_speed / 60.f;
@@ -3256,7 +3241,6 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id,
result.origin_start_pos = initial_position;
result.end_pos = writer.pos_rotated();
result.gcode = writer.gcode();
// Matches BBS: result.is_extruder_change = extruder_change (ramming() L3544)
result.is_extruder_change = extruder_change;
return result;
}
@@ -3697,7 +3681,6 @@ void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinat
buffer += '\n';
return buffer;
};
// Matches BBS: toolchange_wipe_new L4039 — add_M104_by_requirement fires for BOTH carousel and extruder changes.
// m_is_multiple_nozzle gate needed because Orca calls toolchange_wipe_new for ALL printers (BBS has it H2C-only).
bool should_heating = m_is_multiple_nozzle && m_filpar[m_current_tool].filament_cooling_before_tower > EPSILON &&
!solid_tool_toolchange && !is_first_layer();
@@ -3880,8 +3863,6 @@ bool WipeTower::is_in_same_extruder(int filament_id_1, int filament_id_2)
return m_filament_map[filament_id_1] == m_filament_map[filament_id_2];
}
// Vortek H2C: format BBS-compatible NOZZLE_CHANGE_START/END tag with OF/NF/ON/NN payload.
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp format_nozzle_change_line() L3388
std::string WipeTower::format_nozzle_change_tag(bool start, int old_filament_id, int new_filament_id) const
{
const std::string &tag = start ? GCodeProcessor::Nozzle_Change_Start_Tag : GCodeProcessor::Nozzle_Change_End_Tag;
@@ -4092,8 +4073,6 @@ void WipeTower::plan_tower_new()
nozzle_change_depth = nozzle_change_line_count * m_nozzle_change_perimeter_width;
depth += nozzle_change_depth;
}
// Vortek H2C override: carousel rotation also needs ramming depth
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp plan_tower_new() uses is_need_ramming()
if (nozzle_change_depth == 0
&& !m_filament_nozzle_map.empty()
&& toolchange.old_tool < (int)m_filament_nozzle_map.size() && toolchange.new_tool < (int)m_filament_nozzle_map.size()

View File

@@ -58,7 +58,6 @@ public:
Vec2f origin_start_pos; // not rotated
std::vector<Vec2f> wipe_path;
// Matches BBS: BambuStudio/src/libslic3r/GCode/WipeTower.hpp NozzleChangeResult::is_extruder_change
bool is_extruder_change{true};
};
@@ -312,7 +311,6 @@ public:
void set_filament_map(const std::vector<int> &filament_map) { m_filament_map = filament_map; }
// Vortek H2C: filament_id → physical nozzle_id for carousel rotation detection
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.hpp set_nozzle_group_result()
void set_filament_nozzle_map(const std::vector<int> &nozzle_map) { m_filament_nozzle_map = nozzle_map; }
void set_has_tpu_filament(bool has_tpu) { m_has_tpu_filament = has_tpu; }
@@ -361,8 +359,6 @@ public:
// Distance (in mm of filament) that a hotend is allowed to pre-cool before the
// tower is reached; drives the prime-tower heating-during-wipe model (multi-nozzle only).
float filament_cooling_before_tower = 0.f;
// Matches BBS: BambuStudio/src/libslic3r/GCode/WipeTower.hpp L335-339
// Carousel-specific ramming, precool, and reverse travel parameters.
// .first = extruder change, .second = nozzle change (carousel)
std::pair<float,float> max_e_ramming_speed{0.f, 0.f};
std::pair<float,float> ramming_travel_time{0.f, 0.f};
@@ -409,7 +405,6 @@ public:
int get_filament_category(int filament_id);
bool is_in_same_extruder(int filament_id_1, int filament_id_2);
// Vortek H2C: format BBS-compatible NOZZLE_CHANGE_START/END tag with OF/NF/ON/NN payload
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp format_nozzle_change_line()
std::string format_nozzle_change_tag(bool start, int old_filament_id, int new_filament_id) const;
void reset_block_status();
int get_wall_filament_for_all_layer();
@@ -572,7 +567,6 @@ private:
bool is_tpu_filament(int filament_id) const;
bool is_petg_filament(int filament_id) const;
// Matches BBS: BambuStudio/src/libslic3r/GCode/WipeTower.cpp L3080-3085
bool is_need_reverse_travel(int filament_id, bool extruder_change) const;
// BBS

View File

@@ -4018,7 +4018,6 @@ void Print::_make_wipe_tower()
wipe_tower.set_has_tpu_filament(this->has_tpu_filament());
wipe_tower.set_filament_map(this->get_filament_maps());
// Vortek H2C: pass nozzle-level map for carousel rotation detection in tool_change_new()
// Reference to BBS: BambuStudio/src/libslic3r/GCode/WipeTower.hpp set_nozzle_group_result()
wipe_tower.set_filament_nozzle_map(this->get_filament_nozzle_maps());
// Feed the has_filament_switcher device flag (develop-only dynamic key, read defensively from
// the full config — no shipping profile sets it) and the shared printable bed used by the PETG
@@ -4055,12 +4054,14 @@ void Print::_make_wipe_tower()
multi_extruder_flush.emplace_back(wipe_volumes);
}
// 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;
// Fallback (group_result == null) per-physical-nozzle tracking, matching the original
// pre-port behavior: remembers the last filament loaded in each physical nozzle slot.
std::vector<unsigned int> nozzle_cur_filament_ids(nozzle_nums, (unsigned int) -1);
std::vector<int>filament_maps = get_filament_maps();
int layer_idx = -1;
@@ -4071,6 +4072,9 @@ void Print::_make_wipe_tower()
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);
} else {
size_t cur_nozzle_id = filament_maps[current_filament_id] - 1;
nozzle_cur_filament_ids[cur_nozzle_id] = current_filament_id;
}
for (auto& layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
@@ -4088,7 +4092,6 @@ void Print::_make_wipe_tower()
float volume_to_purge = 0;
// Reference to BBS: BambuStudio/src/libslic3r/Print.cpp L3361-3392
// Per-carousel-slot purge tracking via NozzleStatusRecorder
if (group_result) {
auto nozzle_info = group_result->get_nozzle_for_filament(filament_id, layer_idx);
@@ -4111,15 +4114,21 @@ void Print::_make_wipe_tower()
nozzle_recorder.set_nozzle_status(nozzle_id, filament_id, extruder_id);
}
} else {
// Fallback: original Orca per-extruder path (non-carousel printers)
// Fallback: original Orca per-physical-nozzle path (non-carousel printers).
// Flush source is the last filament that occupied THIS nozzle, guarded so the
// first use of a nozzle incurs no flush.
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 = layer_tools.wiping_extrusions().mark_wiping_extrusions(
*this, current_filament_id, filament_id, volume_to_purge);
unsigned int pre_filament_id = nozzle_cur_filament_ids[nozzle_id];
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];
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 = layer_tools.wiping_extrusions().mark_wiping_extrusions(
*this, current_filament_id, filament_id, volume_to_purge);
}
nozzle_cur_filament_ids[nozzle_id] = filament_id;
}
//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.
@@ -4127,10 +4136,8 @@ void Print::_make_wipe_tower()
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);
// Reference to BBS: BambuStudio/src/libslic3r/Print.cpp L3381-3387
// 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;

View File

@@ -7384,7 +7384,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("The flush multiplier used in fast purge mode.");
def->set_default_value(new ConfigOptionFloats{1.2});
// BBS
// Orca: used by the generic (Type2) wipe tower; also the fallback for filament_prime_volume on Type1.
def = this->add("prime_volume", coFloat);
def->label = L("Prime volume");
def->tooltip = L("This is the volume of material to prime the extruder with on the tower.");
@@ -8030,7 +8030,8 @@ void PrintConfigDef::init_fff_params()
def->mode = comDevelop;
def->set_default_value(new ConfigOptionBool(false));
// Reference to BBS: BambuStudio/src/libslic3r/PrintConfig.cpp L2617-2624
// Used by the Type1 wipe tower: filament_prime_volume on a filament change,
// filament_prime_volume_nc on a hotend/nozzle change. Type2 uses prime_volume instead.
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.");
@@ -9059,7 +9060,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
"retraction_distance_when_cut",
"internal_bridge_support_thickness", "top_area_threshold", "reduce_wall_solid_infill","filament_load_time","filament_unload_time",
"smooth_coefficient", "overhang_totally_speed", "silent_mode",
"overhang_speed_classic", "filament_prime_volume",
"overhang_speed_classic",
"anisotropic_surfaces", // superseded by top_surface_fill_order / bottom_surface_fill_order
};

View File

@@ -1841,7 +1841,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
// BBS: wipe tower is only used for priming
((ConfigOptionFloat, prime_volume))
// 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))
((ConfigOptionFloatsNullable, filament_preheat_temperature_delta))