mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-13 10:51:12 +00:00
Fix manual tool change handling when loading G-code files (#15379)
Opened or drag-dropped G-code files ignored `; MANUAL_TOOL_CHANGE` comments, so the preview showed every move on the first filament. Only `apply_config(const PrintConfig&)` read `manual_filament_change`, and loading a file goes through `apply_config(const DynamicPrintConfig&)`. Read the option there too, initialize the flag to false, and add a regression test.
This commit is contained in:
@@ -3598,6 +3598,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
|
||||
if (has_scarf_joint_seam != nullptr)
|
||||
m_detect_layer_based_on_tag = m_detect_layer_based_on_tag || has_scarf_joint_seam->value;
|
||||
|
||||
const ConfigOptionBool* manual_filament_change = config.option<ConfigOptionBool>("manual_filament_change");
|
||||
if (manual_filament_change != nullptr)
|
||||
m_manual_filament_change = manual_filament_change->value;
|
||||
|
||||
const ConfigOptionEnumGeneric *bed_type = config.option<ConfigOptionEnumGeneric>("curr_bed_type");
|
||||
if (bed_type != nullptr)
|
||||
m_result.bed_type = (BedType)bed_type->value;
|
||||
|
||||
@@ -1228,7 +1228,7 @@ inline constexpr float DEFAULT_FILAMENT_DENSITY = 1.245f;
|
||||
// m_result.nozzle_group_result, which is handed over only after the stream for the
|
||||
// pre-heat injector's second pass and gates the richer change-time model.
|
||||
std::shared_ptr<MultiNozzleUtils::NozzleGroupResultBase> m_nozzle_group_result;
|
||||
bool m_manual_filament_change;
|
||||
bool m_manual_filament_change{ false };
|
||||
|
||||
//BBS: x, y offset for gcode generated
|
||||
double m_x_offset{ 0 };
|
||||
|
||||
@@ -178,6 +178,61 @@ bool is_block_move(const GCodeProcessorResult::MoveVertex &move)
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Loaded manual tool change comments switch subsequent moves when enabled", "[GCodeProcessor][Regression]")
|
||||
{
|
||||
const bool manual_filament_change = GENERATE(false, true);
|
||||
CAPTURE(manual_filament_change);
|
||||
const DynamicPrintConfig config = Test::multifilament_config(2, {
|
||||
{ "gcode_flavor", "marlin" },
|
||||
{ "filament_type", "PLA;PETG" },
|
||||
{ "manual_filament_change", manual_filament_change },
|
||||
});
|
||||
const bool was_bbl_printer = GCodeProcessor::s_IsBBLPrinter;
|
||||
const ScopeGuard restore_bbl_printer([was_bbl_printer] { GCodeProcessor::s_IsBBLPrinter = was_bbl_printer; });
|
||||
GCodeProcessor::s_IsBBLPrinter = false;
|
||||
|
||||
ScopedTemporaryFile temp(".gcode");
|
||||
{
|
||||
std::ofstream out(temp.string());
|
||||
REQUIRE(out.is_open());
|
||||
out << "; generated by OrcaSlicer\n"
|
||||
<< "G90\nM83\nT0\n"
|
||||
<< "G1 X10 Y10 Z0.2 F3000\n"
|
||||
<< "G1 X20 E1\n"
|
||||
<< "; MANUAL_TOOL_CHANGE T1\n"
|
||||
<< "G1 X30\nG1 X40 E1\nG1 X50\nG1 X60 E1\n";
|
||||
// Let process_file load the embedded DynamicPrintConfig, as the standalone viewer does.
|
||||
out << "; CONFIG_BLOCK_START\n";
|
||||
for (const std::string &key : config.keys())
|
||||
out << "; " << key << " = " << config.opt_serialize(key) << '\n';
|
||||
out << "; CONFIG_BLOCK_END\n";
|
||||
REQUIRE(out.good());
|
||||
}
|
||||
|
||||
GCodeProcessor processor;
|
||||
processor.process_file(temp.string());
|
||||
const auto &result = processor.get_result();
|
||||
REQUIRE(result.filaments_count == 2);
|
||||
|
||||
constexpr unsigned int tool_change_line = 7;
|
||||
size_t before = 0;
|
||||
size_t after = 0;
|
||||
for (const auto &move : result.moves) {
|
||||
if (!is_block_move(move))
|
||||
continue;
|
||||
CAPTURE(move.gcode_id, move.type);
|
||||
if (move.gcode_id < tool_change_line) {
|
||||
++before;
|
||||
CHECK(move.extruder_id == 0);
|
||||
} else if (move.gcode_id > tool_change_line) {
|
||||
++after;
|
||||
CHECK(move.extruder_id == (manual_filament_change ? 1 : 0));
|
||||
}
|
||||
}
|
||||
REQUIRE(before > 0);
|
||||
REQUIRE(after > 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Actual speed moves are inserted on their block's segment just before its move", "[GCodeProcessor]")
|
||||
{
|
||||
// 60 squares take several planner passes, which remap the blocks kept between passes.
|
||||
|
||||
Reference in New Issue
Block a user