mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-14 08:11:50 +08:00
73 lines
2.5 KiB
C++
73 lines
2.5 KiB
C++
#include "NSVGUtils.hpp"
|
|
|
|
using namespace Slic3r;
|
|
|
|
void NSVGUtils::flatten_cubic_bez(Polygon &polygon,
|
|
float tessTol,
|
|
Vec2f p1,
|
|
Vec2f p2,
|
|
Vec2f p3,
|
|
Vec2f p4,
|
|
int level)
|
|
{
|
|
Vec2f p12 = (p1 + p2) * 0.5f;
|
|
Vec2f p23 = (p2 + p3) * 0.5f;
|
|
Vec2f p34 = (p3 + p4) * 0.5f;
|
|
Vec2f p123 = (p12 + p23) * 0.5f;
|
|
|
|
Vec2f pd = p4 - p1;
|
|
Vec2f pd2 = p2 - p4;
|
|
float d2 = std::abs(pd2.x() * pd.y() - pd2.y() * pd.x());
|
|
Vec2f pd3 = p3 - p4;
|
|
float d3 = std::abs(pd3.x() * pd.y() - pd3.y() * pd.x());
|
|
float d23 = d2 + d3;
|
|
|
|
if ((d23 * d23) < tessTol * (pd.x() * pd.x() + pd.y() * pd.y())) {
|
|
polygon.points.emplace_back(p4.x(), p4.y());
|
|
return;
|
|
}
|
|
|
|
--level;
|
|
if (level == 0) return;
|
|
Vec2f p234 = (p23 + p34) * 0.5f;
|
|
Vec2f p1234 = (p123 + p234) * 0.5f;
|
|
flatten_cubic_bez(polygon, tessTol, p1, p12, p123, p1234, level);
|
|
flatten_cubic_bez(polygon, tessTol, p1234, p234, p34, p4, level);
|
|
}
|
|
|
|
ExPolygons NSVGUtils::to_ExPolygons(NSVGimage *image,
|
|
float tessTol,
|
|
int max_level)
|
|
{
|
|
Polygons polygons;
|
|
for (NSVGshape *shape = image->shapes; shape != NULL;
|
|
shape = shape->next) {
|
|
if (!(shape->flags & NSVG_FLAGS_VISIBLE)) continue;
|
|
Slic3r::Polygon polygon;
|
|
if (shape->fill.type != NSVG_PAINT_NONE) {
|
|
for (NSVGpath *path = shape->paths; path != NULL;
|
|
path = path->next) {
|
|
// Flatten path
|
|
polygon.points.emplace_back(path->pts[0], path->pts[1]);
|
|
for (size_t i = 0; i < path->npts - 1; i += 3) {
|
|
float *p = &path->pts[i * 2];
|
|
Vec2f p1(p[0], p[1]), p2(p[2], p[3]), p3(p[4], p[5]),
|
|
p4(p[6], p[7]);
|
|
flatten_cubic_bez(polygon, tessTol, p1, p2, p3, p4,
|
|
max_level);
|
|
}
|
|
if (path->closed) {
|
|
polygons.push_back(polygon);
|
|
polygon = Slic3r::Polygon();
|
|
}
|
|
}
|
|
}
|
|
polygons.push_back(polygon);
|
|
}
|
|
|
|
// Fix Y axis
|
|
for (Polygon &polygon : polygons)
|
|
for (Point &p : polygon.points) p.y() *= -1;
|
|
|
|
return Slic3r::union_ex(polygons);
|
|
} |