Avoid placement of seams on bridging perimeters, if random seam is enabled.
https://github.com/alexrj/Slic3r/issues/3526#issuecomment-263125049
This commit is contained in:
parent
4256af22ff
commit
7e6390c4b6
4 changed files with 35 additions and 19 deletions
|
@ -204,22 +204,38 @@ ExtrusionLoop::split_at_vertex(const Point &point)
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ExtrusionLoop::split_at(const Point &point)
|
||||
// Splitting an extrusion loop, possibly made of multiple segments, some of the segments may be bridging.
|
||||
void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang)
|
||||
{
|
||||
if (this->paths.empty()) return;
|
||||
if (this->paths.empty())
|
||||
return;
|
||||
|
||||
// find the closest path and closest point belonging to that path
|
||||
// Find the closest path and closest point belonging to that path. Avoid overhangs, if asked for.
|
||||
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();
|
||||
Point p;
|
||||
{
|
||||
double min = std::numeric_limits<double>::max();
|
||||
Point p_non_overhang;
|
||||
size_t path_idx_non_overhang = 0;
|
||||
double min_non_overhang = std::numeric_limits<double>::max();
|
||||
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();
|
||||
}
|
||||
if (prefer_non_overhang && ! path->is_bridge() && dist < min_non_overhang) {
|
||||
p_non_overhang = p_tmp;
|
||||
min_non_overhang = dist;
|
||||
path_idx_non_overhang = path - this->paths.begin();
|
||||
}
|
||||
}
|
||||
if (prefer_non_overhang && min_non_overhang != std::numeric_limits<double>::max()) {
|
||||
// Only apply the non-overhang point if there is one.
|
||||
path_idx = path_idx_non_overhang;
|
||||
p = p_non_overhang;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ class ExtrusionLoop : public ExtrusionEntity
|
|||
Polygon polygon() const;
|
||||
virtual double length() const;
|
||||
bool split_at_vertex(const Point &point);
|
||||
void split_at(const Point &point);
|
||||
void split_at(const Point &point, bool prefer_non_overhang);
|
||||
void clip_end(double distance, ExtrusionPaths* paths) const;
|
||||
// Test, whether the point is extruded by a bridging flow.
|
||||
// This used to be used to avoid placing seams on overhangs, but now the EdgeGrid is used instead.
|
||||
|
|
|
@ -571,7 +571,7 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
|
|||
// or randomize if requested
|
||||
Point last_pos = this->last_pos();
|
||||
if (this->config.spiral_vase) {
|
||||
loop.split_at(last_pos);
|
||||
loop.split_at(last_pos, false);
|
||||
} else if (seam_position == spNearest || seam_position == spAligned) {
|
||||
Polygon polygon = loop.polygon();
|
||||
const coordf_t nozzle_dmr = EXTRUDER_CONFIG(nozzle_diameter);
|
||||
|
@ -682,7 +682,7 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
|
|||
// Split the loop at the point with a minium penalty.
|
||||
if (!loop.split_at_vertex(polygon.points[idx_min]))
|
||||
// The point is not in the original loop. Insert it.
|
||||
loop.split_at(polygon.points[idx_min]);
|
||||
loop.split_at(polygon.points[idx_min], true);
|
||||
|
||||
} else if (seam_position == spRandom) {
|
||||
if (loop.role == elrContourInternalPerimeter) {
|
||||
|
@ -696,7 +696,7 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
|
|||
last_pos = Point(polygon.bounding_box().max.x, centroid.y);
|
||||
last_pos.rotate(fmod((float)rand()/16.0, 2.0*PI), centroid);
|
||||
}
|
||||
loop.split_at(last_pos);
|
||||
loop.split_at(last_pos, true);
|
||||
}
|
||||
|
||||
// clip the path to avoid the extruder to get exactly on the first point of the loop;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
double length();
|
||||
bool split_at_vertex(Point* point)
|
||||
%code{% RETVAL = THIS->split_at_vertex(*point); %};
|
||||
void split_at(Point* point)
|
||||
%code{% THIS->split_at(*point); %};
|
||||
void split_at(Point* point, int prefer_non_overhang = 0)
|
||||
%code{% THIS->split_at(*point, prefer_non_overhang != 0); %};
|
||||
ExtrusionPaths clip_end(double distance)
|
||||
%code{% THIS->clip_end(distance, &RETVAL); %};
|
||||
bool has_overhang_point(Point* point)
|
||||
|
|
Loading…
Reference in a new issue