Skip to content

Commit

Permalink
Fix ArcPolyline::split_at()
Browse files Browse the repository at this point in the history
add point::round, even if it's not really useful.
add & fix assert around ArcPolyline.
  • Loading branch information
supermerill committed Feb 1, 2025
1 parent 1b3600b commit 680679e
Show file tree
Hide file tree
Showing 12 changed files with 203 additions and 98 deletions.
4 changes: 2 additions & 2 deletions src/libslic3r/CutSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1891,8 +1891,8 @@ uint32_t priv::get_closest_point_index(const SearchData &sd,
const Polygon &poly = (id.polygon_index == 0) ?
shape.contour :
shape.holes[id.polygon_index - 1];
Point p_ = p.cast<coord_t>();
return p_ == poly[id.point_index];
assert((p.cast<coord_t>() == poly[id.point_index]) == (Point::round(p) == poly[id.point_index]));
return Point::round(p) == poly[id.point_index];
};

if (use_index) {
Expand Down
8 changes: 4 additions & 4 deletions src/libslic3r/ElephantFootCompensation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ std::vector<float> contour_distance(const EdgeGrid::Grid &grid, const size_t idx
this->idx_point_start = aidx_point_start;
this->pt = apt_start.cast<double>() + SCALED_EPSILON * dir;
dir *= radius;
this->pt_start = this->pt.cast<coord_t>();
this->pt_start = Point::round(this->pt);
// Trim the vector by the grid's bounding box.
const BoundingBox &bbox = this->grid.bbox();
double t = 1.;
Expand All @@ -77,7 +77,7 @@ std::vector<float> contour_distance(const EdgeGrid::Grid &grid, const size_t idx
this->dir = dir;
if (t < 1.)
dir *= t;
this->pt_end = (this->pt + dir).cast<coord_t>();
this->pt_end = Point::round(this->pt + dir);
this->t_min = 1.;
assert(this->grid.bbox().contains(this->pt_start) && this->grid.bbox().contains(this->pt_end));
}
Expand Down Expand Up @@ -321,7 +321,7 @@ std::vector<float> contour_distance2(const EdgeGrid::Grid &grid, const size_t id
// Simple case: Just measure the shortest distance.
this->distance = dist;
#ifdef CONTOUR_DISTANCE_DEBUG_SVG
this->closest_point = foot.cast<coord_t>();
this->closest_point = Point::round(foot);
#endif /* CONTOUR_DISTANCE_DEBUG_SVG */
this->found = true;
}
Expand Down Expand Up @@ -436,7 +436,7 @@ Points resample_polygon(const Points &contour, double dist, std::vector<Resample
for (size_t i = 1; i < n; ++ i) {
double interpolation_parameter = double(i) / n;
Vec2d new_pt = pt_prev + v * interpolation_parameter;
out.emplace_back(new_pt.cast<coord_t>());
out.push_back(Point::round(new_pt));
resampled_point_parameters.emplace_back(idx_this, true, l_step);
}
out.emplace_back(pt);
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Fill/FillGyroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static inline Polyline make_wave(
point(1) = std::clamp(double(point.y()), 0., height);
if (vertical)
std::swap(point(0), point(1));
polyline.points.emplace_back((point * scaleFactor).cast<coord_t>());
polyline.points.push_back(Point::round(point * scaleFactor));
}

return polyline;
Expand Down
31 changes: 18 additions & 13 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4106,7 +4106,7 @@ std::string GCodeGenerator::extrude_loop_vase(const ExtrusionLoop &original_loop
double l2 = v.squaredNorm();
// Shift by no more than a nozzle diameter.
//FIXME Hiding the seams will not work nicely for very densely discretized contours!
inward_point = (/*(nd * nd >= l2) ? p2 : */(p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
inward_point = (/*(nd * nd >= l2) ? p2 : */Point::round(p1 + v * (nd / sqrt(l2))));
inward_point.rotate(angle, paths.front().polyline.front());
}

Expand Down Expand Up @@ -4256,7 +4256,7 @@ std::string GCodeGenerator::extrude_loop_vase(const ExtrusionLoop &original_loop
double l2 = v.squaredNorm();
// Shift by no more than a nozzle diameter.
//FIXME Hiding the seams will not work nicely for very densely discretized contours!
inward_point = (/*(nd * nd >= l2) ? p2 : */(p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
inward_point = (/*(nd * nd >= l2) ? p2 : */Point::round(p1 + v * (nd / sqrt(l2))));
inward_point.rotate(angle, paths.front().polyline.front());

// generate the travel move
Expand Down Expand Up @@ -4589,9 +4589,9 @@ void GCodeGenerator::seam_notch(const ExtrusionLoop& original_loop,
//use a vec that is the mean between the two.
vec_start = (vec_start + vec_end) / 2;

Point moved_start = (start_point.cast<double>() + vec_start * notch_value).cast<coord_t>();
Point moved_start = Point::round(start_point.cast<double>() + vec_start * notch_value);
moved_start.rotate(angle, start_point);
Point moved_end = (end_point.cast<double>() + vec_start * notch_value).cast<coord_t>();
Point moved_end = Point::round(end_point.cast<double>() + vec_start * notch_value);
moved_end.rotate(angle, end_point);

//check if the current angle isn't too sharp
Expand Down Expand Up @@ -4633,6 +4633,7 @@ void GCodeGenerator::seam_notch(const ExtrusionLoop& original_loop,
//reduce the flow of the notch path, as it's longer than previously
path.attributes_mutable().width = path.width() * ratio;
path.attributes_mutable().mm3_per_mm = path.mm3_per_mm() * ratio;
assert(path.polyline.is_valid());
};
for (ExtrusionPath &ep : notch_extrusion_start) {
assert(!ep.can_reverse());
Expand Down Expand Up @@ -4685,9 +4686,12 @@ void GCodeGenerator::seam_notch(const ExtrusionLoop& original_loop,
create_new_extrusion(notch_extrusion_end, model, 0.f, p1, moved_end);
} //else : keep the path as-is
}
for (ExtrusionPath &ep : notch_extrusion_start) {
assert(!ep.can_reverse());
}
for (ExtrusionPath &ep : notch_extrusion_start) {
assert(!ep.can_reverse());
}
for(auto &e : building_paths) assert(e.polyline.empty() || e.polyline.is_valid());
for(auto &e : notch_extrusion_start) assert(e.polyline.empty() || e.polyline.is_valid());
for(auto &e : notch_extrusion_end) assert(e.polyline.empty() || e.polyline.is_valid());
}

std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &original_loop, const std::string_view description, double speed)
Expand Down Expand Up @@ -4891,7 +4895,7 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &original_loop, con
double vec_norm = vec_dist.norm();
const double setting_max_depth = (m_config.wipe_inside_depth.get_abs_value(m_writer.tool()->id(), nozzle_diam));
coordf_t dist = scale_d(nozzle_diam) / 2;
Point pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>();
Point pt = Point::round(current_pos + vec_dist * (2 * dist / vec_norm));
pt.rotate(angle, current_point);
//check if we can go to higher dist
if (nozzle_diam != 0 && setting_max_depth > nozzle_diam * 0.55) {
Expand All @@ -4900,15 +4904,15 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &original_loop, con
if (m_writer.tool()->need_unretract()) {
this->m_throw_if_canceled();
dist = coordf_t(check_wipe::max_depth(wipe_paths, scale_t(setting_max_depth), scale_t(nozzle_diam), [current_pos, current_point, vec_dist, vec_norm, angle](coord_t dist)->Point {
Point pt = (current_pos + vec_dist * (2 * dist / vec_norm)).cast<coord_t>();
Point pt = Point::round(current_pos + vec_dist * (2 * dist / vec_norm));
pt.rotate(angle, current_point);
return pt;
}));
}
}
// Shift by no more than a nozzle diameter.
//FIXME Hiding the seams will not work nicely for very densely discretized contours!
pt = (/*(nd >= vec_norm) ? next_pos : */(current_pos + vec_dist * ( 2 * dist / vec_norm))).cast<coord_t>();
pt = Point::round(/*(nd >= vec_norm) ? next_pos : */(current_pos + vec_dist * ( 2 * dist / vec_norm)));
pt.rotate(angle, current_point);
//gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), 0.0, "move inwards before retraction/seam");
//this->set_last_pos(pt);
Expand Down Expand Up @@ -5078,14 +5082,13 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &original_loop, con
if (nozzle_diam != 0 && setting_max_depth > nozzle_diam * 0.55)
dist = coordf_t(check_wipe::max_depth(wipe_paths, scale_t(setting_max_depth), scale_t(nozzle_diam),
[current_pos, current_point, vec_dist, vec_norm, angle, sin_a](coord_t dist)->Point {
Point pt = (current_pos + vec_dist * (dist / (vec_norm * sin_a))).cast<coord_t>();
Point pt = Point::round(current_pos + vec_dist * (dist / (vec_norm * sin_a)));
pt.rotate(angle, current_point);
return pt;
}));
// Shift by no more than a nozzle diameter.
// FIXME Hiding the seams will not work nicely for very densely discretized contours!
Point pt_inside = (/*(nd >= vec_norm) ? next_pos : */ (current_pos + vec_dist * ( dist / (vec_norm * sin_a))))
.cast<coord_t>();
Point pt_inside = Point::round(/*(nd >= vec_norm) ? next_pos : */ (current_pos + vec_dist * ( dist / (vec_norm * sin_a))));
pt_inside.rotate(angle, current_point);

if (EXTRUDER_CONFIG_WITH_DEFAULT(wipe_inside_end, true)) {
Expand Down Expand Up @@ -5460,6 +5463,7 @@ void GCodeGenerator::use(const ExtrusionEntityCollection &collection) {
std::string GCodeGenerator::extrude_path(const ExtrusionPath &path, const std::string_view description, double speed_mm_per_sec) {
std::string gcode;
ExtrusionPath simplifed_path = path;
assert(simplifed_path.polyline.empty() || simplifed_path.polyline.is_valid());
for (int i = 1; i < simplifed_path.polyline.size(); ++i)
assert(!simplifed_path.polyline.get_point(i - 1).coincides_with_epsilon(simplifed_path.polyline.get_point(i)));

Expand Down Expand Up @@ -5511,6 +5515,7 @@ std::string GCodeGenerator::extrude_path(const ExtrusionPath &path, const std::s
0;
if (scaled_min_length > 0 && simplifed_path.length() < scaled_min_length) {
m_last_too_small = simplifed_path;
assert(m_last_too_small.polyline.empty() || m_last_too_small.polyline.is_valid());
m_last_description = description;
m_last_speed_mm_per_sec = speed_mm_per_sec;
return gcode;
Expand Down
12 changes: 6 additions & 6 deletions src/libslic3r/GCode/SmoothPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ std::optional<Point> sample_path_point_at_distance_from_start(const SmoothPath &
Vec2d v = (point - prev_point).cast<double>();
double lsqr = v.squaredNorm();
if (lsqr > sqr(distance))
return std::make_optional<Point>(prev_point + (v * (distance / sqrt(lsqr))).cast<coord_t>());
return std::make_optional<Point>(prev_point + Point::round(v * (distance / sqrt(lsqr))));
distance -= sqrt(lsqr);
} else {
// Circular segment
float angle = Geometry::ArcWelder::arc_angle(prev_point.cast<float>(), point.cast<float>(), it->radius);
double len = std::abs(it->radius) * angle;
if (len > distance) {
// Rotate the segment end point in reverse towards the start point.
return std::make_optional<Point>(prev_point.rotated(- angle * (distance / len),
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()).cast<coord_t>()));
return std::make_optional<Point>(prev_point.rotated(- angle * (distance / len), Point::round(
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()))));
}
distance -= len;
}
Expand Down Expand Up @@ -78,7 +78,7 @@ std::optional<Point> sample_path_point_at_distance_from_end(const SmoothPath &pa
Vec2d v = (point - prev_point).cast<double>();
double lsqr = v.squaredNorm();
if (lsqr > sqr(distance))
return std::make_optional<Point>(prev_point + (v * (distance / sqrt(lsqr))).cast<coord_t>());
return std::make_optional<Point>(prev_point + Point::round(v * (distance / sqrt(lsqr))));
distance -= sqrt(lsqr);
}
else {
Expand All @@ -87,8 +87,8 @@ std::optional<Point> sample_path_point_at_distance_from_end(const SmoothPath &pa
double len = std::abs(it->radius) * angle;
if (len > distance) {
// Rotate the segment end point in reverse towards the start point.
return std::make_optional<Point>(prev_point.rotated(-angle * (distance / len),
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()).cast<coord_t>()));
return std::make_optional<Point>(prev_point.rotated(-angle * (distance / len), Point::round(
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()).cast<coord_t>())));
}
distance -= len;
}
Expand Down
14 changes: 7 additions & 7 deletions src/libslic3r/GCode/Wipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,16 +554,16 @@ std::optional<Point> sample_path_point_at_distance_from_start(const ExtrusionPat
Vec2d v = (point - prev_point).cast<double>();
double lsqr = v.squaredNorm();
if (lsqr > sqr(distance))
return std::make_optional<Point>(prev_point + (v * (distance / sqrt(lsqr))).cast<coord_t>());
return std::make_optional<Point>(prev_point + Point::round(v * (distance / sqrt(lsqr))));
distance -= sqrt(lsqr);
} else {
// Circular segment
float angle = Geometry::ArcWelder::arc_angle(prev_point.cast<float>(), point.cast<float>(), it->radius);
double len = std::abs(it->radius) * angle;
if (len > distance) {
// Rotate the segment end point in reverse towards the start point.
return std::make_optional<Point>(prev_point.rotated(- angle * (distance / len),
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()).cast<coord_t>()));
return std::make_optional<Point>(prev_point.rotated(- angle * (distance / len), Point::round(
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()).cast<double>())));
}
distance -= len;
}
Expand Down Expand Up @@ -592,7 +592,7 @@ std::optional<Point> sample_path_point_at_distance_from_end(const ExtrusionPaths
Vec2d v = (point - prev_point).cast<double>();
double lsqr = v.squaredNorm();
if (lsqr > sqr(distance))
return std::make_optional<Point>(prev_point + (v * (distance / sqrt(lsqr))).cast<coord_t>());
return std::make_optional<Point>(prev_point + Point::round(v * (distance / sqrt(lsqr))));
distance -= sqrt(lsqr);
}
else {
Expand All @@ -601,8 +601,8 @@ std::optional<Point> sample_path_point_at_distance_from_end(const ExtrusionPaths
double len = std::abs(it->radius) * angle;
if (len > distance) {
// Rotate the segment end point in reverse towards the start point.
return std::make_optional<Point>(prev_point.rotated(-angle * (distance / len),
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()).cast<coord_t>()));
return std::make_optional<Point>(prev_point.rotated(-angle * (distance / len), Point::round(
Geometry::ArcWelder::arc_center(prev_point.cast<float>(), point.cast<float>(), it->radius, it->ccw()).cast<double>())));
}
distance -= len;
}
Expand Down Expand Up @@ -666,7 +666,7 @@ std::optional<Point> wipe_hide_seam(const ExtrusionPaths &paths, bool is_hole, d
}
// Rotate the forward segment inside by 1/3 of the wedge angle.
auto v_rotated = Eigen::Rotation2D(angle_inside) * (p_next - p_current).cast<double>().normalized();
return std::make_optional<Point>(p_current + (v_rotated * wipe_length).cast<coord_t>());
return std::make_optional<Point>(p_current + Point::round(v_rotated * wipe_length));
}

return {};
Expand Down
Loading

0 comments on commit 680679e

Please sign in to comment.