mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 10:17:55 -06:00
ENH: fix for STUDIO-881
Thanks prusa Signed-off-by: salt.wei <salt.wei@bambulab.com> Change-Id: I2e1c1088d29dd5401016ca41d3ed6dec87e0acd1
This commit is contained in:
parent
b4ffa91cb4
commit
61b271f379
31 changed files with 703 additions and 471 deletions
|
@ -15,11 +15,14 @@ using Polygons = std::vector<Polygon>;
|
|||
using PolygonPtrs = std::vector<Polygon*>;
|
||||
using ConstPolygonPtrs = std::vector<const Polygon*>;
|
||||
|
||||
// Returns true if inside. Returns border_result if on boundary.
|
||||
bool contains(const Polygon& polygon, const Point& p, bool border_result = true);
|
||||
bool contains(const Polygons& polygons, const Point& p, bool border_result = true);
|
||||
|
||||
class Polygon : public MultiPoint
|
||||
{
|
||||
public:
|
||||
Polygon() = default;
|
||||
virtual ~Polygon() = default;
|
||||
explicit Polygon(const Points &points) : MultiPoint(points) {}
|
||||
Polygon(std::initializer_list<Point> points) : MultiPoint(points) {}
|
||||
Polygon(const Polygon &other) : MultiPoint(other.points) {}
|
||||
|
@ -38,9 +41,10 @@ public:
|
|||
const Point& operator[](Points::size_type idx) const { return this->points[idx]; }
|
||||
|
||||
// last point == first point for polygons
|
||||
const Point& last_point() const override { return this->points.front(); }
|
||||
const Point& last_point() const { return this->points.front(); }
|
||||
|
||||
Lines lines() const override;
|
||||
double length() const;
|
||||
Lines lines() const;
|
||||
Polyline split_at_vertex(const Point &point) const;
|
||||
// Split a closed polygon into an open polyline, with the split point duplicated at both ends.
|
||||
Polyline split_at_index(int index) const;
|
||||
|
@ -58,15 +62,26 @@ public:
|
|||
void douglas_peucker(double tolerance);
|
||||
|
||||
// Does an unoriented polygon contain a point?
|
||||
// Tested by counting intersections along a horizontal line.
|
||||
bool contains(const Point &point) const;
|
||||
bool contains(const Point &point) const { return Slic3r::contains(*this, point, true); }
|
||||
// Approximate on boundary test.
|
||||
bool on_boundary(const Point &point, double eps) const
|
||||
{ return (this->point_projection(point) - point).cast<double>().squaredNorm() < eps * eps; }
|
||||
|
||||
// Works on CCW polygons only, CW contour will be reoriented to CCW by Clipper's simplify_polygons()!
|
||||
Polygons simplify(double tolerance) const;
|
||||
void simplify(double tolerance, Polygons &polygons) const;
|
||||
void densify(float min_length, std::vector<float>* lengths = nullptr);
|
||||
void triangulate_convex(Polygons* polygons) const;
|
||||
Point centroid() const;
|
||||
Points concave_points(double angle = PI) const;
|
||||
Points convex_points(double angle = PI) const;
|
||||
|
||||
bool intersection(const Line& line, Point* intersection) const;
|
||||
bool first_intersection(const Line& line, Point* intersection) const;
|
||||
bool intersections(const Line &line, Points *intersections) const;
|
||||
|
||||
// Considering CCW orientation of this polygon, find all convex resp. concave points
|
||||
// with the angle at the vertex larger than a threshold.
|
||||
// Zero angle_threshold means to accept all convex resp. concave points.
|
||||
Points convex_points(double angle_threshold = 0.) const;
|
||||
Points concave_points(double angle_threshold = 0.) const;
|
||||
// Projection of a point onto the polygon.
|
||||
Point point_projection(const Point &point) const;
|
||||
std::vector<float> parameter_by_length() const;
|
||||
|
@ -136,14 +151,7 @@ inline void polygons_append(Polygons &dst, Polygons &&src)
|
|||
}
|
||||
}
|
||||
|
||||
inline Polygons polygons_simplify(const Polygons &polys, double tolerance)
|
||||
{
|
||||
Polygons out;
|
||||
out.reserve(polys.size());
|
||||
for (const Polygon &p : polys)
|
||||
polygons_append(out, p.simplify(tolerance));
|
||||
return out;
|
||||
}
|
||||
Polygons polygons_simplify(const Polygons &polys, double tolerance);
|
||||
|
||||
inline void polygons_rotate(Polygons &polys, double angle)
|
||||
{
|
||||
|
@ -164,13 +172,16 @@ inline Points to_points(const Polygon &poly)
|
|||
return poly.points;
|
||||
}
|
||||
|
||||
inline size_t count_points(const Polygons &polys) {
|
||||
size_t n_points = 0;
|
||||
for (const auto &poly: polys) n_points += poly.points.size();
|
||||
return n_points;
|
||||
}
|
||||
|
||||
inline Points to_points(const Polygons &polys)
|
||||
{
|
||||
size_t n_points = 0;
|
||||
for (size_t i = 0; i < polys.size(); ++ i)
|
||||
n_points += polys[i].points.size();
|
||||
Points points;
|
||||
points.reserve(n_points);
|
||||
points.reserve(count_points(polys));
|
||||
for (const Polygon &poly : polys)
|
||||
append(points, poly.points);
|
||||
return points;
|
||||
|
@ -190,11 +201,8 @@ inline Lines to_lines(const Polygon &poly)
|
|||
|
||||
inline Lines to_lines(const Polygons &polys)
|
||||
{
|
||||
size_t n_lines = 0;
|
||||
for (size_t i = 0; i < polys.size(); ++ i)
|
||||
n_lines += polys[i].points.size();
|
||||
Lines lines;
|
||||
lines.reserve(n_lines);
|
||||
lines.reserve(count_points(polys));
|
||||
for (size_t i = 0; i < polys.size(); ++ i) {
|
||||
const Polygon &poly = polys[i];
|
||||
for (Points::const_iterator it = poly.points.begin(); it != poly.points.end()-1; ++it)
|
||||
|
@ -204,18 +212,22 @@ inline Lines to_lines(const Polygons &polys)
|
|||
return lines;
|
||||
}
|
||||
|
||||
inline Polylines to_polylines(const Polygons &polys)
|
||||
inline Polyline to_polyline(const Polygon &polygon)
|
||||
{
|
||||
Polylines polylines;
|
||||
polylines.assign(polys.size(), Polyline());
|
||||
size_t idx = 0;
|
||||
for (Polygons::const_iterator it = polys.begin(); it != polys.end(); ++ it) {
|
||||
Polyline &pl = polylines[idx ++];
|
||||
pl.points = it->points;
|
||||
pl.points.push_back(it->points.front());
|
||||
}
|
||||
assert(idx == polylines.size());
|
||||
return polylines;
|
||||
Polyline out;
|
||||
out.points.reserve(polygon.size() + 1);
|
||||
out.points.assign(polygon.points.begin(), polygon.points.end());
|
||||
out.points.push_back(polygon.points.front());
|
||||
return out;
|
||||
}
|
||||
|
||||
inline Polylines to_polylines(const Polygons &polygons)
|
||||
{
|
||||
Polylines out;
|
||||
out.reserve(polygons.size());
|
||||
for (const Polygon &polygon : polygons)
|
||||
out.emplace_back(to_polyline(polygon));
|
||||
return out;
|
||||
}
|
||||
|
||||
inline Polylines to_polylines(Polygons &&polys)
|
||||
|
@ -223,10 +235,10 @@ inline Polylines to_polylines(Polygons &&polys)
|
|||
Polylines polylines;
|
||||
polylines.assign(polys.size(), Polyline());
|
||||
size_t idx = 0;
|
||||
for (Polygons::const_iterator it = polys.begin(); it != polys.end(); ++ it) {
|
||||
for (auto it = polys.begin(); it != polys.end(); ++ it) {
|
||||
Polyline &pl = polylines[idx ++];
|
||||
pl.points = std::move(it->points);
|
||||
pl.points.push_back(it->points.front());
|
||||
pl.points.push_back(pl.points.front());
|
||||
}
|
||||
assert(idx == polylines.size());
|
||||
return polylines;
|
||||
|
@ -245,11 +257,14 @@ inline Polygons to_polygons(std::vector<Points> &&paths)
|
|||
{
|
||||
Polygons out;
|
||||
out.reserve(paths.size());
|
||||
for (const Points &path : paths)
|
||||
for (Points &path : paths)
|
||||
out.emplace_back(std::move(path));
|
||||
return out;
|
||||
}
|
||||
|
||||
// Do polygons match? If they match, they must have the same topology,
|
||||
// however their contours may be rotated.
|
||||
bool polygons_match(const Polygon &l, const Polygon &r);
|
||||
} // Slic3r
|
||||
|
||||
// start Boost
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue