Skip to content

Commit a9e2a36

Browse files
committed
Merge similar speed regions to avoid generating micro-segments
CURA-11966
1 parent 71c8e14 commit a9e2a36

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

src/FffGcodeWriter.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <optional>
1313
#include <unordered_set>
1414

15+
#include <range/v3/view/chunk_by.hpp>
1516
#include <range/v3/view/concat.hpp>
1617
#include <spdlog/spdlog.h>
1718

@@ -3089,8 +3090,13 @@ bool FffGcodeWriter::processInsets(
30893090
// the supported region is made up of those areas that really are supported by either model or support on the layer below
30903091
// expanded to take into account the overhang angle, the greater the overhang angle, the larger the supported area is
30913092
// considered to be
3092-
const coord_t overhang_width = layer_height * std::tan(AngleRadians(overhang_angle));
3093-
return fully_supported_region.offset(overhang_width + 10);
3093+
if (overhang_angle < 90.0)
3094+
{
3095+
const coord_t overhang_width = layer_height * std::tan(AngleRadians(overhang_angle));
3096+
return fully_supported_region.offset(overhang_width + 10);
3097+
}
3098+
3099+
return Shape();
30943100
};
30953101

30963102
// Build supported regions for all the overhang speeds. For a visual explanation of the result, see doc/gradual_overhang_speed.svg
@@ -3100,17 +3106,46 @@ bool FffGcodeWriter::processInsets(
31003106
const auto wall_overhang_angle = mesh.settings.get<AngleDegrees>("wall_overhang_angle");
31013107
if (overhang_angles_count > 0 && wall_overhang_angle < 90.0)
31023108
{
3109+
struct SpeedRegion
3110+
{
3111+
AngleDegrees overhang_angle;
3112+
Ratio speed_factor;
3113+
};
3114+
3115+
// Create raw speed regions
31033116
const AngleDegrees overhang_step = (90.0 - wall_overhang_angle) / static_cast<double>(overhang_angles_count);
3104-
for (size_t angle_index = 0; angle_index < overhang_angles_count; ++angle_index)
3117+
std::vector<SpeedRegion> speed_regions;
3118+
speed_regions.reserve(overhang_angles_count + 1);
3119+
3120+
speed_regions.push_back(SpeedRegion{ wall_overhang_angle, 1.0_r }); // Initial internal region, always 100% speed factor
3121+
3122+
for (size_t angle_index = 1; angle_index < overhang_angles_count; ++angle_index)
31053123
{
31063124
const AngleDegrees actual_wall_overhang_angle = wall_overhang_angle + static_cast<double>(angle_index) * overhang_step;
3107-
const Ratio speed_factor = angle_index == 0 ? 1.0_r : overhang_speed_factors[angle_index - 1];
3125+
const Ratio speed_factor = overhang_speed_factors[angle_index - 1];
31083126

3109-
overhang_masks.push_back(LayerPlan::OverhangMask{ get_supported_region(actual_wall_overhang_angle), speed_factor });
3127+
speed_regions.push_back(SpeedRegion{ actual_wall_overhang_angle, speed_factor });
31103128
}
31113129

3112-
// Add an empty region, which actually means everything and should be ignored anyway
3113-
overhang_masks.push_back(LayerPlan::OverhangMask{ Shape(), overhang_speed_factors.back() });
3130+
speed_regions.push_back(SpeedRegion{ 90.0, overhang_speed_factors.back() }); // Final "everything else" speed region
3131+
3132+
// Now merge regions that have similar speed factors (saves calculations and avoid generating micro-segments)
3133+
auto merged_regions = speed_regions
3134+
| ranges::views::chunk_by(
3135+
[](const auto& region_a, const auto& region_b)
3136+
{
3137+
return region_a.speed_factor == region_b.speed_factor;
3138+
});
3139+
3140+
// If finally necessary, add actual calculated speed regions
3141+
if (std::ranges::distance(merged_regions) > 1)
3142+
{
3143+
for (const auto& regions : merged_regions)
3144+
{
3145+
const SpeedRegion& last_region = *std::ranges::prev(regions.end());
3146+
overhang_masks.push_back(LayerPlan::OverhangMask{ get_supported_region(last_region.overhang_angle), last_region.speed_factor });
3147+
}
3148+
}
31143149
}
31153150
gcode_layer.setOverhangMasks(overhang_masks);
31163151

0 commit comments

Comments
 (0)