Fixed the orientation of ExtrusionLoops when Arachne is used.
This commit is contained in:
parent
2d7d8ba2f6
commit
f34c1f14da
4 changed files with 51 additions and 7 deletions
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
//#define ARACHNE_STITCH_PATCH_DEBUG
|
||||
|
||||
namespace Slic3r::Arachne
|
||||
{
|
||||
|
||||
|
@ -549,7 +551,7 @@ void WallToolPaths::stitchToolPaths(std::vector<VariableWidthLines> &toolpaths,
|
|||
VariableWidthLines stitched_polylines;
|
||||
VariableWidthLines closed_polygons;
|
||||
PolylineStitcher<VariableWidthLines, ExtrusionLine, ExtrusionJunction>::stitch(wall_lines, stitched_polylines, closed_polygons, stitch_distance);
|
||||
#ifdef DEBUG
|
||||
#ifdef ARACHNE_STITCH_PATCH_DEBUG
|
||||
for (const ExtrusionLine& line : stitched_polylines) {
|
||||
if ( ! line.is_odd && line.polylineLength() > 3 * stitch_distance && line.size() > 3) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Some even contour lines could not be closed into polygons!";
|
||||
|
@ -608,7 +610,7 @@ void WallToolPaths::stitchToolPaths(std::vector<VariableWidthLines> &toolpaths,
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG
|
||||
#endif // ARACHNE_STITCH_PATCH_DEBUG
|
||||
wall_lines = stitched_polylines; // replace input toolpaths with stitched polylines
|
||||
|
||||
for (ExtrusionLine& wall_polygon : closed_polygons)
|
||||
|
|
|
@ -232,6 +232,35 @@ int64_t ExtrusionLine::calculateExtrusionAreaDeviationError(ExtrusionJunction A,
|
|||
}
|
||||
}
|
||||
|
||||
bool ExtrusionLine::is_contour() const
|
||||
{
|
||||
if (!this->is_closed)
|
||||
return false;
|
||||
|
||||
Polygon poly;
|
||||
poly.points.reserve(this->junctions.size());
|
||||
for (const ExtrusionJunction &junction : this->junctions)
|
||||
poly.points.emplace_back(junction.p);
|
||||
|
||||
// Arachne produces contour with clockwise orientation and holes with counterclockwise orientation.
|
||||
return poly.is_clockwise();
|
||||
}
|
||||
|
||||
double ExtrusionLine::area() const
|
||||
{
|
||||
assert(this->is_closed);
|
||||
double a = 0.;
|
||||
if (this->junctions.size() >= 3) {
|
||||
Vec2d p1 = this->junctions.back().p.cast<double>();
|
||||
for (const ExtrusionJunction &junction : this->junctions) {
|
||||
Vec2d p2 = junction.p.cast<double>();
|
||||
a += cross2(p1, p2);
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
return 0.5 * a;
|
||||
}
|
||||
|
||||
} // namespace Slic3r::Arachne
|
||||
|
||||
namespace Slic3r {
|
||||
|
|
|
@ -189,6 +189,10 @@ struct ExtrusionLine
|
|||
* \param weighted_average_width The weighted average of the widths of the two colinear extrusion segments
|
||||
* */
|
||||
static int64_t calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C, coord_t& weighted_average_width);
|
||||
|
||||
bool is_contour() const;
|
||||
|
||||
double area() const;
|
||||
};
|
||||
|
||||
static inline Slic3r::ThickPolyline to_thick_polyline(const Arachne::ExtrusionLine &line_junctions)
|
||||
|
|
|
@ -354,6 +354,8 @@ static ClipperLib_Z::Paths clip_extrusion(const ClipperLib_Z::Path &subject, con
|
|||
struct PerimeterGeneratorArachneExtrusion
|
||||
{
|
||||
Arachne::ExtrusionLine *extrusion = nullptr;
|
||||
// Indicates if closed ExtrusionLine is a contour or a hole. Used it only when ExtrusionLine is a closed loop.
|
||||
bool is_contour = false;
|
||||
// Should this extrusion be fuzzyfied on path generation?
|
||||
bool fuzzify = false;
|
||||
};
|
||||
|
@ -414,11 +416,18 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator &p
|
|||
|
||||
// Append paths to collection.
|
||||
if (!paths.empty()) {
|
||||
if (extrusion->is_closed)
|
||||
extrusion_coll.entities.emplace_back(new ExtrusionLoop(std::move(paths)));
|
||||
else
|
||||
if (extrusion->is_closed) {
|
||||
ExtrusionLoop extrusion_loop(std::move(paths));
|
||||
// Restore the orientation of the extrusion loop.
|
||||
if (pg_extrusion.is_contour)
|
||||
extrusion_loop.make_counter_clockwise();
|
||||
else
|
||||
extrusion_loop.make_clockwise();
|
||||
|
||||
extrusion_coll.append(std::move(extrusion_loop));
|
||||
} else
|
||||
for (ExtrusionPath &path : paths)
|
||||
extrusion_coll.entities.emplace_back(new ExtrusionPath(std::move(path)));
|
||||
extrusion_coll.append(ExtrusionPath(std::move(path)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -541,7 +550,7 @@ void PerimeterGenerator::process_arachne()
|
|||
}
|
||||
|
||||
auto &best_path = all_extrusions[best_candidate];
|
||||
ordered_extrusions.push_back({best_path, false});
|
||||
ordered_extrusions.push_back({best_path, best_path->is_contour(), false});
|
||||
processed[best_candidate] = true;
|
||||
for (size_t unlocked_idx : blocking[best_candidate])
|
||||
blocked[unlocked_idx]--;
|
||||
|
|
Loading…
Add table
Reference in a new issue