Skip to content

Commit

Permalink
Use the most explicit geometric types in PrimeTower
Browse files Browse the repository at this point in the history
  • Loading branch information
wawanbreton committed Jun 17, 2024
1 parent 992d187 commit eced18e
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 66 deletions.
7 changes: 4 additions & 3 deletions include/PrimeTower/PrimeTower.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <vector>

#include "ExtruderUse.h"
#include "geometry/ClosedLinesSet.h"
#include "geometry/Polygon.h"
#include "settings/EnumSettings.h"
#include "settings/types/LayerIndex.h"
Expand Down Expand Up @@ -38,7 +39,7 @@ class PrimeTower
struct ExtruderToolPaths
{
size_t extruder_nr;
Shape toolpaths;
ClosedLinesSet toolpaths;
coord_t outer_radius;
coord_t inner_radius;
};
Expand Down Expand Up @@ -179,7 +180,7 @@ class PrimeTower
* \param outer_radius The radius of the starting outer circle
* \return A tuple containing the newly generated toolpaths, and the inner radius of the newly generated annulus
*/
std::tuple<Shape, coord_t> generatePrimeToolpaths(const size_t extruder_nr, const coord_t outer_radius);
std::tuple<ClosedLinesSet, coord_t> generatePrimeToolpaths(const size_t extruder_nr, const coord_t outer_radius);

/*!
* \brief Generate support toolpaths using the wheel pattern applied on an annulus
Expand All @@ -188,7 +189,7 @@ class PrimeTower
* \param inner_radius The annulis inner radius
* \return
*/
Shape generateSupportToolpaths(const size_t extruder_nr, const coord_t outer_radius, const coord_t inner_radius);
ClosedLinesSet generateSupportToolpaths(const size_t extruder_nr, const coord_t outer_radius, const coord_t inner_radius);

/*!
* \brief Calculates whether an extruder requires priming at a specific layer
Expand Down
9 changes: 6 additions & 3 deletions include/geometry/ClosedPolyline.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ class ClosedPolyline : public Polyline
bool explicitely_closed_{ false };

public:
/*!
* \brief Builds an empty closed polyline
* \warning By default, the line is tagged as non explicitely closed. We need this default
* constructor in various places, but be careful that the interpretation of the points
* added later will depend on this.
*/
ClosedPolyline() = default;

/*!
* \brief Builds an empty closed polyline
* \param explicitely_closed Indicates whether the line will be explicitely closed
* \warning By default, the line is tagged as explicitely closed. We need this default
* constructor in various places, but be careful that the interpretation of the points
* added later will depend on this.
*/
explicit ClosedPolyline(const bool explicitely_closed)
: explicitely_closed_{ explicitely_closed }
Expand Down
30 changes: 19 additions & 11 deletions include/utils/polygonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "PolygonsPointIndex.h"
#include "SparseLineGrid.h"
#include "SparsePointGridInclusive.h"
#include "geometry/ClosedLinesSet.h"
#include "geometry/Polygon.h"

namespace cura
Expand Down Expand Up @@ -599,15 +600,24 @@ class PolygonUtils
static double relativeHammingDistance(const Shape& poly_a, const Shape& poly_b);

/*!
* Create an approximation of a circle.
* Creates a regular polygon that is supposed to approximate a disc.
*
* \param mid The center of the disc.
* \param radius The radius of the disc.
* \param steps The numbers of segments (definition) of the generated disc.
* \return A new Polygon containing the disc.
*/
static Polygon makeDisc(const Point2LL& mid, const coord_t radius, const size_t steps);

/*!
* Creates a closed polyline that is supposed to approximate a circle.
*
* This creates a regular polygon that is supposed to approximate a circle.
* \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.
*/
static Polygon makeCircle(const Point2LL& mid, const coord_t radius, const size_t steps);
static ClosedPolyline makeCircle(const Point2LL& mid, const coord_t radius, const size_t steps);

/*!
* Create a point of a circle.
Expand All @@ -620,17 +630,16 @@ class PolygonUtils
static Point2LL makeCirclePoint(const Point2LL& mid, const coord_t radius, const AngleRadians& angle);

/*!
* Create a "wheel" shape.
* This creates a polyline which represents the shape of a wheel, which is kind of a "circular zigzag" pattern.
*
* This creates a polygon which represents the shape of a wheel.
* \param mid The center of the circle.
* \param inner_radius The radius of the wheel inner circle.
* \param outer_radius The radius of the wheel outer circle.
* \param semi_nb_spokes The semi number of spokes in the wheel. There will actually be N*2 spokes.
* \param arc_angle_resolution The number of segment on each arc.
* \return A new Polygon containing the circle.
* \param arc_angle_resolution The number of segments on each arc.
* \return A new Polyline containing the circle.
*/
static Polygon 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);
static ClosedPolyline 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);

/*!
* Connect all polygons to their holes using zero widths hole channels, so that the polygons and their outlines are connected together
Expand All @@ -641,7 +650,6 @@ class PolygonUtils

static Shape unionManySmall(const Shape& polygon);


/*!
* Intersects a polygon with an AABB.
* \param src The polygon that has to be intersected with an AABB
Expand All @@ -660,7 +668,7 @@ class PolygonUtils
* \param circle_definition The definition (number of segments) of the generated circles
* \return The generated outset circles, and the outer radius or the shape
*/
static std::tuple<Shape, coord_t>
static std::tuple<ClosedLinesSet, coord_t>
generateCirculatOutset(const Point2LL& center, const coord_t inner_radius, const coord_t outer_radius, const coord_t line_width, const size_t circle_definition);

/*!
Expand All @@ -672,7 +680,7 @@ class PolygonUtils
* \param circle_definition The definition (number of segments) of the generated circles
* \return The generated inset circles
*/
static Shape generateCircularInset(const Point2LL& center, const coord_t outer_radius, const coord_t line_width, const size_t circle_definition);
static ClosedLinesSet generateCircularInset(const Point2LL& center, const coord_t outer_radius, const coord_t line_width, const size_t circle_definition);

private:
/*!
Expand Down
24 changes: 12 additions & 12 deletions src/PrimeTower/PrimeTower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ PrimeTower::PrimeTower()
const double base_curve_magnitude = mesh_group_settings.get<double>("prime_tower_base_curve_magnitude");

middle_ = Point2LL(x - tower_radius, y + tower_radius);
outer_poly_ = { PolygonUtils::makeCircle(middle_, tower_radius, circle_definition_), tower_radius };
outer_poly_ = { PolygonUtils::makeDisc(middle_, tower_radius, circle_definition_), tower_radius };
post_wipe_point_ = Point2LL(x - tower_radius, y + tower_radius);

// Generate the base outline
Expand All @@ -53,7 +53,7 @@ PrimeTower::PrimeTower()
const double brim_radius_factor = std::pow((1.0 - static_cast<double>(z) / static_cast<double>(base_height)), base_curve_magnitude);
const coord_t extra_radius = std::llrint(static_cast<double>(base_extra_radius) * brim_radius_factor);
const coord_t total_radius = tower_radius + extra_radius;
base_occupied_outline_.emplace_back(PolygonUtils::makeCircle(middle_, total_radius, circle_definition_), total_radius);
base_occupied_outline_.emplace_back(PolygonUtils::makeDisc(middle_, total_radius, circle_definition_), total_radius);
}
}
}
Expand Down Expand Up @@ -83,11 +83,11 @@ void PrimeTower::generateBase()
const size_t extruder_nr = first_extruder_toolpaths.extruder_nr;
const coord_t line_width = scene.extruders[extruder_nr].settings_.get<coord_t>("prime_tower_line_width");

std::tuple<Shape, coord_t> outset
std::tuple<ClosedLinesSet, coord_t> outset
= PolygonUtils::generateCirculatOutset(middle_, first_extruder_toolpaths.outer_radius, base_ouline_at_this_layer.outer_radius, line_width, circle_definition_);
first_extruder_toolpaths.toolpaths.push_back(std::get<0>(outset));

base_extrusion_outline_.push_back(PolygonUtils::makeCircle(middle_, std::get<1>(outset), circle_definition_));
base_extrusion_outline_.push_back(PolygonUtils::makeDisc(middle_, std::get<1>(outset), circle_definition_));
}
}
}
Expand All @@ -105,13 +105,13 @@ void PrimeTower::generateFirtLayerInset()
const Scene& scene = Application::getInstance().current_slice_->scene;
const size_t extruder_nr = last_extruder_toolpaths.extruder_nr;
const coord_t line_width = scene.extruders[extruder_nr].settings_.get<coord_t>("prime_tower_line_width");
Shape pattern = PolygonUtils::generateCircularInset(middle_, last_extruder_toolpaths.inner_radius, line_width, circle_definition_);
ClosedLinesSet pattern = PolygonUtils::generateCircularInset(middle_, last_extruder_toolpaths.inner_radius, line_width, circle_definition_);
last_extruder_toolpaths.toolpaths.push_back(pattern);
}
}
}

std::tuple<Shape, coord_t> PrimeTower::generatePrimeToolpaths(const size_t extruder_nr, const coord_t outer_radius)
std::tuple<ClosedLinesSet, coord_t> PrimeTower::generatePrimeToolpaths(const size_t extruder_nr, const coord_t outer_radius)
{
const Scene& scene = Application::getInstance().current_slice_->scene;
const Settings& mesh_group_settings = scene.current_mesh_group->settings;
Expand All @@ -123,10 +123,10 @@ std::tuple<Shape, coord_t> PrimeTower::generatePrimeToolpaths(const size_t extru

double current_volume = 0;
coord_t current_outer_radius = outer_radius - semi_line_width;
Shape toolpaths;
ClosedLinesSet toolpaths;
while (current_volume < required_volume && current_outer_radius >= semi_line_width)
{
Polygon circle = PolygonUtils::makeCircle(middle_, current_outer_radius, circle_definition_);
ClosedPolyline circle = PolygonUtils::makeCircle(middle_, current_outer_radius, circle_definition_);
toolpaths.push_back(circle);
current_volume += static_cast<double>(circle.length() * line_width * layer_height) * flow;
current_outer_radius -= line_width;
Expand All @@ -135,15 +135,15 @@ std::tuple<Shape, coord_t> PrimeTower::generatePrimeToolpaths(const size_t extru
return { toolpaths, current_outer_radius + semi_line_width };
}

Shape PrimeTower::generateSupportToolpaths(const size_t extruder_nr, const coord_t outer_radius, const coord_t inner_radius)
ClosedLinesSet PrimeTower::generateSupportToolpaths(const size_t extruder_nr, const coord_t outer_radius, const coord_t inner_radius)
{
const Scene& scene = Application::getInstance().current_slice_->scene;
const double max_bridging_distance = static_cast<double>(scene.extruders[extruder_nr].settings_.get<coord_t>("prime_tower_max_bridging_distance"));
const coord_t line_width = scene.extruders[extruder_nr].settings_.get<coord_t>("prime_tower_line_width");
const coord_t radius_delta = outer_radius - inner_radius;
const coord_t semi_line_width = line_width / 2;

Shape toolpaths;
ClosedLinesSet toolpaths;

// Split annuli according to max bridging distance
const coord_t nb_annuli = static_cast<coord_t>(std::ceil(static_cast<double>(radius_delta) / max_bridging_distance));
Expand Down Expand Up @@ -205,7 +205,7 @@ void PrimeTower::addToGcode(
return;
}

const Shape* toolpaths = nullptr;
const ClosedLinesSet* toolpaths = nullptr;
auto iterator_layer = toolpaths_.find(layer_nr);
if (iterator_layer != toolpaths_.end())
{
Expand All @@ -228,7 +228,7 @@ void PrimeTower::addToGcode(
gotoStartLocation(gcode_layer, new_extruder_nr);

const GCodePathConfig& config = gcode_layer.configs_storage_.prime_tower_config_per_extruder[new_extruder_nr];
gcode_layer.addPolygonsByOptimizer(*toolpaths, config);
gcode_layer.addLinesByOptimizer(*toolpaths, config, SpaceFillType::PolyLines);
}

gcode_layer.setPrimeTowerIsPlanned(new_extruder_nr);
Expand Down
4 changes: 2 additions & 2 deletions src/PrimeTower/PrimeTowerInterleaved.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ std::map<LayerIndex, std::vector<PrimeTower::ExtruderToolPaths>> PrimeTowerInter
{
if (toolpaths_at_layer.empty())
{
toolpaths_at_layer.emplace_back(last_extruder_support, Shape(), outer_radius, support_radius);
toolpaths_at_layer.emplace_back(last_extruder_support, ClosedLinesSet(), outer_radius, support_radius);
}

ExtruderToolPaths& last_extruder_toolpaths = toolpaths_at_layer.back();
Shape support_toolpaths = generateSupportToolpaths(last_extruder_toolpaths.extruder_nr, outer_radius, support_radius);
ClosedLinesSet support_toolpaths = generateSupportToolpaths(last_extruder_toolpaths.extruder_nr, outer_radius, support_radius);
last_extruder_toolpaths.toolpaths.push_back(support_toolpaths);
last_extruder_toolpaths.inner_radius = support_radius;
}
Expand Down
5 changes: 2 additions & 3 deletions src/sliceDataStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,8 @@ Shape SliceDataStorage::getMachineBorder(int checking_extruder_nr) const
}
Point2LL translation(extruder_settings.get<coord_t>("machine_nozzle_offset_x"), extruder_settings.get<coord_t>("machine_nozzle_offset_y"));
prime_pos -= translation;
Shape prime_polygons;
prime_polygons.emplace_back(PolygonUtils::makeCircle(prime_pos, prime_clearance, 64));
disallowed_areas = disallowed_areas.unionPolygons(prime_polygons);
Polygon prime_polygon = PolygonUtils::makeDisc(prime_pos, prime_clearance, 64);
disallowed_areas = disallowed_areas.unionPolygons(prime_polygon);
}

Shape disallowed_all_extruders;
Expand Down
55 changes: 23 additions & 32 deletions src/utils/polygonUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,60 +1303,51 @@ 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 size_t steps)
Polygon PolygonUtils::makeDisc(const Point2LL& mid, const coord_t radius, const size_t steps)
{
Polygon circle;
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;
circle.emplace_back(makeCirclePoint(mid, radius, angle));
disc.push_back(makeCirclePoint(mid, radius, angle));
}
return circle;
return disc;
}

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

Point2LL PolygonUtils::makeCirclePoint(const Point2LL& mid, const coord_t radius, const AngleRadians& angle)
{
return mid + Point2LL(std::llrint(static_cast<double>(radius) * cos(angle)), std::llrint(static_cast<double>(radius) * sin(angle)));
}

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)
ClosedPolyline 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;

std::vector<std::pair<coord_t, coord_t>> target_radii;
target_radii.push_back({ inner_radius, outer_radius });
target_radii.push_back({ outer_radius, inner_radius });
ClosedPolyline wheel;

const size_t nb_spokes = semi_nb_spokes * 2;
const float angle_step = TAU / nb_spokes;
const float arc_step = angle_step / arc_angle_resolution;
float angle = 0.0;
const double spoke_angle_step = TAU / static_cast<double>(nb_spokes);
const double arc_angle_step = spoke_angle_step / static_cast<double>(arc_angle_resolution);

for (size_t spoke = 0; spoke < nb_spokes; ++spoke)
{
const std::pair<coord_t, coord_t>& radii = target_radii.at(spoke % 2);
const double spoke_angle = static_cast<double>(spoke) * spoke_angle_step;
const coord_t radius = spoke % 2 == 0 ? inner_radius : outer_radius;

angle = spoke * angle_step;
float cos_angle = cos(angle);
float sin_angle = sin(angle);
wheel.emplace_back(mid + Point2LL(radii.first * cos_angle, radii.first * sin_angle));

for (size_t arc_part = 0; arc_part < arc_angle_resolution; ++arc_part)
for (size_t arc_part = 0; arc_part <= arc_angle_resolution; ++arc_part)
{
wheel.emplace_back(mid + Point2LL(radii.second * cos_angle, radii.second * sin_angle));
if (arc_part < arc_angle_resolution - 1)
{
angle += arc_step;
cos_angle = cos(angle);
sin_angle = sin(angle);
}
const double angle = spoke_angle + static_cast<double>(arc_part) * arc_angle_step;
wheel.push_back(makeCirclePoint(mid, radius, angle));
}
}

return wheel;
}


Shape PolygonUtils::connect(const Shape& input)
{
Shape ret;
Expand Down Expand Up @@ -1539,10 +1530,10 @@ Shape PolygonUtils::clipPolygonWithAABB(const Shape& src, const AABB& aabb)
return out;
}

std::tuple<Shape, coord_t>
std::tuple<ClosedLinesSet, coord_t>
PolygonUtils::generateCirculatOutset(const Point2LL& center, const coord_t inner_radius, const coord_t outer_radius, coord_t line_width, const size_t circle_definition)
{
Shape outset;
ClosedLinesSet outset;
const coord_t semi_line_width = line_width / 2;
coord_t radius = inner_radius + semi_line_width;

Expand All @@ -1555,9 +1546,9 @@ std::tuple<Shape, coord_t>
return { outset, radius - semi_line_width };
}

Shape PolygonUtils::generateCircularInset(const Point2LL& center, const coord_t outer_radius, const coord_t line_width, const size_t circle_definition)
ClosedLinesSet PolygonUtils::generateCircularInset(const Point2LL& center, const coord_t outer_radius, const coord_t line_width, const size_t circle_definition)
{
Shape inset;
ClosedLinesSet inset;
const coord_t semi_line_width = line_width / 2;
coord_t radius = outer_radius - semi_line_width;

Expand Down

0 comments on commit eced18e

Please sign in to comment.