Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash when using tangent on angles with PI/2 value #2110

Merged
merged 3 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions include/settings/types/Angle.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,19 @@ constexpr inline AngleRadians::AngleRadians(const AngleDegrees& value)
{
}

/*!
* \brief Safe call to "std::tan" which limits the higher angle value to something slightly less that π/2 so that when
* the given angle is higher that this value, the returned value is not a huge number
* \param angle The input angle, which should be [0, π/2]
* \return The tangent value of the angle, limited
* \note This method exists as a convenience because this is a common case in the engine, as we have many settings that
* are angles setup on [0, π/2] and which translate to a distance
*/
inline double boundedTan(const AngleRadians& angle)
{
return std::tan(std::min(static_cast<double>(angle), std::numbers::pi / 2.0 - 0.001));
}

} // namespace cura

#endif // ANGLE_H
14 changes: 7 additions & 7 deletions src/support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,11 +471,11 @@ Shape AreaSupport::join(const SliceDataStorage& storage, const Shape& supportLay
coord_t conical_support_offset;
if (conical_support_angle > 0)
{ // outward ==> wider base than overhang
conical_support_offset = -(tan(conical_support_angle) - 0.01) * layer_thickness;
conical_support_offset = -boundedTan(conical_support_angle) * layer_thickness;
}
else
{ // inward ==> smaller base than overhang
conical_support_offset = (tan(-conical_support_angle) - 0.01) * layer_thickness;
conical_support_offset = boundedTan(-conical_support_angle) * layer_thickness;
}
const bool conical_support = infill_settings.get<bool>("support_conical_enabled") && conical_support_angle != 0;
if (conical_support)
Expand Down Expand Up @@ -888,7 +888,7 @@ Shape AreaSupport::generateVaryingXYDisallowedArea(const SliceMeshStorage& stora
const auto support_distance = z_delta_poly.support_distance;
const auto delta_z = z_delta_poly.delta_z;
const auto layer_delta = z_delta_poly.layer_delta;
const auto xy_distance_natural = support_distance * std::tan(overhang_angle);
const auto xy_distance_natural = support_distance * boundedTan(overhang_angle);

for (auto [current_poly_idx, current_poly] : layer_current | ranges::views::enumerate)
{
Expand Down Expand Up @@ -1244,11 +1244,11 @@ void AreaSupport::generateSupportAreasForMesh(
coord_t conical_support_offset;
if (conical_support_angle > 0)
{ // outward ==> wider base than overhang
conical_support_offset = -(tan(conical_support_angle) - 0.01) * layer_thickness;
conical_support_offset = -boundedTan(conical_support_angle) * layer_thickness;
}
else
{ // inward ==> smaller base than overhang
conical_support_offset = (tan(-conical_support_angle) - 0.01) * layer_thickness;
conical_support_offset = boundedTan(-conical_support_angle) * layer_thickness;
}
const bool conical_support = infill_settings.get<bool>("support_conical_enabled") && conical_support_angle != 0;
for (LayerIndex layer_idx = 1; layer_idx < storage.support.supportLayers.size(); layer_idx++)
Expand Down Expand Up @@ -1447,7 +1447,7 @@ std::pair<Shape, Shape> AreaSupport::computeBasicAndFullOverhang(const SliceData

const coord_t layer_height = mesh.settings.get<coord_t>("layer_height");
const AngleRadians support_angle = mesh.settings.get<AngleRadians>("support_angle");
const double tan_angle = tan(support_angle) - 0.01; // The X/Y component of the support angle. 0.01 to make 90 degrees work too.
const double tan_angle = boundedTan(support_angle); // The X/Y component of the support angle
// overhang areas protruding less then `max_dist_from_lower_layer` don't need support
const coord_t max_dist_from_lower_layer = tan_angle * layer_height; // Maximum horizontal distance that can be bridged.

Expand Down Expand Up @@ -1576,7 +1576,7 @@ void AreaSupport::handleTowers(
}
else
{
const double tan_tower_roof_angle = tan(tower_roof_angle);
const double tan_tower_roof_angle = boundedTan(tower_roof_angle);
tower_roof_expansion_distance = layer_thickness / tan_tower_roof_angle;
}

Expand Down
Loading