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 "../ClipperUtils.hpp"
|
||||||
#include "../EdgeGrid.hpp"
|
#include "../EdgeGrid.hpp"
|
||||||
|
#include "../Geometry.hpp"
|
||||||
#include "../Surface.hpp"
|
#include "../Surface.hpp"
|
||||||
#include "../PrintConfig.hpp"
|
#include "../PrintConfig.hpp"
|
||||||
#include "../libslic3r.h"
|
#include "../libslic3r.h"
|
||||||
|
@ -777,6 +778,8 @@ void mark_boundary_segments_touching_infill(
|
||||||
const Vec2d *pt2;
|
const Vec2d *pt2;
|
||||||
} visitor(grid, boundary, boundary_data, distance_colliding * distance_colliding);
|
} 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) {
|
for (const Polyline &polyline : infill) {
|
||||||
// Clip the infill polyline by the Eucledian distance along the polyline.
|
// Clip the infill polyline by the Eucledian distance along the polyline.
|
||||||
SegmentPoint start_point = clip_start_segment_and_point(polyline.points, clip_distance);
|
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 vperp(-v.y(), v.x());
|
||||||
Vec2d a = pt1 - v - vperp;
|
Vec2d a = pt1 - v - vperp;
|
||||||
Vec2d b = 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;
|
a = pt1 - v + vperp;
|
||||||
b = 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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,79 @@ inline bool segments_intersect(
|
||||||
segments_could_intersect(jp1, jp2, ip1, ip2) <= 0;
|
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);
|
Pointf3s convex_hull(Pointf3s points);
|
||||||
Polygon convex_hull(Points points);
|
Polygon convex_hull(Points points);
|
||||||
Polygon convex_hull(const Polygons &polygons);
|
Polygon convex_hull(const Polygons &polygons);
|
||||||
|
|
|
@ -107,6 +107,17 @@ bool Line::intersection(const Line &l2, Point *intersection) const
|
||||||
return false; // not intersecting
|
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
|
Vec3d Linef3::intersect_plane(double z) const
|
||||||
{
|
{
|
||||||
auto v = (this->b - this->a).cast<double>();
|
auto v = (this->b - this->a).cast<double>();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class BoundingBox;
|
||||||
class Line;
|
class Line;
|
||||||
class Line3;
|
class Line3;
|
||||||
class Linef3;
|
class Linef3;
|
||||||
|
@ -43,6 +44,8 @@ public:
|
||||||
Vector normal() const { return Vector((this->b(1) - this->a(1)), -(this->b(0) - this->a(0))); }
|
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;
|
bool intersection(const Line& line, Point* intersection) const;
|
||||||
double ccw(const Point& point) const { return point.ccw(*this); }
|
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_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)); }
|
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