Files
OrcaSlicer/src/libslic3r/ClipperZUtils.cpp
T
Hanif Koh 65bf48fcdb Re-Add libslic3r Includes After the Clipper2 2.0.1 Migration
Rebasing onto main took main's version of the files the Clipper2 migration rewrote, so their added includes are restored here, along with includes for main's new code. Clipper2's individual headers are now ignored by clang-tidy: they only build the Z variant through clipper2_z.hpp, which defines USINGZ first, so including clipper.core.h and the like directly broke ClipperZUtils.cpp.
2026-10-03 13:51:23 +08:00

80 lines
2.7 KiB
C++

#include "ClipperZUtils.hpp"
#include "ClipperUtils.hpp"
#include <clipper2/clipper2_z.hpp>
#include <cstddef>
namespace Slic3r {
namespace ClipperZUtils {
namespace C2 = Clipper2Lib_Z;
static C2::Paths64 to_paths64(const ZPaths &paths)
{
C2::Paths64 out;
out.reserve(paths.size());
for (const ZPath &path : paths) {
C2::Path64 &dst = out.emplace_back();
dst.reserve(path.size());
for (const ZPoint &pt : path)
dst.emplace_back(pt.x(), pt.y(), pt.z());
}
return out;
}
static void append_zpaths(const C2::Paths64 &paths, ZPaths &out)
{
out.reserve(out.size() + paths.size());
for (const C2::Path64 &path : paths) {
ZPath &dst = out.emplace_back();
dst.reserve(path.size());
for (const C2::Point64 &pt : path)
dst.emplace_back(pt.x, pt.y, pt.z);
}
}
double area(const ZPath &path)
{
const size_t size = path.size();
if (size < 3)
return 0.;
double a = 0.;
for (size_t i = 0, j = size - 1; i < size; j = i ++)
a += (double(path[j].x()) + path[i].x()) * (double(path[j].y()) - path[i].y());
return -a * 0.5;
}
ZPaths clip_zpaths(ClipType clip_type, const ZPaths &subject, bool subject_open, const ZPaths &clip, const ZFillCallback &zfill, bool preserve_collinear)
{
C2::Clipper64 clipper;
clipper.PreserveCollinear(preserve_collinear);
if (zfill)
clipper.SetZCallback([&zfill](const C2::Point64 &e1bot, const C2::Point64 &e1top, const C2::Point64 &e2bot, const C2::Point64 &e2top, C2::Point64 &pt) {
// Clipper2 already copied Z from a coincident input vertex.
auto coincident = [&pt](const C2::Point64 &p) { return p.x == pt.x && p.y == pt.y; };
if (coincident(e1bot) || coincident(e1top) || coincident(e2bot) || coincident(e2top))
return;
ZPoint zpt(pt.x, pt.y, pt.z);
zfill(ZPoint(e1bot.x, e1bot.y, e1bot.z), ZPoint(e1top.x, e1top.y, e1top.z),
ZPoint(e2bot.x, e2bot.y, e2bot.z), ZPoint(e2top.x, e2top.y, e2top.z), zpt);
pt.z = zpt.z();
});
if (subject_open)
clipper.AddOpenSubject(to_paths64(subject));
else
clipper.AddSubject(to_paths64(subject));
clipper.AddClip(to_paths64(clip));
const C2::ClipType type = clip_type == ctIntersection ? C2::ClipType::Intersection :
clip_type == ctUnion ? C2::ClipType::Union :
clip_type == ctDifference ? C2::ClipType::Difference : C2::ClipType::Xor;
C2::Paths64 closed, open;
clipper.Execute(type, C2::FillRule::NonZero, closed, open);
ZPaths out;
append_zpaths(closed, out);
append_zpaths(open, out);
return out;
}
} // namespace ClipperZUtils
} // namespace Slic3r