Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/CURA-9399_sharp_points' into sma…
Browse files Browse the repository at this point in the history
…ller-prime-tower
  • Loading branch information
wawanbreton committed Jun 19, 2024
2 parents 8108a08 + 047aca7 commit d6813bc
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 40 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
24 changes: 21 additions & 3 deletions include/utils/polygonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -614,10 +614,28 @@ class PolygonUtils
*
* \param mid The center of the circle.
* \param radius The radius of the circle.
* \param steps The numbers of segments (definition) of the generated circle.
* \return A new Polygon containing the circle.
* \param segments The numbers of segments (definition) of the generated circle.
* \tparam explicitly_closed Indicates whether the circle should be explicitely (or implicitely) closed
* \return A new object containing the circle points.
*/
static ClosedPolyline makeCircle(const Point2LL& mid, const coord_t radius, const size_t steps);
template<typename T = ClosedPolyline, bool explicitely_closed = false, typename... VA>
static T makeCircle(const Point2LL& mid, const coord_t radius, const size_t segments, VA... args)
{
T circle;
const AngleRadians step_angle = (std::numbers::pi * 2) / static_cast<double>(segments);
for (size_t step = 0; step < segments; ++step)
{
const AngleRadians angle = static_cast<double>(step) * step_angle;
circle.emplace_back(makeCirclePoint(mid, radius, angle), args...);
}

if constexpr (explicitely_closed)
{
circle.push_back(circle.front());
}

return circle;
}

/*!
* Create a point of a circle.
Expand Down
76 changes: 57 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,76 @@ 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>, true>(center, r, 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;
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
14 changes: 1 addition & 13 deletions src/utils/polygonUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1305,19 +1305,7 @@ double PolygonUtils::relativeHammingDistance(const Shape& poly_a, const Shape& p

Polygon PolygonUtils::makeDisc(const Point2LL& mid, const coord_t radius, const size_t steps)
{
Polygon disc;
const AngleRadians step_angle = (std::numbers::pi * 2) / static_cast<double>(steps);
for (size_t step = 0; step < steps; ++step)
{
const AngleRadians angle = static_cast<double>(step) * step_angle;
disc.push_back(makeCirclePoint(mid, radius, angle));
}
return disc;
}

ClosedPolyline PolygonUtils::makeCircle(const Point2LL& mid, const coord_t radius, const size_t steps)
{
return makeDisc(mid, radius, steps);
return makeCircle<Polygon>(mid, radius, steps);
}

Point2LL PolygonUtils::makeCirclePoint(const Point2LL& mid, const coord_t radius, const AngleRadians& angle)
Expand Down

0 comments on commit d6813bc

Please sign in to comment.