mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2026-01-31 05:10:44 -07:00
Some checks failed
* Grid non-crossing for multiline cleaning Replaced negative offset logic with surface contraction to reduce overlap with perimeters. center the infill filltriangles update triangles preallocate memory Update FillRectilinear.cpp Update FillRectilinear.cpp overlapp adjustment Fix Crash Update FillRectilinear.cpp density tunning density tunning fine tunning reserve polilines Grid non-crossing for multiline Co-Authored-By: Ian Bassi <12130714+ianalexis@users.noreply.github.com> Co-Authored-By: discip <53649486+discip@users.noreply.github.com> * Improve multiline fill offset and polyline closure Changed offset type from jtRound to jtMiter in multiline_fill for better geometry. Updated polyline conversion to require at least 3 points and ensured polylines are closed if not already. Updated FillGyroid, FillTpmsD, and FillTpmsFK to pass the 'close' argument to multiline_fill. cleaning FillAdaptive Noncross Only use clipper if worth it safeguard fix overlap Update FillRectilinear.cpp FilllRectilineal multiline clipper Update FillRectilinear.cpp FilllRectilineal multiline clipper Update FillRectilinear.cpp Update FillRectilinear.cpp fix 3d honeycomb Simplify polylines Update FillBase.cpp Update FillBase.cpp cleaning Improved Multiline Function This ensures `multiline_fill()` will correctly generate multiline infill with closed loop polylines if the input infill line is a closedloop polyline. This ensures that the multiline infill doesn't have little gaps or overlaps at the "closed point" of the original infill line. This changes how the tangent is calculated for the first and last points in a polyline if the first and last points are the same, making it a closed loop. Instead of just using the first or last line segment, it uses the line segment between the points before the last point and after the first point, the same way that all the other poly-line mid points are handled. It also uses eigen vector operations to calculate the points instead of explicitly calculating the x and y values. This is probably faster, and if not then it is at least more concise. Hibrid Multiline Function Update FillRectilinear.cpp Update FillRectilinear.cpp Update FillRectilinear.cpp Update FillRectilinear.cpp clipperutils multiline hibrido Update FillBase.cpp Update FillBase.cpp Update FillBase.cpp multiline hibrido arc tolerance multiline con union Update FillBase.cpp Update FillBase.cpp Update FillBase.cpp Co-Authored-By: Ian Bassi <12130714+ianalexis@users.noreply.github.com> Co-Authored-By: Donovan Baarda <dbaarda@gmail.com> * Switch multiline offset logic to Clipper2 Replaces Clipper-based multiline offset logic in FillBase.cpp with Clipper2, using InflatePaths and Union for offsetting and merging. Adds new conversion utilities in Clipper2Utils for handling Paths64 to Polygons/Polylines and updates headers accordingly. * Refactor multiline_fill to always use Clipper2 logic Removed the 'use_clipper' parameter from multiline_fill and updated all callers to use the new signature. The function now consistently applies Clipper2-based offset logic for multiline infill, simplifying the code and ensuring uniform behavior across fill patterns. * Change offset join type to Round in multiline_fill Replaces the Miter join type with Round in the InflatePaths call within multiline_fill. For smotther print travels. * Increase max infill multiline to 10 Raised the maximum allowed value for the 'Fill Multiline' infill parameter from 5 to 10 to support more lines in infill patterns. * Refactor multiline_fill to optimize offset logic Replaces manual conversion of polylines to Clipper2 paths with Slic3rPolylines_to_Paths64 and filters short paths using std::remove_if. Uses ClipperOffset for path inflation and streamlines merging and conversion to polylines, improving performance and code clarity. * half iteration because is bucle * Funciona 1 Refactored the multiline_fill function to streamline the insertion of center lines by directly checking for odd line counts and removing redundant logic. This improves code clarity and reduces unnecessary checks. * Refactor multiline_fill for improved offset logic Reworked the multiline_fill function to simplify and clarify the logic for generating multiple offset lines. The new implementation computes offsets more explicitly for odd and even cases, creates a fresh ClipperOffset for each band, and improves conversion between Clipper2 paths and polylines. This enhances maintainability and correctness of the multiline fill generation. * Quartercubic multiline * fillplanePath fix bounding box Co-Authored-By: Ian Bassi <12130714+ianalexis@users.noreply.github.com> * fillconcentric multiline Co-Authored-By: Ian Bassi <12130714+ianalexis@users.noreply.github.com> * Update FillBase.hpp * cleaning * Refactor multiline_fill to clean polylines and reuse offsetter Invalid polylines with less than two points are now removed before processing. The ClipperOffset object is created once and reused for each offset, improving efficiency and code clarity. trigger build * Optimize Filltrapezoidal Refactored the trapezoidal fill pattern generation to precompute base row templates and reuse them with vertical translation, reducing redundant computations and improving code clarity. This change enhances performance and maintainability by avoiding repeated construction of row patterns within loops. * Replace push_back with emplace_back for Polyline points Updated Polyline point insertion from push_back to emplace_back for efficiency and clarity. Also refactored row copying logic to avoid in-place modification, improving code readability and safety. * Update FillRectilinear.cpp * Reserve space for poliline points * Union not needed * Update FillRectilinear.cpp * unused functions * compactado Update FillRectilinear.cpp * Adjust minimum rows for better performance * Update FillRectilinear.cpp --------- Co-authored-by: Ian Bassi <12130714+ianalexis@users.noreply.github.com> Co-authored-by: discip <53649486+discip@users.noreply.github.com> Co-authored-by: Donovan Baarda <dbaarda@gmail.com> Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
216 lines
No EOL
7.5 KiB
C++
216 lines
No EOL
7.5 KiB
C++
#include "Clipper2Utils.hpp"
|
|
#include "libslic3r.h"
|
|
#include "clipper2/clipper.h"
|
|
|
|
namespace Slic3r {
|
|
|
|
//BBS: FIXME
|
|
Slic3r::Polylines Paths64_to_polylines(const Clipper2Lib::Paths64& in)
|
|
{
|
|
Slic3r::Polylines out;
|
|
out.reserve(in.size());
|
|
for (const Clipper2Lib::Path64& path64 : in) {
|
|
Slic3r::Points points;
|
|
points.reserve(path64.size());
|
|
for (const Clipper2Lib::Point64& point64 : path64)
|
|
points.emplace_back(std::move(Slic3r::Point(point64.x, point64.y)));
|
|
out.emplace_back(std::move(Slic3r::Polyline(points)));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
//BBS: FIXME
|
|
template <typename Container>
|
|
Clipper2Lib::Paths64 Slic3rPoints_to_Paths64(const Container& in)
|
|
{
|
|
Clipper2Lib::Paths64 out;
|
|
out.reserve(in.size());
|
|
for (const auto& item : in) {
|
|
Clipper2Lib::Path64 path;
|
|
path.reserve(item.size());
|
|
for (const Slic3r::Point& point : item.points)
|
|
path.emplace_back(std::move(Clipper2Lib::Point64(point.x(), point.y())));
|
|
out.emplace_back(std::move(path));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
Clipper2Lib::Paths64 Slic3rPolylines_to_Paths64(const Polylines& in)
|
|
{
|
|
return Slic3rPoints_to_Paths64(in);
|
|
}
|
|
|
|
Points Path64ToPoints(const Clipper2Lib::Path64& path64)
|
|
{
|
|
Points points;
|
|
points.reserve(path64.size());
|
|
for (const Clipper2Lib::Point64 &point64 : path64) points.emplace_back(std::move(Slic3r::Point(point64.x, point64.y)));
|
|
return points;
|
|
}
|
|
|
|
static ExPolygons PolyTreeToExPolygons(Clipper2Lib::PolyTree64 &&polytree)
|
|
{
|
|
struct Inner
|
|
{
|
|
static void PolyTreeToExPolygonsRecursive(Clipper2Lib::PolyTree64 &&polynode, ExPolygons *expolygons)
|
|
{
|
|
size_t cnt = expolygons->size();
|
|
expolygons->resize(cnt + 1);
|
|
(*expolygons)[cnt].contour.points = Path64ToPoints(polynode.Polygon());
|
|
|
|
(*expolygons)[cnt].holes.resize(polynode.Count());
|
|
for (int i = 0; i < polynode.Count(); ++i) {
|
|
(*expolygons)[cnt].holes[i].points = Path64ToPoints(polynode[i]->Polygon());
|
|
// Add outer polygons contained by (nested within) holes.
|
|
for (int j = 0; j < polynode[i]->Count(); ++j) PolyTreeToExPolygonsRecursive(std::move(*polynode[i]->Child(j)), expolygons);
|
|
}
|
|
}
|
|
|
|
static size_t PolyTreeCountExPolygons(const Clipper2Lib::PolyPath64& polynode)
|
|
{
|
|
size_t cnt = 1;
|
|
for (size_t i = 0; i < polynode.Count(); ++i) {
|
|
for (size_t j = 0; j < polynode.Child(i)->Count(); ++j) cnt += PolyTreeCountExPolygons(*polynode.Child(i)->Child(j));
|
|
}
|
|
return cnt;
|
|
}
|
|
};
|
|
|
|
ExPolygons retval;
|
|
size_t cnt = 0;
|
|
for (int i = 0; i < polytree.Count(); ++i) cnt += Inner::PolyTreeCountExPolygons(*polytree[i]);
|
|
retval.reserve(cnt);
|
|
for (int i = 0; i < polytree.Count(); ++i) Inner::PolyTreeToExPolygonsRecursive(std::move(*polytree[i]), &retval);
|
|
return retval;
|
|
}
|
|
|
|
void SimplifyPolyTree(const Clipper2Lib::PolyPath64 &polytree, double epsilon, Clipper2Lib::PolyPath64 &result)
|
|
{
|
|
for (const auto &child : polytree) {
|
|
Clipper2Lib::PolyPath64 *newchild = result.AddChild(Clipper2Lib::SimplifyPath(child->Polygon(), epsilon));
|
|
SimplifyPolyTree(*child, epsilon, *newchild);
|
|
}
|
|
}
|
|
|
|
Clipper2Lib::Paths64 Slic3rPolygons_to_Paths64(const Polygons &in)
|
|
{
|
|
Clipper2Lib::Paths64 out;
|
|
out.reserve(in.size());
|
|
for (const Polygon &poly : in) {
|
|
Clipper2Lib::Path64 path;
|
|
path.reserve(poly.points.size());
|
|
for (const Slic3r::Point &point : poly.points) path.emplace_back(std::move(Clipper2Lib::Point64(point.x(), point.y())));
|
|
out.emplace_back(std::move(path));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
Clipper2Lib::Paths64 Slic3rExPolygons_to_Paths64(const ExPolygons& in)
|
|
{
|
|
Clipper2Lib::Paths64 out;
|
|
out.reserve(in.size());
|
|
for (const ExPolygon& expolygon : in) {
|
|
for (size_t i = 0; i < expolygon.num_contours(); i++) {
|
|
const auto &poly = expolygon.contour_or_hole(i);
|
|
Clipper2Lib::Path64 path;
|
|
path.reserve(poly.points.size());
|
|
for (const Slic3r::Point &point : poly.points) path.emplace_back(std::move(Clipper2Lib::Point64(point.x(), point.y())));
|
|
out.emplace_back(std::move(path));
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
Polylines _clipper2_pl_open(Clipper2Lib::ClipType clipType, const Slic3r::Polylines& subject, const Slic3r::Polygons& clip)
|
|
{
|
|
Clipper2Lib::Clipper64 c;
|
|
c.AddOpenSubject(Slic3rPoints_to_Paths64(subject));
|
|
c.AddClip(Slic3rPoints_to_Paths64(clip));
|
|
|
|
Clipper2Lib::ClipType ct = clipType;
|
|
Clipper2Lib::FillRule fr = Clipper2Lib::FillRule::NonZero;
|
|
Clipper2Lib::Paths64 solution, solution_open;
|
|
c.Execute(ct, fr, solution, solution_open);
|
|
|
|
Slic3r::Polylines out;
|
|
out.reserve(solution.size() + solution_open.size());
|
|
polylines_append(out, std::move(Paths64_to_polylines(solution)));
|
|
polylines_append(out, std::move(Paths64_to_polylines(solution_open)));
|
|
|
|
return out;
|
|
}
|
|
|
|
Slic3r::Polylines intersection_pl_2(const Slic3r::Polylines& subject, const Slic3r::Polygons& clip)
|
|
{ return _clipper2_pl_open(Clipper2Lib::ClipType::Intersection, subject, clip); }
|
|
Slic3r::Polylines diff_pl_2(const Slic3r::Polylines& subject, const Slic3r::Polygons& clip)
|
|
{ return _clipper2_pl_open(Clipper2Lib::ClipType::Difference, subject, clip); }
|
|
|
|
ExPolygons union_ex_2(const Polygons& polygons)
|
|
{
|
|
Clipper2Lib::Clipper64 c;
|
|
c.AddSubject(Slic3rPolygons_to_Paths64(polygons));
|
|
|
|
Clipper2Lib::ClipType ct = Clipper2Lib::ClipType::Union;
|
|
Clipper2Lib::FillRule fr = Clipper2Lib::FillRule::NonZero;
|
|
Clipper2Lib::PolyTree64 solution;
|
|
c.Execute(ct, fr, solution);
|
|
|
|
ExPolygons results = PolyTreeToExPolygons(std::move(solution));
|
|
|
|
return results;
|
|
}
|
|
|
|
ExPolygons union_ex_2(const ExPolygons &expolygons)
|
|
{
|
|
Clipper2Lib::Clipper64 c;
|
|
c.AddSubject(Slic3rExPolygons_to_Paths64(expolygons));
|
|
|
|
Clipper2Lib::ClipType ct = Clipper2Lib::ClipType::Union;
|
|
Clipper2Lib::FillRule fr = Clipper2Lib::FillRule::NonZero;
|
|
Clipper2Lib::PolyTree64 solution;
|
|
c.Execute(ct, fr, solution);
|
|
|
|
ExPolygons results = PolyTreeToExPolygons(std::move(solution));
|
|
|
|
return results;
|
|
}
|
|
|
|
// 对 ExPolygons 进行偏移
|
|
ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta)
|
|
{
|
|
Clipper2Lib::Paths64 subject = Slic3rExPolygons_to_Paths64(expolygons);
|
|
Clipper2Lib::ClipperOffset offsetter;
|
|
offsetter.AddPaths(subject, Clipper2Lib::JoinType::Round, Clipper2Lib::EndType::Polygon);
|
|
Clipper2Lib::PolyPath64 polytree;
|
|
offsetter.Execute(delta, polytree);
|
|
ExPolygons results = PolyTreeToExPolygons(std::move(polytree));
|
|
|
|
return results;
|
|
}
|
|
|
|
ExPolygons offset2_ex_2(const ExPolygons& expolygons, double delta1, double delta2)
|
|
{
|
|
// 1st offset
|
|
Clipper2Lib::Paths64 subject = Slic3rExPolygons_to_Paths64(expolygons);
|
|
Clipper2Lib::ClipperOffset offsetter;
|
|
offsetter.AddPaths(subject, Clipper2Lib::JoinType::Round, Clipper2Lib::EndType::Polygon);
|
|
Clipper2Lib::PolyPath64 polytree;
|
|
offsetter.Execute(delta1, polytree);
|
|
|
|
// simplify the result
|
|
Clipper2Lib::PolyPath64 polytree2;
|
|
SimplifyPolyTree(polytree, SCALED_EPSILON, polytree2);
|
|
|
|
// 2nd offset
|
|
offsetter.Clear();
|
|
offsetter.AddPaths(Clipper2Lib::PolyTreeToPaths64(polytree2), Clipper2Lib::JoinType::Round, Clipper2Lib::EndType::Polygon);
|
|
polytree.Clear();
|
|
offsetter.Execute(delta2, polytree);
|
|
|
|
// convert back to expolygons
|
|
ExPolygons results = PolyTreeToExPolygons(std::move(polytree));
|
|
|
|
return results;
|
|
}
|
|
|
|
} |