Skip to content

Commit

Permalink
[CURA-9474] (Some) Seams Not On Vertices (#2087)
Browse files Browse the repository at this point in the history
  • Loading branch information
HellAholic authored Jun 19, 2024
2 parents 6e231e5 + d6f171f commit 3dc1b99
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
9 changes: 9 additions & 0 deletions include/InsetOrderOptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ class InsetOrderOptimizer
Shape retraction_region_; // After printing an outer wall, move into this region so that retractions do not leave visible blobs. Calculated lazily if needed (see
// retraction_region_calculated).

/*!
* Given a closed polygon, insert a seam point at the point where the seam should be placed.
* This should result in the seam-finding algorithm finding that exact point, instead of the
* 'best' vertex on that polygon. Under certain circumstances, the seam-placing algorithm can
* however still deviate from this, for example when the seam-point placed here isn't suppored
* by the layer below.
*/
void insertSeamPoint(ExtrusionLine& closed_line);

/*!
* Determine if the paths should be reversed
* If there is one extruder used, and we're currently printing the inner walls then Reversing the insets now depends on the inverse of
Expand Down
56 changes: 55 additions & 1 deletion src/InsetOrderOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,14 @@ bool InsetOrderOptimizer::addToLayer()
group_outer_walls,
disallowed_areas_for_seams_);

for (const auto& line : walls_to_be_added)
for (auto& line : walls_to_be_added)
{
if (line.is_closed_)
{
if (! settings_.get<bool>("z_seam_on_vertex"))
{
insertSeamPoint(line);
}
order_optimizer.addPolygon(&line);
}
else
Expand Down Expand Up @@ -164,6 +168,56 @@ bool InsetOrderOptimizer::addToLayer()
return added_something;
}

void InsetOrderOptimizer::insertSeamPoint(ExtrusionLine& closed_line)
{
assert(closed_line.is_closed_);
assert(closed_line.size() >= 3);

Point2LL request_point;
switch (z_seam_config_.type_)
{
case EZSeamType::USER_SPECIFIED:
request_point = z_seam_config_.pos_;
break;
case EZSeamType::SHORTEST:
request_point = gcode_layer_.getLastPlannedPositionOrStartingPosition();
break;
default:
return;
}

// NOTE: Maybe rewrite this once we can use C++23 ranges::views::adjacent
size_t closest_junction_idx = 0;
coord_t closest_distance_sqd = std::numeric_limits<coord_t>::max();
for (const auto& [i, junction] : closed_line.junctions_ | ranges::views::enumerate)
{
const auto& next_junction = closed_line.junctions_[(i + 1) % closed_line.junctions_.size()];
const coord_t distance_sqd = LinearAlg2D::getDist2FromLineSegment(junction.p_, request_point, next_junction.p_);
if (distance_sqd < closest_distance_sqd)
{
closest_distance_sqd = distance_sqd;
closest_junction_idx = i;
}
}

const auto& start_pt = closed_line.junctions_[closest_junction_idx];
const auto& end_pt = closed_line.junctions_[(closest_junction_idx + 1) % closed_line.junctions_.size()];
const auto closest_point = LinearAlg2D::getClosestOnLineSegment(request_point, start_pt.p_, end_pt.p_);
constexpr coord_t smallest_dist_sqd = 25;
if (vSize2(closest_point - start_pt.p_) <= smallest_dist_sqd || vSize2(closest_point - end_pt.p_) <= smallest_dist_sqd)
{
return;
}

// NOTE: This could also be done on a single axis (skipping the implied sqrt), but figuring out which one and then using the right values became a bit messy/verbose.
const coord_t total_dist = vSize(end_pt.p_ - start_pt.p_);
const coord_t start_dist = vSize(closest_point - start_pt.p_);
const coord_t end_dist = vSize(closest_point - end_pt.p_);
const coord_t w = ((end_pt.w_ * end_dist) / total_dist) + ((start_pt.w_ * start_dist) / total_dist);

closed_line.junctions_.insert(closed_line.junctions_.begin() + closest_junction_idx + 1, ExtrusionJunction(closest_point, w, start_pt.perimeter_index_));
}

InsetOrderOptimizer::value_type InsetOrderOptimizer::getRegionOrder(const std::vector<ExtrusionLine>& extrusion_lines, const bool outer_to_inner)
{
if (extrusion_lines.empty())
Expand Down

0 comments on commit 3dc1b99

Please sign in to comment.