Fixing the infill order for concentric infill to outside-in.
Relies to: Concentric Fill Start Point - New Feature Request #4948 Feature Request: Archimedean Chords - Option to define direction of travel (Inside-Out or Outside-In) #5214
This commit is contained in:
parent
746729e4fa
commit
3c9f3d2b66
@ -716,45 +716,33 @@ static void traverse_pt_noholes(const ClipperLib::PolyNodes &nodes, Polygons *ou
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void traverse_pt_old(ClipperLib::PolyNodes &nodes, Polygons* retval)
|
static void traverse_pt_outside_in(const ClipperLib::PolyNodes &nodes, Polygons *retval)
|
||||||
{
|
{
|
||||||
/* use a nearest neighbor search to order these children
|
|
||||||
TODO: supply start_near to chained_path() too? */
|
|
||||||
|
|
||||||
// collect ordering points
|
// collect ordering points
|
||||||
Points ordering_points;
|
Points ordering_points;
|
||||||
ordering_points.reserve(nodes.size());
|
ordering_points.reserve(nodes.size());
|
||||||
for (ClipperLib::PolyNodes::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
|
for (const ClipperLib::PolyNode *node : nodes)
|
||||||
Point p((*it)->Contour.front().X, (*it)->Contour.front().Y);
|
ordering_points.emplace_back(node->Contour.front().X, node->Contour.front().Y);
|
||||||
ordering_points.push_back(p);
|
|
||||||
}
|
// Perform the ordering, push results recursively.
|
||||||
|
//FIXME pass the last point to chain_clipper_polynodes?
|
||||||
// perform the ordering
|
for (const ClipperLib::PolyNode *node : chain_clipper_polynodes(ordering_points, nodes)) {
|
||||||
ClipperLib::PolyNodes ordered_nodes = chain_clipper_polynodes(ordering_points, nodes);
|
retval->emplace_back(ClipperPath_to_Slic3rPolygon(node->Contour));
|
||||||
|
if (node->IsHole())
|
||||||
// push results recursively
|
// Orient a hole, which is clockwise oriented, to CCW.
|
||||||
for (ClipperLib::PolyNodes::iterator it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it) {
|
retval->back().reverse();
|
||||||
// traverse the next depth
|
// traverse the next depth
|
||||||
traverse_pt_old((*it)->Childs, retval);
|
traverse_pt_outside_in(node->Childs, retval);
|
||||||
retval->push_back(ClipperPath_to_Slic3rPolygon((*it)->Contour));
|
|
||||||
if ((*it)->IsHole()) retval->back().reverse(); // ccw
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons union_pt_chained(const Polygons &subject, bool safety_offset_)
|
Polygons union_pt_chained_outside_in(const Polygons &subject, bool safety_offset_)
|
||||||
{
|
{
|
||||||
ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_);
|
ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_);
|
||||||
|
|
||||||
Polygons retval;
|
Polygons retval;
|
||||||
traverse_pt_old(polytree.Childs, &retval);
|
traverse_pt_outside_in(polytree.Childs, &retval);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
// TODO: This needs to be tested:
|
|
||||||
// ClipperLib::PolyTree polytree = union_pt(subject, safety_offset_);
|
|
||||||
|
|
||||||
// Polygons retval;
|
|
||||||
// traverse_pt_noholes(polytree.Childs, &retval);
|
|
||||||
// return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons simplify_polygons(const Polygons &subject, bool preserve_collinear)
|
Polygons simplify_polygons(const Polygons &subject, bool preserve_collinear)
|
||||||
|
@ -219,7 +219,7 @@ ClipperLib::PolyTree union_pt(const Slic3r::ExPolygons &subject, bool safety_off
|
|||||||
ClipperLib::PolyTree union_pt(Slic3r::Polygons &&subject, bool safety_offset_ = false);
|
ClipperLib::PolyTree union_pt(Slic3r::Polygons &&subject, bool safety_offset_ = false);
|
||||||
ClipperLib::PolyTree union_pt(Slic3r::ExPolygons &&subject, bool safety_offset_ = false);
|
ClipperLib::PolyTree union_pt(Slic3r::ExPolygons &&subject, bool safety_offset_ = false);
|
||||||
|
|
||||||
Slic3r::Polygons union_pt_chained(const Slic3r::Polygons &subject, bool safety_offset_ = false);
|
Slic3r::Polygons union_pt_chained_outside_in(const Slic3r::Polygons &subject, bool safety_offset_ = false);
|
||||||
|
|
||||||
ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes);
|
ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes);
|
||||||
|
|
||||||
|
@ -24,22 +24,22 @@ void FillConcentric::_fill_surface_single(
|
|||||||
this->spacing = unscale<double>(distance);
|
this->spacing = unscale<double>(distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons loops = (Polygons)expolygon;
|
Polygons loops = to_polygons(std::move(expolygon));
|
||||||
Polygons last = loops;
|
Polygons last = loops;
|
||||||
while (! last.empty()) {
|
while (! last.empty()) {
|
||||||
last = offset2(last, -(distance + min_spacing/2), +min_spacing/2);
|
last = offset2(last, -(distance + min_spacing/2), +min_spacing/2);
|
||||||
loops.insert(loops.end(), last.begin(), last.end());
|
append(loops, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate paths from the outermost to the innermost, to avoid
|
// generate paths from the outermost to the innermost, to avoid
|
||||||
// adhesion problems of the first central tiny loops
|
// adhesion problems of the first central tiny loops
|
||||||
loops = union_pt_chained(loops, false);
|
loops = union_pt_chained_outside_in(loops, false);
|
||||||
|
|
||||||
// split paths using a nearest neighbor search
|
// split paths using a nearest neighbor search
|
||||||
size_t iPathFirst = polylines_out.size();
|
size_t iPathFirst = polylines_out.size();
|
||||||
Point last_pos(0, 0);
|
Point last_pos(0, 0);
|
||||||
for (const Polygon &loop : loops) {
|
for (const Polygon &loop : loops) {
|
||||||
polylines_out.push_back(loop.split_at_index(last_pos.nearest_point_index(loop.points)));
|
polylines_out.emplace_back(loop.split_at_index(last_pos.nearest_point_index(loop.points)));
|
||||||
last_pos = polylines_out.back().last_point();
|
last_pos = polylines_out.back().last_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace Slic3r {
|
|||||||
class FillConcentric : public Fill
|
class FillConcentric : public Fill
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~FillConcentric() override {}
|
~FillConcentric() override = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Fill* clone() const override { return new FillConcentric(*this); };
|
Fill* clone() const override { return new FillConcentric(*this); };
|
||||||
|
@ -1851,10 +1851,7 @@ void Print::_make_brim()
|
|||||||
}
|
}
|
||||||
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
|
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
|
||||||
}
|
}
|
||||||
loops = union_pt_chained(loops, false);
|
loops = union_pt_chained_outside_in(loops, false);
|
||||||
// The function above produces ordering well suited for concentric infill (from outside to inside).
|
|
||||||
// For Brim, the ordering should be reversed (from inside to outside).
|
|
||||||
std::reverse(loops.begin(), loops.end());
|
|
||||||
|
|
||||||
// If there is a possibility that brim intersects skirt, go through loops and split those extrusions
|
// If there is a possibility that brim intersects skirt, go through loops and split those extrusions
|
||||||
// The result is either the original Polygon or a list of Polylines
|
// The result is either the original Polygon or a list of Polylines
|
||||||
|
Loading…
Reference in New Issue
Block a user