mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-22 16:21:24 -06:00
Enforce seam alignment and blend in spiral vase. #2023
This commit is contained in:
parent
254ab29a97
commit
f2c5e799b1
17 changed files with 174 additions and 33 deletions
|
@ -221,7 +221,7 @@ ExtrusionLoop::length() const
|
|||
}
|
||||
|
||||
void
|
||||
ExtrusionLoop::split_at(const Point &point)
|
||||
ExtrusionLoop::split_at_vertex(const Point &point)
|
||||
{
|
||||
for (ExtrusionPaths::iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
|
||||
int idx = path->polyline.find_point(point);
|
||||
|
@ -239,7 +239,7 @@ ExtrusionLoop::split_at(const Point &point)
|
|||
{
|
||||
ExtrusionPath p = *path;
|
||||
p.polyline.points.erase(p.polyline.points.begin(), p.polyline.points.begin() + idx);
|
||||
if (!p.polyline.points.empty()) new_paths.push_back(p);
|
||||
if (p.polyline.is_valid()) new_paths.push_back(p);
|
||||
}
|
||||
|
||||
// then we add all paths until the end of current path list
|
||||
|
@ -252,7 +252,7 @@ ExtrusionLoop::split_at(const Point &point)
|
|||
{
|
||||
ExtrusionPath p = *path;
|
||||
p.polyline.points.erase(p.polyline.points.begin() + idx + 1, p.polyline.points.end());
|
||||
if (!p.polyline.points.empty()) new_paths.push_back(p);
|
||||
if (p.polyline.is_valid()) new_paths.push_back(p);
|
||||
}
|
||||
// we can now override the old path list with the new one and stop looping
|
||||
this->paths = new_paths;
|
||||
|
@ -263,6 +263,39 @@ ExtrusionLoop::split_at(const Point &point)
|
|||
CONFESS("Point not found");
|
||||
}
|
||||
|
||||
void
|
||||
ExtrusionLoop::split_at(const Point &point)
|
||||
{
|
||||
if (this->paths.empty()) return;
|
||||
|
||||
// find the closest path and closest point
|
||||
size_t path_idx = 0;
|
||||
Point p = this->paths.front().first_point();
|
||||
double min = point.distance_to(p);
|
||||
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
|
||||
Point p_tmp = point.projection_onto(path->polyline);
|
||||
double dist = point.distance_to(p_tmp);
|
||||
if (dist < min) {
|
||||
p = p_tmp;
|
||||
min = dist;
|
||||
path_idx = path - this->paths.begin();
|
||||
}
|
||||
}
|
||||
|
||||
// now split path_idx in two parts
|
||||
ExtrusionPath p1 = this->paths[path_idx];
|
||||
ExtrusionPath p2 = p1;
|
||||
this->paths[path_idx].polyline.split_at(p, &p1.polyline, &p2.polyline);
|
||||
|
||||
// install the two paths
|
||||
this->paths.erase(this->paths.begin() + path_idx);
|
||||
if (p2.polyline.is_valid()) this->paths.insert(this->paths.begin() + path_idx, p2);
|
||||
if (p1.polyline.is_valid()) this->paths.insert(this->paths.begin() + path_idx, p1);
|
||||
|
||||
// split at the new vertex
|
||||
this->split_at_vertex(p);
|
||||
}
|
||||
|
||||
void
|
||||
ExtrusionLoop::clip_end(double distance, ExtrusionPaths* paths) const
|
||||
{
|
||||
|
|
|
@ -93,6 +93,7 @@ class ExtrusionLoop : public ExtrusionEntity
|
|||
Point last_point() const;
|
||||
void polygon(Polygon* polygon) const;
|
||||
double length() const;
|
||||
void split_at_vertex(const Point &point);
|
||||
void split_at(const Point &point);
|
||||
void clip_end(double distance, ExtrusionPaths* paths) const;
|
||||
bool has_overhang_point(const Point &point) const;
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
Point::Point(double x, double y)
|
||||
{
|
||||
this->x = lrint(x);
|
||||
this->y = lrint(y);
|
||||
}
|
||||
|
||||
bool
|
||||
Point::operator==(const Point& rhs) const
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ class Point
|
|||
coord_t x;
|
||||
coord_t y;
|
||||
explicit Point(coord_t _x = 0, coord_t _y = 0): x(_x), y(_y) {};
|
||||
Point(double x, double y);
|
||||
bool operator==(const Point& rhs) const;
|
||||
std::string wkt() const;
|
||||
void scale(double factor);
|
||||
|
|
|
@ -56,7 +56,7 @@ Polygon::lines(Lines* lines) const
|
|||
}
|
||||
|
||||
void
|
||||
Polygon::split_at(const Point &point, Polyline* polyline) const
|
||||
Polygon::split_at_vertex(const Point &point, Polyline* polyline) const
|
||||
{
|
||||
// find index of point
|
||||
for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
|
||||
|
|
|
@ -21,7 +21,7 @@ class Polygon : public MultiPoint {
|
|||
Point last_point() const;
|
||||
Lines lines() const;
|
||||
void lines(Lines* lines) const;
|
||||
void split_at(const Point &point, Polyline* polyline) const;
|
||||
void split_at_vertex(const Point &point, Polyline* polyline) const;
|
||||
void split_at_index(int index, Polyline* polyline) const;
|
||||
void split_at_first_point(Polyline* polyline) const;
|
||||
void equally_spaced_points(double distance, Points* points) const;
|
||||
|
|
|
@ -117,6 +117,42 @@ Polyline::simplify(double tolerance)
|
|||
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
|
||||
}
|
||||
|
||||
void
|
||||
Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
|
||||
{
|
||||
if (this->points.empty()) return;
|
||||
|
||||
// find the line to split at
|
||||
size_t line_idx = 0;
|
||||
Point p = this->first_point();
|
||||
double min = point.distance_to(p);
|
||||
Lines lines = this->lines();
|
||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||
Point p_tmp = point.projection_onto(*line);
|
||||
if (point.distance_to(p_tmp) < min) {
|
||||
p = p_tmp;
|
||||
min = point.distance_to(p);
|
||||
line_idx = line - lines.begin();
|
||||
}
|
||||
}
|
||||
|
||||
// create first half
|
||||
p1->points.clear();
|
||||
for (Lines::const_iterator line = lines.begin(); line != lines.begin() + line_idx + 1; ++line) {
|
||||
if (!line->a.coincides_with(p)) p1->points.push_back(line->a);
|
||||
}
|
||||
// we add point instead of p because they might differ because of numerical issues
|
||||
// and caller might want to rely on point belonging to result polylines
|
||||
p1->points.push_back(point);
|
||||
|
||||
// create second half
|
||||
p2->points.clear();
|
||||
p2->points.push_back(point);
|
||||
for (Lines::const_iterator line = lines.begin() + line_idx; line != lines.end(); ++line) {
|
||||
if (!line->b.coincides_with(p)) p2->points.push_back(line->b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
REGISTER_CLASS(Polyline, "Polyline");
|
||||
|
|
|
@ -21,6 +21,7 @@ class Polyline : public MultiPoint {
|
|||
void extend_start(double distance);
|
||||
void equally_spaced_points(double distance, Points* points) const;
|
||||
void simplify(double tolerance);
|
||||
void split_at(const Point &point, Polyline* p1, Polyline* p2) const;
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
void from_SV_check(SV* poly_sv);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue