Skip to content

Commit

Permalink
(Almost) add new setting; reduce fan speed for overhangs.
Browse files Browse the repository at this point in the history
Nearly done, but doesn't handle the engine-plugin code yet, causing it to not show up, since the default is 1.0

part of CURA-11966
  • Loading branch information
rburema committed Jan 30, 2025
1 parent d1534f5 commit 03f728d
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 19 deletions.
3 changes: 3 additions & 0 deletions include/GCodePathConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct GCodePathConfig
SpeedDerivatives speed_derivatives{}; //!< The speed settings (and acceleration and jerk) of the extruded line. May be changed when smoothSpeed is called.
bool is_bridge_path{ false }; //!< whether current config is used when bridging
double fan_speed{ FAN_SPEED_DEFAULT }; //!< fan speed override for this path, value should be within range 0-100 (inclusive) and ignored otherwise
double fan_overhang_factor{ 1.0 }; //!< fan speed overhang factor, multiplicative
double extrusion_mm3_per_mm{ calculateExtrusion() }; //!< current mm^3 filament moved per mm line traversed

[[nodiscard]] constexpr bool operator==(const GCodePathConfig& other) const noexcept = default;
Expand Down Expand Up @@ -61,6 +62,8 @@ struct GCodePathConfig

[[nodiscard]] double getFanSpeed() const noexcept;

[[nodiscard]] double getFanOverhangFactor() const noexcept;

[[nodiscard]] Ratio getFlowRatio() const noexcept;

[[nodiscard]] coord_t getLayerThickness() const noexcept;
Expand Down
6 changes: 4 additions & 2 deletions include/LayerPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ class LayerPlan : public NoCopy
const Ratio flow = 1.0_r,
const Ratio width_factor = 1.0_r,
const bool spiralize = false,
const Ratio speed_factor = 1.0_r);
const Ratio speed_factor = 1.0_r,
const Ratio fan_speed_overhang_factor = 1.0_r);

public:
/*!
Expand Down Expand Up @@ -402,7 +403,8 @@ class LayerPlan : public NoCopy
const bool spiralize = false,
const Ratio speed_factor = 1.0_r,
const double fan_speed = GCodePathConfig::FAN_SPEED_DEFAULT,
const bool travel_to_z = true);
const bool travel_to_z = true,
const Ratio fan_speed_overhang_factor = 1.0_r);

void addExtrusionMoveWithGradualOverhang(
const Point3LL& p,
Expand Down
12 changes: 12 additions & 0 deletions include/pathPlanning/GCodePath.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct GCodePath
std::vector<Point3LL> points{}; //!< The points constituting this path. The Z coordinate is an offset relative to the actual layer height, added to the global z_offset.
bool done{ false }; //!< Path is finished, no more moves should be added, and a new path should be started instead of any appending done to this one.
double fan_speed{ GCodePathConfig::FAN_SPEED_DEFAULT }; //!< fan speed override for this path, value should be within range 0-100 (inclusive) and ignored otherwise
double fan_speed_overhang_factor{ 1.0 }; //!< fan speed overhang factor, multiplicative
TimeMaterialEstimates estimates{}; //!< Naive time and material estimates
bool travel_to_z{ true }; //! Indicates whether we should add a travel move to the Z height of the first point before processing the path

Expand Down Expand Up @@ -86,6 +87,17 @@ struct GCodePath
* \return the value of fan_speed if it is in the range 0-100, otherwise the value from the config
*/
[[nodiscard]] double getFanSpeed() const noexcept;

/*!
* Set the fan speed overhang factor, this needs to be separate from the fan speed because of signalling values.
*/
void setFanSpeedOverhangFactor(const double overhang_factor) noexcept;

/*!
* Get the fan speed overhang factor, this needs to be separate from the fan speed because of signalling values.
* \return the value of fan_overhang_factor
*/
[[nodiscard]] double getFanSpeedOverhangFactor() const noexcept;
};

} // namespace cura
Expand Down
8 changes: 7 additions & 1 deletion include/settings/MeshPathConfigs.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ struct MeshPathConfigs
std::vector<GCodePathConfig> infill_config{};
GCodePathConfig ironing_config{};

MeshPathConfigs(const SliceMeshStorage& mesh, const coord_t layer_thickness, const LayerIndex layer_nr, const std::vector<Ratio>& line_width_factor_per_extruder);
MeshPathConfigs(
const SliceMeshStorage& mesh,
const coord_t layer_thickness,
const LayerIndex layer_nr,
const std::vector<Ratio>& line_width_factor_per_extruder,
const std::vector<Ratio>& fan_overhang_factor_per_extruder
);
void smoothAllSpeeds(const SpeedDerivatives& first_layer_config, const LayerIndex layer_nr, const LayerIndex max_speed_layer);
};

Expand Down
3 changes: 3 additions & 0 deletions include/settings/PathConfigStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class PathConfigStorage
const std::vector<Ratio> line_width_factor_per_extruder;
static std::vector<Ratio> getLineWidthFactorPerExtruder(const LayerIndex& layer_nr);

const std::vector<Ratio> fan_overhang_factor_per_extruder;
static std::vector<Ratio> getFanOverhangFactorPerExtruder();

public:
GCodePathConfig raft_base_config;
GCodePathConfig raft_interface_config;
Expand Down
5 changes: 5 additions & 0 deletions src/GCodePathConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ namespace cura
return fan_speed;
}

[[nodiscard]] double GCodePathConfig::getFanOverhangFactor() const noexcept
{
return fan_overhang_factor;
}

[[nodiscard]] Ratio GCodePathConfig::getFlowRatio() const noexcept
{
return flow;
Expand Down
19 changes: 12 additions & 7 deletions src/LayerPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ GCodePath* LayerPlan::getLatestPathWithConfig(
const Ratio flow,
const Ratio width_factor,
const bool spiralize,
const Ratio speed_factor)
const Ratio speed_factor,
const Ratio fan_speed_overhang_factor)
{
std::vector<GCodePath>& paths = extruder_plans_.back().paths_;
if (paths.size() > 0 && paths.back().config == config && ! paths.back().done && paths.back().flow == flow && paths.back().width_factor == width_factor
&& paths.back().speed_factor == speed_factor && paths.back().z_offset == z_offset
&& paths.back().speed_factor == speed_factor && paths.back().z_offset == z_offset && paths.back().fan_speed_overhang_factor == fan_speed_overhang_factor
&& paths.back().mesh == current_mesh_) // spiralize can only change when a travel path is in between
{
return &paths.back();
Expand All @@ -64,7 +65,8 @@ GCodePath* LayerPlan::getLatestPathWithConfig(
.flow = flow,
.width_factor = width_factor,
.spiralize = spiralize,
.speed_factor = speed_factor });
.speed_factor = speed_factor,
.fan_speed_overhang_factor = fan_speed_overhang_factor });

GCodePath* ret = &paths.back();
ret->skip_agressive_merge_hint = mode_skip_agressive_merge_;
Expand Down Expand Up @@ -544,11 +546,13 @@ void LayerPlan::addExtrusionMove(
const bool spiralize,
const Ratio speed_factor,
const double fan_speed,
const bool travel_to_z)
const bool travel_to_z,
const Ratio fan_speed_overhang_factor)
{
GCodePath* path = getLatestPathWithConfig(config, space_fill_type, config.z_offset, flow, width_factor, spiralize, speed_factor);
GCodePath* path = getLatestPathWithConfig(config, space_fill_type, config.z_offset, flow, width_factor, spiralize, speed_factor, fan_speed_overhang_factor);
path->points.push_back(p);
path->setFanSpeed(fan_speed);
path->setFanSpeedOverhangFactor(fan_speed_overhang_factor);
path->travel_to_z = travel_to_z;
if (! static_cast<bool>(first_extrusion_acc_jerk_))
{
Expand All @@ -571,7 +575,8 @@ void LayerPlan::addExtrusionMoveWithGradualOverhang(
const auto add_extrusion_move = [&](const Point3LL& target, const std::optional<size_t> speed_region_index = std::nullopt)
{
const Ratio overhang_speed_factor = speed_region_index.has_value() ? overhang_masks_[speed_region_index.value()].speed_ratio : 1.0_r;
addExtrusionMove(target, config, space_fill_type, flow, width_factor, spiralize, speed_factor * overhang_speed_factor, fan_speed, travel_to_z);
const double fan_speed_overhang_factor = fan_speed < 0 && currently_overhanging_ ? config.fan_overhang_factor : 1.0;
addExtrusionMove(target, config, space_fill_type, flow, width_factor, spiralize, speed_factor * overhang_speed_factor, fan_speed, travel_to_z, fan_speed_overhang_factor);
};

const auto update_is_overhanging = [this](const Point2LL& target, std::optional<Point2LL> current_position, const bool is_overhanging = false)
Expand Down Expand Up @@ -2831,7 +2836,7 @@ void LayerPlan::writeGCode(GCodeExport& gcode)
if (! path.isTravelPath() || path.fan_speed >= 0)
{
const double path_fan_speed = path.getFanSpeed();
gcode.writeFanCommand(path_fan_speed != GCodePathConfig::FAN_SPEED_DEFAULT ? path_fan_speed : extruder_plan.getFanSpeed());
gcode.writeFanCommand(path.getFanSpeedOverhangFactor() * (path_fan_speed != GCodePathConfig::FAN_SPEED_DEFAULT ? path_fan_speed : extruder_plan.getFanSpeed()));
}

if (path.perform_prime)
Expand Down
10 changes: 10 additions & 0 deletions src/pathPlanning/GCodePath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,14 @@ void GCodePath::setFanSpeed(const double fanspeed) noexcept
return (fan_speed >= 0 && fan_speed <= 100) ? fan_speed : config.getFanSpeed();
}

void GCodePath::setFanSpeedOverhangFactor(const double overhang_factor) noexcept
{
fan_speed_overhang_factor = overhang_factor;
}

[[nodiscard]] double GCodePath::getFanSpeedOverhangFactor() const noexcept
{
return fan_speed_overhang_factor;
}

} // namespace cura
26 changes: 19 additions & 7 deletions src/settings/MeshPathConfigs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,31 @@
namespace cura
{

MeshPathConfigs::MeshPathConfigs(const SliceMeshStorage& mesh, const coord_t layer_thickness, const LayerIndex layer_nr, const std::vector<Ratio>& line_width_factor_per_extruder)
MeshPathConfigs::MeshPathConfigs(
const SliceMeshStorage& mesh,
const coord_t layer_thickness,
const LayerIndex layer_nr,
const std::vector<Ratio>& line_width_factor_per_extruder,
const std::vector<Ratio>& fan_overhang_factor_per_extruder
)
: inset0_config{ .type = PrintFeatureType::OuterWall,
.line_width = static_cast<coord_t>(
mesh.settings.get<coord_t>("wall_line_width_0") * line_width_factor_per_extruder[mesh.settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_]),
.layer_thickness = layer_thickness,
.flow = mesh.settings.get<Ratio>("wall_0_material_flow") * (layer_nr == 0 ? mesh.settings.get<Ratio>("wall_0_material_flow_layer_0") : Ratio{ 1.0 }),
.speed_derivatives = { .speed = mesh.settings.get<Velocity>("speed_wall_0"),
.acceleration = mesh.settings.get<Acceleration>("acceleration_wall_0"),
.jerk = mesh.settings.get<Velocity>("jerk_wall_0") } }
.jerk = mesh.settings.get<Velocity>("jerk_wall_0") },
.fan_overhang_factor = fan_overhang_factor_per_extruder[mesh.settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_] }
, insetX_config{ .type = PrintFeatureType::InnerWall,
.line_width = static_cast<coord_t>(
mesh.settings.get<coord_t>("wall_line_width_x") * line_width_factor_per_extruder[mesh.settings.get<ExtruderTrain&>("wall_x_extruder_nr").extruder_nr_]),
.layer_thickness = layer_thickness,
.flow = mesh.settings.get<Ratio>("wall_x_material_flow") * (layer_nr == 0 ? mesh.settings.get<Ratio>("wall_x_material_flow_layer_0") : Ratio{ 1.0 }),
.speed_derivatives = { .speed = mesh.settings.get<Velocity>("speed_wall_x"),
.acceleration = mesh.settings.get<Acceleration>("acceleration_wall_x"),
.jerk = mesh.settings.get<Velocity>("jerk_wall_x") } }
.jerk = mesh.settings.get<Velocity>("jerk_wall_x") },
.fan_overhang_factor = fan_overhang_factor_per_extruder[mesh.settings.get<ExtruderTrain&>("wall_x_extruder_nr").extruder_nr_] }
, inset0_roofing_config{ .type = PrintFeatureType::OuterWall,
.line_width = static_cast<coord_t>(
mesh.settings.get<coord_t>("wall_line_width_0")
Expand All @@ -37,7 +45,8 @@ MeshPathConfigs::MeshPathConfigs(const SliceMeshStorage& mesh, const coord_t lay
= mesh.settings.get<Ratio>("wall_0_material_flow_roofing") * (layer_nr == 0 ? mesh.settings.get<Ratio>("wall_0_material_flow_layer_0") : Ratio{ 1.0 }),
.speed_derivatives = { .speed = mesh.settings.get<Velocity>("speed_wall_0_roofing"),
.acceleration = mesh.settings.get<Acceleration>("acceleration_wall_0_roofing"),
.jerk = mesh.settings.get<Velocity>("jerk_wall_0_roofing") } }
.jerk = mesh.settings.get<Velocity>("jerk_wall_0_roofing") },
.fan_overhang_factor = fan_overhang_factor_per_extruder[mesh.settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_] }
, insetX_roofing_config{ .type = PrintFeatureType::InnerWall,
.line_width = static_cast<coord_t>(
mesh.settings.get<coord_t>("wall_line_width_x")
Expand All @@ -47,7 +56,8 @@ MeshPathConfigs::MeshPathConfigs(const SliceMeshStorage& mesh, const coord_t lay
= mesh.settings.get<Ratio>("wall_x_material_flow_roofing") * (layer_nr == 0 ? mesh.settings.get<Ratio>("wall_x_material_flow_layer_0") : Ratio{ 1.0 }),
.speed_derivatives = { .speed = mesh.settings.get<Velocity>("speed_wall_x_roofing"),
.acceleration = mesh.settings.get<Acceleration>("acceleration_wall_x_roofing"),
.jerk = mesh.settings.get<Velocity>("jerk_wall_x_roofing") } }
.jerk = mesh.settings.get<Velocity>("jerk_wall_x_roofing") },
.fan_overhang_factor = fan_overhang_factor_per_extruder[mesh.settings.get<ExtruderTrain&>("wall_x_extruder_nr").extruder_nr_] }
, bridge_inset0_config{ .type = PrintFeatureType::OuterWall,
.line_width = static_cast<coord_t>(
mesh.settings.get<coord_t>("wall_line_width_0")
Expand Down Expand Up @@ -77,7 +87,8 @@ MeshPathConfigs::MeshPathConfigs(const SliceMeshStorage& mesh, const coord_t lay
.flow = mesh.settings.get<Ratio>("skin_material_flow") * (layer_nr == 0 ? mesh.settings.get<Ratio>("skin_material_flow_layer_0") : Ratio{ 1.0 }),
.speed_derivatives = { .speed = mesh.settings.get<Velocity>("speed_topbottom"),
.acceleration = mesh.settings.get<Acceleration>("acceleration_topbottom"),
.jerk = mesh.settings.get<Velocity>("jerk_topbottom") } }
.jerk = mesh.settings.get<Velocity>("jerk_topbottom") },
.fan_overhang_factor = fan_overhang_factor_per_extruder[mesh.settings.get<ExtruderTrain&>("top_bottom_extruder_nr").extruder_nr_] }
, bridge_skin_config{ .type = PrintFeatureType::Skin,
.line_width = static_cast<coord_t>(
mesh.settings.get<coord_t>("skin_line_width")
Expand Down Expand Up @@ -125,7 +136,6 @@ MeshPathConfigs::MeshPathConfigs(const SliceMeshStorage& mesh, const coord_t lay
.speed_derivatives = { .speed = mesh.settings.get<Velocity>("speed_ironing"),
.acceleration = mesh.settings.get<Acceleration>("acceleration_ironing"),
.jerk = mesh.settings.get<Velocity>("jerk_ironing") } }

{
infill_config.reserve(MAX_INFILL_COMBINE);

Expand All @@ -141,6 +151,8 @@ MeshPathConfigs::MeshPathConfigs(const SliceMeshStorage& mesh, const coord_t lay
.acceleration = mesh.settings.get<Acceleration>("acceleration_infill"),
.jerk = mesh.settings.get<Velocity>("jerk_infill") } });
}


}

} // namespace cura
13 changes: 12 additions & 1 deletion src/settings/PathConfigStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include "settings/Settings.h" // MAX_INFILL_COMBINE
#include "sliceDataStorage.h" // SliceDataStorage

#include <range/v3/to_container.hpp>
#include <range/v3/view/transform.hpp>

namespace cura
{

Expand All @@ -32,6 +35,13 @@ std::vector<Ratio> PathConfigStorage::getLineWidthFactorPerExtruder(const LayerI
return ret;
}

std::vector<Ratio> PathConfigStorage::getFanOverhangFactorPerExtruder()
{
return Application::getInstance().current_slice_->scene.extruders | ranges::views::transform([](const ExtruderTrain& train) -> Ratio {
return train.settings_.get<Ratio>("cool_fan_speed_overhang_factor");
}) | ranges::to<std::vector<Ratio>>;
}

PathConfigStorage::PathConfigStorage(const SliceDataStorage& storage, const LayerIndex& layer_nr, const coord_t layer_thickness)
: support_infill_extruder_nr(Application::getInstance().current_slice_->scene.current_mesh_group->settings.get<ExtruderTrain&>("support_infill_extruder_nr").extruder_nr_)
, support_roof_extruder_nr(Application::getInstance().current_slice_->scene.current_mesh_group->settings.get<ExtruderTrain&>("support_roof_extruder_nr").extruder_nr_)
Expand All @@ -43,6 +53,7 @@ PathConfigStorage::PathConfigStorage(const SliceDataStorage& storage, const Laye
, support_roof_train(Application::getInstance().current_slice_->scene.extruders[support_roof_extruder_nr])
, support_bottom_train(Application::getInstance().current_slice_->scene.extruders[support_bottom_extruder_nr])
, line_width_factor_per_extruder(PathConfigStorage::getLineWidthFactorPerExtruder(layer_nr))
, fan_overhang_factor_per_extruder(PathConfigStorage::getFanOverhangFactorPerExtruder())
, raft_base_config(GCodePathConfig{ .type = PrintFeatureType::SupportInterface,
.line_width = raft_base_train.settings_.get<coord_t>("raft_base_line_width"),
.layer_thickness = raft_base_train.settings_.get<coord_t>("raft_base_thickness"),
Expand Down Expand Up @@ -126,7 +137,7 @@ PathConfigStorage::PathConfigStorage(const SliceDataStorage& storage, const Laye
mesh_configs.reserve(storage.meshes.size());
for (const std::shared_ptr<SliceMeshStorage>& mesh_storage : storage.meshes)
{
mesh_configs.emplace_back(*mesh_storage, layer_thickness, layer_nr, line_width_factor_per_extruder);
mesh_configs.emplace_back(*mesh_storage, layer_thickness, layer_nr, line_width_factor_per_extruder, fan_overhang_factor_per_extruder);
}

support_infill_config.reserve(MAX_INFILL_COMBINE);
Expand Down
2 changes: 1 addition & 1 deletion tests/FffGcodeWriterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ TEST_F(FffGcodeWriterTest, SurfaceGetsExtraInfillLinesUnderIt)
LayerPlan gcode_layer(*storage, 100, 10000, 100, 0, {fan_settings}, 20, 10, 5000 );
SliceMeshStorage mesh_storage(&mesh, 200);
size_t extruder_nr = 0;
MeshPathConfigs mesh_config(mesh_storage, 10, 100, {0.5});
MeshPathConfigs mesh_config(mesh_storage, 10, 100, { 0.5 }, { 1.0 });
SliceLayerPart part;

part.infill_area_per_combine_per_density = { { outer_square } };
Expand Down

0 comments on commit 03f728d

Please sign in to comment.