Skip to content

Commit

Permalink
Merge branch 'main' into CURA-11804_fix_90_overhang_crash
Browse files Browse the repository at this point in the history
  • Loading branch information
HellAholic authored Jul 3, 2024
2 parents d0ade56 + 2274d30 commit c08f517
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 35 deletions.
32 changes: 24 additions & 8 deletions include/gcodeExport.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#ifdef BUILD_TESTS
#include <gtest/gtest_prod.h> //To allow tests to use protected members.
#endif
#include <optional>
#include <sstream> // for stream.str()
#include <stdio.h>

Expand Down Expand Up @@ -89,7 +90,7 @@ class GCodeExport : public NoCopy

double last_e_value_after_wipe_; //!< The current material amount extruded since last wipe

unsigned fan_number_; // nozzle print cooling fan number
size_t fan_number_; // nozzle print cooling fan number
Point2LL nozzle_offset_; //!< Cache of setting machine_nozzle_offset_[xy]
bool machine_firmware_retract_; //!< Cache of setting machine_firmware_retract

Expand Down Expand Up @@ -150,8 +151,8 @@ class GCodeExport : public NoCopy
//!< other layer parts)

size_t current_extruder_;
double current_fan_speed_;
unsigned fan_number_; // current print cooling fan number
std::map<size_t, double> current_fans_speeds_; //!< Current fan speed, by fan index. No value means the speed has never been set yet.
size_t fans_count_{ 0 };
EGCodeFlavor flavor_;

std::vector<Duration> total_print_times_; //!< The total estimated print time in seconds for each feature
Expand Down Expand Up @@ -533,13 +534,28 @@ class GCodeExport : public NoCopy
void writePrimeTrain(const Velocity& travel_speed);

/*!
* Set the print cooling fan number (used as P parameter to M10[67]) for the specified extruder
*
* \param extruder The current extruder
* \brief Write a set fan speed command, if different from the actual speed
* \param speed The new fan speed, which should be [0.0, 100.0]
* \param extruder The extruder for which we want to set the cooling fan speed, or nullopt to use the current extruder
*/
void writeFanCommand(double speed, std::optional<size_t> extruder = std::nullopt);

/*!
* \brief Write a set fan speed command for the given fan, if different from the actual speed
* \param speed The new fan speed, which should be [0.0, 100.0]
* \param fan_number The fan for which we want to set the speed
*/
void setExtruderFanNumber(int extruder);
void writeSpecificFanCommand(double speed, size_t fan_number);

void writeFanCommand(double speed);
/*! Write cooling fan speeds before proceeding an extruder switch */
void writePrepareFansForNozzleSwitch();

/*!
* \brief Write the cooling fan speeds before starting an actual extrusion
* \param current_extruder_new_speed The new speed for the currently active extruder
* \note All other cooling fans but the active one will be deactivaed
*/
void writePrepareFansForExtrusion(double current_extruder_new_speed);

/*!
* \brief Write a GCode temperature command
Expand Down
10 changes: 10 additions & 0 deletions include/settings/EnumSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,16 @@ enum class BrimLocation
EVERYWHERE = 0x03, // Brim on both the outside and inside of the model
};

/*!
* How to enable/disable cooling fan(s) during extruder switch
*/
enum class CoolDuringExtruderSwitch
{
UNCHANGED, // Let fans as they are during nozzle switch (historical behavior)
ONLY_LAST_EXTRUDER, // Turn on fan of the previously used extruder to cool it down, turn others off
ALL_FANS, // Turn on all fans
};

/*!
* Convenience binary operator to allow testing brim location easily, like (actual_location & BrimLocation::OUTSIDE)
*/
Expand Down
4 changes: 3 additions & 1 deletion src/LayerPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2057,6 +2057,8 @@ void LayerPlan::writeGCode(GCodeExport& gcode)
gcode.switchExtruder(extruder_nr, prev_retraction_config.extruder_switch_retraction_config);
}

gcode.writePrepareFansForNozzleSwitch();

{ // require printing temperature to be met
constexpr bool wait = true;
gcode.writeTemperatureCommand(extruder_nr, extruder_plan.required_start_temperature_, wait);
Expand Down Expand Up @@ -2099,7 +2101,7 @@ void LayerPlan::writeGCode(GCodeExport& gcode)
}
}
}
gcode.writeFanCommand(extruder_plan.getFanSpeed());
gcode.writePrepareFansForExtrusion(extruder_plan.getFanSpeed());
std::vector<GCodePath>& paths = extruder_plan.paths_;

extruder_plan.inserts_.sort();
Expand Down
2 changes: 1 addition & 1 deletion src/PrimeTower/PrimeTower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ PrimeTower::PrimeTower()
const double brim_radius_factor = std::pow((1.0 - static_cast<double>(z) / static_cast<double>(base_height)), base_curve_magnitude);
const coord_t extra_radius = std::llrint(static_cast<double>(base_extra_radius) * brim_radius_factor);
const coord_t total_radius = tower_radius + extra_radius;
base_occupied_outline_.emplace_back(PolygonUtils::makeDisc(middle_, total_radius, circle_definition_), total_radius);
base_occupied_outline_.push_back(OccupiedOutline{ PolygonUtils::makeDisc(middle_, total_radius, circle_definition_), total_radius });
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/PrimeTower/PrimeTowerInterleaved.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ std::map<LayerIndex, std::vector<PrimeTower::ExtruderToolPaths>> PrimeTowerInter
{
if (toolpaths_at_layer.empty())
{
toolpaths_at_layer.emplace_back(last_extruder_support, ClosedLinesSet(), prime_next_outer_radius, inner_support_radius);
toolpaths_at_layer.push_back(ExtruderToolPaths{ last_extruder_support, ClosedLinesSet(), prime_next_outer_radius, inner_support_radius });
}

ExtruderToolPaths& last_extruder_toolpaths = toolpaths_at_layer.back();
Expand Down Expand Up @@ -117,7 +117,7 @@ void PrimeTowerInterleaved::polishExtrudersUses(LayerVector<std::vector<Extruder
// Make sure we always have something to print
if (extruders_use_at_layer.empty())
{
extruders_use_at_layer.emplace_back(last_used_extruder, ExtruderPrime::Support);
extruders_use_at_layer.push_back(ExtruderUse{ last_used_extruder, ExtruderPrime::Support });
}
else if (std::all_of(
extruders_use_at_layer.begin(),
Expand Down
86 changes: 67 additions & 19 deletions src/gcodeExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ GCodeExport::GCodeExport()

current_e_value_ = 0;
current_extruder_ = 0;
current_fan_speed_ = -1;

total_print_times_ = std::vector<Duration>(static_cast<unsigned char>(PrintFeatureType::NumPrintFeatureTypes), 0.0);

Expand All @@ -64,7 +63,6 @@ GCodeExport::GCodeExport()
machine_heated_build_volume_ = false;
ppr_enable_ = false;

fan_number_ = 0;
use_extruder_offset_to_offset_coords_ = false;
machine_name_ = "";
relative_extrusion_ = false;
Expand Down Expand Up @@ -96,6 +94,7 @@ void GCodeExport::preSetup(const size_t start_extruder)
extruder_attr_[extruder_nr].last_retraction_prime_speed_
= train.settings_.get<Velocity>("retraction_prime_speed"); // the alternative would be switch_extruder_prime_speed, but dual extrusion might not even be configured...
extruder_attr_[extruder_nr].fan_number_ = train.settings_.get<size_t>("machine_extruder_cooling_fan_number");
fans_count_ = std::max(fans_count_, extruder_attr_[extruder_nr].fan_number_ + 1);

// Cache some settings that we use frequently.
const Settings& extruder_settings = Application::getInstance().current_slice_->scene.extruders[extruder_nr].settings_;
Expand Down Expand Up @@ -747,8 +746,6 @@ bool GCodeExport::initializeExtruderTrains(const SliceDataStorage& storage, cons
}
}

setExtruderFanNumber(start_extruder_nr);

return should_prime_extruder;
}

Expand Down Expand Up @@ -1313,8 +1310,6 @@ void GCodeExport::startExtruder(const size_t new_extruder)

// Change the Z position so it gets re-written again. We do not know if the switch code modified the Z position.
current_position_.z_ += 1;

setExtruderFanNumber(new_extruder);
}

void GCodeExport::switchExtruder(size_t new_extruder, const RetractionConfig& retraction_config_old_extruder, coord_t perform_z_hop /*= 0*/)
Expand Down Expand Up @@ -1429,21 +1424,23 @@ void GCodeExport::writePrimeTrain(const Velocity& travel_speed)
extruder_attr_[current_extruder_].is_primed_ = true;
}

void GCodeExport::setExtruderFanNumber(int extruder)
void GCodeExport::writeFanCommand(double speed, std::optional<size_t> extruder)
{
if (extruder_attr_[extruder].fan_number_ != fan_number_)
{
fan_number_ = extruder_attr_[extruder].fan_number_;
current_fan_speed_ = -1; // ensure fan speed gcode gets output for this fan
}
const size_t extruder_set_fan = extruder.value_or(current_extruder_);
const size_t fan_number = extruder_attr_[extruder_set_fan].fan_number_;

writeSpecificFanCommand(speed, fan_number);
}

void GCodeExport::writeFanCommand(double speed)
void GCodeExport::writeSpecificFanCommand(double speed, size_t fan_number)
{
if (std::abs(current_fan_speed_ - speed) < 0.1)
auto iterator = current_fans_speeds_.find(fan_number);

if (iterator != current_fans_speeds_.end() && std::abs(iterator->second - speed) < 0.1)
{
return;
}

if (flavor_ == EGCodeFlavor::MAKERBOT)
{
if (speed >= 50)
Expand All @@ -1461,23 +1458,23 @@ void GCodeExport::writeFanCommand(double speed)
*output_stream_ << "M106 S"
<< PrecisionedDouble{ (should_scale_zero_to_one ? static_cast<uint8_t>(2) : static_cast<uint8_t>(1)),
(should_scale_zero_to_one ? speed : speed * 255) / 100 };
if (fan_number_)
if (fan_number)
{
*output_stream_ << " P" << fan_number_;
*output_stream_ << " P" << fan_number;
}
*output_stream_ << new_line_;
}
else
{
*output_stream_ << "M107";
if (fan_number_)
if (fan_number)
{
*output_stream_ << " P" << fan_number_;
*output_stream_ << " P" << fan_number;
}
*output_stream_ << new_line_;
}

current_fan_speed_ = speed;
current_fans_speeds_[fan_number] = speed;
}

void GCodeExport::writeTemperatureCommand(const size_t extruder, const Temperature& temperature, const bool wait, const bool force_write_on_equal)
Expand Down Expand Up @@ -1745,6 +1742,57 @@ void GCodeExport::insertWipeScript(const WipeScriptConfig& wipe_config)
writeComment("WIPE_SCRIPT_END");
}

void GCodeExport::writePrepareFansForNozzleSwitch()
{
const Settings& settings = Application::getInstance().current_slice_->scene.settings;
const auto cool_during_switch = settings.get<CoolDuringExtruderSwitch>("cool_during_extruder_switch");

if (cool_during_switch != CoolDuringExtruderSwitch::UNCHANGED)
{
const size_t current_extruder_fan_number = extruder_attr_[current_extruder_].fan_number_;

for (size_t fan_number = 0; fan_number < fans_count_; ++fan_number)
{
double fan_speed;
if (cool_during_switch == CoolDuringExtruderSwitch::ALL_FANS || fan_number == current_extruder_fan_number)
{
fan_speed = 100.0;
}
else
{
fan_speed = 0.0;
}

writeSpecificFanCommand(fan_speed, fan_number);
}
}
}

void GCodeExport::writePrepareFansForExtrusion(double current_extruder_new_speed)
{
const Settings& settings = Application::getInstance().current_slice_->scene.settings;
const auto cool_during_switch = settings.get<CoolDuringExtruderSwitch>("cool_during_extruder_switch");
const size_t current_extruder_fan_number = extruder_attr_[current_extruder_].fan_number_;

for (size_t fan_number = 0; fan_number < fans_count_; ++fan_number)
{
double new_fan_speed;
if (fan_number == current_extruder_fan_number)
{
new_fan_speed = current_extruder_new_speed;
}
else if (cool_during_switch == CoolDuringExtruderSwitch::UNCHANGED)
{
continue;
}
else
{
new_fan_speed = 0.0;
}
writeSpecificFanCommand(new_fan_speed, fan_number);
}
}

void GCodeExport::setSliceUUID(const std::string& slice_uuid)
{
slice_uuid_ = slice_uuid;
Expand Down
18 changes: 18 additions & 0 deletions src/settings/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,24 @@ BrimLocation Settings::get<BrimLocation>(const std::string& key) const
}
}

template<>
CoolDuringExtruderSwitch Settings::get<CoolDuringExtruderSwitch>(const std::string& key) const
{
const std::string& value = get<std::string>(key);
if (value == "all_fans")
{
return CoolDuringExtruderSwitch::ALL_FANS;
}
else if (value == "only_last_extruder")
{
return CoolDuringExtruderSwitch::ONLY_LAST_EXTRUDER;
}
else // Default.
{
return CoolDuringExtruderSwitch::UNCHANGED;
}
}

template<>
std::vector<double> Settings::get<std::vector<double>>(const std::string& key) const
{
Expand Down
4 changes: 0 additions & 4 deletions tests/GCodeExportTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class GCodeExportTest : public testing::Test
gcode.current_e_value_ = 0;
gcode.current_e_offset_ = 0;
gcode.current_extruder_ = 0;
gcode.current_fan_speed_ = -1;
gcode.total_print_times_ = std::vector<Duration>(static_cast<unsigned char>(PrintFeatureType::NumPrintFeatureTypes), 0.0);
gcode.current_speed_ = 1.0;
gcode.current_print_acceleration_ = -1.0;
Expand All @@ -61,7 +60,6 @@ class GCodeExportTest : public testing::Test
gcode.setFlavor(EGCodeFlavor::MARLIN);
gcode.bed_temperature_ = 0;
gcode.initial_bed_temp_ = 0;
gcode.fan_number_ = 0;
gcode.total_bounding_box_ = AABB3D();
gcode.current_layer_z_ = 0;
gcode.relative_extrusion_ = false;
Expand Down Expand Up @@ -211,7 +209,6 @@ class GriffinHeaderTest : public testing::TestWithParam<size_t>
gcode.layer_nr_ = 0;
gcode.current_e_value_ = 0;
gcode.current_extruder_ = 0;
gcode.current_fan_speed_ = -1;
gcode.total_print_times_ = std::vector<Duration>(static_cast<unsigned char>(PrintFeatureType::NumPrintFeatureTypes), 0.0);
gcode.current_speed_ = 1.0;
gcode.current_print_acceleration_ = -1.0;
Expand All @@ -221,7 +218,6 @@ class GriffinHeaderTest : public testing::TestWithParam<size_t>
gcode.setFlavor(EGCodeFlavor::MARLIN);
gcode.initial_bed_temp_ = 0;
gcode.bed_temperature_ = 0;
gcode.fan_number_ = 0;
gcode.total_bounding_box_ = AABB3D();

gcode.new_line_ = "\n"; // Not BFB flavour by default.
Expand Down

0 comments on commit c08f517

Please sign in to comment.