Fix of the new gyroid infill path planning. Fixes #3226
This commit is contained in:
parent
232f324999
commit
9c4dc80057
4 changed files with 94 additions and 2 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../EdgeGrid.hpp"
|
||||
#include "../Geometry.hpp"
|
||||
#include "../Surface.hpp"
|
||||
#include "../PrintConfig.hpp"
|
||||
#include "../libslic3r.h"
|
||||
|
@ -777,6 +778,8 @@ void mark_boundary_segments_touching_infill(
|
|||
const Vec2d *pt2;
|
||||
} visitor(grid, boundary, boundary_data, distance_colliding * distance_colliding);
|
||||
|
||||
BoundingBoxf bboxf(boundary_bbox.min.cast<double>(), boundary_bbox.max.cast<double>());
|
||||
bboxf.offset(- SCALED_EPSILON);
|
||||
for (const Polyline &polyline : infill) {
|
||||
// Clip the infill polyline by the Eucledian distance along the polyline.
|
||||
SegmentPoint start_point = clip_start_segment_and_point(polyline.points, clip_distance);
|
||||
|
@ -814,10 +817,12 @@ void mark_boundary_segments_touching_infill(
|
|||
Vec2d vperp(-v.y(), v.x());
|
||||
Vec2d a = pt1 - v - vperp;
|
||||
Vec2d b = pt1 + v - vperp;
|
||||
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor);
|
||||
if (Geometry::liang_barsky_line_clipping(a, b, bboxf))
|
||||
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor);
|
||||
a = pt1 - v + vperp;
|
||||
b = pt1 + v + vperp;
|
||||
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor);
|
||||
if (Geometry::liang_barsky_line_clipping(a, b, bboxf))
|
||||
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,6 +137,79 @@ inline bool segments_intersect(
|
|||
segments_could_intersect(jp1, jp2, ip1, ip2) <= 0;
|
||||
}
|
||||
|
||||
// Based on Liang-Barsky function by Daniel White @ http://www.skytopia.com/project/articles/compsci/clipping.html
|
||||
template<typename T>
|
||||
bool liang_barsky_line_clipping(
|
||||
// Start and end points of the source line, result will be stored there as well.
|
||||
Eigen::Matrix<T, 2, 1, Eigen::DontAlign> &x0,
|
||||
Eigen::Matrix<T, 2, 1, Eigen::DontAlign> &x1,
|
||||
// Bounding box to clip with.
|
||||
const BoundingBoxBase<Eigen::Matrix<T, 2, 1, Eigen::DontAlign>> &bbox)
|
||||
{
|
||||
Eigen::Matrix<T, 2, 1, Eigen::DontAlign> v = x1 - x0;
|
||||
double t0 = 0.0;
|
||||
double t1 = 1.0;
|
||||
|
||||
// Traverse through left, right, bottom, top edges.
|
||||
for (int edge = 0; edge < 4; ++ edge)
|
||||
{
|
||||
double p, q;
|
||||
switch (edge) {
|
||||
case 0: p = - v.x(); q = - bbox.min.x() + x0.x(); break;
|
||||
case 1: p = v.x(); q = bbox.max.x() - x0.x(); break;
|
||||
case 2: p = - v.y(); q = - bbox.min.y() + x0.y(); break;
|
||||
default: p = v.y(); q = bbox.max.y() - x0.y(); break;
|
||||
}
|
||||
|
||||
if (p == 0) {
|
||||
if (q < 0)
|
||||
// Line parallel to the bounding box edge is fully outside of the bounding box.
|
||||
return false;
|
||||
// else don't clip
|
||||
} else {
|
||||
double r = q / p;
|
||||
if (p < 0) {
|
||||
if (r > t1)
|
||||
// Fully clipped.
|
||||
return false;
|
||||
if (r > t0)
|
||||
// Partially clipped.
|
||||
t0 = r;
|
||||
} else {
|
||||
assert(p > 0);
|
||||
if (r < t0)
|
||||
// Fully clipped.
|
||||
return false;
|
||||
if (r < t1)
|
||||
// Partially clipped.
|
||||
t1 = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clipped successfully.
|
||||
x1 = x0 + t1 * v;
|
||||
x0 += t0 * v;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Based on Liang-Barsky function by Daniel White @ http://www.skytopia.com/project/articles/compsci/clipping.html
|
||||
template<typename T>
|
||||
bool liang_barsky_line_clipping(
|
||||
// Start and end points of the source line.
|
||||
const Eigen::Matrix<T, 2, 1, Eigen::DontAlign> &x0src,
|
||||
const Eigen::Matrix<T, 2, 1, Eigen::DontAlign> &x1src,
|
||||
// Bounding box to clip with.
|
||||
const BoundingBoxBase<Eigen::Matrix<T, 2, 1, Eigen::DontAlign>> &bbox,
|
||||
// Start and end points of the clipped line.
|
||||
Eigen::Matrix<T, 2, 1, Eigen::DontAlign> &x0clip,
|
||||
Eigen::Matrix<T, 2, 1, Eigen::DontAlign> &x1clip)
|
||||
{
|
||||
x0clip = x0src;
|
||||
x1clip = x1src;
|
||||
return liang_barsky_line_clipping(x0clip, x1clip, bbox);
|
||||
}
|
||||
|
||||
Pointf3s convex_hull(Pointf3s points);
|
||||
Polygon convex_hull(Points points);
|
||||
Polygon convex_hull(const Polygons &polygons);
|
||||
|
|
|
@ -107,6 +107,17 @@ bool Line::intersection(const Line &l2, Point *intersection) const
|
|||
return false; // not intersecting
|
||||
}
|
||||
|
||||
bool Line::clip_with_bbox(const BoundingBox &bbox)
|
||||
{
|
||||
Vec2d x0clip, x1clip;
|
||||
bool result = Geometry::liang_barsky_line_clipping<double>(this->a.cast<double>(), this->b.cast<double>(), BoundingBoxf(bbox.min.cast<double>(), bbox.max.cast<double>()), x0clip, x1clip);
|
||||
if (result) {
|
||||
this->a = x0clip.cast<coord_t>();
|
||||
this->b = x1clip.cast<coord_t>();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec3d Linef3::intersect_plane(double z) const
|
||||
{
|
||||
auto v = (this->b - this->a).cast<double>();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
class BoundingBox;
|
||||
class Line;
|
||||
class Line3;
|
||||
class Linef3;
|
||||
|
@ -43,6 +44,8 @@ public:
|
|||
Vector normal() const { return Vector((this->b(1) - this->a(1)), -(this->b(0) - this->a(0))); }
|
||||
bool intersection(const Line& line, Point* intersection) const;
|
||||
double ccw(const Point& point) const { return point.ccw(*this); }
|
||||
// Clip a line with a bounding box. Returns false if the line is completely outside of the bounding box.
|
||||
bool clip_with_bbox(const BoundingBox &bbox);
|
||||
|
||||
static double distance_to_squared(const Point &point, const Point &a, const Point &b);
|
||||
static double distance_to(const Point &point, const Point &a, const Point &b) { return sqrt(distance_to_squared(point, a, b)); }
|
||||
|
|
Loading…
Reference in a new issue