OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
anonymous_namespace{NSVGUtils.cpp} Namespace Reference

Classes

struct  LinesPath
struct  DashesParam

Functions

bool is_line (const float *p, float precision=1e-4f)
LinesPath linearize_path (NSVGpath *first_path, const NSVGLineParams &param)
HealedExPolygons fill_to_expolygons (const LinesPath &lines_path, const NSVGshape &shape, const NSVGLineParams &param)
HealedExPolygons stroke_to_expolygons (const LinesPath &lines_path, const NSVGshape &shape, const NSVGLineParams &param)
Point::coord_type to_coor (float val, double scale)
bool need_flattening (float tessTol, const Vec2f &p1, const Vec2f &p2, const Vec2f &p3, const Vec2f &p4)
void flatten_cubic_bez (Points &points, float tessTol, const Vec2f &p1, const Vec2f &p2, const Vec2f &p3, const Vec2f &p4, int level)
 Convert cubic curve to lines Inspired by nanosvgrast.h function nsvgRasterize -> nsvg__flattenShape -> nsvg__flattenCubicBez https://github.com/memononen/nanosvg/blob/f0a3e1034dd22e2e87e5db22401e44998383124e/src/nanosvgrast.h#L335.
Polylines to_dashes (const Polyline &polyline, const DashesParam &param)

Class Documentation

◆ anonymous_namespace{NSVGUtils.cpp}::LinesPath

struct anonymous_namespace{NSVGUtils.cpp}::LinesPath
Collaboration diagram for anonymous_namespace{NSVGUtils.cpp}::LinesPath:
Class Members
Polygons polygons
Polylines polylines

Function Documentation

◆ fill_to_expolygons()

HealedExPolygons anonymous_namespace{NSVGUtils.cpp}::fill_to_expolygons ( const LinesPath & lines_path,
const NSVGshape & shape,
const NSVGLineParams & param )
390{
391 Polygons fill = lines_path.polygons; // copy
392
393 // close polyline to create polygon
394 polygons_append(fill, to_polygons(lines_path.polylines));
395 if (fill.empty())
396 return {};
397
398 // if (shape->fillRule == NSVGfillRule::NSVG_FILLRULE_NONZERO)
399 bool is_non_zero = true;
400 if (shape.fillRule == NSVGfillRule::NSVG_FILLRULE_EVENODD)
401 is_non_zero = false;
402
403 return Emboss::heal_polygons(fill, is_non_zero, param.max_heal_iteration);
404}
HealedExPolygons heal_polygons(const Polygons &shape, bool is_non_zero=true, unsigned max_iteration=10)
Fix duplicit points and self intersections in polygons. Also try to reduce amount of points and remov...
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22
Polygons to_polygons(const ExPolygon &src)
Definition ExPolygon.hpp:307
void polygons_append(Polygons &dst, const ExPolygon &src)
Definition ExPolygon.hpp:411
Polygons polygons
Definition NSVGUtils.cpp:29
Polylines polylines
Definition NSVGUtils.cpp:30
unsigned max_heal_iteration
Definition NSVGUtils.hpp:41

References Slic3r::Emboss::heal_polygons(), Slic3r::NSVGLineParams::max_heal_iteration, anonymous_namespace{NSVGUtils.cpp}::LinesPath::polygons, Slic3r::polygons_append(), anonymous_namespace{NSVGUtils.cpp}::LinesPath::polylines, and Slic3r::to_polygons().

Here is the call graph for this function:

◆ flatten_cubic_bez()

void anonymous_namespace{NSVGUtils.cpp}::flatten_cubic_bez ( Points & points,
float tessTol,
const Vec2f & p1,
const Vec2f & p2,
const Vec2f & p3,
const Vec2f & p4,
int level )

Convert cubic curve to lines Inspired by nanosvgrast.h function nsvgRasterize -> nsvg__flattenShape -> nsvg__flattenCubicBez https://github.com/memononen/nanosvg/blob/f0a3e1034dd22e2e87e5db22401e44998383124e/src/nanosvgrast.h#L335.

Parameters
polygonResult points
tessTolTesselation tolerance
p1Curve point
p2Curve point
p3Curve point
p4Curve point
levelActual depth of recursion
315{
316 if (!need_flattening(tessTol, p1, p2, p3, p4)) {
317 Point::coord_type x = static_cast<Point::coord_type>(std::round(p4.x()));
318 Point::coord_type y = static_cast<Point::coord_type>(std::round(p4.y()));
319 points.emplace_back(x, y);
320 return;
321 }
322
323 --level;
324 if (level == 0)
325 return;
326
327 Vec2f p12 = (p1 + p2) * 0.5f;
328 Vec2f p23 = (p2 + p3) * 0.5f;
329 Vec2f p34 = (p3 + p4) * 0.5f;
330 Vec2f p123 = (p12 + p23) * 0.5f;
331 Vec2f p234 = (p23 + p34) * 0.5f;
332 Vec2f p1234 = (p123 + p234) * 0.5f;
333 flatten_cubic_bez(points, tessTol, p1, p12, p123, p1234, level);
334 flatten_cubic_bez(points, tessTol, p1234, p234, p34, p4, level);
335}
coord_t coord_type
Definition Point.hpp:201
Eigen::Matrix< float, 2, 1, Eigen::DontAlign > Vec2f
Definition Point.hpp:64
bool need_flattening(float tessTol, const Vec2f &p1, const Vec2f &p2, const Vec2f &p3, const Vec2f &p4)
Definition NSVGUtils.cpp:269
void flatten_cubic_bez(Points &points, float tessTol, const Vec2f &p1, const Vec2f &p2, const Vec2f &p3, const Vec2f &p4, int level)
Convert cubic curve to lines Inspired by nanosvgrast.h function nsvgRasterize -> nsvg__flattenShape -...
Definition NSVGUtils.cpp:314

References flatten_cubic_bez(), and need_flattening().

Referenced by flatten_cubic_bez(), and linearize_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_line()

bool anonymous_namespace{NSVGUtils.cpp}::is_line ( const float * p,
float precision = 1e-4f )
287 {
288 //Vec2f p1(p[0], p[1]);
289 //Vec2f p2(p[2], p[3]);
290 //Vec2f p3(p[4], p[5]);
291 //Vec2f p4(p[6], p[7]);
292 float dx_3 = (p[6] - p[0]) / 3.f;
293 float dy_3 = (p[7] - p[1]) / 3.f;
294
295 return
296 is_approx(p[2], p[0] + dx_3, precision) &&
297 is_approx(p[4], p[6] - dx_3, precision) &&
298 is_approx(p[3], p[1] + dy_3, precision) &&
299 is_approx(p[5], p[7] - dy_3, precision);
300}
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:320

References Slic3r::is_approx().

Referenced by linearize_path(), and to_dashes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ linearize_path()

LinesPath anonymous_namespace{NSVGUtils.cpp}::linearize_path ( NSVGpath * first_path,
const NSVGLineParams & param )
338{
339 LinesPath result;
340 Polygons &polygons = result.polygons;
341 Polylines &polylines = result.polylines;
342
343 // multiple use of allocated memmory for points between paths
344 Points points;
345 for (NSVGpath *path = first_path; path != NULL; path = path->next) {
346 // Flatten path
347 Point::coord_type x = to_coor(path->pts[0], param.scale);
348 Point::coord_type y = to_coor(path->pts[1], param.scale);
349 points.emplace_back(x, y);
350 size_t path_size = (path->npts > 1) ? static_cast<size_t>(path->npts - 1) : 0;
351 for (size_t i = 0; i < path_size; i += 3) {
352 const float *p = &path->pts[i * 2];
353 if (is_line(p)) {
354 // point p4
355 Point::coord_type xx = to_coor(p[6], param.scale);
356 Point::coord_type yy = to_coor(p[7], param.scale);
357 points.emplace_back(xx, yy);
358 continue;
359 }
360 Vec2f p1(p[0], p[1]);
361 Vec2f p2(p[2], p[3]);
362 Vec2f p3(p[4], p[5]);
363 Vec2f p4(p[6], p[7]);
365 p1 * param.scale, p2 * param.scale, p3 * param.scale, p4 * param.scale,
366 param.max_level);
367 }
368 assert(!points.empty());
369 if (points.empty())
370 continue;
371
372 if (param.is_y_negative)
373 for (Point &p : points)
374 p.y() = -p.y();
375
376 if (path->closed) {
377 polygons.emplace_back(points);
378 } else {
379 polylines.emplace_back(points);
380 }
381 // prepare for new path - recycle alocated memory
382 points.clear();
383 }
384 remove_same_neighbor(polygons);
385 remove_same_neighbor(polylines);
386 return result;
387}
Definition Point.hpp:199
bool remove_same_neighbor(ExPolygons &expolygons)
Definition ExPolygon.cpp:496
std::vector< Polyline > Polylines
Definition Polyline.hpp:22
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73
bool is_line(const float *p, float precision=1e-4f)
Definition NSVGUtils.cpp:287
Point::coord_type to_coor(float val, double scale)
Definition NSVGUtils.cpp:267
double tesselation_tolerance
Definition NSVGUtils.hpp:25
int max_level
Definition NSVGUtils.hpp:28
bool is_y_negative
Definition NSVGUtils.hpp:35
double scale
Definition NSVGUtils.hpp:32

References flatten_cubic_bez(), is_line(), Slic3r::NSVGLineParams::is_y_negative, Slic3r::NSVGLineParams::max_level, anonymous_namespace{NSVGUtils.cpp}::LinesPath::polygons, anonymous_namespace{NSVGUtils.cpp}::LinesPath::polylines, Slic3r::remove_same_neighbor(), Slic3r::NSVGLineParams::scale, Slic3r::NSVGLineParams::tesselation_tolerance, and to_coor().

Here is the call graph for this function:

◆ need_flattening()

bool anonymous_namespace{NSVGUtils.cpp}::need_flattening ( float tessTol,
const Vec2f & p1,
const Vec2f & p2,
const Vec2f & p3,
const Vec2f & p4 )
269 {
270 // f .. first
271 // s .. second
272 auto det = [](const Vec2f &f, const Vec2f &s) {
273 return std::fabs(f.x() * s.y() - f.y() * s.x());
274 };
275
276 Vec2f pd = (p4 - p1);
277 Vec2f pd2 = (p2 - p4);
278 float d2 = det(pd2, pd);
279 Vec2f pd3 = (p3 - p4);
280 float d3 = det(pd3, pd);
281 float d23 = d2 + d3;
282
283 return (d23 * d23) >= tessTol * pd.squaredNorm();
284}
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124

References Slic3r::f().

Referenced by flatten_cubic_bez().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stroke_to_expolygons()

HealedExPolygons anonymous_namespace{NSVGUtils.cpp}::stroke_to_expolygons ( const LinesPath & lines_path,
const NSVGshape & shape,
const NSVGLineParams & param )
513{
514 // convert stroke to polygon
515 JoinType join_type = jtSquare;
516 switch (static_cast<NSVGlineJoin>(shape.strokeLineJoin)) {
517 case NSVGlineJoin::NSVG_JOIN_BEVEL: join_type = jtSquare; break;
518 case NSVGlineJoin::NSVG_JOIN_MITER: join_type = jtMiter; break;
519 case NSVGlineJoin::NSVG_JOIN_ROUND: join_type = jtRound; break;
520 }
521
522 double mitter = shape.miterLimit * param.scale;
523 if (join_type == jtRound) {
524 // mitter is used as ArcTolerance
525 // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
526 mitter = std::pow(param.tesselation_tolerance, 1/3.);
527 }
528 float stroke_width = static_cast<float>(shape.strokeWidth * param.scale);
529
530 EndType end_type = etOpenButt;
531 switch (static_cast<NSVGlineCap>(shape.strokeLineCap)) {
532 case NSVGlineCap::NSVG_CAP_BUTT: end_type = etOpenButt; break;
533 case NSVGlineCap::NSVG_CAP_ROUND: end_type = etOpenRound; break;
534 case NSVGlineCap::NSVG_CAP_SQUARE: end_type = etOpenSquare; break;
535 }
536
537 Polygons result;
538 if (shape.strokeDashCount > 0) {
539 DashesParam params(shape, param.scale);
540 Polylines dashes;
541 for (const Polyline &polyline : lines_path.polylines)
542 polylines_append(dashes, to_dashes(polyline, params));
543 for (const Polygon &polygon : lines_path.polygons)
544 polylines_append(dashes, to_dashes(to_polyline(polygon), params));
545 result = offset(dashes, stroke_width / 2, join_type, mitter, end_type);
546 } else {
547 result = contour_to_polygons(lines_path.polygons, stroke_width, join_type, mitter);
548 polygons_append(result, offset(lines_path.polylines, stroke_width / 2, join_type, mitter, end_type));
549 }
550
551 bool is_non_zero = true;
552 return Emboss::heal_polygons(result, is_non_zero, param.max_heal_iteration);
553}
Definition Polygon.hpp:31
Definition Polyline.hpp:25
JoinType
Definition ClipperUtils.hpp:21
@ jtRound
Definition ClipperUtils.hpp:21
@ jtSquare
Definition ClipperUtils.hpp:21
@ jtMiter
Definition ClipperUtils.hpp:21
void polylines_append(Polylines &dst, const Polylines &src)
Definition Polyline.hpp:220
EndType
Definition ClipperUtils.hpp:22
@ etOpenSquare
Definition ClipperUtils.hpp:22
@ etOpenButt
Definition ClipperUtils.hpp:22
@ etOpenRound
Definition ClipperUtils.hpp:22
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582
Polygons contour_to_polygons(const Polygon &polygon, const float line_width, JoinType join_type, double miter_limit)
Definition ClipperUtils.cpp:623
static Polyline to_polyline(const std::vector< TravelPoint > &travel)
Definition AvoidCrossingPerimeters.cpp:370
Polylines to_dashes(const Polyline &polyline, const DashesParam &param)
Definition NSVGUtils.cpp:451

References Slic3r::contour_to_polygons(), Slic3r::etOpenButt, Slic3r::etOpenRound, Slic3r::etOpenSquare, Slic3r::Emboss::heal_polygons(), Slic3r::jtMiter, Slic3r::jtRound, Slic3r::jtSquare, Slic3r::NSVGLineParams::max_heal_iteration, Slic3r::offset(), anonymous_namespace{NSVGUtils.cpp}::LinesPath::polygons, Slic3r::polygons_append(), anonymous_namespace{NSVGUtils.cpp}::LinesPath::polylines, Slic3r::polylines_append(), Slic3r::NSVGLineParams::scale, Slic3r::NSVGLineParams::tesselation_tolerance, to_dashes(), and Slic3r::to_polyline().

Here is the call graph for this function:

◆ to_coor()

Point::coord_type anonymous_namespace{NSVGUtils.cpp}::to_coor ( float val,
double scale )
267{ return static_cast<Point::coord_type>(std::round(val * scale)); }
int scale(const int val)
Definition WipeTowerDialog.cpp:58

References scale().

Referenced by linearize_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ to_dashes()

Polylines anonymous_namespace{NSVGUtils.cpp}::to_dashes ( const Polyline & polyline,
const DashesParam & param )
452{
453 Polylines dashes;
454 Polyline dash; // cache for one dash in dashed line
455 Point prev_point;
456
457 bool is_line = param.is_line;
458 unsigned char dash_index = param.dash_index;
459 float dash_length = param.dash_length; // current rest of dash distance
460 for (const Point &point : polyline.points) {
461 if (&point == &polyline.points.front()) {
462 // is first point
463 prev_point = point; // copy
464 continue;
465 }
466
467 Point diff = point - prev_point;
468 float line_segment_length = diff.cast<float>().norm();
469 while (dash_length < line_segment_length) {
470 // Calculate intermediate point
471 float d = dash_length / line_segment_length;
472 Point move_point = diff * d;
473 Point intermediate = prev_point + move_point;
474
475 // add Dash in stroke
476 if (is_line) {
477 if (dash.empty()) {
478 dashes.emplace_back(Points{prev_point, intermediate});
479 } else {
480 dash.append(prev_point);
481 dash.append(intermediate);
482 dashes.push_back(dash);
483 dash.clear();
484 }
485 }
486
487 diff -= move_point;
488 line_segment_length -= dash_length;
489 prev_point = intermediate;
490
491 // Advance dash pattern
492 is_line = !is_line;
493 dash_index = (dash_index + 1) % param.dash_count;
494 dash_length = param.dash_array[dash_index];
495 }
496
497 if (is_line)
498 dash.append(prev_point);
499 dash_length -= line_segment_length;
500 prev_point = point; // copy
501 }
502
503 // add last dash
504 if (is_line){
505 assert(!dash.empty());
506 dash.append(prev_point); // prev_point == polyline.points.back()
507 dashes.push_back(dash);
508 }
509 return dashes;
510}
Points points
Definition MultiPoint.hpp:22
bool empty() const
Definition MultiPoint.hpp:51
void clear()
Definition Polyline.hpp:118
void append(const Point &point)
Definition Polyline.hpp:65
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:731
unsigned char dash_index
Definition NSVGUtils.cpp:415
std::array< float, max_dash_array_size > dash_array
Definition NSVGUtils.cpp:417
unsigned char dash_count
Definition NSVGUtils.cpp:418
float dash_length
Definition NSVGUtils.cpp:408
bool is_line
Definition NSVGUtils.cpp:412

References Slic3r::Polyline::append(), Slic3r::Polyline::clear(), anonymous_namespace{NSVGUtils.cpp}::DashesParam::dash_array, anonymous_namespace{NSVGUtils.cpp}::DashesParam::dash_count, anonymous_namespace{NSVGUtils.cpp}::DashesParam::dash_index, anonymous_namespace{NSVGUtils.cpp}::DashesParam::dash_length, Slic3r::diff(), Slic3r::MultiPoint::empty(), anonymous_namespace{NSVGUtils.cpp}::DashesParam::is_line, is_line(), and Slic3r::MultiPoint::points.

Referenced by stroke_to_expolygons().

Here is the call graph for this function:
Here is the caller graph for this function: