Skip to content

Commit

Permalink
[CURA-9399] Fix 'Innacurate Tops Of Sharp Objects' (#2092)
Browse files Browse the repository at this point in the history
  • Loading branch information
HellAholic authored Jun 21, 2024
2 parents 2f395b0 + 5c24075 commit 6b461c7
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 35 deletions.
2 changes: 1 addition & 1 deletion include/SkeletalTrapezoidationJoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class SkeletalTrapezoidationJoint
{
beading_ = storage;
}
std::shared_ptr<BeadingPropagation> getBeading()
std::shared_ptr<BeadingPropagation> getBeading() const
{
return beading_.lock();
}
Expand Down
4 changes: 2 additions & 2 deletions include/WallToolPaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ class WallToolPaths
static void stitchToolPaths(std::vector<VariableWidthLines>& toolpaths, const Settings& settings);

/*!
* Remove polylines shorter than half the smallest line width along that polyline.
* Remove polylines shorter than half the smallest line width along that polyline, if that polyline isn't part of an outer wall.
*/
static void removeSmallLines(std::vector<VariableWidthLines>& toolpaths);
static void removeSmallFillLines(std::vector<VariableWidthLines>& toolpaths);

/*!
* Simplifies the variable-width toolpaths by calling the simplify on every line in the toolpath using the provided
Expand Down
11 changes: 10 additions & 1 deletion include/utils/polygonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,16 @@ class PolygonUtils
* \param a_step The angle between segments of the circle.
* \return A new Polygon containing the circle.
*/
static Polygon makeCircle(const Point2LL mid, const coord_t radius, const AngleRadians a_step = std::numbers::pi / 8);
template<typename T = Polygon, typename... VA>
static T makeCircle(const Point2LL& mid, const coord_t radius, const AngleRadians a_step = std::numbers::pi / 8, VA... args)
{
T circle;
for (double a = 0; a < 2 * std::numbers::pi; a += a_step)
{
circle.emplace_back(mid + Point2LL(radius * cos(a), radius * sin(a)), args...);
}
return circle;
}

/*!
* Create a "wheel" shape.
Expand Down
83 changes: 64 additions & 19 deletions src/SkeletalTrapezoidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "utils/VoronoiUtils.h"
#include "utils/linearAlg2D.h"
#include "utils/macros.h"
#include "utils/polygonUtils.h"

#define SKELETAL_TRAPEZOIDATION_BEAD_SEARCH_MAX \
1000 // A limit to how long it'll keep searching for adjacent beads. Increasing will re-use beadings more often (saving performance), but search longer for beading (costing
Expand Down Expand Up @@ -2184,39 +2185,83 @@ void SkeletalTrapezoidation::generateLocalMaximaSingleBeads()
{
std::vector<VariableWidthLines>& generated_toolpaths = *p_generated_toolpaths;

for (auto& node : graph_.nodes)
const auto addCircleToToolpath = [&](const Point2LL& center, coord_t width, size_t inset_index)
{
if (inset_index >= generated_toolpaths.size())
{
generated_toolpaths.resize(inset_index + 1);
}
constexpr bool is_odd = true;
generated_toolpaths[inset_index].emplace_back(inset_index, is_odd);
ExtrusionLine& line = generated_toolpaths[inset_index].back();
// total area to be extruded is pi*(w/2)^2 = pi*w*w/4
// Width a constant extrusion width w, that would be a length of pi*w/4
// If we make a small circle to fill up the hole, then that circle would have a circumference of 2*pi*r
// So our circle needs to be such that r=w/8
const coord_t r = width / 8;
constexpr coord_t n_segments = 6;
const auto circle = PolygonUtils::makeCircle<std::vector<ExtrusionJunction>>(center, r, 2 * std::numbers::pi / n_segments, width, inset_index);
line.junctions_.insert(line.junctions_.end(), circle.begin(), circle.end());
};

Point2LL local_maxima_accumulator;
coord_t width_accumulator = 0;
size_t accumulator_count = 0;

for (const auto& node : graph_.nodes)
{
if (! node.data_.hasBeading())
{
continue;
}
Beading& beading = node.data_.getBeading()->beading_;
if (beading.bead_widths.size() % 2 == 1 && node.isLocalMaximum(true) && ! node.isCentral())
const Beading& beading = node.data_.getBeading()->beading_;
if (beading.bead_widths.size() % 2 == 1 && node.isLocalMaximum(true))
{
const size_t inset_index = beading.bead_widths.size() / 2;
constexpr bool is_odd = true;
if (inset_index >= generated_toolpaths.size())
const coord_t width = beading.bead_widths[inset_index];
local_maxima_accumulator += node.p_;
width_accumulator += width;
++accumulator_count;
if (! node.isCentral())
{
generated_toolpaths.resize(inset_index + 1);
addCircleToToolpath(node.p_, width, inset_index);
}
generated_toolpaths[inset_index].emplace_back(inset_index, is_odd);
ExtrusionLine& line = generated_toolpaths[inset_index].back();
const coord_t width = beading.bead_widths[inset_index];
// total area to be extruded is pi*(w/2)^2 = pi*w*w/4
// Width a constant extrusion width w, that would be a length of pi*w/4
// If we make a small circle to fill up the hole, then that circle would have a circumference of 2*pi*r
// So our circle needs to be such that r=w/8
const coord_t r = width / 8;
constexpr coord_t n_segments = 6;
for (coord_t segment = 0; segment < n_segments; segment++)
}
}

if (accumulator_count > 0)
{
bool replace_with_local_maxima = generated_toolpaths.empty() || generated_toolpaths[0].empty();
coord_t total_path_length = 0;
if (! replace_with_local_maxima)
{
coord_t min_width = std::numeric_limits<coord_t>::max();
for (const auto& line : generated_toolpaths[0])
{
double a = 2.0 * std::numbers::pi / n_segments * segment;
line.junctions_.emplace_back(node.p_ + Point2LL(r * cos(a), r * sin(a)), width, inset_index);
total_path_length += line.length();
for (const ExtrusionJunction& j : line)
{
min_width = std::min(min_width, j.w_);
}
}
replace_with_local_maxima |= total_path_length <= min_width / 2;
}
if (replace_with_local_maxima)
{
const coord_t width = width_accumulator / accumulator_count;
local_maxima_accumulator = local_maxima_accumulator / accumulator_count;
if (generated_toolpaths.empty())
{
generated_toolpaths.emplace_back();
}
else
{
generated_toolpaths[0].clear();
}
addCircleToToolpath(local_maxima_accumulator, width, 0);
}
}
}

//
// ^^^^^^^^^^^^^^^^^^^^^
// TOOLPATH GENERATION
Expand Down
8 changes: 6 additions & 2 deletions src/WallToolPaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ const std::vector<VariableWidthLines>& WallToolPaths::generate()
scripta::PointVDI{ "width", &ExtrusionJunction::w_ },
scripta::PointVDI{ "perimeter_index", &ExtrusionJunction::perimeter_index_ });

removeSmallLines(toolpaths_);
removeSmallFillLines(toolpaths_);
scripta::log(
"toolpaths_2",
toolpaths_,
Expand Down Expand Up @@ -274,13 +274,17 @@ void WallToolPaths::stitchToolPaths(std::vector<VariableWidthLines>& toolpaths,
}
}

void WallToolPaths::removeSmallLines(std::vector<VariableWidthLines>& toolpaths)
void WallToolPaths::removeSmallFillLines(std::vector<VariableWidthLines>& toolpaths)
{
for (VariableWidthLines& inset : toolpaths)
{
for (size_t line_idx = 0; line_idx < inset.size(); line_idx++)
{
ExtrusionLine& line = inset[line_idx];
if (line.is_outer_wall())
{
continue;
}
coord_t min_width = std::numeric_limits<coord_t>::max();
for (const ExtrusionJunction& j : line)
{
Expand Down
10 changes: 0 additions & 10 deletions src/utils/polygonUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1386,16 +1386,6 @@ double PolygonUtils::relativeHammingDistance(const Shape& poly_a, const Shape& p
return hamming_distance / total_area;
}

Polygon PolygonUtils::makeCircle(const Point2LL mid, const coord_t radius, const AngleRadians a_step)
{
Polygon circle;
for (double a = 0; a < 2 * std::numbers::pi; a += a_step)
{
circle.emplace_back(mid + Point2LL(radius * cos(a), radius * sin(a)));
}
return circle;
}

Polygon PolygonUtils::makeWheel(const Point2LL& mid, const coord_t inner_radius, const coord_t outer_radius, const size_t semi_nb_spokes, const size_t arc_angle_resolution)
{
Polygon wheel;
Expand Down

0 comments on commit 6b461c7

Please sign in to comment.