From 66adc991a021b7f8f3c50835a0b2ef032c41eeeb Mon Sep 17 00:00:00 2001 From: "Justin F. Hallett" Date: Thu, 4 Jul 2024 15:12:20 -0600 Subject: [PATCH 1/2] Add 3 new gcode settings - Add bool to set if the start_gcode needs to be the first gcode run. Requires `machine_start_gcode_first` be added to the machine UI as a checkbox - Add a prestart_gcode to extruders, this will allow use set temperatures before the change call so we can preheat the next extruder. Requires `machine_extruder_prestart_code` text box be added to the extruder UI page. - Add a time duration to calculate time required to change extruders. Requires `machine_extruder_change_duration` float box to be added to the exturder UI page. - Fix a bug in the export code that was checking num_extruders instead of used_extruders, this was adding a tool change on start to T0 when only one extruder is used which we do not want, with one extruder it should output like normal and let the user choose the extruder they want to use. --- src/gcodeExport.cpp | 46 +++++++++++++++++++++++++++++++++------- src/sliceDataStorage.cpp | 6 ++++++ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/gcodeExport.cpp b/src/gcodeExport.cpp index 43fdc8ba3b..b508bc3e33 100644 --- a/src/gcodeExport.cpp +++ b/src/gcodeExport.cpp @@ -682,6 +682,11 @@ bool GCodeExport::initializeExtruderTrains(const SliceDataStorage& storage, cons writeComment("Generated with Cura_SteamEngine " CURA_ENGINE_VERSION); + if (mesh_group_settings.get("machine_start_gcode_first")) + { + writeCode(mesh_group_settings.get("machine_start_gcode").c_str()); + } + if (getFlavor() == EGCodeFlavor::GRIFFIN) { std::ostringstream tmp; @@ -693,8 +698,11 @@ bool GCodeExport::initializeExtruderTrains(const SliceDataStorage& storage, cons processInitialLayerTemperature(storage, start_extruder_nr); } + if (!mesh_group_settings.get("machine_start_gcode_first")) + { + writeCode(mesh_group_settings.get("machine_start_gcode").c_str()); + } writeExtrusionMode(false); // ensure absolute extrusion mode is set before the start gcode - writeCode(mesh_group_settings.get("machine_start_gcode").c_str()); // in case of shared nozzle assume that the machine-start gcode reset the extruders as per machine description if (Application::getInstance().current_slice_->scene.settings.get("machine_extruders_share_nozzle")) @@ -767,6 +775,8 @@ void GCodeExport::processInitialLayerTemperature(const SliceDataStorage& storage const bool material_print_temp_prepend = scene.current_mesh_group->settings.get("material_print_temp_prepend"); const bool material_print_temp_wait = scene.current_mesh_group->settings.get("material_print_temp_wait"); bool wait_start_extruder = false; + std::vector extruders_used = storage.getExtrudersUsed(); + size_t used_extruders = std::count(extruders_used.begin(), extruders_used.end(), true); switch (getFlavor()) { @@ -776,7 +786,7 @@ void GCodeExport::processInitialLayerTemperature(const SliceDataStorage& storage wait_start_extruder = true; break; default: - if (num_extruders > 1 || getFlavor() == EGCodeFlavor::REPRAP) + if (used_extruders > 1 || getFlavor() == EGCodeFlavor::REPRAP) { std::ostringstream tmp; tmp << "T" << start_extruder_nr; @@ -794,7 +804,6 @@ void GCodeExport::processInitialLayerTemperature(const SliceDataStorage& storage }; std::vector all_extruders; - std::vector extruders_used = storage.getExtrudersUsed(); for (size_t extruder_nr = 0; extruder_nr < extruders_used.size(); ++extruder_nr) { if (extruders_used[extruder_nr]) @@ -1267,6 +1276,29 @@ void GCodeExport::writeZhopEnd(Velocity speed /*= 0*/) void GCodeExport::startExtruder(const size_t new_extruder) { + const auto extruder_settings = Application::getInstance().current_slice_->scene.extruders[new_extruder].settings_; + const auto prestart_code = extruder_settings.get("machine_extruder_prestart_code"); + const auto start_code = extruder_settings.get("machine_extruder_start_code"); + const auto start_code_duration = extruder_settings.get("machine_extruder_start_code_duration"); + const auto extruder_change_duration = extruder_settings.get("machine_extruder_change_duration"); + + // Be nice to be able to calculate the extruder change time verses time + // to heat and run this so it's run before the change call. **Future note** + if (! prestart_code.empty()) + { + if (relative_extrusion_) + { + writeExtrusionMode(false); // ensure absolute extrusion mode is set before the prestart gcode + } + + writeCode(prestart_code.c_str()); + + if (relative_extrusion_) + { + writeExtrusionMode(true); // restore relative extrusion mode + } + } + extruder_attr_[new_extruder].is_used_ = true; if (new_extruder != current_extruder_) // wouldn't be the case on the very first extruder start if it's extruder 0 { @@ -1278,15 +1310,16 @@ void GCodeExport::startExtruder(const size_t new_extruder) { *output_stream_ << "T" << new_extruder << new_line_; } + // Only add time is we are actually changing extruders + estimate_calculator_.addTime(extruder_change_duration); } + estimate_calculator_.addTime(start_code_duration); current_extruder_ = new_extruder; assert(getCurrentExtrudedVolume() == 0.0 && "Just after an extruder switch we haven't extruded anything yet!"); resetExtrusionValue(); // zero the E value on the new extruder, just to be sure - const auto extruder_settings = Application::getInstance().current_slice_->scene.extruders[new_extruder].settings_; - const auto start_code = extruder_settings.get("machine_extruder_start_code"); if (! start_code.empty()) { if (relative_extrusion_) @@ -1302,9 +1335,6 @@ void GCodeExport::startExtruder(const size_t new_extruder) } } - const auto start_code_duration = extruder_settings.get("machine_extruder_start_code_duration"); - estimate_calculator_.addTime(start_code_duration); - Application::getInstance().communication_->setExtruderForSend(Application::getInstance().current_slice_->scene.extruders[new_extruder]); Application::getInstance().communication_->sendCurrentPosition(getPositionXY()); diff --git a/src/sliceDataStorage.cpp b/src/sliceDataStorage.cpp index 697721ccd0..729b9845b9 100644 --- a/src/sliceDataStorage.cpp +++ b/src/sliceDataStorage.cpp @@ -398,6 +398,12 @@ std::vector SliceDataStorage::getExtrudersUsed() const std::vector ret; ret.resize(Application::getInstance().current_slice_->scene.extruders.size(), false); + // set all the false to start, we set them to true if used + for (size_t extruder_nr = 0; extruder_nr < Application::getInstance().current_slice_->scene.extruders.size(); extruder_nr++) + { + ret[extruder_nr] = false; + } + const Settings& mesh_group_settings = Application::getInstance().current_slice_->scene.current_mesh_group->settings; const EPlatformAdhesion adhesion_type = mesh_group_settings.get("adhesion_type"); if (adhesion_type == EPlatformAdhesion::SKIRT || adhesion_type == EPlatformAdhesion::BRIM) From 2960fd6f2a0c31469967266372c2d6ed70f0c914 Mon Sep 17 00:00:00 2001 From: "Justin F. Hallett" Date: Sat, 10 Aug 2024 15:16:14 -0600 Subject: [PATCH 2/2] Fix merge issue --- src/gcodeExport.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gcodeExport.cpp b/src/gcodeExport.cpp index 9263c25e73..4eec8d6a5b 100644 --- a/src/gcodeExport.cpp +++ b/src/gcodeExport.cpp @@ -787,6 +787,7 @@ void GCodeExport::processInitialLayerExtrudersTemperatures(const SliceDataStorag }; std::vector all_extruders; + std::vector extruders_used = storage.getExtrudersUsed(); for (size_t extruder_nr = 0; extruder_nr < extruders_used.size(); ++extruder_nr) { if (extruders_used[extruder_nr])