mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-10 17:21:10 +00:00
feat: firmware-agnostic per-tool PA emission for IMEX parallel modes
Extends set_pressure_advance() with an optional tool index (default -1, preserving existing behavior for all non-IMEX call sites). Per-firmware: - Klipper: EXTRUDER=extruder[N] when tool >= 0, bare command otherwise - RRF: M572 D<N> when tool >= 0, bare M572 otherwise (no D0 fallback) - Marlin 2: M900 K<X> T<N> when tool >= 0, bare M900 otherwise - Marlin Legacy / fallback: M900 K<X> always Adds m_imex_parallel_mode to GCode, set once per export from the active plate mode. PA and layer-transition temperature tool-qualification are gated on this being a non-primary parallel mode — primary mode prints use regular tool-change PA exactly like any non-IMEX printer. Secondary active tools in parallel modes receive explicit per-tool PA at print start since they never go through a tool-change sequence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
84fc851846
commit
af59501f4a
+26
-10
@@ -3094,9 +3094,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
std::string imex_active_mode;
|
||||
int imex_active_mode_index = 0;
|
||||
std::string imex_active_mode_gcode;
|
||||
m_imex_parallel_mode.clear();
|
||||
if (print.config().is_imex.value && !print.objects().empty()) {
|
||||
const std::string& raw = print.objects().front()->config().imex_parallel_mode.value;
|
||||
imex_active_mode = raw.empty() ? "primary" : raw;
|
||||
m_imex_parallel_mode = imex_active_mode;
|
||||
const auto& mode_names = print.config().imex_mode_names.values;
|
||||
const auto& mode_gcodes = print.config().imex_mode_gcodes.values;
|
||||
for (size_t i = 0; i < mode_names.size(); ++i) {
|
||||
@@ -3161,13 +3163,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
// mark the first filament used in print
|
||||
file.write_format(";VT%d\n", initial_extruder_id);
|
||||
}
|
||||
// Orca: add missing PA settings for initial filament
|
||||
if (m_config.enable_pressure_advance.get_at(initial_non_support_extruder_id)) {
|
||||
file.write(m_writer.set_pressure_advance(m_config.pressure_advance.get_at(initial_non_support_extruder_id)));
|
||||
// Orca: Adaptive PA
|
||||
// Reset Adaptive PA processor last PA value
|
||||
m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(initial_non_support_extruder_id));
|
||||
}
|
||||
}
|
||||
|
||||
//flush FanMover buffer to avoid modifying the start gcode if it's manual.
|
||||
@@ -3227,6 +3222,19 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
// Set initial extruder only after custom start G-code.
|
||||
// Ugly hack: Do not set the initial extruder if the extruder is primed using the MMU priming towers at the edge of the print bed.
|
||||
file.write(this->set_extruder(initial_extruder_id, 0.));
|
||||
|
||||
// IMEX parallel modes only: emit PA for all secondary active tools.
|
||||
// In primary mode, regular tool-change PA handles each tool as it becomes active.
|
||||
// In parallel modes no tool changes occur, so every carriage must be addressed
|
||||
// explicitly here before printing starts.
|
||||
if (!m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary") {
|
||||
for (int tool_idx : get_imex_active_tools(print)) {
|
||||
if (tool_idx == (int)initial_extruder_id) continue;
|
||||
if (!print.config().enable_pressure_advance.get_at(tool_idx)) continue;
|
||||
file.write(m_writer.set_pressure_advance(
|
||||
print.config().pressure_advance.get_at(tool_idx), tool_idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
// BBS: set that indicates objs with brim
|
||||
for (auto iter = print.m_brimMap.begin(); iter != print.m_brimMap.end(); ++iter) {
|
||||
@@ -4678,7 +4686,8 @@ LayerResult GCode::process_layer(
|
||||
// IMEX parallel modes: secondary carriages (T1-T3) never receive tool-change commands,
|
||||
// so they're not in m_writer.extruders() and multiple_extruders==false (max id==0).
|
||||
// Use the static set_temperature path for IMEX so the T index is always emitted.
|
||||
if (print.config().is_imex.value) {
|
||||
// In primary mode, fall through to the standard path — tool changes handle temps normally.
|
||||
if (!m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary") {
|
||||
// All active tools need explicit temps — none receive tool-change commands,
|
||||
// so we can't rely on the condition used for non-IMEX (temp != initial_layer_temp).
|
||||
// A tool whose initial and regular temps are the same still needs to be set here.
|
||||
@@ -7550,7 +7559,12 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
|
||||
}
|
||||
|
||||
if (m_config.enable_pressure_advance.get_at(new_filament_id)) {
|
||||
gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id));
|
||||
// In IMEX parallel modes each carriage needs an explicit tool address.
|
||||
// In primary mode (single active tool) regular tool changes handle PA
|
||||
// so no qualifier is needed — same as a non-IMEX printer.
|
||||
const bool imex_parallel = !m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary";
|
||||
const int pa_tool = imex_parallel ? (int)new_filament_id : -1;
|
||||
gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id), pa_tool);
|
||||
// Orca: Adaptive PA
|
||||
// Reset Adaptive PA processor last PA value
|
||||
m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(new_filament_id));
|
||||
@@ -7849,7 +7863,9 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
|
||||
gcode += m_ooze_prevention.post_toolchange(*this);
|
||||
|
||||
if (m_config.enable_pressure_advance.get_at(new_filament_id)) {
|
||||
gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id));
|
||||
const bool imex_parallel = !m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary";
|
||||
const int pa_tool = imex_parallel ? (int)new_filament_id : -1;
|
||||
gcode += m_writer.set_pressure_advance(m_config.pressure_advance.get_at(new_filament_id), pa_tool);
|
||||
// Orca: Adaptive PA
|
||||
// Reset Adaptive PA processor last PA value
|
||||
m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(new_filament_id));
|
||||
|
||||
@@ -592,6 +592,11 @@ private:
|
||||
|
||||
std::unique_ptr<AdaptivePAProcessor> m_pa_processor;
|
||||
|
||||
// IMEX: active parallel mode name ("primary", "copy", "iq-copy", etc.).
|
||||
// Set at the start of export. Empty string means non-IMEX or not yet set.
|
||||
// PA and temperature tool-qualification is only applied when this is not "primary".
|
||||
std::string m_imex_parallel_mode;
|
||||
|
||||
std::unique_ptr<WipeTowerIntegration> m_wipe_tower;
|
||||
|
||||
std::unique_ptr<SmallAreaInfillFlowCompensator> m_small_area_infill_flow_compensator;
|
||||
|
||||
@@ -351,22 +351,39 @@ std::string GCodeWriter::set_junction_deviation(double junction_deviation){
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
std::string GCodeWriter::set_pressure_advance(double pa) const
|
||||
std::string GCodeWriter::set_pressure_advance(double pa, int tool) const
|
||||
{
|
||||
std::ostringstream gcode;
|
||||
if (pa < 0)
|
||||
return gcode.str();
|
||||
if(m_is_bbl_printers){
|
||||
//SoftFever: set L1000 to use linear model
|
||||
gcode << "M900 K" <<std::setprecision(4)<< pa << " L1000 M10 ; Override pressure advance value\n";
|
||||
}
|
||||
else{
|
||||
if (FLAVOR_IS(gcfKlipper))
|
||||
gcode << "SET_PRESSURE_ADVANCE ADVANCE=" << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else if(FLAVOR_IS(gcfRepRapFirmware))
|
||||
gcode << ("M572 D0 S") << std::setprecision(4) << pa << "; Override pressure advance value\n";
|
||||
else
|
||||
gcode << "M900 K" <<std::setprecision(4)<< pa << "; Override pressure advance value\n";
|
||||
if (m_is_bbl_printers) {
|
||||
// SoftFever: set L1000 to use linear model
|
||||
gcode << "M900 K" << std::setprecision(4) << pa << " L1000 M10 ; Override pressure advance value\n";
|
||||
} else if (FLAVOR_IS(gcfKlipper)) {
|
||||
// Klipper routes PA by extruder name, not active tool.
|
||||
// Convention: first extruder is "extruder", subsequent are "extruder1", "extruder2", etc.
|
||||
gcode << "SET_PRESSURE_ADVANCE ADVANCE=" << std::setprecision(4) << pa;
|
||||
if (tool > 0)
|
||||
gcode << " EXTRUDER=extruder" << tool;
|
||||
else if (tool == 0)
|
||||
gcode << " EXTRUDER=extruder";
|
||||
gcode << " ; Override pressure advance value\n";
|
||||
} else if (FLAVOR_IS(gcfRepRapFirmware)) {
|
||||
// RRF: M572 without D applies to the current tool; with D targets a specific extruder.
|
||||
// Use D only when an explicit tool index is provided (IMEX parallel modes).
|
||||
gcode << "M572";
|
||||
if (tool >= 0)
|
||||
gcode << " D" << tool;
|
||||
gcode << " S" << std::setprecision(4) << pa << " ; Override pressure advance value\n";
|
||||
} else if (FLAVOR_IS(gcfMarlinFirmware)) {
|
||||
// Marlin 2.x supports T parameter for per-extruder LA
|
||||
gcode << "M900 K" << std::setprecision(4) << pa;
|
||||
if (tool >= 0)
|
||||
gcode << " T" << tool;
|
||||
gcode << " ; Override pressure advance value\n";
|
||||
} else {
|
||||
// Marlin Legacy and everything else: single-extruder M900, no tool parameter
|
||||
gcode << "M900 K" << std::setprecision(4) << pa << " ; Override pressure advance value\n";
|
||||
}
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
// Orca: set acceleration and jerk in one command for Klipper
|
||||
std::string set_accel_and_jerk(unsigned int acceleration, double jerk);
|
||||
std::string set_junction_deviation(double junction_deviation);
|
||||
std::string set_pressure_advance(double pa) const;
|
||||
std::string set_pressure_advance(double pa, int tool = -1) const;
|
||||
std::string set_input_shaping(char axis, float damp, float freq, std::string type) const;
|
||||
std::string reset_e(bool force = false);
|
||||
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
|
||||
|
||||
Reference in New Issue
Block a user