Skip to content

Commit

Permalink
Update z-seam handling and improve path optimization
Browse files Browse the repository at this point in the history
This update tweaks handling of the z-seam by allowing it to shift away from the model based on specific settings. It also introduces better path optimization, by calculating the shortest distance from a point to a line segment, optimizing how the best position is retrieved if such support exists and dealing with edge cases where no optimal starting path is found.

CURA-11227
  • Loading branch information
saumyaj3 committed Apr 23, 2024
1 parent 8c6d99e commit 9d35904
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 13 deletions.
61 changes: 52 additions & 9 deletions include/PathOrderOptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class PathOrderOptimizer

// For some Z seam types the start position can be pre-computed.
// This is faster since we don't need to re-compute the start position at each step then.
precompute_start &= seam_config_.type_ == EZSeamType::SUPPORT || seam_config_.type_ == EZSeamType::RANDOM || seam_config_.type_ == EZSeamType::USER_SPECIFIED
precompute_start &= seam_config_.type_ == EZSeamType::RANDOM || seam_config_.type_ == EZSeamType::USER_SPECIFIED
|| seam_config_.type_ == EZSeamType::SHARPEST_CORNER;
if (precompute_start)
{
Expand Down Expand Up @@ -578,17 +578,46 @@ class PathOrderOptimizer
{
for (const auto& points : ranges::front(mesh_paths_))
{
for (const auto& polygon_point : points)
const int len = points.size();

for (int i = 0; i < len; ++i)
{
double distance = std::sqrt(std::pow(static_cast<double>(polygon_point.X - point.X), 2) + std::pow(static_cast<double>(polygon_point.Y - point.Y), 2));
const auto& polygon_point1 = points[i];
const auto& polygon_point2 = points[(i + 1) % len]; // Ensures looping back to the first point to create the final segment

// Definitions
double x = static_cast<double>(point.X);
double y = static_cast<double>(point.Y);
double x1 = static_cast<double>(polygon_point1.X);
double y1 = static_cast<double>(polygon_point1.Y);
double x2 = static_cast<double>(polygon_point2.X);
double y2 = static_cast<double>(polygon_point2.Y);

// Calculate the shortest distance from the point to the line segment
double dx = x2 - x1;
double dy = y2 - y1;

// Calculate the t parameter
double t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);

// If t is outside bounds [0,1], point is closest to an endpoint of the segment
t = std::max(0.0, std::min(1.0, t));

// Compute the coordinates of the point on the line segment nearest to the external point
double nearestX = x1 + t * dx;
double nearestY = y1 + t * dy;

// Calculate squared distance from external point to its nearest point on the line segment
double dx_nearest = x - nearestX;
double dy_nearest = y - nearestY;
double squared_distance = dx_nearest*dx_nearest + dy_nearest*dy_nearest;

if (distance <= min_size_support_zeam_)
if (squared_distance <= min_size_support_zeam_ * min_size_support_zeam_)
{
return true;
}
}
}

return false;
}

Expand Down Expand Up @@ -638,14 +667,28 @@ class PathOrderOptimizer

size_t pathIfzeamSupportIsCloseToModel(size_t best_pos, const OrderablePath& path)
{
if (! mesh_paths_.empty())
static size_t number_of_paths_analysed = 0;
size_t path_size = path.converted_->size();
if (path_size > number_of_paths_analysed)
{
Point2LL current_candidate = (*path.converted_)[best_pos];
if (isVertexCloseToPolygonPath(current_candidate))
if (! mesh_paths_.empty())
{
best_pos = pathIfzeamSupportIsCloseToModel(best_pos + 1, path);
Point2LL current_candidate = (path.converted_)->at(best_pos);
if (isVertexCloseToPolygonPath(current_candidate))
{
size_t next_best_position = (path_size > best_pos + 1) ? best_pos + 1 : 0;
best_pos = pathIfzeamSupportIsCloseToModel(next_best_position, path);
number_of_paths_analysed +=1;
}
}
}
else
{
number_of_paths_analysed = 0;
spdlog::warn("no start path found for support z seam distance");
// We can also calculate the best point to start at this point.
// This usually happens when the distance of support seam from model is bigger than the whole support wall points.
}
return best_pos;
}

Expand Down
15 changes: 11 additions & 4 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
#include "utils/Simplify.h" //Removing micro-segments created by offsetting.
#include "utils/ThreadPool.h"
#include "utils/linearAlg2D.h"
#include "utils/polygonUtils.h"
#include "utils/math.h"
#include "utils/orderOptimizer.h"
#include "utils/polygonUtils.h"

namespace cura
{
Expand Down Expand Up @@ -3452,11 +3452,18 @@ bool FffGcodeWriter::processSupportInfill(const SliceDataStorage& storage, Layer
const GCodePathConfig& config = configs[0];
constexpr bool retract_before_outer_wall = false;
constexpr coord_t wipe_dist = 0;
EZSeamType z_seam_type = EZSeamType::SHORTEST;
ZSeamConfig z_seam_config;
Point2LL start_pos;
Point2LL start_pos = gcode_layer.getLastPlannedPositionOrStartingPosition();
if (infill_extruder.settings_.get<bool>("support_z_seam_away_from_model"))
{
z_seam_type = EZSeamType::SUPPORT;
}

start_pos = gcode_layer.getLastPlannedPositionOrStartingPosition();
z_seam_config = ZSeamConfig(EZSeamType::SUPPORT, start_pos, EZSeamCornerPrefType::Z_SEAM_CORNER_PREF_NONE, false);
z_seam_config = ZSeamConfig(z_seam_type,
start_pos,
EZSeamCornerPrefType::Z_SEAM_CORNER_PREF_NONE,
false);


InsetOrderOptimizer wall_orderer(
Expand Down

0 comments on commit 9d35904

Please sign in to comment.