Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4379cbf
Use different minimum layer time when layer has an overhang
wawanbreton Dec 16, 2024
d30de99
Merge remote-tracking branch 'origin/CURA-11966_reduce-speed-on-overh…
wawanbreton Jan 9, 2025
ca2211f
Apply clang-format
wawanbreton Jan 9, 2025
9de740a
Apply the minimum overhanging extrusion length
wawanbreton Jan 9, 2025
7302cea
Merge remote-tracking branch 'origin/CURA-12352_different-minimum-lay…
wawanbreton Jan 9, 2025
80fab60
Merge branch 'CURA-11966_reduce-speed-on-overhang' into CURA-12352_di…
wawanbreton Jan 9, 2025
1953eb5
Don't skip last speed-region w.r.t. overhang wall angles.
rburema Jan 16, 2025
0540d55
There should always be an internal region, even if the speed is 100%.
rburema Jan 16, 2025
7f2ced5
Small optimization refactors.
rburema Jan 16, 2025
93907a5
Remove debugging code.
rburema Jan 16, 2025
2cb9722
Gradual overhang speed: Make sure to avoid microsegments.
rburema Jan 16, 2025
ccf07dc
Update altered overhang wall-speed setting.
rburema Jan 16, 2025
f3f26c7
Make sure differences to detect min-line-lenght are positive values.
rburema Jan 16, 2025
2353e64
Apply clang-format
rburema Jan 16, 2025
a98e7d0
Apple clang can't deal properly with emplace_back apparently.
rburema Jan 16, 2025
c468d03
Merge branch 'main' into CURA-12352_different-minimum-layer-time-for-…
HellAholic Jan 17, 2025
588a838
Improve micro-segment filtering
wawanbreton Jan 22, 2025
d1534f5
Apply clang-format
wawanbreton Jan 22, 2025
0ca9c26
Merge remote-tracking branch 'origin/main' into CURA-12352_different-…
wawanbreton Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions include/FanSpeedLayerTime.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
//Copyright (c) 2020 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.
// Copyright (c) 2020 Ultimaker B.V.
// CuraEngine is released under the terms of the AGPLv3 or higher.

#ifndef FAN_SPEED_LAYER_TIME_H
#define FAN_SPEED_LAYER_TIME_H

#include <utils/Coord_t.h>

#include "settings/types/Duration.h"
#include "settings/types/LayerIndex.h"
#include "settings/types/Velocity.h"

namespace cura
namespace cura
{

/*!
Expand All @@ -19,7 +21,7 @@ namespace cura
* store these settings over and over again for each part, even though the
* settings may be different for each part on a layer.
*/
struct FanSpeedLayerTimeSettings
struct FanSpeedLayerTimeSettings
{
public:
/*!
Expand All @@ -28,6 +30,16 @@ struct FanSpeedLayerTimeSettings
*/
Duration cool_min_layer_time;

/*!
* Similar to Minimum layer time, but to be applied for layers that contain overhanging extrusion.
*/
Duration cool_min_layer_time_overhang;

/*!
* The specific minimum layer time for overhanging will be applied only if there is at least one overhanging segment longer that this threshold
*/
coord_t cool_min_layer_time_overhang_min_segment_length;

/*!
* "Regular/Maximum Fan Speed Threshold". If the layers take longer to print
* than this, they'll use the regular fan speed. If they take shorter, we'll
Expand Down
4 changes: 4 additions & 0 deletions include/LayerPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ class LayerPlan : public NoCopy
std::vector<OverhangMask> overhang_masks_; //!< The regions of a layer part where the walls overhang, calculated for multiple overhang angles. The latter is the most
//!< overhanging. For a visual explanation of the result, see doc/gradual_overhang_speed.svg
Shape seam_overhang_mask_; //!< The regions of a layer part where the walls overhang, specifically as defined for the seam
bool currently_overhanging_{ false }; //!< Indicates whether the last extrusion move was overhanging
coord_t current_overhang_length_{ 0 }; //!< When doing consecutive overhanging moves, this is the current accumulated overhanging length
coord_t max_overhang_length_{ 0 }; //!< From all consecutive overhanging moves in the layer, this is the longest one

Shape roofing_mask_; //!< The regions of a layer part where the walls are exposed to the air

bool min_layer_time_used = false; //!< Wether or not the minimum layer time (cool_min_layer_time) was actually used in this layerplan.
Expand Down
12 changes: 8 additions & 4 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ void FffGcodeWriter::setConfigFanSpeedLayerTime()
fan_speed_layer_time_settings_per_extruder.emplace_back();
FanSpeedLayerTimeSettings& fan_speed_layer_time_settings = fan_speed_layer_time_settings_per_extruder.back();
fan_speed_layer_time_settings.cool_min_layer_time = train.settings_.get<Duration>("cool_min_layer_time");
fan_speed_layer_time_settings.cool_min_layer_time_overhang = train.settings_.get<Duration>("cool_min_layer_time_overhang");
fan_speed_layer_time_settings.cool_min_layer_time_overhang_min_segment_length = train.settings_.get<coord_t>("cool_min_layer_time_overhang_min_segment_length");
fan_speed_layer_time_settings.cool_min_layer_time_fan_speed_max = train.settings_.get<Duration>("cool_min_layer_time_fan_speed_max");
fan_speed_layer_time_settings.cool_fan_speed_0 = train.settings_.get<Ratio>("cool_fan_speed_0") * 100.0;
fan_speed_layer_time_settings.cool_fan_speed_min = train.settings_.get<Ratio>("cool_fan_speed_min") * 100.0;
Expand Down Expand Up @@ -3112,16 +3114,18 @@ bool FffGcodeWriter::processInsets(
{
AngleDegrees overhang_angle;
Ratio speed_factor;
bool chunk = true;
};

// Create raw speed regions
const AngleDegrees overhang_step = (90.0 - wall_overhang_angle) / static_cast<double>(overhang_angles_count);
std::vector<SpeedRegion> speed_regions;
speed_regions.reserve(overhang_angles_count + 1);
speed_regions.reserve(overhang_angles_count + 2);

speed_regions.push_back(SpeedRegion{ wall_overhang_angle, 1.0_r }); // Initial internal region, always 100% speed factor
constexpr bool dont_chunk_first = false; // Never merge internal region in order to detect actual overhanging
speed_regions.push_back(SpeedRegion{ wall_overhang_angle, 1.0_r, dont_chunk_first }); // Initial internal region, always 100% speed factor

for (size_t angle_index = 1; angle_index < overhang_angles_count; ++angle_index)
for (size_t angle_index = 1; angle_index <= overhang_angles_count; ++angle_index)
{
const AngleDegrees actual_wall_overhang_angle = wall_overhang_angle + static_cast<double>(angle_index) * overhang_step;
const Ratio speed_factor = overhang_speed_factors[angle_index - 1];
Expand All @@ -3136,7 +3140,7 @@ bool FffGcodeWriter::processInsets(
| ranges::views::chunk_by(
[](const auto& region_a, const auto& region_b)
{
return region_a.speed_factor == region_b.speed_factor;
return region_a.chunk && region_b.chunk && region_a.speed_factor == region_b.speed_factor;
});

// If finally necessary, add actual calculated speed regions
Expand Down
98 changes: 92 additions & 6 deletions src/LayerPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,14 +568,32 @@ void LayerPlan::addExtrusionMoveWithGradualOverhang(
const double fan_speed,
const bool travel_to_z)
{
const auto add_extrusion_move = [&](const Point3LL& target, const Ratio& overhang_speed_factor = 1.0_r)
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 auto update_is_overhanging = [this](const Point2LL& target, std::optional<Point2LL> current_position, const bool is_overhanging = false)
{
if (is_overhanging != currently_overhanging_)
{
max_overhang_length_ = std::max(current_overhang_length_, max_overhang_length_);
current_overhang_length_ = 0;
}

if (is_overhanging && current_position.has_value())
{
current_overhang_length_ += vSize(target - current_position.value());
}

currently_overhanging_ = is_overhanging;
};

if (overhang_masks_.empty() || ! last_planned_position_.has_value())
{
// Unable to apply gradual overhanging (probably just disabled), just add the basic extrusion move
update_is_overhanging(p.toPoint2LL(), last_planned_position_);
add_extrusion_move(p);
return;
}
Expand Down Expand Up @@ -619,7 +637,13 @@ void LayerPlan::addExtrusionMoveWithGradualOverhang(
}
};

const std::vector<SVG::Color> colors = { SVG::Color::RED, SVG::Color::GREEN, SVG::Color::BLUE, SVG::Color::YELLOW };
struct SegmentExtrusionMove
{
Point2LL position;
size_t speed_region_index;
};

std::vector<SegmentExtrusionMove> extrusion_moves;

// Now move along segment and split it where we cross speed regions
while (true)
Expand Down Expand Up @@ -658,7 +682,7 @@ void LayerPlan::addExtrusionMoveWithGradualOverhang(

// Move to intersection at current region speed
const Point2LL split_position = start + vector * intersection_parameter;
add_extrusion_move(split_position, overhang_masks_[actual_speed_region_index].speed_ratio);
extrusion_moves.push_back(SegmentExtrusionMove{ split_position, actual_speed_region_index });

// Prepare for next move in different region
actual_speed_region_index = next_speed_region_index;
Expand All @@ -667,10 +691,68 @@ void LayerPlan::addExtrusionMoveWithGradualOverhang(
else
{
// We cross no border, which means we can reach the end of the segment within the current speed region, so we are done
add_extrusion_move(p, overhang_masks_[actual_speed_region_index].speed_ratio);
return;
extrusion_moves.push_back(SegmentExtrusionMove{ p.toPoint2LL(), actual_speed_region_index });
break;
}
}

// Filter out micro-segments
std::vector<SegmentExtrusionMove> extrusion_moves_filtered;
extrusion_moves_filtered.reserve(extrusion_moves.size());
Point2LL current_position = start;
for (const SegmentExtrusionMove& extrusion_move : extrusion_moves | ranges::views::drop_last(1))
{
if (vSize2(extrusion_move.position - current_position) >= MINIMUM_SQUARED_LINE_LENGTH)
{
extrusion_moves_filtered.push_back(extrusion_move);
}

current_position = extrusion_move.position;
}

if (extrusion_moves_filtered.empty() || vSize2(extrusion_moves.back().position - current_position) >= MINIMUM_SQUARED_LINE_LENGTH)
{
extrusion_moves_filtered.push_back(extrusion_moves.back());
}
else
{
extrusion_moves_filtered.back().position = extrusion_moves.back().position;
}

// Calculate max consecutive overhanging segment length
current_position = start;
for (const SegmentExtrusionMove& extrusion_move : extrusion_moves_filtered)
{
const bool is_overhanging = extrusion_move.speed_region_index > 0;
update_is_overhanging(extrusion_move.position, current_position, is_overhanging);
current_position = extrusion_move.position;
}

// Merge consecutive sub-segments that in the end have the same speed
std::vector<SegmentExtrusionMove> extrusion_moves_merged;
extrusion_moves_merged.reserve(extrusion_moves_filtered.size());
extrusion_moves_merged.push_back(extrusion_moves_filtered.front());

for (const SegmentExtrusionMove& extrusion_move : extrusion_moves_filtered | ranges::views::drop(1))
{
const Ratio previous_speed_factor = overhang_masks_[extrusion_moves_merged.back().speed_region_index].speed_ratio;
const Ratio next_speed_factor = overhang_masks_[extrusion_move.speed_region_index].speed_ratio;

if (next_speed_factor == previous_speed_factor)
{
extrusion_moves_merged.back().position = extrusion_move.position;
}
else
{
extrusion_moves_merged.push_back(extrusion_move);
}
}

// Finally, add extrusion moves
for (const SegmentExtrusionMove& extrusion_move : extrusion_moves_merged)
{
add_extrusion_move(extrusion_move.position, extrusion_move.speed_region_index);
}
}

template<class PathType>
Expand Down Expand Up @@ -2561,7 +2643,11 @@ void LayerPlan::processFanSpeedAndMinimalLayerTime(Point2LL starting_position)
{
other_extr_plan_time += extruder_plan.estimates_.getTotalTime();
}
maximum_cool_min_layer_time = std::max(maximum_cool_min_layer_time, extruder_plan.fan_speed_layer_time_settings_.cool_min_layer_time);

const FanSpeedLayerTimeSettings& settings = extruder_plan.fan_speed_layer_time_settings_;
const bool apply_minimum_layer_time_overhang = max_overhang_length_ > settings.cool_min_layer_time_overhang_min_segment_length;
maximum_cool_min_layer_time
= std::max(maximum_cool_min_layer_time, apply_minimum_layer_time_overhang ? settings.cool_min_layer_time_overhang : settings.cool_min_layer_time);

// Modify fan speeds for the first layer(s)
extruder_plan.processFanSpeedForFirstLayers();
Expand Down
2 changes: 1 addition & 1 deletion stress_benchmark/resources/001.settings
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ acceleration_support_roof=300
material_print_temp_wait=True
support_roof_angles=[]
machine_gcode_flavor=Griffin
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
jerk_support_infill=12.5
wall_0_wipe_dist=0
jerk_wall_0_roofing=12.5
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/002.settings
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ adaptive_layer_height_threshold=0.1
support_interface_height=0.8
support_brim_enable=True
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
acceleration_travel=500
support_bottom_material_flow=100
raft_base_extruder_nr=0
Expand Down Expand Up @@ -972,7 +972,7 @@ extruder_prime_pos_abs=False
support_tower_maximum_supported_diameter=3.0
support_tree_angle=45
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
infill_before_walls=False
material=0
brim_width=8.0
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/003.settings
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ adaptive_layer_height_threshold=0.2
support_interface_height=0.96
support_brim_enable=True
jerk_support_infill=12.0
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
acceleration_travel=500
support_bottom_material_flow=95.0
raft_base_extruder_nr=0
Expand Down Expand Up @@ -973,7 +973,7 @@ extruder_prime_pos_abs=False
support_tower_maximum_supported_diameter=3.0
support_tree_angle=50
jerk_support_infill=12.0
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
infill_before_walls=False
material=0
brim_width=8.0
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/004.settings
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ adaptive_layer_height_threshold=0.2
support_interface_height=0.8
support_brim_enable=True
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
acceleration_travel=500
support_bottom_material_flow=100
raft_base_extruder_nr=0
Expand Down Expand Up @@ -973,7 +973,7 @@ extruder_prime_pos_abs=False
support_tower_maximum_supported_diameter=3.0
support_tree_angle=55
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
infill_before_walls=False
material=0
brim_width=8.0
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/005.settings
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ adaptive_layer_height_threshold=0.2
support_interface_height=0.8
support_brim_enable=True
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
acceleration_travel=500
support_bottom_material_flow=100
raft_base_extruder_nr=0
Expand Down Expand Up @@ -974,7 +974,7 @@ extruder_prime_pos_abs=False
support_tower_maximum_supported_diameter=3.0
support_tree_angle=65.0
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
infill_before_walls=False
material=0
brim_width=3
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/006.settings
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ adaptive_layer_height_threshold=0.2
support_interface_height=0.8
support_brim_enable=True
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
acceleration_travel=500
support_bottom_material_flow=100
raft_base_extruder_nr=0
Expand Down Expand Up @@ -974,7 +974,7 @@ extruder_prime_pos_abs=False
support_tower_maximum_supported_diameter=3.0
support_tree_angle=60.0
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
infill_before_walls=False
material=0
brim_width=8.0
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/007.settings
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ adaptive_layer_height_threshold=0.2
support_interface_height=0.8
support_brim_enable=True
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
acceleration_travel=500
support_bottom_material_flow=100
raft_base_extruder_nr=0
Expand Down Expand Up @@ -974,7 +974,7 @@ extruder_prime_pos_abs=False
support_tower_maximum_supported_diameter=3.0
support_tree_angle=45
jerk_support_infill=8
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
infill_before_walls=False
material=0
brim_width=8.0
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/008.settings
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ travel_speed=150
speed=0
cool_fan_speed_min=50
wipe_move_distance=20
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
jerk_support_infill=20
material_adhesion_tendency=10
extruder_prime_pos_abs=True
Expand Down Expand Up @@ -816,7 +816,7 @@ optimize_wall_printing_order=True
line_width=0.4
switch_extruder_prime_speed=20
min_bead_width=0.34
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
jerk_support_infill=20
material_adhesion_tendency=0
extruder_prime_pos_abs=True
Expand Down
4 changes: 2 additions & 2 deletions stress_benchmark/resources/009.settings
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ travel_speed=150
speed=0
cool_fan_speed_min=50
wipe_move_distance=20
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
jerk_support_infill=20
material_adhesion_tendency=10
extruder_prime_pos_abs=True
Expand Down Expand Up @@ -816,7 +816,7 @@ optimize_wall_printing_order=True
line_width=0.4
switch_extruder_prime_speed=20
min_bead_width=0.34
wall_overhang_speed_factor=100
wall_overhang_speed_factors=[100]
jerk_support_infill=20
material_adhesion_tendency=0
extruder_prime_pos_abs=True
Expand Down
Loading
Loading